Problem with serial communication

Hallo!

At first i would like to apologize for my bad English.
I am working on a project, an important part of it is the communication between two microcontrollers by using TX RX ports.

Both microcontrollers have similar task so the programs on each will be the same.

This is what i want them to do:

  1. each sends its own value of var “send”
  2. value of “send” must be reduced by 20 and save in var “vijanddoel”
  3. each sends its own value of var “raak”

But there are two problems:

  1. The incoming value of “send” is never correct
  2. Durring the proces one microcontroller goes all the way to state 6 and another one stays in state 4

I am not sure if i am using right functions on the right way.

Here is my code:

case STATE_4:
			
		    
			
				 Serial.print(send, DEC);
		     
		
		       if(Serial.available()>19 && Serial.available()<70)
						  {
							  recive = Serial.read();
							  vijanddoel = recive-20;
								enemytarget[vijanddoel] = 1;
								if(vijanddoel > 19)
								{
									state = STATE_5;
								  break;
								}
						   }
							break;
							
			
		case STATE_5:
			
		Serial.print(send, DEC);
			
		if( myships[vijanddoel] == 1)
		{
			raak = 15;
			myships[vijanddoel] = 2;
			state = STATE_6;
			break;
		}
		else
		{
			raak = 16;
			state = STATE_6;
			break;
		}

		case STATE_6:
			
		   Serial.print(raak, DEC);
		   Serial.print(send, DEC);
		   
	    
			 if(Serial.available()>14 && Serial.available()<17)
			 {
				 raak2 = Serial.read();
				 state = STATE_7;
				 break;
			 }
			 break;

		
		
		
		case STATE_7:
			
			
		Serial.print(raak, DEC);
		Serial.print(send, DEC);

You write "I am not sure if i am using right functions on the right way. ". But how are we to know what you are referring to when a snippet of your code is all you post.

And please get rid of ALL the blank lines.

Paul

You might want to check the documentation for what Serial.available() returns. It returns the number of chars available to read, not a number so your line:

if(Serial.available()>19 && Serial.available()<70)

will only be true if the number of chars in the input buffer is more than 19 but less than 70.

When you use Serial.print(), it takes a number and converts it into a string representation of that number and sends it over the wire. For example, if send = 12, the what gets sent over the wire is the string “12” which is two bytes (0x31, 0x32) so reading that in, you will never get the number 12 unless you convert it back Serial.parseint();

Thank you for your answer.

The microcontrollers have to send two numbers between 15 and 70 to each other. All var’s are integers and i want the incoming values to finally be integers as well. The rest of the code works well and is not important for the communication so i am not sure if its needed.

case STATE_4:
Serial.print(send, DEC);     
 if(Serial.available()>19 && Serial.available()<70)
  {
    recive = Serial.read();
    vijanddoel = recive-20;
    enemytarget[vijanddoel] = 1;
   if(vijanddoel > 19)
 {
 state = STATE_5;
         break;
 }
 }
 break; 
case STATE_5: 
Serial.print(send, DEC); 
if( myships[vijanddoel] == 1)
{
raak = 15;
myships[vijanddoel] = 2;
state = STATE_6;
break;
}
else
{
raak = 16;
state = STATE_6;
break;
}
case STATE_6: 
 Serial.print(raak, DEC);
Serial.print(send, DEC);      
 if(Serial.available()>14 && Serial.available()<17)
 {
   raak2 = Serial.read();
   state = STATE_7;
   break;
 }
    break; 
case STATE_7:
Serial.print(raak, DEC);
Serial.print(send, DEC);

blh64:
You might want to check the documentation for what Serial.available() returns. It returns the number of chars available to read, not a number so your line:

if(Serial.available()>19 && Serial.available()<70)

will only be true if the number of chars in the input buffer is more than 19 but less than 70.

When you use Serial.print(), it takes a number and converts it into a string representation of that number and sends it over the wire. For example, if send = 12, the what gets sent over the wire is the string “12” which is two bytes (0x31, 0x32) so reading that in, you will never get the number 12 unless you convert it back Serial.parseint();

Thank you for your anwser.

So i should replace Serial.read with Serial.parseint if i want just number and not a string, character or something else?

Or you can use Serial.write() which sends the byte directly. Serial.write(12) sends one byte (0x0C) which is different than Serial.print(12) which sends "12".

I'd suggest you read the manual. It's WAY faster than posting basic questions and waiting for responses.
https://www.arduino.cc/reference/en/language/functions/communication/serial/

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

The technique in the 3rd example will be the most reliable.

You can send data in a compatible format with code like this

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

And if you need more help please post your complete program.

…R

Try these functions, it might not be exactly want you need though but anyway here:

void sendSerial(long data) {
  Serial.begin(9600);
  Serial.print(data);
  while (Serial.read() != "*") {
    ;
  }
  Serial.print("+");
  while (Serial.read() != "^") {
    ;
  }
  delay(5);
}



