Chat freely about anything...

User avatar
By Thomas S.
#52117 Hello,

I want to use the esp8266 for PC controlled robot control. I send all 10 ms data from the esp to the PC, and sometimes data from the PC to the esp.

Sending data all 10 ms from the esp to the PC works great, but whenever I send some data from the PC to the esp, the esp "freezes" for around 40 ms, e.g. it does not send out data for that time period.

I first thought to blame the mqtt lib for that, but now I made the same thing over an connected TCP socket, and got exactly the same result.

I was expecting some milli secs delay for the tcp/ip stuff the cpu has to deal with, but 40 ms for one packet receive is a bit much for a 80 MHz CPU.

I can supply source code if wanted.

This is my mesured output. The first number is the millis on the PC when printing out, the 2nd is the millis on the ESP when sending the value.
1470321366141 got value: 709552 sensor1=10
1470321366150 got value: 709562 sensor1=10
1470321366161 got value: 709572 sensor1=10
1470321366171 got value: 709582 sensor1=10
1470321366182 got value: 709592 sensor1=10
Sending new value 11
1470321366191 got value: 709602 sensor1=10
1470321366231 got value: 709641 sensor1=11
1470321366240 got value: 709651 sensor1=11
1470321366250 got value: 709661 sensor1=11
1470321366260 got value: 709671 sensor1=11
1470321366270 got value: 709681 sensor1=11

Any thoughts on that?
User avatar
By bbx10node
#52144 Please post source code. If possible, modify the sending program to set TCP NoDelay/disable Nagle to see if this helps or not. The method varies from language to language.

EDIT: UDP does not have Nagle delay so this might be a better choice for real-time data transfer.
User avatar
By Thomas S.
#52206 I tried the plain socket version with setNoDelay(true), but same result. In that version the esp was the server and the PC connected to it. I added the setNoDelay(true) to the client. Adding it to the server chrashed the programm.

Code: Select allWiFiServer server(80);
WiFiClient client;
...
  client = server.available();  // non blocking!
  if (client) {
      client.setNoDelay(true);
...

But as I said, it had no effect.

As the plain socket version is very bloated and ugly, I will attach the mqtt version.
However, the 40 ms delay is the same in both versions, and the Output on the PC looks basicly the same. As it is mqtt, the PC side can be replaced by any mqtt logging or so, but if you want me to post the PC side java prog as well, let me know. As mqtt server I used moskitto.

Code: Select all#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define wifi_ssid "XXXXX"
#define wifi_password "XXXXX"

#define mqtt_server "192.168.0.2"

WiFiClient wifi;
PubSubClient mqtt(wifi);

int sensor1;

void setup() {
  Serial.begin(115200);
  setup_wifi();
  mqtt.setServer(mqtt_server, 1883);
  mqtt.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  while (!mqtt.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (mqtt.connect("ESP8266Client")) {
      Serial.println("connected");
      mqtt.subscribe("/robot/actors", 1);
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {

  // each receiving msg stopps the ESP for 40 ms
 
  payload[length] = '\0';
  String s = String((char*)payload);
  sensor1 = s.toInt();
}


long lastMsg = 0;

void loop() {
  if (!mqtt.connected()) {
    reconnect();
  }
  mqtt.loop();

  long now = millis();
  if (now - lastMsg >= 10) {
    lastMsg = now;

    //Serial.print("New temperature:");
    //Serial.println(String(temp).c_str());
    now = millis();
    mqtt.publish("/robot/sensors", String(now).c_str() , true);
    mqtt.publish("/robot/sensors", String(sensor1).c_str(), true);
    now = millis();
    mqtt.publish("/robot/sensors", String(now).c_str() , true);

  }
}
User avatar
By bbx10node
#52209 I will take a closer look today.

Also I had some small test programs from an investigation I did a few years ago showing 100 small packets/sec is possible using UDP. And maybe TCP can do this too with some tuning. It was for a different system but the ESP is much faster. I will try to fix up and post the code.

Another possibility especially with Arduino code is there are calls to delay() in the sketch or a library. This will reduce the ability of the sketch to send/receive network packets. For example, if the sketch calls a function to read a sensor and the function does this.

Code: Select allint read_sensor() {
  start conversion
  delay(40);
  read result
  return result
}