Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT/Ethernet message throttling at control cycle of <0.03 (1 message every 30ms) #9996

Open
1 task done
programmeddeath1 opened this issue Jul 8, 2024 · 0 comments
Open
1 task done
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@programmeddeath1
Copy link

programmeddeath1 commented Jul 8, 2024

Board

Olimex esp32-EVB-IND

Device Description

Default esp32-evb-ind connected using LAN link-local only with Static IP connected to laptop

Hardware Configuration

Only LAN Cable conncted

Version

v3.0.0

IDE Name

Arduino IDE

Operating System

Ubuntu 22

Flash frequency

80MHz

PSRAM enabled

yes

Upload speed

115200

Description

I am using the olimex esp32-evb-ind to execute the position,velocity and acceleration of a robotic arm. The path is generated on a cpu and the coordinates are then sent to the esp32 over ethernet cable.

When sending data over a control cycle of 0.04 (1 point generated every 0.04s or 40ms). The communication time from the cpu to esp32 is avg around 4ms (RTT) ie 2ms for communication
<style type="text/css"></style>

ID sentTime ReceiveTime ExecutedTime Communication time Execution time
1 1720436672 1720436672 1720436672 4.03 4.96
2 1720436673 1720436673 1720436673 3.72 4.54
3 1720436673 1720436673 1720436673 4.01 4.96
4 1720436673 1720436673 1720436673 3.5 4.37
5 1720436673 1720436673 1720436673 4.19 5.49
6 1720436673 1720436673 1720436673 3.24 4.32
7 1720436673 1720436673 1720436673 3.62 4.5
8 1720436673 1720436673 1720436673 3.87 4.64
9 1720436674 1720436674 1720436674 4.27 5.19
10 1720436674 1720436674 1720436674 4.27 5.17

But if i reducee the control cycle to below 0.03, eg at 0.01, there seems to be significant lag and pile-up of messages causing constant lag
<style type="text/css"></style>

Test 1 sentTime ReceiveTime ExecutedTime Communication time Execution time
1 1719317147 1719317147 1719317147 6.15 14.68
2 1719317147 1719317147 1719317147 14.63 25.86
3 1719317147 1719317147 1719317147 25.57 26.35
4 1719317147 1719317147 1719317147 25.49 26.54
5 1719317147 1719317147 1719317147 26.25 27.66
6 1719317147 1719317147 1719317147 25.65 26.82
7 1719317147 1719317147 1719317147 25.97 27.35
8 1719317147 1719317147 1719317147 25.17 26.31
9 1719317147 1719317147 1719317147 24.14 25.3
10 1719317147 1719317147 1719317147 24.15 25.05

I tried controlling the background processes by creating the mqtt callback task to pin to a core using xTaskCreatePinnedToCore. Such that it was run on core 0 as well as core 1, but the lag seems to remain.

Also the lag seems to be more on control cycle of 0.02 and 0.03 - <style type="text/css"></style>

1 1720436867 1720436867 1720436867 3.12 28.74
2 1720436867 1720436867 1720436867 28.88 55.37
3 1720436867 1720436867 1720436867 55.61 56.43
4 1720436867 1720436867 1720436867 55.33 56.06
5 1720436867 1720436867 1720436867 52.8 53.77
6 1720436867 1720436867 1720436867 47.12 48
7 1720436867 1720436867 1720436867 47.66 48.47
8 1720436867 1720436867 1720436867 47.18 47.99
9 1720436867 1720436867 1720436867 47.01 47.81
10 1720436867 1720436867 1720436867 47.2 48.27

I tried changing the message data size, sending in json format or as encoded byte format, but there seems to be almost no difference in the processing time.

Is this a limitation with the cpu processing capabilities of the esp32 that its not able to process points at such high frequencies.

The esp32 DOIT kit which runs WROOM-32 is able to achieve faster times with uart at a baud rate of 4000000. It seems counterintuitive that uart is faster here than ethernet or mqtt over LAN.

I have connected the esp32 over a link-local only lan setup and no router, the ping times are around 0.3ms.

Sketch

#include <Arduino.h>
#include <ETH.h>
#include <string.h>

#include <PubSubClient.h>
#include <SPI.h>
#include "utilities.h"          // Board PinMap   
#include <WiFi.h>
#include <FastAccelStepper.h>
#include <cppQueue.h>
#include <ArduinoJson.h>

