I want to turn ON and OFF an LED with one button (micropython raspberry pi pico) - micropython

Guys Hi could you please help me with my project:
I want to turn on an LED with 2 modes:
1-with button one it should starts and after 5 second it should tun off
2-with button two, it should turn on and stays ON and then if I push Button 2 I want it to be turned off.
here is my code, I know I should compare different states but I don't understand it, I can use another button, but I like to learn how to use memory.
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
def func(pin):
if button2.value() == 1:
White_LED.on()
while True:
button2.irq(func)
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
I could manage o solve it with two functions now, but the problem is that the button2 won't react as fast as it should and I have to push it couple of times to turn the LED, ON and OFF
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
Blue_LED = Pin(16,Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
def func(pin):
if button2.value() == 1 & White_LED.value()== 0:
White_LED.on()
def func2(pin):
if button2.value() == 1 & White_LED.value()== 1:
White_LED.off()
while True:
button2.irq(func)
button2.irq(func2)
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
I did this and it seems it's working:
from machine import Pin, Timer
import time
White_LED = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(13, Pin.IN, Pin.PULL_DOWN)
while True:
if button1.value() == 1:
White_LED.on()
time.sleep(5)
White_LED.off()
elif button2.value() == 1:
if White_LED.value()==0:
time.sleep(2)
White_LED.on()
else:
time.sleep(2)
White_LED.off()

The way you've written your code, you effectively have your while loop fighting your IRQ routines. If you just want the two buttons to act like toggle switches, the easiest solution is probably something like this:
from machine import Pin
LED = Pin(2, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_UP)
button2 = Pin(12, Pin.IN, Pin.PULL_UP)
while True:
if LED() and not button1():
print("ON")
LED(0)
elif not LED() and not button2():
print("OFF")
LED(1)
I've tested this code on Wemos D1 Mini running micropython v1.18.
Note that I've configured the buttons as Pin.PULL_UP, and the
switches on my board are connected to ground (so pressing a switch
brings the corresponding pin to logic 0).

Related

Second button is not working Raspberry pi pico

I'm new in micropython and I'm following the book about Raspberry pi pico. And I just wanted to know, how can I just make led ON if button1 or button2 are pressed.
Here is my code, and only the first button works, I checked, both buttons are not broken, but the second only shows the value 0 in this code.
from machine import Pin
led = Pin(15, Pin.OUT)
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(16, Pin.IN, Pin.PULL_DOWN)
while True:
if button1.value() == 1 or button2.value() == 1:
led.value(0)
elif button1.value() == 0 or button2.value() == 1:
led.value(1)
Try:
while True:
if button1.value() or button2.value():
led.value(1)
else:
led.value(0)

Does GPIO.IN need to be linked to GPIO.OUT in RPi.GPIO in order for it to work properly?

I was writing code on an raspbian emulator with GPIO. I am able to get it to work, but for some reason when I change the order of GPIO.HIGH and the print statement in the conditionals, it does not run properly and stops after the first click. Anyone know if this is an issue with the emulator or just a property of raspberry pi and hooking it up to hardware? It also does not work at all if I do not link the GPIO.IN with a GPIO.OUT.
this gif shows what happens when I change order or remove - It turns on the first time, but it does not turn off or on again after that. It for some reason breaks it out of the while loop.
Here is the code I am using:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
import time
#initialise a previous input variable to 0 (assume button not pressed last)
prev_input = 0
prev_input1 = 0
inputs = [11, 13, 15]
outputs = [3, 5, 7]
GPIO.setup(inputs, GPIO.IN)
GPIO.setup(outputs, GPIO.OUT)
secs = 0
def main():
while True:
button_press(15, 7)
timer = add_secs(11, 5, 2)
#print(timer)
def button_press(button1, button2):
#take a reading
global prev_input
inputa = GPIO.input(button1)
#if the last reading was low and this one high, print
if ((not prev_input) and inputa):
print("Light on")
GPIO.output(button2, GPIO.HIGH) #code does not work if I remove/reorder this statement
if((not inputa) and prev_input):
print("Light off")
GPIO.output(button2, GPIO.LOW) #code does not work if I remove/reorder this statement
#update previous input
prev_input = inputa
#slight pause to debounce
time.sleep(0.05)
def add_secs(button1, button2, num):
global prev_input1
secs = 0
inputa = GPIO.input(button1)
if((not prev_input1) and inputa):
secs = num
print(secs)
GPIO.output(button2, GPIO.LOW) #code does not work if I remove/reorder this statement
prev_input1 = inputa
time.sleep(0.05)
return secs
main()
I contacted the developer of the emulator and he let me know there was an issue with the emulator that is now resolved.
The code runs properly after clearing the browsing data in chrome and re-running the program.

Using DS2408 with Raspberry Pi GPIO 4 1wire linux driver

I have a Raspberry Pi B+ with the latest raspbian.
I activated 1wire support through interface options in raspi-config command and I connected my DS2408 chip on to the GPIO 4.
When I try to check for the list of devices, they all show up
ls -la /sys/bus/w1/devices/
when I try to cat their output or status I receive ?.
when I try to write on the output file, the nothing happens.
I have two questions:
Is there an easier software interface to communicate with the DS2408? There is a lot of documentation for reading temperature sensor data but DS2408 does not work like that.
I tried with a 1wire USB dongle and OWFS which works, but is there a possibility to make the GPIO 4 as the bus master for OWFS and communicate using the OWFS software interface?
answer to any one of these questions would solve my problem of talking to DS2408 connected to GPIO 4 of a RPI B+
Actually I have managed to operate DS2408 with Raspberry Pi 4 but I had really tough time getting it to work. First of all it had to be connected properly: RSTZ through 10k resistor to Vcc, I/O pin to GPIO4 and GPIO4 to 3V3 through 4,7k resistor.
After that I was able to read and write using "echo -n -e '\x02' > output", where output was in /sys/bus/w1/devices/29-...
I implemented my 345 nodes with a 23 1wire bus.
The idea was to simplify cost by using the 1wire GPIO on the RPi but the implementation was limited or I wasn't able to easily find the DS2408 driver implementation on the 1wire interface from RPi.
So went down this path of having a dongle per RPi to drive the 1wire using OWFS.
to answer my own question:
the 1wire implementation in RPi is limited.
USB dongle with OWFS is the only way to drive DS2408. If it is not possible, you would have to write your own extension.
The DS2408 works well with the Raspberry Pi using 1-wire, I am using a 8 port relay from http://denkovi.com.
To turn a relay on all you have to do is set the correct bit in the "/sys/bus/w1/devices/29-xxxxx/output" file, however to ensure you don't change any of the other relays it is best to read "/sys/bus/w1/devices/29-xxxx/state" and OR or XOR to turn a relay on or off.
Here is a VERY basic python script (I am by no means a programmer):
#!/usr/bin/python
import sys
from time import sleep
readfile = "/sys/bus/w1/devices/29-xxxxx/state"
writefile = "/sys/bus/w1/devices/29-xxxxx/output"
def getTheState():
try:
f = open(readfile, 'rb')
while True:
binarycontent = f.read(-1)
if not binarycontent:
break
mynum = int.from_bytes(binarycontent,byteorder=sys.byteorder)
f.close()
except IOError:
print('Error While Opening the file!')
return(mynum)
def turnOnRelay(theRelay,theState):
theTag = theRelay
# Turn On Relay
if theTag == 1 :
tagMask = 0b11111110
elif theTag == 2 :
tagMask = 0b11111101
elif theTag == 3 :
tagMask = 0b11111011
elif theTag == 4 :
tagMask = 0b11110111
elif theTag == 5 :
tagMask = 0b11101111
elif theTag == 6 :
tagMask = 0b11011111
elif theTag == 7 :
tagMask = 0b10111111
elif theTag == 8 :
tagMask = 0b01111111
else:
print("Error")
theNewState = theState & tagMask
print("theNewState",theNewState)
return theNewState
def turnOffRelay(theRelay,theState):
theTag = theRelay
# Turn Off Relay
if theTag == 1 :
tagMask = 0b00000001
elif theTag == 2 :
tagMask = 0b00000010
elif theTag == 3 :
tagMask = 0b00000100
elif theTag == 4 :
tagMask = 0b00001000
elif theTag == 5 :
tagMask = 0b00010000
elif theTag == 6 :
tagMask = 0b00100000
elif theTag == 7 :
tagMask = 0b01000000
elif theTag == 8 :
tagMask = 0b10000000
else:
print("Error")
theNewState = theState ^ tagMask
print("theNewState",theNewState)
return theNewState
def updateTheState(theNewState):
try:
newFileBytes = [theNewState]
newFile = open(writefile, "wb")
# write to file
for byte in newFileBytes:
newFile.write(byte.to_bytes(1, byteorder='big'))
except:
print('Error While Opening the file!')
def main():
print("turn relay 1 on")
x = getTheState()
y = turnOnRelay(1,x)
updateTheState(y)
sleep(5)
print("turn relay 1 off")
x = getTheState()
y = turnOffRelay(1,x)
updateTheState(y)
if __name__ == '__main__':
main()
Good luck hope this helps.
j.

I am trying to create cookie clicker in python. I have implemented an autoclicker, however, each time I click it adds another autoclicker

I am fairly new to python and I have challenged myself to create a cookie clicker like game using python and Tkinter. I have just implemented an autoclicker but I am having an issue where each time I click, another autoclicker is added.
I want it so that the user can continue to click, but when the auto clicker is activated, it will automatically add 1 click per second.
I have tried puting window.after(1000, nClick) on different lines as well as adjusting the value. I have tried making new functions but I just can't seem to get it working.
import sys
import random
import tkinter
import time
global counter
counter = 0
autoclicker = counter + 1
def nClick():
global counter
global autoclicker
counter += 1
mButton1.config(text = counter)
print(counter)
if counter >= 10:
autoclicker
window.after(1000, nClick)
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
# pack is used to show the object in the window
mButton1 = tkinter.Button(text = counter, command = nClick, fg = "darkgreen", bg = "white")
mButton1.pack()
mButton1.config(font=("Courier", 44))
window.mainloop()
#input('Press ENTER to exit')
I expect the counter to automatically + 1 to counter after 10 clicks. It does this until the user clicks again where it automatically adds the click to the autoclicker
You need to separate out the things "user clicks to add a cookie", "autoclicker adds a cookie", and "turn autoclicker on/off", so there are clear places where those things happen. e.g.
import sys
import random
import tkinter
import time
global counter
counter = 0
autoclicker_enabled = False
# autoclicker gets its own function to call,
# which updates the counter,
# and calls itself
def autoClick():
global counter
counter += 1
mButton1.config(text = counter)
window.after(1000, autoClick)
def nClick():
global counter
global autoclicker_enabled
counter += 1
mButton1.config(text = counter)
print(counter)
if counter >= 10:
# autoclicker_enabled is a toggle,
# so autoclicker can only be enabled once.
# It starts the autoClick self-loop,
# and then sets itself so that won't happen again.
if not autoclicker_enabled:
window.after(1000, autoClick)
autoclicker_enabled = True
window = tkinter.Tk()
# to rename the title of the window
window.title("GUI")
# pack is used to show the object in the window
mButton1 = tkinter.Button(text = counter, command = nClick, fg = "darkgreen", bg = "white")
mButton1.pack()
mButton1.config(font=("Courier", 44))
window.mainloop()
You can then see that the autoClick function does not print the text as well, and that the counter increase and button text change code is repeated, and maybe move that out to its own function, which both clicks use..

Raspberry Pi PWM control becomes affected when I combine it with FLASK

Im trying to implement a control using Raspberry Pi's PWM. I had success controlling the intensity of a LED with the following code:
# Pin Definitons:
pwmPin = 18 # Broadcom pin 18 (P1 pin 12)
# Pin Setup:
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme
GPIO.setup(pwmPin, GPIO.OUT) # PWM pin set as output
pwm = GPIO.PWM(pwmPin, 50) # Initialize PWM on pwmPin 100Hz frequency
# Initial state for LEDs:
pwm.start(10)
try:
while 1:
cycle = raw_input("Introduce Duty Cycle")
dc = int(cycle)
pwm.ChangeDutyCycle(dc)
except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly:
pwm.stop() # stop PWM
GPIO.cleanup() # cleanup all GPIO
Then I wanted to control the LED brightness through a web page. For that I used FLASK and the previous code. When I set the Duty Cycle from the web page the LED brightness change accordingly but it fluctuates randomly.
It's a strange behavior and I dont know why it is happening. Right here the code implemented on FLASK:
# Pin Definitons:
pwmPin = 18 # Broadcom pin 18 (P1 pin 12)
# Pin Setup:
GPIO.setmode(GPIO.BCM) # Broadcom pin-numbering scheme
GPIO.setup(pwmPin, GPIO.OUT) # PWM pin set as output
pwm = GPIO.PWM(pwmPin, 50) # Initialize PWM on pwmPin 100Hz frequency
# Initial state for LEDs:
pwm.start(10)
app = Flask(__name__)
#app.route('/')
def index():
return render_template('motor.html')
#app.route('/motor', methods=['POST'])
def motor():
dc = int(request.form['valor'])
pwm.ChangeDutyCycle(dc)
return redirect(url_for('index'))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=81, debug=True)
pwm.stop() # stop PWM
GPIO.cleanup() # cleanup all GPIO