Asked

Alternative To Ezrobot Ezb For Robot Head Project

My course has primarily focused on robotics projects using the EZ-B controller and a camera for real-time interfacing. With recent developments, I am planning to create an additional video that incorporates Synthiam's support for other types of controllers. Although I've successfully flashed an alternative controller, it lacked compatibility with camera integration and Wi-Fi capabilities. The absence of an onboard computer limits the use of a USB camera, posing a significant challenge.

This dependency on specific components like the EZ-B, IO Tiny, and cameras can be problematic. For my course project, Mecha Morphix, which involves controlling five servos, the Arduino Mega seems excessive. I am in search of a suitable controller, compatible with Synthiam ARC, that includes both Wi-Fi and camera support to effectively replace the EZ-B.

I noticed that the ESP32 with a camera is listed among the supported controllers for ARC. Has anyone experimented with using the ESP32 in conjunction with a camera for such applications? Any insights or experiences would be appreciated.


Related Hardware ESP32 Cam

ARC Pro

Upgrade to ARC Pro

Subscribe to ARC Pro, and your robot will become a canvas for your imagination, limited only by your creativity.

#25  

I'm not sure how your setup works. However is it possible that you need a faster baud rate set some where?

@Athena , Is it possible to set the serial baud rate for the Doit ESP 32 that fxrtst is using to a faster setting to allow a servo motor to respond to movement commands faster?

Author Avatar
PRO
USA
#26  

...it looks like its 115200...

Author Avatar
PRO
Canada
#27  

Good thread - lots of useful context. Here’s a focused troubleshooting checklist and recommendations to reduce the servo lag you’re seeing with the DoIt ESP32 (ESP32-CAM style) + camera streaming.

Quick summary of likely causes

  • UART bandwidth / baud rate too low for the command rate.
  • Using the wrong UART (software/virtual vs hardware) or wrong pins.
  • CPU starvation/jitter from the camera streaming (camera + WiFi is CPU/network heavy).
  • Host-side sending commands continuously (no batching/caching).
  • Power/grounding issues for servos (voltage droop causes slow responses).
  • No hardware flow control and/or serial buffer buildup.

What to try now (ordered, minimal changes first)

  1. Verify and raise the serial baud (both ends)
  • If the ESP32 sketch uses Serial.begin(115200) and ARC/Serial Toolbox is set to 115200, try a higher baud like 921600 or 2,000,000 (ESP32 UARTs support multi-Mbps).
  • Change both sides to match.

Example (Arduino/ESP32):

void setup() {
  Serial.begin(115200);                // logs to USB
  // Use a hardware UART for ARC/servo bridge:
  // Serial1 uses (TX1, RX1) pins you choose on ESP32
  Serial1.begin(921600, SERIAL_8N1, RX_PIN, TX_PIN);
}
  • Replace RX_PIN/TX_PIN with the pins you use. If you’re using the ESP32-CAM board, be careful which pins are free (camera pins may conflict).
  1. Use a hardware UART (not bit-banged)
  • Ensure you are using one of the ESP32’s UARTs (Serial1 or Serial2) mapped to real GPIO pins, not a software implementation. Hardware UART is much more reliable at high throughput.
  1. Reduce camera load while testing
  • Lower camera resolution and fps temporarily to see if camera streaming is starving the MCU or WiFi:
    • Lower frame size (VGA or lower) and reduce FPS.
    • If the lag improves, camera streaming is interfering-either reduce streaming load or move servo control to a dedicated MCU.
  1. Batch/cached servo updates instead of continuous flooding
  • Don’t send a servo command every mouse pixel. Buffer servo positions and send them at a limited rate (e.g., 20-30 Hz) or only when position delta > threshold.
  • If you’re using the Single Camera servo Server or a custom client, use the "cache and send" approach (SetCachedServoPosition + SendCachedServoPositions pattern) so ARC or the client sends bulk updates fewer times per second.
  1. Power & wiring
  • Ensure servos have a proper 5V supply able to source peak current. If battery/USB only, the servo signals may lag under load.
  • Common ground between ESP32 and servo power supply is required.
  • Add decoupling caps near servo power rails.
  1. Consider hardware flow control or a faster USB/bridge MCU
  1. If you continue with ESP32-CAM: accept limitations and/or split responsibilities
  • ESP32-CAM is cheap and supported by Synthiam firmware (see ESP32-Cam EZB firmware): https://synthiam.com/Support/Hardware/ESP32-Cam
  • It’s fine for a small head (up to ~5 servos) but avoid heavy simultaneous tasks. If you need camera + many servos + complex sensor processing, use a separate MCU for servos or a more capable board (ESP32-S3, Teensy, or a USB-capable board).

