Python while loop driving me nuts! PLEASE - python

This script is supposed to continuously read different rfid tags once, print out the tag number and send it to the remote xbee. However, it keeps reading tags in a continuous loop. I want it to read a tag once display the result and send it to the remote xbee, then wait for a different tag and repeat the process.
def main():
ann = as3992_api.AntennaDevice()
print "Firmware info: %s\nHardware info: %s" % ann.get_system_info()
print "Activating antenna"
ann.set_antenna_state(True)
print " Reading Tags:"
while True:
try:
for epc, rssi in ann.iter_epc_rssi():
#time.sleep(1)
print "---------------------------------------"
print "Scanning Tag..."
time.sleep(1)
print "Tag code epc:" +epc.encode("HEX"),rssi
#send tag info to remote xbee
xbee.tx_long_addr(frame='0x1', dest_addr=XBEE1_ADDR_LONG, data=epc.encode("HEX"))
print "---------------------------------------"
time.sleep(1)
print "Sending tag information to XBee 1 ..."
except KeyboardInterrupt:
ann.set_antenna_state(False)
break
if __name__ == "__main__":
main()

def main():
ann = as3992_api.AntennaDevice()
print "Firmware info: %s\nHardware info: %s" % ann.get_system_info()
print "Activating antenna"
ann.set_antenna_state(True)
print " Reading Tags:"
ok=[]
while True:
try:
for epc, rssi in ann.iter_epc_rssi():
if epc+rssi not in ok:
#time.sleep(1)
print "---------------------------------------"
print "Scanning Tag..."
time.sleep(1)
print "Tag code epc:" +epc.encode("HEX"),rssi
#send tag info to remote xbee
xbee.tx_long_addr(frame='0x1', dest_addr=XBEE1_ADDR_LONG, data=epc.encode("HEX"))
print "---------------------------------------"
time.sleep(1)
print "Sending tag information to XBee 1 ..."
ok.append( epc+rssi )
except KeyboardInterrupt:
ann.set_antenna_state(False)
break

Related

Connecting python script to microcontroller

I am trying to send textual commands to a microcontroller through usb serial port (ttyUSB0), the controller should respond with 'Y' or 'N' and execute the command. Commands are given in the following form '#01a' where the # is beginning symbol 0 is position for A channel and 1 position for B channel and 'a' is checksum of A+B.
I'm stuck and a beginner in python so any help is welcome and appreciated.
p.s. when I connect using putty everything works as expected
also the OS is Ubuntu 16.04 LTS
This is my code:
import time
import serial
import binascii
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=19200,
)
print 'Enter your commands below.\r\nInsert "exit" to leave the application.'
AT = chr(int('1000000',2))
A = chr(int('100000',2))
B = chr(int('100000',2))
AB = chr(int('1000000',2))
input = AT + A + B + AB
print input
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#and discard all that is in buffer
#write data
ser.write(input)
# print("write data: AT+CSQ")
time.sleep(0.5) #give the serial port sometime to receive the data
numOfLines = 0
while True:
response = ser.readline()
print("read data: " + response)
numOfLines = numOfLines + 1
if (numOfLines >= 5):
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "

Function is not defined python

I am trying to use the return from my scan_db() return to pass it through to the next function json_create(response) and use the return from my json_create(response) to pass to my broadcast_string(Sensor_IP, jsonString).
Every time I try to run the program I get the error "NameError: name 'response' is not defined" I cannot find useful examples anywhere.
I am using python 2.7
mycursor = conn.cursor()
def scan_db():
print "Scanning DB"
mycursor.execute("SELECT * FROM outputs ORDER BY ID DESC LIMIT 1;")
response = mycursor.fetchall()
return response
def json_create(response):
ID, Sensor_ID, Sensor_IP, State, Pending_Update, TimeStamp = response[0]
print "Json string creating"
print ""
print "ID", ID
print "Sensor Name", Sensor_ID
print "Sensor IP", Sensor_IP
print "State", State
print "Pending update", Pending_Update
print "Time", TimeStamp
print ""
jsonSwitch = {'Sensor_Name': Sensor_ID, 'Sensor_IP': Sensor_IP, 'State': State,
'Pending_Update': Pending_Update}
jsonString = json.dumps(jsonSwitch)
return jsonString, Sensor_IP
def broadcast_string(Sensor_IP, jsonString):
UDP_IP = Sensor_IP # broadcast
UDP_PORT = 5002
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", jsonString
cs = socket(AF_INET, SOCK_DGRAM)
cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
cs.sendto(jsonString, (UDP_IP, UDP_PORT))
while True:
print "while loop started"
scan_db()
print "scanning db"
json_create(response)
print "creating Json string"
broadcast_string(Sensor_IP, jsonString)
print "broadcasting packet"
time.sleep(2)
You haven't stored the result which scan_db() returns so in json_create(response) the response is nothing. Try creating a variable response and setting its contents equal to the value scan_db() returns like so:
while True:
print "while loop started"
response = scan_db() # edit this line
print "scanning db"
json_create(response)
print "creating Json string"
broadcast_string(Sensor_IP, jsonString)
print "broadcasting packet"
time.sleep(2)
similarly you could also do json_create(scan_db())
You should replace this piece of code:
while True:
print "while loop started"
scan_db()
print "scanning db"
json_create(response)
# the rest of your code
# ...
by
while True:
print "while loop started"
# create a new response variable
response = scan_db()
print "scanning db"
json_create(response)
# the rest of your code
# ....
Explication:
Your scan_db() method will return the response variable that you'll use in your json_create(response).
In the while loop, You should
while True:
print "while loop started"
response = scan_db()
print "scanning db"
jsonString, Sensor_IP = json_create(response)
print "creating Json string"
broadcast_string(Sensor_IP, jsonString)
print "broadcasting packet"
time.sleep(2)
Maybe you should learn what is local variable?

