Software reset from Python

Status
Not open for further replies.
Simple question. I have a Python program on a Mac that talks via USB to a teensy 3.1 board for data collection and also sets parameters for the DAC. During the setup procedure the teensy board and Python go through a simple handshake routine to check that they can communicate. If I quit the Python program and then restart the Python program it now tries to talk to the teensy board, which is now stuck in the main loop, and the handshake routine obviously doesn't work so the Python program just hangs, waiting to complete the handshake.

Ideally I would make the teensy board reset each time the Python program starts so that the handshake routine runs correctly. Is there a way to do this? I could reset the teensy every time I quit the Python program but this assumes it quits in a defined way, which is not always the case, at least when programming. Another alternative are to do the handshake in the main loop. Not sure how best to do this. Or, I could also just eliminate the handshake, it doesn't do anything particularly useful I guess, and just assume that things are OK and wait for data to be uploaded.

Any suggestions appreciated.
 
I don't know what your handshake or protocol looks like (I presume you wrote both sides), but you could define some reset character that, whenever received by the Teensy firmware, will reset the Teensy. If you're using a plain text protocol, then using a control character like "\x01" (control-A, ASCII SOH or "start of header") or "\x18" (control-X, ASCII CAN or "cancel"). In your Python program, just send that byte at program startup. In your "read a command" or "read a byte" routine on the Teensy, if you ever get that character, reset your protocol (just exit to the top of your program and start over). If you reset the whole Teensy, you'll disconnect and reconnect to the USB which is probably not what you want. In fact I use a Mac too and I happen to know it will disconnect your Python program from the virtual serial port /dev/tty.usbmodemXXXXX.

You could get fancier and have the Python program toggle DTR (the USB serial driver will deliver that as an out-of-band signal to the Teensy) and then check for it in the Teensy firmware with this:

Code:
unsigned char dtr = Serial.dtr();
if ( dtr ) {
    // set a flag or return a code that will exit to the top of the program
}

And whenever you see DTR, reset your command loop (make sure you wait until DTR is off again before accepting commands). But this is more work, and will require the Python app to control the modem lines.

On the other hand, you might have it easier in the long run if you make your protocol stateless. That is, your Teensy is always waiting for simple commands that it processes all at once, and these either set variables or trigger actions, but you only have one command loop that processes all of the input from the Python program. Your most common command can just be "here's the next bit of data" or "send me the next bit of data".

Then, it's much harder to accidentally get out of sync because your Teensy is always ready for any kind of input. This is just event-driven programming.

Something like (no, sorry I haven't tested this code, it's just the idea):

Code:
void loop() {
    while ( Serial.available() >= 0 ) {
        String command = Serial.readStringUntil( '\n' );
        // now parse the string for a command 
        if ( command.startsWith( "data " ) ) {
            float data = command.subString( 5 ).toFloat();
            process_data( data );
        } else if ( command.equals( "reset" ) ) {
            reset_state();
        } else {
            // don't know what this command is, maybe just ignore it
        }
    }
    run_background_processing();
}

If that doesn't answer the question, you should probably follow the "forum rule" (look at the top of the page) and post the source code (to your Teensy program at least).
 
On the other hand, you might have it easier in the long run if you make your protocol stateless. That is, your Teensy is always waiting for simple commands that it processes all at once, and these either set variables or trigger actions, but you only have one command loop that processes all of the input from the Python program. Your most common command can just be "here's the next bit of data" or "send me the next bit of data".

Then, it's much harder to accidentally get out of sync because your Teensy is always ready for any kind of input. This is just event-driven programming.

Yes. I think I will rewrite to implement this. I more or less talked myself into this as I wrote the question. It will give more flexibility to allow the teensy program to perform more complex functions.
 
Status
Not open for further replies.
Back
Top