Useful links

How to change robot skill / plugin settings (kebab menu)

  1. Project Add robot skill choose the skill (Serial Toolbox / Single Camera servo Server).
  2. Open the robot skill window.
  3. Click the three-line kebab menu (top-right of the skill window) Settings.
  4. Adjust baud, serial port, frame-rate, buffering, etc., and Save.

Follow-up questions so I can give precise steps or a sample sketch

  • Which exact firmware/sketch did you flash to the DoIt ESP32? (If it’s a Synthiam build, which version?)
  • Are you using ARC to connect to the ESP32 over WiFi (EZB protocol) or are you using the Serial Toolbox (USB serial bridge) approach?
  • Are servos driven directly by the ESP32 GPIO PWM, or are you forwarding commands to a separate servo controller?
  • How are the servos powered (5V USB? battery? regulated supply and capacity)?
  • Can you paste the exact serial settings in the plugin and the Serial.begin lines from your sketch? (I can’t view images - paste text here.)

If you want, I can:

  • Provide a minimal ESP32 sketch that reads simple binary/batched servo packets and updates servos from a timer (low jitter).
  • Suggest concrete baud values and Serial1 pin choices for your exact ESP32 module.
  • Help tune Single Camera servo Server or Serial Toolbox settings for lower latency.

Which of the above would you like me to prepare next?


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
Author Avatar
PRO
USA
#29   — Edited

I've increased the baud rate nothing has changed. Moves same speed. Its about a nine second delay.

Author Avatar
PRO
Canada
#30  

Thanks - that clarifies a lot. Because you are using an ESP32 DevKit v1 in AdHoc (AP) WiFi mode (not USB/UART), the 9second lag is almost certainly network/firmware/CPU scheduling related rather than a pure serial baud issue.

Below is a focused checklist and stepbystep tests to isolate the problem and fixes you can try. I’ll also include small code snippets you can flash to the ESP32 to help diagnose and tune.

Quick checklist (most likely causes)

  • WiFi AP mode or PC WiFi adapter behavior causing high latency or packet buffering.
  • ESP32 firmware doing camera streaming + servo updates on the same loop, starving servo updates.
  • WiFi power save enabled on the ESP32 or PC adapter, causing long micro bursts or aggregated packets.
  • ARC/skill update interval or batching is set too slow (plugin throttling).
  • Camera encode/upload saturating CPU or WiFi bandwidth.
  • Power wiring for servos (if servos power is drooping, behavior can appear like a delay).

Immediate isolation tests (do these first)

  1. Ping test (measure raw network latency)
  • On the PC connect to the ESP32 AP and open a Command Prompt: ping <ESP32 IP> -n 20
  • Look at response times and packet loss. Typical good latencies should be single/double-digit ms. If pings show many seconds or timeouts, network is the culprit.
  1. Disable camera streaming in ARC temporarily
  • Stop the Single Camera / camera feed in ARC and test servo commands.
  • If lag disappears or drops dramatically, the camera stream is interfering (CPU/network/bandwidth).
  1. Disable other robot skills / traffic
  • Remove or pause Serial Toolbox / other skills so only the ESP32 device is connected. Test again.
  1. Test a simple HTTP/UDP servo set (bypass ARC flow)
  • Make the ESP32 listen for a simple UDP packet or HTTP get that immediately updates a servo. From the PC, use a small script / browser / curl call to trigger the servo and watch responsiveness.
  • This proves whether the ESP32 can respond quickly independent of ARC.

