ESP8266 programmed with Arduino => How to clear RX-buffer?

I’ve got less experience with programming in Arduino but I’m working on my first project.

It’s a project for sending smartcard-data (I/O) from one ESP-01-module (accesspoint) via TCP to other ESP-01-modules (clients).

Because the I/O-line uses the same wire for transmitting as for receiving data and the ESP-modules have a seperate RX- and TX-pin, the RX- and TX-pins are connected to eachother via a level-shifter.

Here’s the problem.
If the ESP-module transmits data from the TX-buffer to the TX-pin, this data goes to the I/O-line but it also loopbacks via the RX-pin into the RX-buffer and that’s a problem.

I’m looking for a solution to clear the RX-buffer immediately after the TX-buffer has send all the data.

Serial.flush doesn’t work anymore.

I’ve searched all the internet but I can’t find a solution that works.

Can somebody tell me how to clear the RX-buffer?

Just keep reading whatever is available, and discard/ignore the results.

joentje1978:
Serial.flush doesn’t work anymore.

flush clears the send buffer. It is how you stop and make sure you wait until you’re done sending. Nothing to do with receiving.

It sounds like you just need to remove those bytes from the buffer. The easiest way is to just read them out. Keep track of how many bytes you send (print will return this for you) and simply read those out.

for(int i=0; i<numberOfBytesSent; i++){
   Serial.read();
}

This is the script:

void loop()
{
client.connect(server, 23); // Connection to the server

if (client) {
while(client.connected()){

// Read data from the connected client and write it to the serial-port
while(client.available()>0){
Serial.write(client.read());

=> AT THIS POINT I WANT TO CLEAR THE RX-BUFFER <=
}

// Read data from serial-port and send it to the connected client
while(Serial.available()>0){
client.write(Serial.read());
}
}

// Disconnect client from server
client.stop();
}
}

Do just what I said and count the bytes and read them back out.

Hangon, I'm trying to write you an example but I can't deal with your code formatting. I gotta take it to the editor to figure out which braces go with what.

RE-EDIT: Nope, back to my original comment. Please also use Control-T to format your code. That lines up the blocks and makes it easier to see.

I'll be right back.

void loop()
{
  client.connect(server, 23);   // Connection to the server

  if (client) {
    while (client.connected()) {

      // Read data from the connected client and write it to the serial-port
      int byteCounter = 0;
      while (client.available() > 0) {
        Serial.write(client.read());
        byteCounter++;
      }
      ///  Clear the receive buffer of byteCounter bytes
      while(byteCounter){
        if(Serial.read() > -1){
          byteCounter--;
        }
      }

      // Read data from serial-port and send it to the connected client
      while (Serial.available() > 0) {
        client.write(Serial.read());
      }
    }

    // Disconnect client from server
    client.stop();
  }
}

We're checking against -1 because that's what read will return if the byte hasn't made it back to the receive buffer yet. You have to leave time for it to make the round trip.

But you're going to have a bigger problem because it looks like on the next line you're expecting that something will be sending serial data to you. If there's also traffic on the line from something else echoing that last statement then you're going to have collisions. It really sounds like this is a band-aid for a bigger problem and you're still going to have issues.

"I'm looking for a solution to clear the RX-buffer immediately after the TX-buffer has send all the data."

Is this a client/server rx buffer or a serial rx buffer?

Isn't the rx buffer a ring-buffer ? don't you just change the ptr for the next byte to be read, to the next byte to be received ? the re is no real eed to actually read the bytes, you can adapt or i think you can actually take control of the hwSerial (i've seen some libraries do that) anyway the answer should be harwareSerial.cpp (and it's related files, it will be a bit of a search)

Yeah, was just trying to keep it simple since it’s really a fools errand here anyways. Unless there’s some code somewhere we’re not seeing that’s going to know to hold up the sender side of that serial connection while the loop back is happening.

Imagine doing all that work learning about ring buffers and the Serial libraries just to have it not help the real issue in the end.

I think I have found a simple solution which I had already found a few months ago.

I had seen that I could clear the buffer with:
while(Serial.available()>0){
Serial.read();
}

But that didn't work because not only the loopbacked data in the RX-buffer cleared but also the serial data from the smardcard.

Tonight I only tried Serial.read(); but it didn't work either but I've just discovered I have to place a short delay so first all the loopbacked data must be in the RX-buffer and then clear the buffer.

I only hope the delay doesn't give problems, it has to be adjusted so it works with short data and longer data.

Had a problem with that settings when I disconnected the RX-pin of the ESP-module with a MOSFET-transistor.

Serial.flush doesn’t work anymore.

Mind you, before you set the pointers to the same valuu, you should do Serial.flush(); just to make sure that the last byte has been sent, or the buffer won’t be empty before you start receiving.
Look for Serial.available() within the core. available() actually just deduct one of the pointers from the other and returns the number of bytes that way.

I only hope the delay doesn't give problems, it has to be adjusted so it works with short data and longer data.

And there it is. If you keep with this road this problem will vex you to no end. Every time you change anything you’ll have to wonder if this is going to mess you up.

A better solution must be had to stop data collisions. Don’t code around them. Stop them.

Show us a schematic how this is wired up. I don’t understand why you have this loop back issue in the first place. But it would be way smarter to fix that instead.

Another way would be to perform a read immediately after any write. You can even compare them to see if they have the same value, just to be on the safe side.

Another option would be to start reading bytes while you are still sending them. What Baud rate are you using ? There is some 'lag' in the transmission, the request for the next byte in memory from the UART comes the moment that the previous byte is (nearly) completely sent, but only once that byte has been completely received does it get moved into the UART receive buffer, from which it gets moved into memory, there is always at least 1 byte 'in transit' so not only will you have to keep the buffer near empty, but you will have to clear that last byte as well. I would go for the first method, but there as well, you may need to wait just a tiny bit after Serial.flush() before you set the pointer to the same (funnily enough it doesn't really matter which you set what, either way that means the buffer is empty.)

And what about a hardware option ? Now you connect the ESP TX-> RX, but yo can put a logic AND or OR gate in between where the other input comes from one of the pins, that way you can block path to the RX pin while you are transmitting, again you would need to .flush() and wait just a little.

aarg:
Another way would be to perform a read immediately after any write. You can even compare them to see if they have the same value, just to be on the safe side.

Well not immediately immediately. You’ll have to wait a little bit for the transmission to happen.