Weird serial communication issue

Hi,

I have a weird serial communication issue.

Unidirectional serial communication in simple examples works pretty well using the “Serial Monitor” in Arduino IDE as well as in simple c programs. Now I am working on a more complex program for the Arduino using bidirectional communication doing something useful on serial input and sending confirmation messages.

As the commands consist of up to 4 bytes, I wrote the following:

void setup(void) { 
	Serial.begin(9600);
	// skipping stuff for LED and so on...
}

unsigned char receiveData(void) {
	unsigned char data = 0xFF;	

	while(Serial.available() <= 0){
		delay(5);
	}
	data = Serial.read();

	return data;
}

void loop(void) {
	unsigned char received_char,received_char_2,received_char_3,received_char_4;

	received_char=receiveData();
	if(received_char=='a') {
		received_char_2=receiveData();
		received_char_3=receiveData();
		received_char_4=receiveData();
		// check command
		// perform action
		//  e.g. turn on LED

		// send confirmation
		Serial.write('O');
	}
}

So, when I upload this code to my Arduino MEGA 2560 and try to send commands to it, there is no correct reaction (e.g. not turning on the LED, or having the LED lit all the time although no turn-on command was sent). I already thought, that my busy-waiting would interfere with arduino’s way of reading the serial port.

But now the weird part comes: As soon as I start the “Serial Monitor” in parallel to my code, the communication seems to go smooth! LED is turned on and off according to sent commands, only the confirmation messages go to “Serial Monitor” instead of my code.

So, the monitor seems to do something I am missing here. Did anybody see anything like this before? Or has an idea what the problem might be?

My code to open the serial connection:

int initSerial(unsigned char* COMPORT) {

	int serial_fd=-1;
	while(serial_fd == -1) {
		serial_fd=open(COMPORT, O_RDWR | O_NOCTTY | O_NDELAY);
		if(serial_fd == -1) {
			printf("Unable to open Serial Device %s\n", COMPORT);
			sleep(1);
		};
	}
	tcgetattr(serial_fd,&oldtio);

	cfsetospeed(&newtio,B9600);
	cfsetispeed(&newtio,B9600);

	// 8N1
	newtio.c_cflag &= ~PARENB;
	newtio.c_cflag &= ~CSTOPB;
	newtio.c_cflag &= ~CSIZE;
	newtio.c_cflag |= CS8;
	// no flow control
	newtio.c_cflag &= ~CRTSCTS;

	newtio.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
	newtio.c_cflag |= B9600;

	newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
	newtio.c_oflag &= ~OPOST; // make raw

	newtio.c_cc[VMIN] = 0;
	newtio.c_cc[VTIME] = 0;

	newtio.c_lflag = 0;
	newtio.c_iflag = 0;
	newtio.c_oflag = 0;

	tcflush(serial_fd, TCIFLUSH);
	tcsetattr(serial_fd,TCSANOW,&newtio);

	return serial_fd;
}

Receiving and sending messages is done using write() and read() commands.

I tested this on two (Linux) machines with the same result and effects.

Thanks for your help and regards!

PS: I hope, that’s the right category for this kind of issue… could not find a better suited one!

When you open using serial monitor, that makes me think that somehow the serial monitor is changing the baudrate or maybe some other configuration, so it works. perhaps it overrides whatever the GUI usually uses. Perhaps chagning one of the arduino configurations will help.

Hi,

Thanks for the reply!

Yes, I am also thinking that the Serial Monitor changes one of the relevant settings. Although I do not know, which one it should be :~ All three (Arduino, Serial Monitor and my code) should be set to 9600 baud. My serial initialization should also set 8 databits, 1 stopbit, no parity.

In the meantime I also changed the Arduino code to avoid the “busy-waiting” loops to wait for serial input. But the effect is the same: My c-program does not read and write successfully, while as soon as I open Serial Monitor, writing works in my program while reading works most of the time in Serial Monitor and sometimes in my code (they are “stealing” the input from the other ;)).

What do you mean by

Perhaps chagning one of the arduino configurations will help.

?

Any other ideas why my initialization of the serial port might be wrong?

After ages of testings thousands of different combinations, I at least found that my code for opening the serial port and reading and writing data is working fine :slight_smile: In a simple test program sending valid commands, I can see the LED changing its state and also I am able to receive Arduino's replies.

Then I started to investigate for differences between the simple test program and my more complex one. Lastly I found that I am using usleep in the real application, while I was using sleep in the testing one. After replacing sleep by usleep in the test-application, it also stopped working :wink:

So, when I replace usleep with sleep in my application, I am now able to receive some data :slight_smile: However, there still seems to be some issues... the communication is very unrealiable and produces lots of errors. And also sleep is much too slow for my needs.

Does anybody now this problem or has a good replacement for usleep?