I have made the connections in my board where I read the state of a reed switch. When the magnet nearby it shows "0" and I store the data at the "x" variable.
I'm using this to read the state of a fridge door so I can control some relays when the door is open (0) and then turn it off when closed (1).
When I use a while loop, I get the script running but it keeps counting when the variable is 1. I need this script to count when the door opens, (one) closes, and opens again (two).
Here is the code so far with the while loop.
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BOARD)
inPin=15
outPin=12
GPIO.setup(inPin,GPIO.IN)
GPIO.setup(outPin,GPIO.OUT)
counter = 0
while True:
x = GPIO.input(inPin)
previousValue = 0
print(x)
if x==1:
GPIO.output(outPin,GPIO.LOW)
if x==0:
GPIO.output(outPin,GPIO.HIGH)
if x == 1 and previousValue == 0:
counter += 1
print(counter)
You could change the previous value
if x == 1 and previousValue == 0:
counter += 1
print(counter)
previousValue == 1
elif x == 0 and previousValue == 1:
previousValue == 0
Related
I'm trying to figure out how I can solve this issue. I have a Raspberry Pi that is set up with a breadboard that consists of:
1 RGB light
2 buttons (left and right)
1 OLED screen
Each component works and I can run each one. What I'm trying to do is write a script that will allow me to select the "mode" with the left button (everything off vs lights vs screen on).
When a mode is selected, the right button then allows me to select between options within that mode. Below is the code as I have it:
def off():
lights = [red,green,blue]
for light in lights:
light.off()
def lightSelector():
off()
number = 0
while number < 5:
if rightButton.is_pressed:
if number == 0:
off()
red.on()
sleep(1)
number += 1
elif number == 1:
off()
green.on()
sleep(1)
number += 1
elif number == 2:
off()
blue.on()
sleep(1)
number += 1
elif number == 3:
off()
row()
sleep(1)
number+= 1
else:
number = 0
def picture():
image = Image.open('grant.jpeg')
image_r = image.resize((width,height), Image.BICUBIC)
image_bw = image_r.convert("1")
for x in range(width):
for y in range(height):
oled.pixel(x,y,bool(int(image_bw.getpixel((x,y)))))
oled.show()
def oledOff():
oled.fill(0)
oled.show()
def buttons():
x = 0
y = 0
while y is 0:
print('x = ' , x)
print('y = ' , y)
if leftButton.is_pressed:
if x == 0 :
oledOff()
off()
sleep(0.5)
x += 1
elif x == 1:
oledOff()
off()
lightSelector()
sleep(0.5)
x += 1
elif x == 2:
oledOff()
off()
picture()
sleep(0.5)
x += 1
else:
x = 0
oledOff()
off()
buttons()
The idea is that the buttons() function is the main overall function and will call the others as needed. My issue is that once I get to y == 1, or the lightSelector() function, it no longer registers that the leftButton is being pressed and won't switch to the next mode and I'm stuck in the lightSelector() function.
I know at baseline I can spell out lightSelector within the buttons function instead of calling another function but I'm trying to not be as verbose. I don't have any experience with threading or multprocessing and looked into it but couldn't see how that would help.
I got these this board Pyboard D-series which has internal LED diode with three different colours.
My goal is to make it change the LED colour on button press so basically if u press for the first time, red goes red, second time led goes green, third time led goes blue and at the fourth time I would love it to ("reset") and go back to red.
I tried making this fucntion based on stuff I found online, but it doest seem to be working.
I am new to IoT and micropython so I might be missing something important, but have no clue what.
Thanks for any advice
from pyb import Switch
from pyb import LED
led_R = LED(1)
led_G = LED(2)
led_B = LED(3)
# 1=red, 2=green, 3=blue
sw = pyb.Switch()
def cycle():
counter = 0
buttonState = ''
buttonState = sw.value()
print(buttonState)
if buttonState == True:
counter = counter + 1
print(counter)
elif counter == 0:
led_R.off()
led_G.off()
led_B.off()
elif counter == 1:
led_R.on()
led_G.off()
led_B.off()
elif counter == 2:
led_R.off()
led_G.on()
led_B.off()
elif counter == 3:
led_R.off()
led_G.off()
led_B.on()
else:
counter = 0
sw.callback(cycle())
Your callback cycle is called when button state transitions from off to on
In the callback sw.value() will always evalluate into true so it does not make sense to check it.
your counter should be initialized outside of callback
from pyb import Switch
from pyb import LED
led_R = LED(1)
led_G = LED(2)
led_B = LED(3)
# 1=red, 2=green, 3=blue
sw = pyb.Switch()
counter = 0
def cycle():
counter = counter + 1
if counter == 4:
counter = 0
print(counter)
if counter == 0:
led_R.off()
led_G.off()
led_B.off()
elif counter == 1:
led_R.on()
led_G.off()
led_B.off()
elif counter == 2:
led_R.off()
led_G.on()
led_B.off()
elif counter == 3:
led_R.off()
led_G.off()
led_B.on()
sw.callback(cycle())
I try to loop inside loop and when starts second loop, first stops instantly. I need to check endless if RELE1 is True and I need to print for example 'alarm' only once, because of that I loop second time to check is alarm 0 or 1. Here is my code:
while True:
if (GPIO.input(RELE1) == True):
print('3.3')
GPIO.setup(RELE360, GPIO.OUT)
alarm = 0
while 1:
if (GPIO.input(RELE0) == True):
alarm += 1
if(alarm == 1 ):
print('alarm')
else:
alarm = 0
else:
print('0')
GPIO.setup(RELE360, GPIO.IN)
sleep(1);
You have an infinite loop. This will never terminate:
while True:
if (GPIO.input(RELE1) == True):
print('3.3')
GPIO.setup(RELE360, GPIO.OUT)
alarm = 0
while 1:
if (GPIO.input(RELE0) == True):
alarm += 1
if(alarm == 1 ):
print('alarm')
else:
alarm = 0
# -- you will never escape this loop! --
else:
print('0')
GPIO.setup(RELE360, GPIO.IN)
sleep(1);
You can either just remove the loop, or break to escape it.
while True:
if some_condition:
break # this will exit the loop
Alternatively, you can just roll your second loop into the first; from looking at your code, it seems like you could do this:
alarm = 0
while True:
if (GPIO.input(RELE1) == True):
print('3.3')
GPIO.setup(RELE360, GPIO.OUT)
if (GPIO.input(RELE0) == True):
alarm += 1
if(alarm == 1 ):
print('alarm')
else:
print('0')
GPIO.setup(RELE360, GPIO.IN)
sleep(1);
this is the main code:
import MainMod
print("Welcome!")
print("Note: In this games you use wasd+enter to move!\nYou press 1 key and then enter,if you press multiple kets it wont work.\nYou will always move by 5 meters.")
CurrentRoom = 1
#Limits work this way!1st and 2nd number are X values(1st is <---- limit,2nd is ---> limit)
#3rd and 4th are y values(1st is v limit,2nd is ^ limit)
# X and Y are coordinates; 0,0 is the starting point of every room
while True:
if CurrentRoom ==1:
print("This is room 1")
MainMod.roomlimits = [-15 , 15, -15 , 15]
MainMod.doorloc1 = [-15,10,15]
MainMod.doorloc2 = [15,-2,2]
while CurrentRoom == 1:
MainMod.MainLel()
if MainMod.door1 == 1:
print("DAMN SON")
CurrentRoom = 2
break
elif MainMod.door2 == 1:
print("Plz no")
CurrentRoom = 3
break
while CurrentRoom == 2:
MainMod.MainLel()
and this is the MainMod module is :
x = 0
y = 0
roomlimits = 0
doorloc1=0
doorloc2=0
door1 = 0
door2 = 0
direct = 0
def MainLel():
global direct
movementinput()
movement(direct)
doorcheck()
def movement(dir):
global x,y,roomlimits,door1,door2,doorloc1,doorloc2
if dir == "w":
y += 5
if y > roomlimits[3]:
y = roomlimits[3]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "s":
y -= 5
if y < roomlimits[2]:
y = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "d":
x += 5
if x > roomlimits[1]:
x = roomlimits[1]
print("Youre current coordinates are x:",x," y:",y)
elif dir == "a":
x -= 5
if x < roomlimits[0]:
x = roomlimits[2]
print("Youre current coordinates are x:",x," y:",y)
def movementinput():
global direct
while True:
direct = input("")
if direct in ("w","a","s","d","W","A","D","S"):
break
else:
print("You failure.")
def doorcheck():
global x,y,doorloc1,doorloc2,door1,door2
if x == doorloc1[0] and doorloc1[1] <= y <= doorloc1[2]:
door1 = 1
elif y == doorloc2[0] and doorloc2[1] <= x <= doorloc2[2]:
door2 = 1
else:
door1,door2 = 0,0
Im using a module instead of classes because i dont know how to use classes yet,anyways,what happens in the program is that if i am in the door location,it simply prints "DAMN SON" and doesnt break out of the Room loop,any help? EDIT NOTE: I added the break statement later on to try if it would help,sadly it didnt,i am also a bit tired so im guessing i made a logic mistake somewhere,thanks in advance for help.
Final edit: The code was functional all along,i was just testing it incorrectly!Thanks for the awnsers,ill close this question now.
Since I could not imagine it didn't work, I added two markers (print commands), to room 1 and 2:
while CurrentRoom == 1:
print("one")
mod.MainLel()
and
while CurrentRoom == 2:
print("two")
mod.MainLel()
This is what happened:
Youre current coordinates are x: -5 y: 15
one
a
Youre current coordinates are x: -10 y: 15
one
a
Youre current coordinates are x: -15 y: 15
DAMN SON
two
a
Youre current coordinates are x: -15 y: 15
two
It turned out to be working fine. The break is redundant however. The loop will break anyway, since the condition becomes False.
Here is my situation
import win32api
while True:
x,y = win32api.GetCursorPos()
if x < 0:
print("2")
else:
print("1")
This constantly prints '1' or '2' depending on the x co-ordinate of the mouse being less than 0 (dual monitors, RHS is primary so < 0 means mouse is on second monitor). How can I make it only print one instance of the string '1' or '2' when x becomes < 0 or x becomes >= 0?
You need to remember the last state printed so that you can detect when a new state is entered.
last_state = False
while True:
x,y = win32api.GetCursorPos()
state = x < 0
if state == last_state:
continue
last_state = state
if state:
print("2")
else:
print("1")