ich habe vor kurzem mit Python angefangen ein wenig zu programmieren.
Ich arbeite mit einem Arduino Board und einem Raspberry PI, das Python Script läuft auf dem RaspberryPi und kommuniziert mittels SMBus mit dem Arduino.
Das Script macht folgendes:
In einem Thread wird regelmäßig ein Ping Request auf mein Handy losgeschickt. Wenn das Handy im WLAN ist, dann wird die Funktion writeNumber ausgeführt und eine Zahl an das Arduino Board geschickt, wenn nicht, dann eine andere. Das lief bis vor kurzem auch stabil und fehlerfrei.
Nun habe ich den Code erweitert und einen Webserver aufgesetzt, über den ich weitere Befehle das Arduino Board schicken kann. Dieser Server läuft in einem Thread, der Ping-Vorgang in einem anderen.
Seitdem läuft das ganze nicht mehr stabil, ich erhalte nach einiger Zeit diesen Fehler:
Code: Alles auswählen
Sat Oct 25 16:30:41 2014 Server Starts - 192.168.178.9:8080
Traceback (most recent call last):
File "new.py", line 56, in pingRequest
writeNumber(1);
File "new.py", line 27, in writeNumber
bus.write_byte(address, value)
IOError: [Errno 5] Input/output error
Nun ist die Frage, wo ich da den Fehler habe? Ich habe den Thread mittels lock-Variable im kritischen Bereich großzügig gesichert und zusätzlich um die Funktion While-Schleife gesetzt, die solange wartet, bis der letzte Aufruf abgeschlossen war.
Wie kann ich den Fehler abfangen und verhindern? Ich dachte eigentlich, dass der Try/Catch Block den Fehler abfängt, aber das ist nicht der Fall.
Der Code ist ein wenig eingekürzt, ich hoffe alle wichtigen Teile sind drin.
Code: Alles auswählen
bus = smbus.SMBus(1)
offlineCounter = 0
lock = thread.allocate_lock()
lastSuccessful = 1
lastRelaiseState = 0
def doNoting():
return -1
def writeNumber(value):
try:
global lock
lock.acquire()
global lastSuccessful
while lastSuccessful == 0:
sleep(0.1)
lastSuccessful = 0
address = 0x04
bus.write_byte(address, value)
sleep(0.25)
lastSuccessful = 1
lock.release()
# bus.write_byte_data(address, 0, value)
return 1
except:
raise
return 0
def pingRequest():
global lastRelaiseState
global offlineCounter
while True:
try:
hostname = "android-588e9d891161229e" #example
response = os.system("ping -c 1 " + hostname)
time.sleep(10)
if response == 0:
offlineCounter=0
else:
offlineCounter=offlineCounter+1
if offlineCounter <= 10:
writeNumber(1);
if lastRelaiseState == 0: #Anlage anschalten bei erstem Start
lastRelaiseState = 1
writeNumber(6);
else:
writeNumber(0)
lastRelaiseState = 0
except:
os.system("rm /home/pi/log");
raise
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_HEAD(s):
s.send_response(200)
s.send_header("Content-type", "text/html")
s.end_headers()
def do_GET(s):
#gekürzt
"""Respond to a GET request."""
s.send_response(200)
s.send_header("Content-type", "text/html")
s.end_headers()
f = open("index.html")
s.wfile.write(f.read())
f.close()
# If someone went to "http://something.somewhere.net/foo/bar/",
# then s.path equals "/foo/bar/".
s.wfile.write("<p>You accessed path: %s</p>" % s.path[5:])
s.wfile.write("</body></html>")
def httpServer():
PORT_NUMBER = 8080
HOST_NAME = '192.168.178.9'
server_class = BaseHTTPServer.HTTPServer
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
try:
httpd.serve_forever ()
except KeyboardInterrupt:
raise
httpd.server_close()
print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
if __name__ == '__main__':
try:
thread.start_new_thread(pingRequest,())
httpServer()
except:
raise
Viele Grüße
Joachim