Serial.available() returns different values

I am going to build a 121212 RGB LEDCube and I am testing a few things for this.
I will let an ESP8266 communcicate via UART with a Teensy 3.6, which I currently do not have.

For testing is a ESP8266 sending 6 bytes at 9600baud and after doing that does it pulls a pin to GND to trigger an Interrupt on an Arduino Mega that should read the 6 bytes.

If I read out the 6 Bytes my sketch did complete bullshit so I debugged it a bit and tried this:

void setup() {
	Serial.begin(9600);
	Serial2.begin(9600); //to ESP8266
	pinMode(2, INPUT_PULLUP); //Connected to the Pin that the ESP pulls to GND after sending the 6 bytes
	attachInterrupt(digitalPinToInterrupt(2), test, FALLING);
}

void test() { //Interrupt function
	delay(100);
	Serial.println("bla");
	if (Serial2.available())
		Serial.println(Serial2.available()); //prints 5, Why?
}

void loop() {
	if (Serial2.available())
		Serial.println(Serial2.available()); //prints like it is supposed to do, 6
	delay(1000);
}

When I let the ESP8266 send 6 bytes my Output looks like this:

bla
5
6
6
6
6
6

Why on earth does it deliver different values? The ESP8266 is caught in a infinity loop with ESP.wdtFeed(); which causes the ESP to do absolutely nothing.

I do not think that the code causes the error but a part of the code of the ESP looks like that:

Serial.write(send, 6);
		Serial.flush();
		digitalWrite(InterruptPin, LOW);
		while (!Serial.available()) { ESP.wdtFeed(); } //Waits for the Mega to send a byte to confirm everything went well, but the Mega does not send anything ->Infinity loop

Looks to me that the ESP is sending bytes, but the first check in setup, it has only received 5 of the 6. The second check in loop shows all 6 received.

SurferTim:
Looks to me that the ESP is sending bytes, but the first check in setup, it has only received 5 of the 6. The second check in loop shows all 6 received.

Yes, that should not be like that. The ESP sends 6 bytes with:

Serial.write(send, 6);
Serial.flush();

Serial.flush() lets the ESP wait until it has sent all 6 bytes. After all 6 bytes are sent it does pull the Interrupt Pin to GND. When the InterruptPin is pulled to GND the Mega executes the function 'test' and the test function does print the value of Serial2.available().
The value of Serial2.available() shows up as 5? Why on earth?!

The ESP just cannot send anything after the test function(which delivers 5) is called / the 6 bytes are sent because it is caught in the loop.

What also does not make sense:
The ESP sends 6 bytes and then executes the 'test' function but test say Serial2.available() equals 5? How?

hallolo:
Yes, that should not be like that. The ESP sends 6 bytes with:

What is happening is normal. Serial data arrives very slowly by Arduino standards. At 9600 baud there is about 1 millisec between characters. In 1 millisec a 16MHz Arduino can do 16,000 instructions.

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

...R

Robin2:
What is happening is normal. Serial data arrives very slowly by Arduino standards. At 9600 baud there is about 1 millisec between characters. In 1 millisec a 16MHz Arduino can do 16,000 instructions.

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

...R

I already had a look at your great article and read it now a second time but I cannot see what I am doing wrong here. I knew that it arrives pretty slowly and that's why I had a 100ms delay in the function 'test' that delivers wrong values.

If I increase the delay and insert one extra delay does it still produce the wrong output:

void test() {
	delay(1000); //was 100ms before
	Serial.println("bla");
	if (Serial2.available())
		delay(1000); //didnt exist before
		Serial.println(Serial2.available()); // Serial2.available() returns 5
}

100ms after all the data is sent by the ESP should be enough or am I wrong? Even 1000ms delivers wrong values

hallolo:
I already had a look at your great article and read it now a second time but I cannot see what I am doing wrong here. I knew that it arrives pretty slowly and that's why I had a 100ms delay in the function 'test' that delivers wrong values.

You may have noted that there are no delay()s in my code.

You may also notice that my code is only checking to see if there is at least one character and then it collects however many happen to be there.

Why does it matter to you that Serial.available() returns different values? if you want to receive 6 characters then check the value and if not try again later to see if all 6 are available. Don't stand around twiddling your thumbs for a delay() period.

...R

Robin2:
You may have noted that there are no delay()s in my code.

You may also notice that my code is only checking to see if there is at least one character and then it collects however many happen to be there.

Why does it matter to you that Serial.available() returns different values? if you want to receive 6 characters then check the value and if not try again later to see if all 6 are available. Don't stand around twiddling your thumbs for a delay() period.

...R

I will have running code for animations for the LEDCube on a Teensy 3.6 board. When the ESP8266 has to send data to the Teensy for example changing a color or changing the speed of an animation does the ESP send that data. After sending all that data(e. g. 6 bytes) does it pull a InterruptPin on the Teensy to GND to execute a function on the Teensy to read the data on the Teensy. The Code on the Teensy is blocking, it is not possible for me to repetedly read stuff.

I just do not understand what is happening there:
The ESP sends 6 bytes that should be after 100ms or even 1sec in the Serial buffer of the Mega(just for testing)/Teensy. After waiting 100ms or 1sec after the data is sent Serial2.available() returns 5(called in the ISR function) but 6 bytes were sent -> 6 bytes in the buffer -> Serial2.available() should be 6?
In loop() Serial2.available() returns 6. Do you understand what my problem is? I cannot use loop() to read the data. All the data reading has to happen in the function called by the Interrupt pin.

I just keep getting the wrong value of available():

The ESP sends 6 bytes to the RX2 Pin of the Mega. After waiting to send all that using Serial.flush() does the ESP pull Pin 2 of the Mega to GND to execute test().

test looks like that:

void test() {
 delay(100);
 Serial.println("bla");
 while (Serial2.available() != 6) { Serial.println(Serial2.available()); delay(200); } //Should print 6 because 6 bytes are sent -> 6 bytes in the buffer -> available() = bytes in buffer //but it prints 5 FOREVER
 Serial.println(Serial2.available());
}

Output of Serial monitor:

5
5
5
5
5
5
5
5

hallolo:
When the ESP8266 has to send data to the Teensy for example changing a color or changing the speed of an animation does the ESP send that data. After sending all that data(e. g. 6 bytes) does it pull a InterruptPin on the Teensy to GND to execute a function on the Teensy to read the data on the Teensy.

This is a poor way to do this.

The ESP8266 should not be puling any interrupt pin.

ESP8266 sends all 6 bytes.
Teensy continuously reads until it reads 6 bytes, then do something.

ieee488:
This is a poor way to do this.

The ESP8266 should not be puling any interrupt pin.

ESP8266 sends all 6 bytes.
Teensy continuously reads until it reads 6 bytes, then do something.

Adding a 100ms delay on the ESP8266 somehow solved my problem... I hope it will continue working.

I would like to avoid doing this like this but to do that, the code on the Teensy would have to periodically check if there is something in the Serial Buffer. Writing animations for a 121212 RGB LEDCube nonblocking is a lot more difficult than writing it blocking and using a Timer to check if there is new data would be uglier than the Interrupt. Do you have an alternative idea?

You should check whether you can actually do the animation straight from the Teensy before you add the complication of the ESP8266.

hallolo:
The Code on the Teensy is blocking, it is not possible for me to repetedly read stuff.

Then make it non-blocking.

...R

Making animations for 1728 LEDs which are partly created by several instances of different classes non-blocking is pretty difficult and I am not expereienced enough in C++ to do that. Maybe in the future. THank you all