Serial Event Communication

hi, below without serial event code working and with serial event code also working .

what is exactly Serial Event doing in my understanding is .
[SerialEvent() examplecode not working with Arduino Mega. - #4 by system]

  1. it's won't miss the data received in hardware rx .

if i have wrong understanding correct me . One more doubt is
String in_chars = ""; without reserve exactly how much byte it's take RAM memory as default .

String inputString = ""; inputString.reserve(200); - 200 bytes is understandable

without serial event & with Serial event :

String in_chars = "";

void setup() {
  Serial.begin(9600);
}

void loop() {
  char in_char = ' ';
  while (Serial.available()){
    in_char = Serial.read();
    if (int(in_char)!=-1){
      in_chars+=in_char;
    }
  }
  if (in_char=='\n'){
    Serial.print("Text Entered: ");
    Serial.print(in_chars);
    in_chars = "";
  }
}
///////////////////////////////////////////////////////////////


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

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

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 (Serial.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 use SerialEvent in my code, but there’s no need to if you don’t want to…

It is the same as testing if Serial.available() every pass around loop(), and subsequently calling the SeriallEvent() function.

No tricks. It’s convenient for some purposes.

Unfortunately that's wrong. SerialEvent() executes just before loop().

If your loop() takes too much time you still can miss characters. Else if you read multiple characters in serialEvent() you can block loop() until all characters have been transmitted.

I would suggest to study Serial Input Basics to have a better grasp on serial communication

Actually it is executed after loop() has been run

 for (;;) {
 loop();
 if (serialEventRun) serialEventRun();
 }

Of course, that only matters the first time that loop() runs

1 Like

consider

// -----------------------------------------------------------------------------
void loop (){
    char s [40];
    if (Serial.available ())  {
        int n = Serial.readBytesUntil ('\n', s, sizeof(s));
        s [n] = 0;      // ** un-corrected ** terminate with NULL

        Serial.println (s);
    }
}

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);
}

I have always regarded the SerialEvent() function as a waste of time, preferring to choose when and where in the code I check for serial input. If it were interrupt driven it would probably be more useful

Careful if you read 40 bytes…

as far as I know, it doesn't terminate with a NULL
??

It does not but s[40] does not exist

Why? That function will only consume sizeof(s) bytes from Serial and nothing more. Anything greater than that will be left in the buffer, available to read later

thanks

The risk is on the second line where you get a buffer overflow if n is 40

s [n] = 0;      // terminate with NULL, replace \n

You are correct. If you get exactly the size of the buffer, there will not be room to terminate it. Also, the comment replace \n is not correct since that character will be removed from the Serial input but not transferred to the return buffer s

Probably best to

int n = Serial.readBytesUntil ('\n', s, sizeof(s)-1);
s[n] = 0;

all programs will start to execute from the vector

int main(void)

in main.cpp deep within the arduino core:

int main(void) {
	init();
	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
	return 0;
}

As you can see, this main function initializes, calls setup() and then enters an infinite loop where it repeatedly calls loop() and serialEventRun() (if serialEventRun is true). All of the serial stuff is found in HardwareSerial.cpp. Here you can see that serialEventRun() is more conditional checks on the hardware, and then a call to serialEvent(), which is weakly defined in this same file, which you redefine in your INO file. This is the magic and mystery of what exactly happens.

1 Like

If you have to write a function with a 'magic' name to process serial data when there is some available then you might just as well write your own function with a name of your choice and call it at the end of loop() or anywhere else that is convenient

serialEvent() ?
Just say NO !

I fully agree.

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