serial read

Hello.
I try to read data from a sensor via a serial port. What I do without any problems in SuperCollider and Pd I can’t sort out in OF.
At the first trial I would like that all incoming data are shown in the terminal.
So far OF connects (recognizes) my serial unit correctly but no data is shown in the terminal.
Where is my error?

  
#include "testApp.h"  
  
int baud = 115200;  
ofSerial M_serial;  
  
//--------------------------------------------------------------  
void testApp::setup(){  
  
    M_serial.listDevices();  
	vector <ofSerialDeviceInfo> deviceList = M_serial.getDeviceList();  
	M_serial.setup(0, baud); //open the first device  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
  
  
        char myByte = 0;  
  
        myByte = M_serial.readByte();  
        if ( myByte > 1 )   
        printf("myByte is %d ", myByte);  
  
  
}  

Because OF is a little more low-level than PD or SuperCollider, we don’t wait for data to come from the Serial port, we see if there’s anything in the buffer and if there’s nothing there, then we continue on with our program. The problem is that the OS automatically clears the buffer when we read from it.

The easiest strategy to deal with this is to just put a while() loop around the readByte()

  
  
while( myByte == -1 ) {  
    myByte = M_serial.readByte();  
}  
  

the better way of dealing with this is to use the available() method:

  
  
if(M_serial.available()){  
    myByte = M_serial.readByte();  
    cout << myByte << endl;  
}  
  

Hope that helps a little.

Thanks for the tip.
Still, with the most simple example from above (while function) the data is read random like. I intent to get data from an accelerometer and the data should be received as a uninterrupted smooth data stream.

My protocol is simple, using only 4-bytes packages:
header: 0x00;
address: 0x00; // 0x00, 0x01, 0x02: to be able to distinguish between the 3 axis.
data: LoByte;
data: HiByte; // max 16 Byte resolution.

My code looks now like this: //

  
  
void testApp::update(){  
  
  
unsigned char header, address, LoByte, HiByte, nRead;  
unsigned char bytesReturned[4];  
  
if ( serial.available() > 0){  
  
    while (nRead = serial.readBytes(bytesReturned, 4) > 0){  
            nTimesRead++;  
		};  
  
        header  = bytesReturned[0];  
        address = bytesReturned[1];  
        LoByte  = bytesReturned[12;  
        HiByte  = bytesReturned[3];  
  
        int result = (HiByte<<8)| LoByte;  
        myResult = result;  
        cout << myResult << endl;  
		}  
}  

Uff I think it should be:

if ( serial.available() > 4){ // becasue I have packages of 4 bytes (but still doesn’t work)

Are you using an Arduino or ATMega? If so, could you post up the .ino or .c file that you’re using there, or at least, the parts of it that you’re using to send the Serial message? I think your code for reading from the Serial looks correct, so there might be some issue on the Serial side?

Also, small point, but if you’re expecting 4 bytes, you’d want:

  
if(serial.available() > 3) {  

No I’m using a PIC18F4420.
I send wireless data (with a Nordic nRF24L01) to a FT232 USB/SERIAL converter.
The Nordic sends packages of 4 bytes: 0x00 //header; 0xXX //address; 0xXX // LoByte; 0xXX // HiByte.
As I mentioned above this works great with SuperCollider (https://vimeo.com/62999020)
I observe that, for some reason, OF on every package received sends also something back (why?).

Thanks for help

Here is a screenshot of one package made with GtkTerm.
I get 4 bytes. // I don’d know whether one can see the image, but I get clearly: 0x00 0x01 0x86 0x00 (header, address, LoByte, HiByte).

I attached an other receiver to my laptop and I see using a GtkTerm that FO sends 4 bytes back every time I send a package. The package from FO is: 0x5E 0x40 0x5E 0x41.

Thanks Martin

I just got the same problem with AVR microcontroller.
This is caused by lflag setting in ofSerial.cpp.
in the code the lflag (local flag) is not set at all. it means the serial I/O works in cronical mode.

http://man7.org/linux/man-pages/man3/termios.3.html

and we have to chenge it to cronical mode.
I just inserted

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

write before the second tcsetattr() in setup and it worked.