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

Hello @bakercp.

I will continue looking in to this.
But in the meantime, I notice the same blocking moment when using the line_buffer example.
Here a video in which you can see the fps freezing every time my Arduino is sending a message.


I am on macOS 10.15.7, OF 0.11.0, Xcode 12.4

I changed DEFAULT_READ_TIMEOUT_CONSTANT_MS = 1000, to DEFAULT_READ_TIMEOUT_CONSTANT_MS = 100, which greatly reduced the blocking moment. It’s still visible.
When setting it to 0 then all is well. I am just not sure if that could create other problems.
I don’t remember this being an issue a couple of years ago when I used the add-on … ?
I will keep at it. Thank you for all your advice :slight_smile:

1 Like