ARC / robot skill checks

  • Open the robot skill window that controls the ESP32 (Project Add robot skill or open the existing skill).
  • Click the kebab (three-line) menu Settings.
  • Check for any "Update Interval", "Send Interval", "Frame Rate" or buffering options. Reduce to something like 20-50 ms for servo updates while testing.
  • If the skill has a camera encoding/frame-size option, reduce frame size/FPS (e.g., VGA or QVGA and 10-15 FPS) to test.

WiFi power save and AP vs Station mode

  • AP (AdHoc) mode can be slower / behave differently depending on the PC WiFi adapter. Try switching the ESP32 to Station mode (connect the ESP32 to your router and put your PC on same LAN). Station mode often reduces latency.
  • Disable WiFi power save on the ESP32 (this avoids the ESP sleeping/aggregating TX which can add latency).

ESP32 code to disable WiFi power save (Arduino core)

#include <WiFi.h>
#include "esp_wifi.h"

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_AP); // or WIFI_STA (recommended: use WIFI_STA connected to your router)
  WiFi.softAP("ESP32-AP");
  // Disable Wi-Fi power save
  esp_wifi_set_ps(WIFI_PS_NONE);
  // setup servo outputs, tasks, etc.
}

void loop() {
  // lightweight: handle a UDP or HTTP socket and update servos in a high-priority task
}

If you use Station (WIFI_STA) mode, connect the ESP32 to your local router and test from PC on same LAN.

CPU & firmware architecture

  • If the same task is encoding frames and controlling servos, create separate tasks: one highpriority task that reads incoming network commands and writes servos, and another (lowerpriority) task for camera capture and upload.
  • Keep servo updates very lightweight: parse packet, write PWM/ledc, return.

Batching and throttling

  • Don’t flood the ESP32 with every tiny mouse movement update. Batch to a fixed update rate (20-30Hz) or only send when delta > threshold.
  • If you’re using Single Camera servo Server or a client, use the "cache and send" pattern (SetCachedServoPosition + SendCachedServoPositions) so you send grouped updates instead of hundreds/sec.

Power & wiring

  • Confirm servo power supply is adequate and share common ground with the ESP32.
  • If powered from USB only, servo voltage/current sag could cause slow behavior. Use a proper 5V regulated supply with enough current headroom for your servos.

If you want a quick test firmware to confirm lowlatency control:

  • I can prepare a minimal ESP32 sketch that:
    • Runs in STA mode (or AP, your choice)
    • Disables WiFi power save
    • Opens a UDP port and immediately applies servo commands on receipt
    • Uses a dedicated task for servo writes and a low-latency ledcWrite Would you like that? If yes, tell me:
  • Do you prefer AP mode or STA (router) mode for testing?
  • Which GPIO pins are your servos connected to? (ESP32 devkit GPIO numbers)
  • How many servos and how are they powered?

Follow-up diagnostic info I need from you

  • Which ESP32 firmware did you flash (Synthiam ESP32 DevKit v1 firmware link if used)? Version? https://synthiam.com/Support/Hardware/Esp32-DevKit-v1
  • Are the servos physically connected to the ESP32 DevKit v1 (direct PWM) or controlled via another servo controller?
  • Are you controlling servos using Single Camera servo Server or some other robot skill? Which skill sends the servo commands?
  • Is the camera still on while testing? (Try turning it off temporarily.)
  • What IP (AP default 192.168.4.1?) are you connecting to - can you run ping and paste results?
  • How are the servos powered (USB 5V, separate battery, regulator)? Please include voltage and battery type.

Recommendations if you need a more robust solution

  • If you need camera + reliable low-latency servo control and ESP32 is struggling, split functions:
    • Use the ESP32-CAM or DevKit dedicated to camera/streaming.
    • Use a small dedicated microcontroller (Teensy, Pro Micro, or another ESP32) to handle servos and accept compact UDP packets - communicate between them or to ARC.
  • Or use a single-board computer (Raspberry Pi/Jetson) for camera + local servo control (preferred when you need heavy vision + many servos).

Next step offer Tell me:

  1. The firmware version you flashed (link or text) and whether ARC connects over "EZB (WiFi)" skill or a custom skill.
  2. Whether you want the minimal UDP test sketch I described (and AP or STA mode). I’ll prepare the sketch and the exact ARC test steps (Net.hTTPGet/POST or UDP test client) to measure true latency and fix the 9second delay.

