ofSerial fast simple serial read in OF not working properly (and linux problems too)

hi all.

i have a simple arduino protocol sending 3 bytes + message terminator ‘,’

void setup(){
  Serial.begin(9600);
}
int frame = 0;
void loop(){
  Serial.write(frame);
  Serial.write(random(255));
  Serial.write(random(255));
  Serial.write(',');
  delay(33);
  frame=(frame+1)%255;
}

in OF (from github), this is how i am trying to read the bytes (ofApp.cpp):

#include "ofApp.h"

ofSerial	serial;
int			incoming[3];
int			nRead = 0;

//#define SERIALLINUX

void ofApp::setup(){
#ifdef SERIALLINUX
	serial.setup("/dev/ttyUSB0", 9600); //open the first device
#else
	serial.setup(0, 9600); //open the first device
#endif
	
	incoming[0] = incoming[1] = incoming[2] = -1;
}

void ofApp::update(){
	
	if(serial.available()>3){
		unsigned char incomingBytes[4];
		memset(incomingBytes, 0, 4);
		
		while ( (nRead = serial.readBytes(incomingBytes, 4)  > 0)) {

			string datastring = ofToString(incomingBytes);
			
			if(datastring.size()>3  && datastring.at(3) == ','){
				for(int i=0; i<3; i++) { incoming[i] = (int)  datastring.at(i); }
				serial.flush(); // should be used after sucessfull read? less weird packets
			} else {
				cout << "weird packet at frame " << ofGetFrameNum() << " : " << datastring << endl;
			}

			
		}
	}
}

//--------------------------------------------------------------
void ofApp::draw(){
	ofBackground(255);
	string info = "fps: "+ofToString(ofGetFrameRate())+"\n";
	info += "nRead: "+ofToString(nRead)+"\n";
	for(int i=0; i<3; i++) { info += ofToString(i)+"  :  " + ofToString(incoming[i])+"\n"; }
	ofSetColor(0);
	ofDrawBitmapString(info, 10, 10);
}

this code sort of works ok, but there are several problems with it, could you help out?

1 - on Linux systems (debian, lubuntu) app behaves erratically, just once every 100 launches works as expected, most of the times i open the app and only get serial data every 2 seconds. i found a good solid workaround that works every time, but is not good for gallery installations: if you first open Arduino’s Serial Monitor, then close it and open the app, it always works as expected.

2 - with this fast code there are a lot of dropped serial packets, which i am guessing due to syncing serial and of, ie, sometimes serial messages larger than 3bytes don’t have the message terminator ‘,’ at the right index. should i move to a buffered read a byte at time, then exec if the byte is my terminator approach?

i’d like to avoid other solutions like firmata for instance, which is too heavy weight for my bare bones needs.

thanks for reading and looking forward to hearing your suggestions.

this approach yields no problems in processing with readBytesUntil function…

&& finally

3 - sometimes after the app working for 5+ hours, ofSerial does not read anymore bytes and i have to restart the app… any hints? i could always refresh the serial object by making it a pointer, destroying it and reconstruct it after a couple of hours and inactivity, but i’d like to avoid that

ok, moving to a buffered serial read approach (using serial.readByte() ) works well and no serial packets are lost - solves 2.

but serial on linux still is weird, ie, have to open serialmonitor before the app so that it receives the stream constantly and not every two seconds. anyone knows a solid way for serial to work on linux without going to arduino’s serial monitor before?

If you are looking for an alternative serial implementation, you might look at ofxSerial. https://github.com/bakercp/ofxserial It includes a buffered serial device and Arduino examples. Currently it is working long term – e.g. has been running for a few months controlling 20+ printers here https://twitter.com/search?q=%23murmurstudy&src=typd

thanks for the ptr, will definitely check it out.

did you use linux on your project?

ever noticed the serial connection bug on linux i describe above? need to fix this for upcoming exhibitions…

will try this soon and report back asap. thanks

i just tried it on linux, it works, but with the same bug i describe above, ie, if i launch the app after connecting the arduino i only get data every 2 seconds approx,

with native ofSerial, after opening and closing serial monitor, the stream is fast & constant.

with your addon ofxSerial, even after opening and closing serial monitor, i only get data every 2 seconds.

any ideas where to look for solving this behaviour?

Yeah, the installation runs on Linux.

Does the ofxSerial example + included Arduino code still give you the same problems? Or is it happening with you Arduino code alone?

still problems, i am trying with echo example. also tried to reduce the buffer size to a packet of 4 bytes, instead of 1024 default, but only get big chunks of data every two seconds instead of a constant fast stream…

EDIT: sorry, wrong baud rate on OF, now with your example i get a constant stream and no opening serial monitor before! just have to double check with my code and your addon, seems like it works!

Super! Keep me posted if you run into any problems …

