Hooperstu
Hooperstu

Reputation: 99

Why would this Python script crash?

This Python script works fine for days and then crashes, do you know why this would happen or how to debug it? It is connected to an Arduino that sends a pin high when it receives a '1' through serial. The script starts when the computer boots up and should run forever. If it did crash however, I don't have a way of restarting the script as the computer is in a remote location.

import json
import urllib
from pprint import pprint
import time
import serial

#to collect the first tweet without telling the arduino
countTweet = 0
tweet= 0
noTweet= 0

#the infinate loop
while True:
    #the connection to the arduino
    ser = serial.Serial('COM3',9600)
    #not connected to arduino before connection is made
    connected = False

    #loop until the arduino is connected
    while not connected:
        serin = ser.read()
        connected = True
    #debug arduino connection
    if connected == True:
        pprint('connected to arduino')

    #j contains the JSON
    j =json.loads(urllib.urlopen('http://search.twitter.com/search.json?q=%23workrestandplayground&result_type=recent&rpp=1&filter:retweets').read())

    #Debug JSON from twitter (for faults on the Twitter end or possible GET limit id below 15 seconds per request)
    pprint(j)

    #find the text and the tweet id
    if j['results']:
        text = j['results'][0]['text']
        id = j['results'][0]['id']
        #how many times the Json is correct
        tweet+= 1
    else:
        #How many times the Json is false
        noTweet += 1

    #print the text and id to the screen
#    pprint(text)
#    pprint(id)

    #to isolate the first loop, if the first ID has been stored already (count == 1)
    if countTweet != 0:
        pprint ("new loop")
        #if lastID is not equal to ID
        if lastID != id:
        #Tell Arduino to Vend
            ser.write('1')
            #ser.write('0')
            #loop until the arduino tells us it is done vending
            while ser.read() == '1':
                ser.read()
            #Debug
            pprint(text)
            pprint(id)
            #Make lastID equal to ID
            lastID = id
            pprint ('lastID updated')
        #if no new tweets, print     
        else:
            pprint ('no new tweets')
    #If it's the first loop, confirm by printing to the screen
    else:
        pprint("First loop complete")
        lastID = id
        pprint(lastID)


    #make count not equal to 0 after first loop
    countTweet += 1

    pprint ('closing arduino connection')
    ser.close()

    #wait
    pprint('waiting 15 seconds')
    pprint ('Number of Tweets')
    pprint (countTweet)
    pprint('Working JSON')
    pprint(tweet)
    pprint('Broken JSON')
    pprint(noTweet)
    time.sleep(15)

The Error Message is as follows

    Traceback (most recent call last):
  File "C:\Users\3d Exposure\Desktop\M001.py", line 19, in <module>
    ser = serial.Serial('COM3',9600)
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 31, in __init__
    SerialBase.__init__(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\serial\serialutil.py", line 261, in __init__
    self.open()
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 71, in open
    self._reconfigurePort()
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 186, in _reconfigurePort
    raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % ctypes.WinError())
ValueError: Cannot configure port, some setting was wrong. Original message: [Error 31] A device attached to the system is not functioning.

I believe it to be an issue with this statement

while ser.read() == '1':
    ser.read()

I have been informed that this will omit every other piece of serial data. How can I write this so that it does not omit anything? will

while ser.read() == '0':
   break

work?

Upvotes: 1

Views: 1254

Answers (2)

unutbu
unutbu

Reputation: 879361

You can protect the urllib.urlopen call with a try...except:

try:
   response = urllib.urlopen('http://search.twitter.com/search.json?q=%23workrestandplayground&result_type=recent&rpp=1&filter:retweets')
except IOError:
   # This includes urllib.ContentTooShortError
   time.sleep(60)
   continue
j =json.loads(response.read())

Upvotes: 1

kindall
kindall

Reputation: 184141

I don't see any error handling. So, anything that goes wrong will cause the script to exit. For example, if the Internet connection or Twitter goes down, the urlopen call will fail and the whole script will cease to work. That's the most obvious place to add error handling, but what happens if you disconnect the serial port?

Add error handling to handle potential errors, otherwise Python will handle the errors, and you won't like the way it does that.

Upvotes: 5

Related Questions