Varying data rate Arduino nano with ESP8266 NodeMCU

Hello,

I am using an Arduino nano that is reading from 2 analog sensors at a rate of 1khz, and sends serial data to ESP8266 NodeMCU that then should send data to laptop over WIFI. The issue is that as I receive the data on my laptop, the data rate is lower (around 800 readings/sec), and is varying a lot +- 50 readings. I do some computations that require the sampling frequency to be almost 1khz, so this is causing troubles. I would appreciate some feedback on the code below.

Arduino:

#include <SoftwareSerial.h>

//Initialise Arduino to NodeMCU (5=Rx & 6=Tx)
SoftwareSerial nodemcu(5, 6);

unsigned int ch1, ch2;
byte buffer[10];

void setup() {
  Serial.begin(115200);
  nodemcu.begin(57600);
  delay(1000);
  Serial.println("Program started");
}

unsigned long t;
void loop() {
  static uint32_t last_conversion_time = micros();
    if (micros() - last_conversion_time >= 1000) {
        
        last_conversion_time += 1000;
        ch1 = analogRead(A0);
        ch2 = analogRead(A1);

        buffer[0] = '<';
        
        buffer[1] = (ch1 >> 8);
        buffer[2] = ch1 % 256;

        buffer[3] = (ch2 >> 8);
        buffer[4] = ch2 % 256;

        buffer[5] = '>';
        
        nodemcu.write(buffer, 6);
        Serial.print(buffer[1]*256+buffer[2]);
        Serial.print(buffer[2]*256+buffer[4]);
        
        
    }
}

NodeMcu code:

#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>

int port = 5555;  //Port number
WiFiServer server(port);

//Edit this to add your network ssid and password
//const char *ssid = "";
//const char *password = "";

unsigned int ch1, ch2;

const int BUFFER_SIZE = 16;
byte buf[BUFFER_SIZE];

SoftwareSerial nodemcu(D6, D5);

void setup() 
{
  Serial.begin(115200);
  nodemcu.begin(57600);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password); //Connect to wifi
 
  // Wait for connection  
  Serial.println("Connecting to Wifi");
  while (WiFi.status() != WL_CONNECTED) {   
    delay(500);
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  
  server.begin();
  Serial.print("Open Telnet and connect to IP:");
  Serial.print(WiFi.localIP());
  Serial.print(" on port ");
  Serial.println(port);
}

void loop() 
{
  WiFiClient client = server.available();
  
  if (client) {
    if(client.connected())
    {
      Serial.println("Client Connected");
    }
    
    while(client.connected()){   
      //discard incomplete readings
      if(nodemcu.available() > 5)
      {
        buf[0] = nodemcu.read();
        if(buf[0] == '<')
        {
          for(int i = 1; i < 6; ++i)
          {
            buf[i] = nodemcu.read();
          }
          if(buf[5] == '>')
          {
            ch1 = buf[1]*256 + buf[2];
            ch2 = buf[3]*256 + buf[4];
            client.print(ch1);
            client.print(",");
            client.println(ch2); 
          }
        }
        }
      }
      
     client.stop();
     Serial.println("Client disconnected");   
  }
}

You know that TCP/IP (the internet transport mechanism) and also Wifi have unpredictable latency?

Not without external or internal documentation provided.

Does that really = 1000khz ?

leave away the Arduino UNO
switch over to an ESP32 with more AnalogInputs or use an ADC for the NodeMCU.

Sorry I mean 1Khz, I'll edit the question.

My required rate is 1Khz, and I am sending 6 bytes so that makes my data rate 6 kilobytes per second. Isn't this rate very low that the latency of TCP/IP and WiFi should be negligible in comparison with? I am just listening to the port on my laptop, do you think using a messaging queue instead would help? Or are there other alternatives?

Your serial communications between the Nano and ESP8266 is not adequate. 57600 baud allows for 5760 characters/seconds (at 1 start bit + 8 data bits + 1 stop bit). Each sample sends 6 characters, at 1000 samples /seconds that would need 6000 characters/second. The analog inputs are each 10 bits, so you could get creative in how to combine these into fewer bytes (3 bytes total should be possible).

I'm not familiar with sending data over WiFi, can you guarantee that the client.print() statements can complete rapidly enough that the serial buffer does not overflow? Is there a possibility of a latency spike in the WiFi link?

There always is. That was my point. That is why streaming services are buffered at the receive end.

assuming you have access to the TCP server code as well as the WiFiClient try buffing your data as into a byte array and transmitting using

size_t WiFiClient::write(const uint8_t *buf, size_t size)

would be a good idea to add a sequence number to the buffer so you can check for lost packets

are you sure the NodeMcu is receiving a 1000samples/second ? could you be loosing data on the Arduino to NodeMCU serial link

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