I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#31  

Quote:

Its about a nine second delay.
Yikes, that's insane. Not usable.

I wish I had a set of this hard ware so I could test along with you. At least we could compare results. I'll look into getting something if you cant resolve.

Do you think this is a result of the camera dragging the board down? Sorry, I lost track if you even have the camera on this board.

Author Avatar
PRO
Canada
#32  

Thanks - useful info. Since you’re on an ESP32 DevKit v1 over WiFi (Ad-Hoc/AP) and you’re seeing ~9 seconds of lag, that strongly points to network/firmware buffering or WiFi power-save/aggregation issues rather than baud rates (which only matter for UART). Below is a targeted plan: quick checks, a minimal low-latency UDP test sketch you can flash to the ESP32, a small PC test client (Python) to measure true latency, and next steps depending on results.

Quick checklist (do these first)

Important things to check/configure

  • WiFi mode: AP is convenient for direct connection but some PC WiFi adapters behave badly with AP mode. If possible use Station (WIFI_STA) mode connecting both ESP32 and PC to the same router - that often lowers latency.
  • Disable WiFi power save on the ESP32 to avoid TX aggregation delays.
  • Avoid doing heavy camera encoding and servo control in the same single loop on the ESP32 - use separate tasks or keep servo handling extremely lightweight.
  • Power: ensure servos have a proper 5V supply and common ground with the ESP32. Power sag can look like weird delays.

Minimal low-latency UDP test (ESP32 Arduino sketch)

  • Purpose: bypass ARC for a moment; verify how fast the ESP32 actually applies commands when receiving network packets.
  • Behavior: starts AP (or STA if you change), disables WiFi power save, listens UDP port 8888, parses packets of form "servoIndex,microseconds" (e.g. "0,1500"), updates servo PWM immediately, and sends an ACK back so you can measure RTT.

Flash this to your ESP32 (adjust SERVO_PIN and AP vs STA block as needed):

// UDP servo Test for ESP32 DevKit v1
#include <WiFi.h>
#include <esp_wifi.h>
#include <WiFiUdp.h>

// --- CONFIG ---
#define USE_AP true           // set to false to use STA mode (connect to router)
const char* ap_ssid = "ESP32-TEST";
const char* sta_ssid = "YOUR_ROUTER_SSID";
const char* sta_pass = "YOUR_ROUTER_PASS";

const int UDP_PORT = 8888;
const int SERVO_PIN = 18;    // change to the GPIO you use
const int LEDC_CHANNEL = 0;
const int LEDC_FREQ = 50;    // 50 Hz for hobby servos
const int LEDC_RES = 16;     // 16-bit resolution

WiFiUDP udp;
char packetBuf[128];

void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("UDP servo Test start");

  if (USE_AP) {
    WiFi.mode(WIFI_AP);
    WiFi.softAP(ap_ssid);
    Serial.print("AP IP: "); Serial.println(WiFi.softAPIP());
  } else {
    WiFi.mode(WIFI_STA);
    WiFi.begin(sta_ssid, sta_pass);
    Serial.print("Connecting to AP...");
    unsigned long t=millis();
    while (WiFi.status() != WL_CONNECTED && millis()-t < 10000) {
      delay(200);
      Serial.print(".");
    }
    Serial.println();
    if (WiFi.status()==WL_CONNECTED) {
      Serial.print("STA IP: "); Serial.println(WiFi.localIP());
    } else {
      Serial.println("STA connect failed");
    }
  }

  // Disable WiFi power save
  esp_wifi_set_ps(WIFI_PS_NONE);

  // Setup servo PWM via LEDC
  ledcSetup(LEDC_CHANNEL, LEDC_FREQ, LEDC_RES);
  ledcAttachPin(SERVO_PIN, LEDC_CHANNEL);

  // Start UDP
  udp.begin(UDP_PORT);
  Serial.print("UDP listening on port "); Serial.println(UDP_PORT);
}