long receiveSerial() {
  Serial.begin(9600);
  long returnData = Serial.read();
  Serial.print("*");
  while (Serial.read() != "+") {
     ;
  }
  Serial.print("^");
  return returnData;
}

The function sendSerial() sends the data in the provided parameters, and it waits for a comfirmination before continuing. The function receiveSerial() returns what data sent. This ensures that the processors don't get out of sync.

Hope this helps.

Unsigned_Arduino:
The function sendSerial() sends the data in the provided parameters, and it waits for a comfirmination before continuing.

What happens if the confirmation does not happen?

Don't use a blocking WHILE. Just listen for input in the regular non-blocking way (as in Serial Input Basics) and maybe add a timeout so that the sender can deal with a failed confirmation - perhaps by re-sending the message.

...R

Let's try this then...

boolean sendSerial(long data, byte attempts) {
  byte Iattempts = attempts;
  Serial.begin(9600);
  Serial.print(data);
  while (Serial.read() != "*") {
    unsigned long startTime1 = millis();
    if (millis - startTime = 5000) {
      Serial.print("!");
      Iattempts =- 1;
    }
    if (Iattempts = 0) {
      return 0;
    }
  }
  Serial.print("+");
  while (Serial.read() != "^") {
    startTime1 = millis();
    if (millis - startTime = 5000) {
      Serial.print("!");
      Iattempts =- 1;
    }
    if (Iattempts = 0) {
      return 0;
    }
  }
  delay(5);
  return 1;
}



long receiveSerial() {
  Serial.begin(9600);
  long returnData = Serial.read();
  Serial.print("*");
  while (Serial.read() != "+") {
    unsigned long startTime2 = millis();
    if (millis - startTime = 5000) {
       return 0;
    }
  }
  Serial.print("^");
  return returnData;
}


[code]

If input buffer size is default then seria.available cant be more than 64. No need to check <70

&&serial.available()<65

Unsigned_Arduino:
Let's try this then...

Maybe I have not understood your code but it looks to me like it blocks for up to 5 seconds while waiting for a response.

That may be OK for a particular project but it is hardly a general solution.

My approach, as an extension of the 3rd example in Serial Input Basics would be something like this

sendTheData();
dataSentMillis = millis();
waitingForReply = true;

if (newData == true) {
   waitingForReply = false;
}
if (waitingForReply == false and millis() - dataSentMillis >= timeoutMillis) {
   // waiting too long - do whatever
}

This way the Arduino can continue doing other things while waiting for the response

...R

Let’s try this then:

boolean sendSerial(long data, long waitTime) {
  byte Iattempts = attempts;
  Serial.begin(9600);
  Serial.print(data);
  unsigned long startTime;
  while (Serial.read() != "*") {
    if (millis() - startTime =< waitTime) {
      return 0;
    }
  }
  Serial.print("+");
  while (Serial.read() != "^") {
    startTime = millis();
    if (millis() - startTime =< waitTime) {
      return 0;
    }
  }
  delay(5);
  return 1;
}



char receiveSerial(long waitTime2) {
  Serial.begin(9600);
  long returnData = Serial.read();
  Serial.print("*");
  while (Serial.read() != "+") {
    unsigned long startTime2 = millis();
    if (millis - startTime = waitTime2) {
       return 0;
    }
  }
  Serial.print("^");
  return returnData;
}

The function sendSerial() sends data and waits for a comfirmination. If the timeout goes to 0, sendSerial() returns 0, indicating that there was no comfirmination.

The function receiveSerial() returns what data was transmitted, and it also waits for a confirmination. If the timeout goes to 0, receiveSerial() returns 0, indicating no data or a timeout.

It is also possible to communicate between Arduino boards with I2C or SPI.

You also might want to move this thread to the "networking, protocols, devices" section. I bet there are a ton of users that can help you with this.

There are the things to take a hard look at , perhaps the “switch” needs some more work too.

case STATE_6:

	Serial.print(raak, DEC);      // print raak in decimal format  
	Serial.print(send, DEC);

	if(Serial.available()>14 && Serial.available()<17)  

This should  just detect presence of data - generic term , the actual data format is irrelevant 
       
just      if(Serial,available())   NOTHING else , no HIGH , == 1 , >0 , != -1 etc. 

		raak2 = Serial.read();  reads SINGLE 8 bits  variable from serial buffer 

[b]now is the time to check the value of raak2 and analyze its format - numeric value between 13 and 17  or ASCII character or "end marker " or whatever [/b]
 
		state = STATE_7;
change state and apparently ignore raak2 in this state , just pass it on ? 
Perhaps just result of the initial if() being as  it was.  

		break;
	}
	break;

	case STATE_7:

Referring to Reply #12 ...

Unsigned_Arduino:
Let's try this then:

No thanks.

and to Reply #13 ...

You also might want to move this thread to the "networking, protocols, devices" section. I bet there are a ton of users that can help you with this.

Don't worry they will all have seen it where it is now.

...R

Before I do the following…

Unsigned_Arduino:
Let’s try this then:

What project are you working on exactly?