Trouble with Serial event

Im sending two integers from one mega to another, both on Serial3.
Im formatting the outgoing message like this

   char ToSend[22];
sprintf_P(ToSend, (PGM_P)F("%04d, %04d, %02d"), THRO_VAL, RUDD_VAL, '\n');
      Serial.println (ToSend);
    Serial3.write (ToSend);

The data is going out. I put the oscilloscope on the TX of the sender and RX of the receiver. I see data.
on the receiving Arduino I have the basic serial event code.

String inputString = "test";      // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
   Serial.begin(115200);
   Serial3.begin(115200);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
   Serial.println(inputString);
}

void loop() {
  // print the string when a newline arrives:

  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial3.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
      
    }
  }
}

I am not receiving anything
Please help

Mitch

I suspect this wiped out the string you earlier put into inputString.

I tried it without reserve , and no results.

If you want to reserve memory, do that before putting anything into a string.

After you initialize the serial, give it time to begin. Delay a bit! It is NOT a blocking function.

Your serialEvent routine will look for incoming data on Serial, not Serial3.

If you want to check for incoming data on Serial3, you have to use serialEvent3, no?

In the serialEvent routine, you then check for data available on Serial3.

You then try to read from Serial.

Could you explain what it is you're trying to do here? I can't make heads nor tails of it.

1 Like

This will never send a newline ( \n ) to Serial3. Exactly why you are printing the decimal value of the newline character I'm not sure, but write() does not add a newline so you will have to include that in the text.

Try it this way:

  //Serial.println (ToSend); char ToSend[22];
  sprintf_P(ToSend, PSTR("%04d, %04d, %02d\n"), THRO_VAL, RUDD_VAL, '\n');

It would be better to not use String, and not even use Serial event. Instead, see example 2 of Serial Input Basics

2 Likes

David,
I tried all you recommended, including example 2.
It all works now. I thought SerialEvent was good, I used it in the past...

Would you know how to parse that data in 2 integers?
On the receiving side?

Thanks a lot Brother,
Mitch

I think I figured the parsing,
Works good.

void showNewData() 
{
    if (newData == true) {
       
    char* ptr;
    ptr = strtok(receivedChars, ",");
    X1_Latest = atof(ptr);
    ptr = strtok(NULL, ",");
    X2_Latest = atof(ptr);
      Serial.print("  X1 Latest: ");
      Serial.print(X1_Latest);
     Serial.print("  X2 Latest: ");
      Serial.println(X2_Latest);
 
  
        Serial.println(receivedChars);
        newData = false;
    }
}

Why do you use atof() when receiving integers? atoi() would be more suitable.

When using atoX() functions, it's advisable to check if the data is indeed correct. If you e.g. receive 12z, atoi() will return 0 (not sure what atof() does). Alternative to using the atoX() functions are the strtoX() functions like strtol(), strtod() etc; they do the checking for you

Great, atoi works great
thanks

Trying anther communication and Im having a hard time sending a float.

using
float f =3.33;
sprintf_P(ToSend, PSTR("%04f, %c, %02d\n"), f, 'D', '\n');
Serial3.write (ToSend);
Serial.println(ToSend);

Gets me back nonsense in the serial monitor.
?, D, 10
What am I doing wrong?
Thanks a lot buddy.

On AVR boards like the UNO and Mega, the support for floating point was removed from sprintf because the code was just too large. The usual workaround is to use dtostrf to convert the float to a char array and then use that in sprintf.

1 Like

Thanks, I just made it an int times 100 and divided it at the other end

I am trying to open another line of communication on Serial2. The data is sent like this

  sprintf_P(ToSend2, PSTR("%04d, %04d,  %04d, %04d, %04d, %04d, %02d\n"),  THRO_VAL, RUDD_VAL, GEAR_VAL, MIX_VAL, AUX4_VAL, AUX5_VAL,'\n');
   Serial2.write (ToSend2);

each value is a 4 digit integer, unsigned.

On the receiving end I got

const byte numChars2 = 36;
char receivedChars2[numChars];   // an array to store the received data
boolean newData2 = false;


void recvWithEndMarker2() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (Serial2.available() > 0 && newData2 == false) {
//Serial.println (rc);
    if (rc != endMarker) {
      receivedChars2[ndx] = rc;
      ndx++;
      if (ndx >= numChars2) {
        ndx = numChars2 - 1;
      }
    }
    else {
      receivedChars2[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData2 = true;
    }
  }
}

void showNewData2()

{
  if (newData2 == true) {
 // values int=  THRO_VAL, RUDD_VAL, GEAR_VAL, MIX_VAL, AUX4_VAL, AUX5_VAL;
 
    char* ptr;
    ptr = strtok(receivedChars2, ",");
    THRO_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    RUDD_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    GEAR_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    MIX_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    AUX4_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    AUX5_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");


    Serial.println(receivedChars2);
    //Serial.println(String(THRO_VAL) +" "+ String(RUDD_VAL)+ " "+ " "+ String(GEAR_VAL) +" "+ String(MIX_VAL)+ " "+ String(AUX4_VAL)+ " "+  String(AUX5_VAL));


    newData2 = false;
  }
}

No data shows up. What to do?
Thanks

Look at the difference between print and write. The write function with one argument only sends one character. There is also a write function that takes an array and a length, two arguments.

What you want though is Serial.print. It will send your whole array and stop at the '\n'.

The text you are sending is longer than 36 characters.

I did a Read string approach



  while (Serial2.available() > 0) {
    String Remote_Str = Serial2.readStringUntil('\n');
    int str_len = Remote_Str.length() + 1;
    char char_array[str_len];
    Remote_Str.toCharArray(char_array, str_len);
    Serial.println (char_array);

    char* ptr;
    ptr = strtok(char_array, ",");
    THRO_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    RUDD_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    GEAR_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    MIX_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    AUX4_VAL = atoi(ptr);
    ptr = strtok(NULL, ",");
    AUX5_VAL = atoi(ptr);
    Serial.println (THRO_VAL);
    Serial.println (RUDD_VAL);
    Serial.println (GEAR_VAL);
    Serial.println (MIX_VAL);
    Serial.println (AUX4_VAL);
    Serial.println (AUX5_VAL);
  }

Seems to work, but in the serial monitor I get a bunch of zeros printed again.
1084, 1464, 1872, 1096, 1064, 1100, 10
1084
1464
1872
1096
1064
1100

0
0
0
0
0
0

Figure why?
Thanks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.