How can I detect a speed from a gps in python? - python

I am using a gps chip with my raspberry pi using python for coding and I want to get the speed from the gps and convert it to mph in a loop using a 1 second loop.
How can this be accomplished with fairly precise data? I am currently using the following code:
From gps import *
import time
import threading
import math
import RPi.GPIO as GPIO ## Import GPIO library
import time ## Import 'time' library. Allows us to use 'sleep'
GPIO.setmode(GPIO.BOARD) ## Use board pin numbering
GPIO.setup(40,GPIO.OUT) ## Setup GPIO Pin 40 to OUT
class GpsController(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.running = False
def run(self):
self.running = True
while self.running:
# grab EACH set of gpsd info to clear the buffer
self.gpsd.next()
def stopController(self):
self.running = False
#property
def fix(self):
return self.gpsd.fix
#property
def utc(self):
return self.gpsd.utc
#property
def satellites(self):
return self.gpsd.satellites
mph = 15
if __name__ == '__main__':
# create the controller
gpsc = GpsController()
try:
# start controller
gpsc.start()
while True:
if gpsc.fix.speed < mph :
print "speed is under 15 mph",gpsc.fix.speed
print mph
GPIO.output(40,GPIO.HIGH)
time.sleep(1)
GPIO.output(40,GPIO.LOW)
time.sleep(1)
#GPIO.output(40,True)
#time.sleep(.5)
#GPIO.output(40,False)
#time.sleep(.10)
elif gpsc.fix.speed > mph :
print "speed (m/s) ",gpsc.fix.speed
# GPIO.cleanup()
else:
print "fine"
#GPIO.cleanup()
#print "latitude ", gpsc.fix.laif
#print "longitude ", gpsc.fix.longitude
#print "time utc ", gpsc.utc, " + ", gpsc.fix.time
#print "altitude (m)", gpsc.fix.altitude
#print "eps ", gpsc.fix.eps
#print "epx ", gpsc.fix.epx
#print "epv ", gpsc.fix.epv
#print "ept ", gpsc.gpsd.fix.ept
#print "speed (m/s) ", gpsc.fix.speed
#print "climb ", gpsc.fix.climb
#print "track ", gpsc.fix.track
#print "mode ", gpsc.fix.mode
#print "sats ", gpsc.satellites
time.sleep(1)
#Error
#except:
# print "Unexpected error:", sys.exc_info()[0]
# raise
#Ctrl C
except KeyboardInterrupt:
print "User cancelled"
finally:
print "Stopping gps controller"
gpsc.stopController()
#wait for the thread to finish
gpsc.join()
print "Done"
GPIO.cleanup()
The current code gives me a reading but it appears to be approximately 15 mph out of sync.

You need to grab the GPS coordinates from your chip, convert them to cartesian coordinates, and subtract the current second from the previous second. The distance between the two points is then your distance traveled in one second. This will be noisy at low speeds so you may want to do some filtering of some kind.

Related

get and use updated variables from a text file in a python function

Here is my problem:
I have a text file (settings.txt) with some variables:
dataLogging=0
bootDelay=10
shutdownDelay=30
decimal1=5
...etc
I change the values of these variables from a web page. This is working fine.
I run a script (test.py) which imports and uses these variables:
import MySQLdb
from gps import *
import threading
from datetime import datetime
import sys
import os
import imp
f = open('/var/www/html/scripts/settings.txt')
global data
data = imp.load_source('data', '', f)
f.close()
global dataLogging, bootDelay, shutdownDelay, decimal1, ...
# variables
dataLogging = data.dataLogging
bootDelay = data.bootDelay
shutdownDelay = data.shutdownDelay
decimal1 = data.decimal1
...
Now, the rest of the script runs a class:
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
global gpsd, lonvalue, latvalue, oldlon, oldlat, newlon, newlat, maxtrip
gpsd=gps(mode=WATCH_ENABLE)
self.current_value = None
self.running = True
def run(self):
global gpsd, lonvalue, latvalue, oldlon, oldlat, newlon, newlat, maxtrip
oldlon = ("%0.*f" % (int(decimal1), float(gpsd.fix.longitude))) <---- here is my second problem
oldlat = ("%0.*f" % (int(decimal1), float(gpsd.fix.latitude)))
etc...
which is being called with ...
if __name__ == '__main__':
if (int(float(dataLogging)) == 1): <---- here is my first problem
gpsp=GpsPoller()
try:
gpsp.start()
while True:
print "Loop running success"
time.sleep(int(sleep))
except(KeyboardInterrupt,SystemExit):
# Close the database object
db.close()
gpsp.running = False
gpsp.join()
The problem is that when I change the variables in the settings file via my web page, the changes are not being reflected in the test.py script until the script is stopped and then restarted.
For example, 'if (int(float(dataLogging)) == 1):' should start the script, but when the variable dataLogging is changed to '0', the script should stop. Basically, the variables should update after a predefined number of seconds.
Hope anyone can help!
Many thanks.
UPDATE:
This is what I have in the 'if(int(float(dataLogging)) == 1) block:
if(int(float(dataLogging)) == 1):
# more variables
lonvalue = "0.00"
latvalue = "0.00"
gpsd = None
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
global gpsd, lonvalue, latvalue, oldlon, oldlat, newlon, newlat, maxtrip, dataLogging
print "hello 1"
gpsd=gps(mode=WATCH_ENABLE)
self.current_value = None
self.running = True
def run(self):
global gpsd, lonvalue, latvalue, oldlon, oldlat, newlon, newlat, maxtrip
print "hello 2"
#########
#
# If I commment out everything from here to...
#
#########
oldlon = ("%0.*f" % (int(decimal1), float(gpsd.fix.longitude)))
oldlat = ("%0.*f" % (int(decimal1), float(gpsd.fix.latitude)))
while gpsp.running:
gpsd.next()
# set new latitude/longitude to 4 decimal accuracy
newlon = ("%0.*f" % (int(decimal2), float(gpsd.fix.longitude)))
newlat = ("%0.*f" % (int(decimal2), float(gpsd.fix.latitude)))
# compare old settings with new settings
if ((oldlon != newlon) or (oldlat != newlat) or (dataLogging != 0)):
# set old latitude/longitude to 4 decimal accuracy
oldlon = ("%0.*f" % (int(decimal2), float(gpsd.fix.longitude)))
oldlat = ("%0.*f" % (int(decimal2), float(gpsd.fix.latitude)))
# set latitude/longitude to 7 decimal accuracy to enter into db
lonvalue = ("%0.*f" % (int(decimal3), float(gpsd.fix.longitude)))
latvalue = ("%0.*f" % (int(decimal3), float(gpsd.fix.latitude)))
# datetime object containing current date and time
now = datetime.now()
dt = now.strftime("%Y-%m-%d %H:%M:%S")
try:
if ((int(float(latvalue)) != 0) or (latvalue != nan) or (dataLogging != 0)):
# Write data to GPSData.txt
f = open("/var/www/html/scripts/GPSData.txt", "a+")
f.write("%s" % maxtrip + "|" + lonvalue + "|" + latvalue + "|" + dt + "\n")
f.flush()
f.close()
print "lonvalue: ",lonvalue,"latvalue: ",latvalue, " maxtrip: ",maxtrip," time: ",dt
# Write to the database
cursor.execute("INSERT INTO gps_data VALUES(null,%s,%s,%s,%s)", (maxtrip,latvalue,lonvalue,dt))
# Commit the changes
db.commit()
# Snap-to-roads recommends an interval of 1-10 sec
#time.sleep(int(sleepTime))
time.sleep(10)
# Unless there is a problem
except:
print "Loop running fail"
gpsp=GpsPoller()
try:
gpsp.start()
while True:
print "Loop running success"
time.sleep(5)
except(KeyboardInterrupt,SystemExit):
# Close the database object
db.close()
gpsp.running = False
gpsp.join()
#########
#
# ...here, then the block stops executing if 'dataLogging = 0'
# and restarts when 'dataLogging = 1'
#
#########
def testing():
updateSettings()
global dataLogging
print "datalogging: ",dataLogging
if (int(float(dataLogging)) == 1):
gpsp=GpsPoller()
try:
gpsp.start()
while True:
print "Loop running success"
time.sleep(int(sleep))
testing()
except(KeyboardInterrupt,SystemExit):
# Close the database object
db.close()
gpsp.running = False
gpsp.join()
testing()
Basically, I need the code within the commented out section to react to the change in the variable 'dataLogging'.
Many thanks
===================================
So, I've simplyfied the code. The object of the exercise is to take the 'dataLogging' value from the settings.txt file and, if the value is '1' get the lon/lat coordinates and if the value is '0' do nothing.
The code below correctly reacts to the change in the settings.txt file.
It prints 'dataLogging ON' if the value is '1' and changes to 'dataLogging OFF' if the value is changed to '0'. I can change the value at will and it always works.
The problem lies with the commented out code. If I uncomment the code, and the value is set to '1', then the logging of the coordinates does not stop even when the value is returned to '0'.
Sorry, my ignorance, but I am used to coding in php.
UPDATE 2:
# loop settings.txt file every 5 seconds and declare global variables
def updateSettings():
f = open('/var/www/html/scripts/settings.txt')
global data
data = imp.load_source('data', '', f)
f.close()
# variables
global dataLogging
dataLogging = data.dataLogging
print "New datalogging from settings.txt ", dataLogging
if dataLogging == 1:
getGPSon()
else:
getGPSoff()
def getGPSon():
print "dataLogging ON"
"""
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
print 'latitude\tlongitude\ttime utc\t\t\taltitude\tepv\tept\tspeed\tclimb\tdataLogging' # '\t' = TAB to try and output the data in columns.
try:
while True:
report = gpsd.next()
if report['class'] == 'TPV':
print getattr(report,'lat',0.0),"\t",
print getattr(report,'lon',0.0),"\t",
print getattr(report,'time',''),"\t",
print getattr(report,'alt','nan'),"\t\t",
print getattr(report,'epv','nan'),"\t",
print getattr(report,'ept','nan'),"\t",
print getattr(report,'speed','nan'),"\t",
print getattr(report,'climb','nan'),"\t",
print dataLogging,"\t"
time.sleep(2)
#update()
except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
print "Done.\nExiting."
"""
def getGPSoff():
print "dataLogging OFF"
def update():
while True:
updateSettings()
time.sleep(5)
update()

gps events and if statements

I am developing a program to produce an event whenever a speed is reached on a gps. The code I am currently trying to modify is below:
from gps import *
import time
import threading
import math
class GpsController(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.running = False
def run(self):
self.running = True
while self.running:
# grab EACH set of gpsd info to clear the buffer
self.gpsd.next()
def stopController(self):
self.running = False
#property
def fix(self):
return self.gpsd.fix
#property
def utc(self):
return self.gpsd.utc
#property
def satellites(self):
return self.gpsd.satellites
if __name__ == '__main__':
# create the controller
gpsc = GpsController()
try:
# start controller
gpsc.start()
while True:
#print "latitude ", gpsc.fix.laif
#print "longitude ", gpsc.fix.longitude
#print "time utc ", gpsc.utc, " + ", gpsc.fix.time
#print "altitude (m)", gpsc.fix.altitude
#print "eps ", gpsc.fix.eps
#print "epx ", gpsc.fix.epx
#print "epv ", gpsc.fix.epv
#print "ept ", gpsc.gpsd.fix.ept
print "speed (m/s) ", gpsc.fix.speed
#print "climb ", gpsc.fix.climb
#print "track ", gpsc.fix.track
#print "mode ", gpsc.fix.mode
#print "sats ", gpsc.satellites
time.sleep(1)
#Error
#except:
# print "Unexpected error:", sys.exc_info()[0]
# raise
#Ctrl C
except KeyboardInterrupt:
print "User cancelled"
finally:
print "Stopping gps controller"
gpsc.stopController()
#wait for the thread to finish
gpsc.join()
print "Done"
I am wanting to add an "if" statement to the program to first look at the speed being transmitted and printing or enabling an event whenever the speed reaches a certain number.
I am not sure where and when to add the "if" code.
In the while loop would make the most sense. There was no specification as to whether the event should happen once or multiple times when hitting the 'certain amount'.
from gps import *
import time
import threading
import math
class GpsController(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
self.running = False
def run(self):
self.running = True
while self.running:
# grab EACH set of gpsd info to clear the buffer
self.gpsd.next()
def stopController(self):
self.running = False
#property
def fix(self):
return self.gpsd.fix
#property
def utc(self):
return self.gpsd.utc
#property
def satellites(self):
return self.gpsd.satellites
if __name__ == '__main__':
# create the controller
gpsc = GpsController()
try:
# start controller
gpsc.start()
while True:
if gspc.fix.speed > event_trigger_amt:
print "speed (m/s) ", gpsc.fix.speed
doEvent()
time.sleep(1)
#Ctrl C
except KeyboardInterrupt:
print "User cancelled"
finally:
print "Stopping gps controller"
gpsc.stopController()
#wait for the thread to finish
gpsc.join()

How to average last ten instances of a variable and display

Hi ladies and gentleman,
please forgive me if I've inputted the below code wrong as this is my first time posting here. I have a python script here that polls a capacitor every tenth of a second that is currently being used with a light dependent resistor to determine the brightness outside.
The only problem is that the numerical value often varies by around +/- 5. I would like to implement a line of code that averages the last ten polls every second and prints them. I have no idea where to start, any help would be appreciated!!
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
import I2C_LCD_driver
GPIO.setmode(GPIO.BOARD)
mylcd = I2C_LCD_driver.lcd()
#define the pin that goes to the circuit
pin_to_circuit = 40
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
mylcd.lcd_display_string("->%s" %a)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
You could define a list in your main loop:
polls = []
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
#add current poll to list of polls
polls.append(a)
#remove excess history
if len(polls) > 10:
polls.pop(0)
#calculate average
avg = sum(polls)/len(polls)
mylcd.lcd_display_string("->%s" %avg)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()

Python Multiprocessing Stops after a while

So basically we're using raspberry pi for a project and a part of it includes the usage of ultrasonic sensors. We have three, and we've been able to get readings from all of them (I actually came from multi-threading but decided to move to multiprocessing). Here is my code:
#Libraries
from multiprocessing import Process, Lock
import RPi.GPIO as GPIO
import time
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#set GPIO Pins
GPIO_TRIGGER1 = 23
GPIO_ECHO1 = 24
GPIO_TRIGGER2 = 27
GPIO_ECHO2 = 22
GPIO_TRIGGER3 = 25
GPIO_ECHO3 = 17
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER1, GPIO.OUT)
GPIO.setup(GPIO_ECHO1, GPIO.IN)
GPIO.setup(GPIO_TRIGGER2, GPIO.OUT)
GPIO.setup(GPIO_ECHO2, GPIO.IN)
GPIO.setup(GPIO_TRIGGER3, GPIO.OUT)
GPIO.setup(GPIO_ECHO3, GPIO.IN)
def sense_distance(lock, processName):
#lock.acquire()
gpio_echo_var = ''
gpio_trigger_var = ''
if processName == "Sensor-1":
gpio_echo_var = GPIO_ECHO1
gpio_trigger_var = GPIO_TRIGGER1
elif processName == "Sensor-2":
gpio_echo_var = GPIO_ECHO2
gpio_trigger_var = GPIO_TRIGGER2
elif processName == "Sensor-3":
gpio_echo_var = GPIO_ECHO3
gpio_trigger_var = GPIO_TRIGGER3
print "%s process created." % (processName)
try:
while True:
# set Trigger to HIGH
GPIO.output(gpio_trigger_var, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(gpio_trigger_var, False)
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(gpio_echo_var) == 0:
StartTime = time.time()
# save time of arrival
while GPIO.input(gpio_echo_var) == 1:
StopTime = time.time()
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
if distance <= 10:
print "%s has read less than 10 cm." % (processName)
else:
pass
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
#lock.release()
if __name__ == '__main__':
lock = Lock()
Process(target=sense_distance, args=(lock, "Sensor-1")).start()
Process(target=sense_distance, args=(lock, "Sensor-2")).start()
Process(target=sense_distance, args=(lock, "Sensor-3")).start()
It successfully reads the input and prints out the text when input goes smaller than 10 cm. However, after some time, they stop. I have run out of ideas and have searched all over only to come up short. Any sort of help will be appreciated.

Restarting socket connection following client disconnect

I have this code which listens/sends from/to a Scratch program with remote sensor connections enabled (e.g communicates by Port 42001 on 127.0.0.1)
# This code is copyright Simon Walters under GPL v2
# This code is derived from scratch_handler by Thomas Preston
# Version 5dev 11Aug08 Much better looping supplied by Stein #soilandreyes
# and someone else #MCrRaspJam who've name I've forgotton!
# Version 6dev - Moved Allon/AllOff to be processed before single pins :)
# Vesion 7dev - start to tidy up changes
# Vesion 8dev - use gpio-output system and broadcast allon, 1on system
# V0.1 - change to 6 out 2 in and sanitise the code
# V0.2 -
from array import *
import threading
import socket
import time
import sys
import struct
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
GPIO.setup(16,GPIO.OUT)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(22,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(7,GPIO.IN,pull_up_down=GPIO.PUD_UP)
'''
from Tkinter import Tk
from tkSimpleDialog import askstring
root = Tk()
root.withdraw()
'''
PORT = 42001
DEFAULT_HOST = '127.0.0.1'
#HOST = askstring('Scratch Connector', 'IP:')
BUFFER_SIZE = 240 #used to be 100
SOCKET_TIMEOUT = 1
SCRATCH_SENSOR_NAME_INPUT = (
'gpio-input0',
'gpio-input1'
)
SCRATCH_SENSOR_NAME_OUTPUT = (
'gpio-output0',
'gpio-output1',
'gpio-output2',
'gpio-output3',
'gpio-output4',
'gpio-output5'
)
SCRATCH_BROADCAST_NAME_OUTPUT = (
'1on','1off','2on','2off','3on','3off','4on','4off','5on','5off','6on','6off'
)
#Map gpio to real connector P1 Pins
GPIO_PINS = array('i',[11,12,13,15,16,18,22,7])
GPIO_PIN_OUTPUT = array('i')
GPIO_PIN_INPUT = array('i')
print "Output Pins are:"
for i in range(0,len(SCRATCH_SENSOR_NAME_OUTPUT)):
print GPIO_PINS[i]
GPIO_PIN_OUTPUT.append(GPIO_PINS[i])
print "Input Pins are:"
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT),8):
print GPIO_PINS[i]
GPIO_PIN_INPUT.append(GPIO_PINS[i])
class ScratchSender(threading.Thread):
#Not needed as its a Listening issue
...
class ScratchListener(threading.Thread):
def __init__(self, socket):
threading.Thread.__init__(self)
self.scratch_socket = socket
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
def physical_pin_update(self, pin_index, value):
physical_pin = GPIO_PIN_OUTPUT[pin_index]
print 'setting GPIO %d (physical pin %d) to %d' % (pin_index,physical_pin,value)
GPIO.output(physical_pin, value)
def run(self):
#This is main listening routine
while not self.stopped():
#time.sleep(0.1) # be kind to cpu
try:
data = self.scratch_socket.recv(BUFFER_SIZE)
dataraw = data[4:].lower()
print 'Length: %d, Data: %s' % (len(dataraw), dataraw)
if len(dataraw) == 0:
#This is probably due to client disconnecting
#I'd like the program to retry connecting to the client
time.sleep(2)
except socket.timeout:
print "sockect timeout"
time.sleep(1)
continue
except:
break
if 'sensor-update' in dataraw:
#gloablly set all ports
if 'gpio-outputall' in dataraw:
outputall_pos = dataraw.find('gpio-outputall')
sensor_value = dataraw[(outputall_pos+16):].split()
#print sensor_value[0]
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
self.physical_pin_update(i,int(sensor_value[0]))
#check for individual port commands
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
if 'gpio-output'+str(i) in dataraw:
#print 'Found '+ 'gpio-output'+str(i)
outputall_pos = dataraw.find('gpio-output'+str(i))
sensor_value = dataraw[(outputall_pos+14):].split()
#print sensor_value[0]
self.physical_pin_update(i,int(sensor_value[0]))
#Use bit pattern to control ports
if 'gpio-pattern' in dataraw:
#print 'Found gpio-outputall'
num_of_bits = len(SCRATCH_SENSOR_NAME_OUTPUT)
outputall_pos = dataraw.find('gpio-pattern')
sensor_value = dataraw[(outputall_pos+14):].split()
#print sensor_value[0]
bit_pattern = ('0000000000000000'+sensor_value[0])[-num_of_bits:]
#print 'bit_pattern %s' % bit_pattern
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
#bit_state = ((2**i) & sensor_value) >> i
#print 'dummy gpio %d state %d' % (i, bit_state)
physical_pin = GPIO_PIN_OUTPUT[i]
if bit_pattern[-(i+1)] == '0':
print 'setting GPIO %d (physical pin %d) low' % (i,physical_pin)
GPIO.output(physical_pin, 0)
else:
print 'setting GPIO %d (physical pin %d) high' % (i,physical_pin)
GPIO.output(physical_pin, 1)
elif 'broadcast' in dataraw:
#print 'received broadcast: %s' % data
if 'allon' in dataraw:
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
self.physical_pin_update(i,1)
if 'alloff' in dataraw:
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
self.physical_pin_update(i,0)
for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
#check_broadcast = str(i) + 'on'
#print check_broadcast
if str(i+1)+'on' in dataraw:
self.physical_pin_update(i,1)
if str(i+1)+'off' in dataraw:
self.physical_pin_update(i,0)
if 'pin' + str(GPIO_PIN_OUTPUT[i])+'on' in dataraw:
GPIO.output(physical_pin, 1)
if 'pin' + str(GPIO_PIN_OUTPUT[i])+'off' in dataraw:
GPIO.output(physical_pin, 0)
elif 'stop handler' in dataraw:
cleanup_threads((listener, sender))
sys.exit()
else:
print 'received something: %s' % dataraw
def create_socket(host, port):
while True:
try:
print 'Trying'
scratch_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratch_sock.connect((host, port))
break
except socket.error:
print "There was an error connecting to Scratch!"
print "I couldn't find a Mesh session at host: %s, port: %s" % (host, port)
time.sleep(3)
#sys.exit(1)
return scratch_sock
def cleanup_threads(threads):
for thread in threads:
thread.stop()
for thread in threads:
thread.join()
if __name__ == '__main__':
if len(sys.argv) > 1:
host = sys.argv[1]
else:
host = DEFAULT_HOST
# open the socket
print 'Connecting...' ,
the_socket = create_socket(host, PORT)
print 'Connected!'
the_socket.settimeout(SOCKET_TIMEOUT)
listener = ScratchListener(the_socket)
sender = ScratchSender(the_socket)
listener.start()
sender.start()
# wait for ctrl+c
try:
while True:
time.sleep(0.5)
except KeyboardInterrupt:
cleanup_threads((listener, sender))
sys.exit()
The issue I'm having is in this section of code
def run(self):
#This is main listening routine
while not self.stopped():
#time.sleep(0.1) # be kind to cpu
try:
data = self.scratch_socket.recv(BUFFER_SIZE)
dataraw = data[4:].lower()
print 'Length: %d, Data: %s' % (len(dataraw), dataraw)
if len(dataraw) == 0:
#This is probably due to client disconnecting
#I'd like the program to retry connecting to the client
time.sleep(2)
except socket.timeout:
print "sockect timeout"
time.sleep(1)
continue
except:
break
If the client disconnects e.g Scratch is closed, I need this program to basically restart looking for a connection again and wait for Scratch to re-connect.
Could I have some suggestions as to how to achieve this please as I am a python newbie
regards
Simon
My solution was to use a global variable and change main loop structure
if len(dataraw) == 0:
#This is probably due to client disconnecting
#I'd like the program to retry connecting to the client
#tell outer loop that Scratch has disconnected
if cycle_trace == 'running':
cycle_trace = 'disconnected'
break
is used to break out of loop and
cycle_trace = 'start'
while True:
if (cycle_trace == 'disconnected'):
print "Scratch disconnected"
cleanup_threads((listener, sender))
time.sleep(1)
cycle_trace = 'start'
if (cycle_trace == 'start'):
# open the socket
print 'Starting to connect...' ,
the_socket = create_socket(host, PORT)
print 'Connected!'
the_socket.settimeout(SOCKET_TIMEOUT)
listener = ScratchListener(the_socket)
sender = ScratchSender(the_socket)
cycle_trace = 'running'
print "Running...."
listener.start()
sender.start()
# wait for ctrl+c
try:
#just pause
time.sleep(0.5)
except KeyboardInterrupt:
cleanup_threads((listener,sender))
sys.exit()
this is now my main outer loop
Seems to work :)

Categories