Error on socket.recv (Python)

I got a small python program that communicates with an EV3 robot (lego's robot) via BT. The program sends the EV3 a number 1/2 or 3, the robot makes a predefined movement and send back 'A' to indicate that the movement is done and that it is ready for next command.
The system works great but once in a while the python app crushes with this error message:
'An established connection was aborted by the software in your host machine.' this comes from socket.recv that is called inside btListener() thread.
The relevant python parts:
import bluetooth
from gmail import *
import re
from gtts import gTTS
from time import sleep
import pygame
import serial
import thread
import os
import ftplib
from StringIO import StringIO
from blynkapi import Blynk
def a(): #Send 'a' to 'Status' mailbox
print "Send a to robot"
for i in commandA:
client_sock.send(chr(i))
sleep(1)
def b(): # Send 'b' to 'Status' mailbox
def c(): # Send 'c' to 'Status' mailbox
def clear(): # Send clear array to 'Status' mailbox
for i in clearArray:
client_sock.send(chr(i))
def btListener():
# Listen for end of run reply from the EV3
global ev3Flag, listenFlag
while True:
if listenFlag and (not ev3Flag):
try:
data = client_sock.recv(1024) #Check if EV3 is ready for new command
if data[-2] == 'A':
ev3Flag = True
print "Received 'Ready' from EV3 "
sleep(1)
except Exception as e:
print(e)
print "Failed to read data from socket"
def queueHandler():
# Read next command from QueueArray, call sendFunc and clear the queue
global ev3Flag, listenFlag, queueArray
while True:
if len(queueArray) > 0 and ev3Flag:
sendFunc(queueArray[0])
queueArray.pop(0)
def sendFunc(cmd):
#Send the next command on QueueArray to the EV3
global ev3Flag, listenFlag
if cmd == 1:
try:
ev3Flag = False
listenFlag = False
a()
listenFlag = True
sleep(3)
clear() # clear the EV3 btsocket with a default message
except Exception as e:
print "Error on sendFunc cmd = 1"
print(e)
elif cmd == 2:
try:
except Exception as e:
elif cmd == 3:
try:
except Exception as e:
if __name__ == "__main__":
# Blynk setup
blynk = Blynk(auth_token)
switch1 = Blynk(auth_token, pin = "V0")
switch2 = Blynk(auth_token, pin = "V1")
switch3 = Blynk(auth_token, pin = "V2")
print "Blynk connected"
queueArray = [] # Queue array to hold incoming commands
listenFlag = True # Listen to message from EV3
ev3Flag = True # EV3 ready for new command flag
# BT CONNECTION WITH EV3 #
print "Searching for BT connections: "
nearby_devices = bluetooth.discover_devices()
for bdaddr in nearby_devices:
print bdaddr + " - " + bluetooth.lookup_name(bdaddr)
if target_name == bluetooth.lookup_name(bdaddr):
target_address = bdaddr
break
server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
port = 1
server_sock.bind(("", port))
server_sock.listen(1)
client_sock, address = server_sock.accept()
print "Accepted connection from ", address
if target_address is not None:
print "found target bluetooth device with address ", target_address
else:
print "could not find target bluetooth device nearby"
# END BT CONNECTION WITH EV3 #
try:
thread.start_new_thread(queueHandler, ())
except Exception as e: print(e)
try:
thread.start_new_thread(btListener, ())
except Exception as e: print(e)
while True:
res1 = switch1.get_val()
res2 = switch2.get_val()
res3 = switch3.get_val()
if (int)(res1[0]) == 1:
print "Add 1 to queue"
queueArray.append(1)
if (int)(res2[0]) == 1:
print "Add 2 to queue"
queueArray.append(2)
if (int)(res3[0]) == 1:
print "Add 3 to queue"
queueArray.append(3)
Edit 1:
I tested it a bit more and it seems that the crush happens when the program tries to recv data and send data the same time. (via the clear() or a()/b()/c() functions), could that be the situation?
I'm new to sockets so the first solution that comes in mind is create a flag to limit the action of the socket, is there a better/smarter way to keep that from happening?
Edit 2:
I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.
I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.

Thread, Network and Python

I'm trying to create a little chat program that connect two (or more) computers, so I tried this :
import socket
tcpSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
tcpSocket.bind(("0.0.0.0",8000))
tcpSocket.listen(3)
print "Waiting for a Client ... "
(client, (ip,sock)) = tcpSocket.accept()
print "Received connection from : ",ip
print "Starting ECHO output ..."
data = 'dump'
client.send("Enter you're name : ")
name=client.recv(1024)
name=name.strip()
while len(data) :
send_data = raw_input("Me : ")
try :
client.send("Server : "+send_data)
client.send("\n"+name+" : ")
except :
print "Connection lost !"
break
data = client.recv(2048)
data = data.strip()
print name+" : "+data
print "Closing connection ..."
client.close()
print "Shutting down server ..."
tcpSocket.close()
And it worked well, the only problem is that I can't connect more than one computer to the server! I tried with the thread module by using this fonction:
import socket
import thread
def thread_send() :
print "Received connection from : ",ip
print "Starting ECHO output ..."
data = 'dump'
client.send("Enter you're name : ")
name=client.recv(1024)
name=name.strip()
while len(data) :
send_data = raw_input("Me : ")
try :
client.send("Server : "+send_data)
client.send("\n"+name+" : ")
except :
print "Connection lost !"
break
data = client.recv(2048)
data = data.strip()
print name+" : "+data
tcpSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
tcpSocket.bind(("0.0.0.0",8000))
tcpSocket.listen(5)
print "Waiting for a Client ... "
(client, (ip,sock)) = tcpSocket.accept()
for i in range(5) :
thread.start_new_thread(thread_send,())
while True :
pass
print "Closing connection ..."
client.close()
print "Shutting down server ..."
tcpSocket.close()
But it doesn't work :/
Below is an example of how you do it. Sorry, I have not tested this code nor ran it to check for any kind of syntax issue, this is just for giving an idea.
def thread_send(cli_sock):
data = 'dump'
cli_sock.send("Enter you're name : ")
name=cli_sock.recv(1024)
if len(name) == 0: ## If client disconnected or terminated
return
name=name.strip()
while len(data) :
send_data = raw_input("Me : ")
try :
cli_sock.send("Server : "+send_data)
cli_sock.send("\n"+name+" : ")
except :
print "Connection lost !"
break
data = client.recv(2048)
data = data.strip()
print name+" : "+data
serv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv_sock.bind(('localhost', 8080))
serv_sock.listen(1)
print "After listen...waiting for accept\n"
try:
while True:
client_sock, address = serv_sock.accept()
print "Connection accepted\n"
thread.start_new_thread(thread_send, (client_sock))
finally:
serv_sock.close()

Access the Twitter API + GetDirectMessages + Arduino in Python

Following a tutorial I was able to get and parse the Twitter stream for my own account and send this information through the serial connection to interact with my Arduino project. However I need to get messages sent directly to me and not my public feed. Below is the code to get the public feed then my attempt at trying to get my direct messages.
How can I achieve this?
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='*************', consumer_secret='**************', access_token_key='************', access_token_secret='*************')
##set to your serial port
ser = serial.Serial('/dev/tty.usbmodem1a21', 19200)
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Starting Wooden Wave!'
def driptwit():
status = []
x = 0
status = api.GetUserTimeline('wooden_wave') ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
Attempt at gaining direct messages:
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='***********', consumer_secret='***********', access_token_key='***********', access_token_secret='***********')
##set to your serial port
ser = serial.Serial('/dev/tty.usbmodem1a21', 19200)
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Starting Wooden Wave!'
def driptwit():
status = []
x = 0
status = api.GetDirectMessages() ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
//// UPDATE //
def driptwit():
status = []
x = 0
status = api.GetMentions() ##grab latest statuses
print [s.text for s in status]
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
From your comment, it sounds like api.GetDirectMessages() returned an empty list. Print len(status) directly after the API call to verify that. Are you sure there are new direct messages available to read? Have you tried setting a specific date with api.GetDirectMessages() using the since parameter?
Instead of checking for hash tags in the first token only, check the entire string. In other words test if '#high' in drip instead of if drip[0] == '#high'.

Categories

Resources