So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By bhageria
#63603 Hi

I am using the default UART on the nodeMCU board with the latest build from master branch.

The problem I am facing is that when I receive data, it gets split.
Here's the code:

Code: Select alluart.on("data", 0, function(data)
print("receive from uart:", data)
    if data==45 then
      uart.on("data") -- unregister callback function
end, 0)

When I send 6382548 from the serial terminal to the esp, it prints the following:

receive from uart: 6
receive from uart: 382548

Similarly for every data that is received on the esp through UART.

If I send 445, the esp receives 4 and 45 separately and unregisters the callback.

Could someone please help me with this problem?

User avatar
By jdavies
#63619 I don't think the data is actually being split, I think what is happening is that when you do the first read, only the 6 character is in the receive buffer, then the next pass of the loop you read the rest of the data that was received while you were still processing the first byte/char. This is referred to as a "race condition".

If your serial connection is set to send/rec a CR/LF line terminator, then I'd recommend you copying the characters you receive into an intermediate buffer until you get the CR/LF line terminators, then activate your code for processing the completed line. This will eliminate the problem you are seeing because you are processing the data before it is fully received.

I don't write LUA, but I have an example in C that better illustrates what I mean. I took this code from one of my projects and then cut out the section that I don't think are pertinent.

Code: Select all/*
   The purpose of this program is to test using the serial interface to setup a Bleu Farms
   board configuration in EEPROM. In this program I minimize the use of dynamic memory

#include <EEPROM.h>
#include <SoftwareSerial.h>

#define CR 0xD
#define LF 0xA

char cmdBuffer[COMMAND_BUFFER_SIZE]; // Allocate some space for the command string
int cmdBufferIndex;
char inChar = -1; // Where to store the character read
byte index = 0; // Index into array; where to store the character

void setup() {
  BTSerial.begin(9600);  // 38400

void loop() {
  // Check to see if the user has entered the setup command
  // over the serial connection
  if (serialDataAvailable() > 0) {

   Check to see if there is a command (or part of one) waiting to be processed
boolean serialDataAvailable(void) {
  char receivedChar;
  static unsigned long receivedTimeOut = millis();
  while (BTSerial.available() > 0) {
    receivedChar =;
    delay(10);  // Believe it or not, this slight delay is very important!
    if (receivedChar == CR || receivedChar == LF || cmdBufferIndex == COMMAND_BUFFER_SIZE - 1) {
      // Either the command is ended by a terminator character
      // or we have filled the buffer
      cmdBuffer[cmdBufferIndex] = 0; // terminate the string
      cmdBufferIndex = 0; // Start at the beginning of the buffer for the next command
      return true;  // There is data to be used in the cmdBuffer
    else {
      // Store the character in the buffer
      cmdBuffer[cmdBufferIndex] = receivedChar;
  return false;  // No data available, or the newLine terminator has not been received.

void processCommandLine() {
   // Your command processing code goes here.