I am running in the same troubles with ofserial on linux(pc and raspberry pi). I wanted to use the native of serial not the add-on. By now i figured out that it is something with the serial port opening. I wrote a short python script which is opening the serial port send a byte wait some seconds and read the received bytes. If i run my app after this script everything works like expected. On a mac i didn’t have this issues.

Here is the python script

import serial
import time
port = "/dev/ttyACM0"
ser = serial.Serial(port, 57600, timeout=1)
ser.close()
ser.open()
time.sleep(5)
ser.write("1")
time.sleep(3)
read_val = ser.read(size=64)
print read_val
if read_val is not '':
    print port

Not sure why ofSerial isn’t working… Any reason not to try ofxSerial? It’s working for me and others on the Pi.

There is no reason, i will give it a try. But it is still curious why it is not working.

There were some changes I made to ofSerial that I should probably submit in a PR though I feel as though we may as well just replace ofSerial with ofxSerial for future releases maybe 0.9.1 @bakercp is there any reason you know of not to do that?

The underlying library (https://github.com/wjwwood/serial) is solid, MIT licensed and would be great to have as part of the oF core IMHO. A direct import of ofxSerial might be too much (it is modeled around my IO buffer work in ofxIO), but it could certainly be trimmed down. It seems to be quite robust across platforms. It has been discussed and if you’d like to advocate for it, I’ll certainly support it :smile:

1 Like

hi. just to chime in a bit. i also ended up using native ofSerial class, had to do a lot of changes to use ofxSerial, and this solution i ended up with is working nicely and very solid workaround.

i did a small processing app that opens the serial port and quits after some time, and then a bash script to automate the process.

i like how native ofSerial is modelled, but ofxSerial seems more robust across platforms.

fiy, here are the processing and bash scripts:

processing:

// processing simple serial opener closer

import processing.serial.*;

Serial serial;

String data="";
int baud = 57600;
int portnum = 0;
String portName = "";
int framesToExit = 240;

void setup() {
  size(500, 100);
  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  
  for(int i=0; i<Serial.list().length;i++){
     println("serial "+i+" "+Serial.list()[i]); 
  }  
  portName = Serial.list()[portnum];  
  serial = new Serial(this, portName, baud);
}

void draw()
{
  if ( serial.available() > 0) {  // If data is available,
    data +=""+(char) serial.read();         // read it and store it in val
    if(data.length()>21){
       data = data.substring(1, 21); 
    }
  }
  background(255);             // Set background to white
 
  fill(0);
  text("serial: "+ portName+"\ndata: "+data, 10, 25);
 
  if(frameCount>framesToExit){
     exit(); 
  }
}

bash script:

#!/bin/bash          
SERIALAPP=/path/to/processingapp
DMZAPP=/path/to/dmzapp

echo "launching debug serial opener"
$SERIALAPP
wait
sleep 2
echo "launching DMZ"
$DMZAPP

I dont think this is a viable solution, it might work for your purpose but requiring a shell script and utilizing processing rather than native c++ isn’t ideal. I havent had problems on osx or windows so this might be isolated to the linux versions

Hi @bakercp. First, let me thank you for ofxIO and ofxSerial. They have been amazing for me, working from windows to raspbian. Really reliable until few weeks ago: suddenly I am getting this error message:

Unhandled exception at 0x74B43E28 in ofxSerial_debug.exe: Microsoft C++ exception: serial::IOException at memory location 0x0019F388.

VS opens win.cc in this lines:

// Use this->getPort to convert to a std::string
ss << "Specified port, " << this->getPort() << ", does not exist.";
THROW (IOException, ss.str().c_str());

Maybe is my computer but I have tried reinstalling drivers, different adapters (FTDI, Bluetooth 2.0), nothing. Any clue? This is going on even on the examples, so I am not adding any particular code. I am on a Win10 machine, VS2015, OF 0.9.

Hey @Nabetse first, you can catch the exception with a try / catch block. Second, it sounds like the name of the port is not being recognized on win 10 for some reason.

What version of ofxIO / ofxSerial are you using? 0.9.0 works only with the develop branches of ofSerial / ofxIO.

Do any of the issues here seem to sound similar? (https://github.com/wjwwood/serial/issues)

Finally, if you try to open the same device with ofSerial do you get the same or similar errors?

Thanks bakercp. Well, I was using the master branches (which I had to tweek for OF9.0). Anyway, I downloaded the develop branches. In order to compile I had to add these lines at the beggining of snappy.cc (C2061: syntax error: identifier ‘ssize_t’)

#include <BaseTsd.h>
typedef SSIZE_T ssize_t;

The program run but the same problem appeared, just with a more elegant code underneath (execution was not stoped and the error message appeared in the console):

[ error ] SerialDevice::setup: IO Exception:Specified port, COM 19, does not exist. …win.cc, line 71.

The same port is working without any problem in the Arduino IDE and no problem at all with ofSerial in OF. I tried in another win10 machine and the addon works perfect. Something happened to my computer but I have no idea what is the specific issue or how to track the solution.