I'm studying pyFirmata protocol with some examples. As an exercise I'm doing PIR sensor system. When I'm running the code pyFirmata always outputs 'None' value. However if I'm doing debugging in PyCharm everything works as it should be. On Arduino the StandardFirmata sketch is uploaded. Anyone knows what is the cause of this behaviour?
The code:
import pyfirmata
from time import sleep
def blinkled(pin, message):
print(message)
board.digital[pin].write(1)
sleep(1)
board.digital[pin].write(0)
sleep(1)
port = '/dev/cu.usbmodem1411'
board = pyfirmata.Arduino(port)
it = pyfirmata.util.Iterator(board)
it.start()
pirPin = board.get_pin('d:7:i')
redPin = 12
greenPin = 13
while True:
value = pirPin.read()
while value is None:
print("None")
sleep(1)
pass
if value is True:
blinkled(redPin, "Motion Detected.")
else:
blinkled(greenPin, "No Motion Detected.")
board.exit()
Ok, found that "while" statement should be replaced by "if". Then everything working. Do not understand this behaviour.
Why program stuck with "while" on receiving None?
Why in debug mode everything is fine?
I will appreciate if anyone can explain.
The code resolved this issue:
if value is None:
print("None")
In addition to switching to the if clause as OP pointed out, a continue statement should be used to continue at the top of the loop:
if value is None:
print("None")
continue
This would result in the code logic not running through the additional clauses after it fails the initial "None value" test.
Related
Not sure what's wrong here, function's not printing anything (tried '1' as argument i). I've seen an answer suggesting adding flush=True to print, but that doesn't solve the issue. Any hints appreciated! More broadly - should I even be using the try/except framework if I want the function to be keyboard-controled, or is there a better way?
def i_printer(i):
while True:
try:
if keyboard.is_pressed('q'):
break
except:
print(i)
time.sleep(3)
EDIT: using Windows, apparently keyboard doens't work with it, looking for different solution.
Try and except blocks are used to handle exception. Since you are not going to face any error when clicking 'q', I don't think the usage of them is any good here. Just simple if statement would do the job.
def i_printer(i):
while True:
if keyboard.is_pressed('q'):
break
print(i)
time.sleep(3)
EDIT: In case you wanna record keyboard press try this out. The following code will record all the keys except 'q' and print recorded keys.
import keyboard
def i_printer():
rk = keyboard.record(until ='q')
return keyboard.play(rk, speed_factor = 1)
i_printer()
Got the ball rolling this way, with a generator function and an iterator (using windows, not linux):
import keyboard
import time
def printer():
while True:
yield '1'
time.sleep(1)
def iterator():
for i in aaa():
if keyboard.is_pressed('q'):
break
else:
print(i)
iterator()
I found this post which asks a similar question. However, the answers were not what I expected to find so I'm going to try asking it a little differently.
Let's assume a function searching_for_connection will run indefinitely in a while True loop. It that function, we'll loop and preform a check to see if a new connection has been made with /dev/ttyAMA0. If that connection exists, exit the loop, finish searching_for_connection, and begin some other processes. Is this possible to do and how would I go about doing that?
My current approach is sending a carriage return and checking for a response. My problem is that this method has been pretty spotty and hasn't yielded consistent results for me. Sometimes this method works and sometimes it will just stop working
def serial_device_connected(serial_device: "serial.Serial") -> bool:
try:
serial_device.write(b"\r")
return bool(serial_device.readlines())
except serial.SerialException
return False
I suggest having a delay to allow time for the device to respond.
import time
def serial_device_connected(serial_device: "serial.Serial") -> bool:
try:
serial_device.write(b"\r")
time.sleep(0.01)
return bool(serial_device.readlines())
except serial.SerialException
return False
UPDATE: I found the source of the program hanging. In my pdthread it calls mysocket1.sendall(mydata). It doesn't seem to be able to get past this. Does anyone know why this might be an issue?
I have the following code:
mysocket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysocket1.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
mysocket1.connect(('127.0.0.1', 10001))
while mysocket1:
try:
msg = mysocket1.recv(4092)
msg = pickle.loads(msg)
print(msg)
for pd in pd_objects:
if msg[0] == pd.cam_ip and str(msg[1]) == 'ON' and pd.pd_active == False:
pd.pd_active = True
pdthread = Thread(target=get_pd_data(pd.cam_ip))
pdthread.daemon = True
pdthread.start()
print("testing1")
elif msg[0] == pd.cam_ip and msg[1] == 'OFF':
pd.pd_active = False
print("testing else")
print("testing2")
except:
traceback.print_exc(file=sys.stdout)
break
print("reached end")
I have another python program connected on the other end. This connects and runs perfectly the first time I press a button to activate it. I have my data sending over in the pdthread and all works swell. It's what happens afterwards that's the problem. Future button presses are NOT picked up by this side. The data is being sent over the socket just fine from the other end, it's just not being received here.
I've put in some prints for testing and I found a few interesting things that I cannot explain which is why I'm asking here:
The print("testing1") is never printed. Ever. Not even after the first successful click. Which makes me think that pdthread.start() is behaving like pdthread.join()... which confuses me.
The print("testing else") is never printed. This is expected given my testing but I wanted to rule it out.
Here's the weirdest one. I have two items in my pd_objects list. When I click the button that sends the pd.cam_ip of the first item, print("testing2") does not print, but it DOES print if I click the one for the second item in the list.
Can anyone help explain this bizarre behaviour?
EDIT: the final print is also never printed
I've been hung up on a problem for a couple of days, now. I've spent hours searching message boards and have come up empty.
I have a program that pulls data from an API, parses it with JSON, and displays it on an LCD screen. I want an LED light to blink when data meets a certain condition. I have been fairly successful so far. The issue I am running into is when a thread is called to start the blink from my main while loop, and the main while loop restarts, it appears that the thread is then called again. This causes my LEDs to start acting wacky after each subsequent while loop restart. Any suggestions?
I tried using v.isAlive() == False" in hopes that the thread wouldn't restart but that wasn't helpful. I just want the thread to start once if the condition is met and then continue blinking the LED until the condition is not met. Since I use an LCD screen, the data is on a continuous loop.
Here is a very simplified snippet of my program:
def partCloudBlink():
while True:
allLEDon()
time.sleep(2.5)
yellowLEDon()
time.sleep(1)
allLEDoff()
def partCloudBlink_start():
v = threading.Thread(target=partCloudBlink)
if v.isAlive() == False:
v.daemon = True
v.start()
RUNNING = True
try:
while RUNNING:
if weather in ("Partly Cloudy"):
partCloudBlink_start()
print "Current conditions: %s" % (conditions) #unrelated to the question, just program filler
except KeyboardInterrupt:
RUNNING = False
Thank you very much!
It's because a new thread object is created every time partCloudBlink_start is called. v.isAlive() is always False since it's a new thread.
You can create a global variable or something similar to store the thread object depending on your code structure.
I am looping a function in python as I created my own constant listener. My question is how can I ensure I don't overflow / crash? Logically this is telling me I am leaving a lot of open functions in the background. Once parameters of my application are met I exit(0) for a clean shut down. but how can I ensure this doesn't eat up memory?
This code works fine btw, but I am simply trying to improve it because it feels really wrong to me that I am calling the function within its self without closing the previous use of it and it just feels dirty. constructive comments please.
e.g. (this is now my actual code)
import serial
import sys
import time
def enterdata():
ser = serial.Serial(sys.argv[1], sys.argv[2])
ser.write("\r")
time.sleep(0.5)
while True:
data = ser.read(ser.inWaiting())
if (len(data) > 0):
a = []
for i in range(len(data)):
a.append(data[i])
if "Please press Enter to activate this console." in "".join(a):
print ("1")
exit(0)
break
ser.close()
enterdata()
ser = serial.Serial(sys.argv[1], sys.argv[2])
ser.write("\r\n")
enterdata()
NEW VERSION SO FAR FROM POSTS MADE:
import serial
import sys
import time
def enterdata():
ser = serial.Serial(sys.argv[1], sys.argv[2])
ser.write("\r")
time.sleep(0.5)
while True:
data = ser.read(ser.inWaiting())
if (len(data) > 0):
a = []
for i in range(len(data)):
a.append(data[i])
if "Please press Enter to activate this console." in "".join(a):
print ('1')
return True
exit(0)
break
ser.close()
ser = serial.Serial(sys.argv[1], sys.argv[2])
ser.write("\r\n")
state = False
while state is not True:
state = enterdata()
This code you showed will give a "RuntimeError: maximum recursion depth exceeded" Error because of Python sets a default value for how many recursions can occur in one function at a time.
Any yours is infinite and definitely will cause problems even if you change this default limit.
Why not make a loop yourself and call the function at will ?
found = False
while not found:
extracted_data = lookfordata()
if extracted_data == "I want it to be equal to this":
found = True
I see you edited the post. Whatever you are trying to do, that method is not efficent, not recommended and not pretty. All the good reasons not to use it.
Imagine that you will handle some data larger than you are using now, you won't know if the recursion stopping condition will come to pass before you exceed the limit. It's also no use to increase limit all the time you encounter a bigger data. I think it should be any programmer's goal to avoid repetition and coming up with programs that can handle any type of unexpected input.
You updated your post again. This way of input handling is much better than raw recursion. Just to mention, instead of;
for i in range(len(data)):
a.append(data[i])
use
for i in data:
a.append(i)