// MQTT Broker settings
const char* mqtt_broker = "169.254.1.1";
const int mqtt_port = 1883;
// const char* mqtt_client_id = "ESP32Client";
String mqtt_client_id = "ESP32Client-";
const char* mqtt_username = "";  // Leave empty if not used
const char* mqtt_password = "";  // Leave empty if not used

IPAddress staticIP(169, 254, 1, 2);
IPAddress gateway(169, 254, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress dns(169, 254, 1, 1);

WiFiClient ethClient;
PubSubClient client(ethClient);
void mqttCallback(char* topic, uint8_t* payload, unsigned int length) {
//    Serial.print("MQTT callback Task running on core ");
//    Serial.println(xPortGetCoreID());    
    MqttMessage message;
    strncpy(message.topic, topic, sizeof(message.topic) - 1);
    message.topic[sizeof(message.topic) - 1] = '\0';
    memcpy(message.payload, payload, length);
    message.length = length;
    if (xQueueSend(mqttQueue, &message, portMAX_DELAY) != pdPASS) {
        Serial.println("Failed to send to mqttQueue");
    }
}
void executeArm() {
    MqttMessage message;
    if (xQueueReceive(mqttQueue, &message, portMAX_DELAY) == pdPASS) {
        if (String(message.topic) == "delta_arm/command") {
            float positions[3], velocities[3], accelerations[3], effort;
            unsigned int count;
//                memcpy(positions, message.payload, 3 * sizeof(float));
//                memcpy(velocities, message.payload + 3 * sizeof(float), 3 * sizeof(float));
//                memcpy(accelerations, message.payload + 6 * sizeof(float), 3 * sizeof(float));
//                memcpy(&effort, message.payload + 9 * sizeof(float), sizeof(float));
//                memcpy(&count, message.payload + 10 * sizeof(float), sizeof(unsigned int));
            memcpy(&count, message.payload, sizeof(unsigned int));
            sendFeedback(1, count); // Feedback at the start of callback

            // Print the unpacked data
//                Serial.print("Positions: ");
//                for (int i = 0; i < 3; i++) {
//                    Serial.print(positions[i]);
//                    Serial.print(" ");
//                }
//                Serial.println();
//                Serial.print("Velocities: ");
//                for (int i = 0; i < 3; i++) {
//                    Serial.print(velocities[i]);
//                    Serial.print(" ");
//                }
//                Serial.println();
//                Serial.print("Accelerations: ");
//                for (int i = 0; i < 3; i++) {
//                    Serial.print(accelerations[i]);
//                    Serial.print(" ");
//                }
//                Serial.println();
//                Serial.print("Effort: ");
//                Serial.println(effort);
//                Serial.print("Count: ");
//                Serial.println(count);

            sendFeedback(2, count); // Feedback at the end of callback
        }
    }
}

void setup() {
    Serial.begin(115200);
    Serial.println("Setup started");

    WiFi.onEvent(WiFiEvent);
    ETH.begin();


    if (ETH.config(staticIP, gateway, subnet, dns, dns) == false) {
        Serial.println("Static IP Configuration failed.");
    }

    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(mqttCallback);

    while (!client.connected()) {
        Serial.println("Connecting to MQTT...");
        if (client.connect(mqtt_client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Connected to MQTT Broker!");
        } else {
            Serial.print("Failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }

    client.subscribe("delta_arm/command");


    delay(1500);
    Serial.println("Homing.......");
    // motorHoming();
    delay(1000);
    Serial.println("Homing Done !!");

//    for (int num = 0; num < MOTOR_COUNT; num++) {
//        set_point(num, HOME_POS, SPEED_IN_MM_S, ACCEL_IN_MM_S);
//    }
    // Create the queue
    mqttQueue = xQueueCreate(10, sizeof(MqttMessage));
    if (mqttQueue == NULL) {
        Serial.println("Error creating the queue");
    }

    // Create the MQTT task and pin it to Core 0
    xTaskCreatePinnedToCore(
        mqttTask,
        "MQTT Task",
        4096,
        NULL,
        2,
        &mqttTaskHandle,
        1 // Core 0
    );

    Serial.println("Setup completed");
}


void loop() {
  
  executeArm();

Debug Message

NA

Other Steps to Reproduce

Try publishing messages over MQTT at a rate of 10ms or 20ms or 30ms.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@programmeddeath1 programmeddeath1 added the Status: Awaiting triage Issue is waiting for triage label Jul 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

1 participant