uint32_t pulseUsToDuty(uint32_t pulseUs) {
  // 20ms period = 20000 us
  // duty = pulseUs / 20000 * (2^16 -1)
  float dutyf = (float)pulseUs / 20000.0f * 65535.0f;
  if (dutyf < 0) dutyf = 0;
  if (dutyf > 65535) dutyf = 65535;
  return (uint32_t)dutyf;
}

void loop() {
  int packetSize = udp.parsePacket();
  if (packetSize) {
    int len = udp.read(packetBuf, sizeof(packetBuf)-1);
    if (len > 0) packetBuf[len] = 0;
    String s = String(packetBuf);
    // Expected format: "servoIndex,pulseUs" e.g. "0,1500"
    int comma = s.indexOf(',');
    if (comma > 0) {
      int idx = s.substring(0, comma).toInt();
      int pulse = s.substring(comma+1).toInt();
      // For now we only support single servo channel mapping (idx unused)
      uint32_t duty = pulseUsToDuty(pulse);
      ledcWrite(LEDC_CHANNEL, duty);
      // Send ACK
      IPAddress remote = udp.remoteIP();
      uint16_t remotePort = udp.remotePort();
      String ack = String("ACK,") + String(millis());
      udp.beginPacket(remote, remotePort);
      udp.write(ack.c_str());
      udp.endPacket();
      Serial.printf("Recv:%s -> pulse=%d duty=%u\n", packetBuf, pulse, duty);
    }
  }
}

PC test client (Python) - measures RTT and shows latency

  • Replace ESP32_IP with your board IP (AP default 192.168.4.1). This sends a few packets and prints RTT.
import socket, time

ESP32_IP = "192.168.4.1"   # change if using STA mode
PORT = 8888
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1.0)

def send_pulse(pulse_us):
    msg = f"0,{pulse_us}".encode()
    t0 = time.time()
    sock.sendto(msg, (ESP32_IP, PORT))
    try:
        data, addr = sock.recvfrom(1024)
        rtt = (time.time()-t0)*1000.0
        print(f"ACK from {addr}, RTT = {rtt:.1f} ms, data={data}")
    except socket.timeout:
        print("No ACK (timeout)")

# test
for pulse in [1000, 1500, 2000, 1500]:
    send_pulse(pulse)
    time.sleep(0.1)

How to interpret results

  • If ping shows low ms but your UDP RTTs are low (tens of ms) and servo moves instantly, then the ESP32 can handle low-latency control - the problem is likely ARC skill settings, camera streaming, or how ARC/client is sending (flooding or batching).
  • If ping shows very high latency or packet loss, that’s the network/AP problem. Try STA mode via router or different PC WiFi adapter.
  • If ping is fine but UDP RTT is high or ACKs delayed, then the ESP32 firmware is probably CPU-starved by camera encoding/streaming or WiFi power-save/aggregation (disable PS and separate tasks).

ARC-side checks (kebab menu + skill settings)

  • Open the Single Camera servo Server or whichever skill is sending commands.
  • Click the kebab menu (three-lines) -> Settings.
  • Look for Update Interval / Send Interval / Frame Rate options and set low intervals for servo updates (e.g. 20-50 ms) while testing.
  • If the skill has a "Cache & Send" pattern, enable it so updates are batched (this reduces send overhead).

Follow-up questions (I need this to continue)

  1. Is the camera running on that DevKit while you see the 9-second delay? Try the UDP test with camera turned OFF first and report results.
  2. How many servos and which GPIO pins are you using (list pins)? How are they powered (USB, battery, separate 5V regulator)? Describe battery type and voltage.
  3. Did ping to 192.168.4.1 show large RTTs or packet loss? Paste 10 lines of ping output here.
  4. Are you using Single Camera servo Server or a Synthiam EZB (WiFi/EZB protocol) skill to talk to the board, or a custom client? Which skill in ARC is sending the servo commands?

If you want, I will:

  • Provide a variant of the ESP32 sketch that runs camera stream in a separate lower-priority task while keeping servo updates in a high-priority task (helpful if camera is on-board).
  • Provide recommended ARC skill settings (exact names/locations) you should change in the kebab menu once you confirm which skill you’re using.

Which do you want to try next - run the UDP test (I can help adjust the sketch for STA mode and your pins), or should I prepare the "separate tasks" sketch with camera + servo split?


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.