0

I have a script that runs on an infinite loop collecting data from an Arduino and adds this information to a json file. when I stop the program with cnt c that cuts the while loop and thus but doesn't properly finish sending the data to the json file.

I have looked at other stack overflow questions. like this one "[How to stop an infinite loop safely in Python?"][1] which I used to implement in my code but it only sometimes properly terminates the json data.

my while loop looks like so :

interrupted = False

while True:
    serialDataDic= ArduinoSerial(arduinoSerial,68,startTimeofData)# gather x amount of samples of data at 8.9kHz
    # print(serialDataDic)
    

    
    decompositionCoeffiecients=DWT(serialDataDic['voltage'],'haar',2)
    # print(decompositionCoeffiecients)
   
   #looping through each of our functions and placing that info in our dictionary to go to our json file  
    for key in serialDataDic:
        plottingDicData[key].append(serialDataDic[key])
    for key in decompositionCoeffiecients:
        plottingDicData[key].append(decompositionCoeffiecients[key])
    # print(plottingDicData)
    #sending out sensor data into a json file 
    jsonfileData=JsonData(fileName,plottingDicData)
    
    if interrupted:
        print("Gotta go")
        break

how do I properly terminate this while loop so it will complete the json data collection before terminating?

Bob
  • 279
  • 6
  • 13

1 Answers1

0

I think you probably want some form of a try loop in conjuction with an except line that captures explicitly a keyboard interruption and then uses the sys.exit() method to force quit at the end (as well as send the message you include in the parenthesis).

This way, your script will run normally under the try loop, and then the KeyboardInterrupt will capture your ctrl-C but force it to w/e you want, followed by forcing a quit.

This can certainly be cleaned up a bit but hopefully, this is clear.

import sys

while True:
    try:
        serialDataDic= ArduinoSerial(arduinoSerial,68,startTimeofData)# gather x amount of samples of data at 8.9kHz
        # print(serialDataDic)
        decompositionCoeffiecients=DWT(serialDataDic['voltage'],'haar',2)
        # print(decompositionCoeffiecients)
   
        #looping through each of our functions and placing that info in our dictionary to go to our json file  
        for key in serialDataDic:
            plottingDicData[key].append(serialDataDic[key])
        for key in decompositionCoeffiecients:
            plottingDicData[key].append(decompositionCoeffiecients[key])
        # print(plottingDicData)
        #sending out sensor data into a json file 
        jsonfileData=JsonData(fileName,plottingDicData)
    
    except KeyboardInterrupt:
        decompositionCoeffiecients=DWT(serialDataDic['voltage'],'haar',2)
        # print(decompositionCoeffiecients)
   
        #looping through each of our functions and placing that info in our dictionary to go to our json file  
        for key in serialDataDic:
            plottingDicData[key].append(serialDataDic[key])
        for key in decompositionCoeffiecients:
            plottingDicData[key].append(decompositionCoeffiecients[key])
        # print(plottingDicData)
        #sending out sensor data into a json file 
        jsonfileData=JsonData(fileName,plottingDicData)
        # The below line force quits and prints the included string
        sys.exit("User manually terminated script with ctrl-C")

mdeverna
  • 322
  • 3
  • 9
  • ok ill try that, my only concern is that when ever I was trying to end the while loop with ctrl-c it would immedilty cut things and thus wouldn't finish the json data collection properly. will this not do the same? – Bob Feb 02 '21 at 13:42
  • Happy it helped! As I mentioned there may be a more elegant way to solve this problem. Right now the `try` and the `except KeyboardInterrupt` blocks repeat themselves and it's a bit sloppy. Perhaps a `finally` block could be helpful. Hard to say without more details. Happy coding. :) – mdeverna Feb 02 '21 at 20:49
  • so just to clarify, is the keyboardinterrupt acting as like a flag. so if I press ctrl C while still executing in a for loop inside the try block it doesn't interrupt that loop, it finishes it and then checks for the interrupt and then goes to the except block? – Bob Feb 02 '21 at 21:13
  • No. If you press `control-c`, then you are manually raising a `KeyboardInterrupt` error. This is equivalent to there being an error _inside_ your for-loop. In this case, where ever your code is inside the `try` block (or for-loop) at the time you raise the `KeyboardInterrupt` error, it will halt and then check the errors which broke the `try` block against `except` conditions. Since you specify `KeyboardInterrupt`, it catches that error and then executes what is under that exception block. I would check out this [real python article](https://realpython.com/python-exceptions/) if still confused – mdeverna Feb 03 '21 at 22:11