ofxSerial - onSerialBuffer is blocking

I am noticing that when ever I receive a serial signal with ofxSerial from my Arduino in

void onSerialBuffer(const ofxIO::SerialBufferEventArgs& args){
}

my app freezes for a split second.

Is there a way to make this event non-blocking?

Thanks for any advice.

Here the whole function:

   void onSerialBuffer(const ofxIO::SerialBufferEventArgs& args){
        // Buffers will show up here when the marker character is found.
        ofLog()<<"serial args.buffer() "<<args.buffer();
        vector<string> splitStr = ofSplitString(args.buffer().toString(), ":");
        
        if(splitStr[0] == "s"){
            //states
            ofLog()<<"serial state:"<<splitStr[1] <<" splitStr[2] "<<splitStr[2];
            if(ofIsStringInString(splitStr[1], "upper")){
                
                upperSwitchState_str = splitStr[2];
                if(splitStr[2] == "ON"){
                    upperSwitchState = true; 
                } else {
                    upperSwitchState = false;
                }
            } else if(ofIsStringInString(splitStr[1], "lower")){
                lowerSwitchState_str = splitStr[2];
                
                if(splitStr[2] == "ON"){
                    lowSwitchState = true; 
                } else {
                    lowSwitchState = false;
                }
                
            }
            
        } else if(splitStr[0] == "i"){
            //info
            ofLog()<<"serial info:"<<splitStr[1];
            
        } else if(splitStr[0] == "a"){
            //alive
            aliveTimer = ofGetElapsedTimef();
            aliveCounter = ofToInt(splitStr[1]);
        } else {
            
        }
        
        
    }

Hey @stephanschulz, currently when using a ofxIO::BufferedSerialDevice, all serial reads are done in the - during ofEvents::update callbacks. We subscribe to the update() event here.

Then whenever update() is called from your main thread, all serial process (read / write) is done here.

It is possible modify the read timeout of the underlying serial device, making it as small as possible to not block (e.g. here or in another of the inherited setup(…) functions), ultimately polling for serial communication (via the update event) in the main thread is likely the reason for the read-delay.

One solution might be to create a modified version of ofxIO::BufferedSerialDevice runs serial communication in an internal thread, delivering buffers to an internal queue via a thread-channel, then passing all of those enqueued buffers back to the main onSerialBuffer() when the main thread update() is called.

1 Like

By the way, I use this technique of internal thread -> thread channel -> mainthread sync’d callbacks in this class.

Thanks for the tip.
I will see if I can make your suggestion to make a new threaded ofxIO::BufferedSerialDevice work somehow.

1 Like