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

Your robot can be more than a simple automated machine with the power of ARC Pro!

Author Avatar
PRO
USA
#89  

@nink goto the firmware page for ESP32 CAM DJ has all the info there.

Author Avatar
PRO
USA
#90  

@DJ did you use the AI Thinker or the CAMERA_MODEL_WROVER_KIT for the camera on this board? In the instructions you say "NOTE: For most ESP32-CAM modules (AI-Thinker style), use CAMERA_MODEL_AI_THINKER. How do we know what the camera module is on the board?

Author Avatar
PRO
Canada
#91  

Great thread - lots of good testing and experience here. Below I’ll summarize what’s working, explain the common Gotchas, give recommended hardware/architecture options, and show exactly how to configure ARC to use an ESP32-CAM (or a separate ESP32 controller + ESP32-CAM) so you can run servos and camera at the same time.

Useful links

Summary - what people reported that works

  • DJ_Sures: ESP32 WROVER + camera module on v9 of the ESP32-CAM EZB firmware - 20-28 fps and moving servos doesn’t affect camera. That’s the clearest evidence an ESP32-WROVER-based board can run the camera and servos together reliably.
  • Others: Freenove ESP32-S3 also reported working, but you may need to select/uncomment the correct CAMERA_MODEL define (see firmware build step below).

Why some boards fail with camera + servos

  • Many ESP32 camera modules and dev boards reuse the same GPIO lines for camera signals and other peripherals. If a GPIO used by the camera is also used for PWM/servo, you will have conflicts.
  • Different ESP32 models/board variants wire those GPIOs differently. So "works on one board" "works on all boards".
  • Some ESP32 types (WROVER) include PSRAM and different camera pin mapping, which is why the firmware needs the correct CAMERA_MODEL define.

Recommended approaches (pick one)

  1. Best practical approach (recommended)
  • Use an ESP32-CAM (camera module e.g. WROVER or AI-Thinker) flashed with the Synthiam ESP32-CAM EZB firmware for video streaming.
  • Use a separate ESP32 Dev board (DoIt DevKit, Freenove ESP32-S3, or similar) flashed with Synthiam EZB-compatible firmware for servos/IO.
  • Connect both boards to the same Wi-Fi router (Client mode). ARC on PC can connect to both simultaneously. This avoids GPIO conflicts, keeps camera streaming high FPS, and gives plenty of IO for servos. Benefits:
    • No pin conflicts.
    • Camera module can use all camera-dedicated pins and PSRAM on WROVER for better FPS.
    • Controller board can use free GPIOs for servos (and use multiple LEDC PWM channels). Notes:
    • You do NOT need two Wi-Fi networks if both boards join the same router; only one Wi-Fi network is required for the iPad/phone/computer to access both devices.
    • If you run the ESP32 devices in AP mode (each created its own AP), then you’d have to switch networks, which is inconvenient for mobile. So set both to client (STA) mode connecting to your home/ lab router.
  1. Single-board approach (if you prefer only one board)
  • Use an ESP32 WROVER kit (camera module variant) - DJ’s results show WROVER gives good performance and can move servos without affecting camera.
  • Make sure you use the firmware build for the correct camera model (WROVER vs AI_THINKER etc.) and choose servo GPIOs not used by the camera on your specific board. Limitations:
  • Must verify which GPIOs are free on that exact board revision.
  • Some boards still have limited usable IO for servos; testing and mapping required.

Which camera model to select when building/flashing firmware

  • In the ESP32 camera firmware source you typically have lines like:
// #define CAMERA_MODEL_AI_THINKER
// #define CAMERA_MODEL_WROVER_KIT
  • Uncomment the one that matches your board and comment the others.
  • How to know which one you have:
    • Check markings on the camera module/board (AI-Thinker or WROVER often printed).
    • WROVER boards often have PSRAM chips printed and are labeled "WROVER".
    • If unsure, check the vendor page/box or open the serial monitor at boot - sometimes boot log prints board info.
    • If still unsure, try WROVER first if you have a WROVER module (DJ reported using a WROVER produced reliable performance). If you try and camera fails to initialize, switch to AI_THINKER and reflash.

Pins and servos - practical notes

  • Synthiam notes (empirical): on AI-Thinker style boards servos have worked on D2, D12, D13, D14, D15 - but "your mileage may vary" depending on board.
  • ESP32 supports up to 16 LEDC PWM channels (hardware PWM) - so CPU/PWM-wise you can drive many servos, but which GPIOs are available depends on camera wiring.
  • For the two-board approach, the controller board gives you many free GPIOs without camera conflicts.
  • If you keep everything on one board (ESP32-CAM), you must carefully map which GPIOs the camera uses and avoid them. The camera uses multiple GPIOs (D0-D7, PCLK, VSYNC, HREF, XCLK, etc.) that overlap many pins on compact dev boards.

Audio, Bluetooth, microphone, TTS, and STT

  • Bluetooth audio / speaker: ESP32 hardware can support Bluetooth audio in principle, but Synthiam’s ESP32-CAM EZB firmware primarily focuses on camera and IO features - Bluetooth audio is not part of the standard firmware features. So don’t count on built-in Bluetooth speaker support via ARC.
  • Microphone (I2S): ESP32 supports I2S mics. Whether the Synthiam firmware exposes I2S mic audio to ARC or integrates STT is not guaranteed. For TTS/STT and AI audio features, the typical ARC approach is:
    • Use PC (ARC) for TTS and STT (computer audio or cloud speech services) - easiest.
    • If you want on-board STT/TTS on the ESP32, you’ll need custom firmware + custom ARC robot skill to shuttle data; that’s an advanced path. Recommendation:
  • Use ARC/PC for TTS/STT and image recognition. Stream video from ESP32-CAM into ARC (Stream All The Video Sources) and do image analysis in ARC or an external AI service.

How to set this up in ARC (step-by-step)

  1. Add the camera device to ARC
  • Project Add robot skill Camera Device (add one if you don’t have).
  • Configure the Camera Device to use the incoming stream (or use Stream All The Video Sources).
  1. Add Stream All The Video Sources skill
  • Project Add robot skill Stream All The Video Sources.
  • Open the Stream All skill window click the kebab menu (three lines, top-right) Configure choose the Camera Device to stream to and SAVE.
  • Paste the ESP32-CAM stream URL (the EZB firmware provides MJPEG/RTSP/HTTP endpoints) into the skill UI and START.
  1. Add your controller (ESP32 Dev board) to ARC
  • If you installed Synthiam EZB firmware to your controller, ARC will see it as an EZB (connect via IP).
  • Add TCP Script Server Raw if you plan to send commands or use the raw TCP plugin:
    • Project Add robot skill TCP Script Server Raw (configure port/language).
    • Use it to accept script commands (if you want to talk directly to a microcontroller skill or run remote commands).
  1. Configure servos
  • In ARC you’ll use servo ports d0..d23 constants when scripting (do not quote them).
  • To test a servo setPosition example script, open a Script (JavaScript recommended) and try:
// move servo on d2 to 90 degrees
Servo.setPosition(d2, 90);
print("Moved d2 to 90");
  • Use Servo.setSpeed, Servo.setPosition, etc., then test with servos connected to your controller board’s free GPIOs.
  1. Kebab menu usage (configure skill options)
  • Open any robot skill window click the three horizontal lines (top-right) Configure settings change and press SAVE.
  • Use the kebab to access advanced skill options (ports, IP, camera URL, language, etc).

Example test workflow

  • Flash ESP32-CAM firmware for camera (select CAMERA_MODEL_WROVER_KIT or AI_THINKER as appropriate) and set it to connect to your Wi-Fi network.
  • Flash separate ESP32 Dev board with EZB-compatible firmware for IO (connect it to same Wi-Fi).
  • In ARC:
    • Add Camera Device, add Stream All skill, paste camera URL, start.
    • Connect to the controller board EZB and test a servo command from an ARC script.
  • Confirm camera FPS and servo movement together.

What to ask next / what I can provide

  • Which exact ESP32 board(s) do you / DJ / Freenove have? (give board markings or product link)
  • Do you want a single-board solution or are you OK running two boards (camera + controller)?
  • Do you plan to use mobile devices (iPad / iPhone) to control the robot? If so, are the boards connecting to a Wi-Fi router or running as APs?
  • Want help producing a step-by-step flash/build guide for a specific board (I can show the exact camera model define to uncomment and the Arduino/PlatformIO build steps)?
  • Want a sample ARC JavaScript to test servos and camera together once you have both devices connected?

If you tell me your board model (Freenove link or the board silkscreen), I’ll give exact camera define, recommended free GPIO list for servos, and a sample ARC script to test the setup.


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
#92  

Morning testing. Mixed results maybe based on the Cam module I chose based on a Google search?

Board: Freenove ESP32 S3 Wrover board (red board pictured above and same board DJ tested with.

Results: servo works on different pins listed. Camera works prolly 28-30 FPS

BUT, I can't get them to work together, If I move the servo while camera is on i get the following message :EZ-B v4 Camera Error: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. Camera Disabled

And the servo stops responding after that. I have to reboot the board.

Could this be from choosing the wrong CAM: Google said to use CAMERA_MODEL_ESP32S3_EYE which i used or CAMERA_MODEL_XIAO_ESP32S3 for the Freenove ESP32 S3 Wrover. I would think if it was wrong that the camera would not start at all.

Google had me also change a few things in the IDE before I uploaded firmware for this board: Under tools:

  • Enable USB CDC on Boot
  • Flash size increased to 16MB
  • PS RAM set to : OPI PSRAM
  • Then camera either CAMERA_MODEL_ESP32S3_EYE (which i used) or CAMERA_MODEL_XIAO_ESP32S3
  • I used the ESP32S3 Dev Module for the uploading to the board

Not sure if any of these would have an effect on camera/servo combo?!

@DJ maybe you could share what settings you used on your board.

Author Avatar
PRO
Canada
#93  

Thanks - good details. Based on the symptoms (camera OK alone, servos OK alone, but camera+servo together causes the EZ-B TCP connection to fail and the board to require reboot) the problem is most likely one of the following (in order of probability):

  • Power / brown-out: servo movement draws a current spike that causes the ESP32 to brown-out or WiFi to drop (most common).
  • GPIO / pin conflict: the servo PWM GPIO(s) you used overlap pins the camera or PSRAM uses (causes the camera driver or firmware to crash).
  • Firmware / camera model mismatch or PSRAM setting: wrong CAMERA_MODEL define or PSRAM settings can make the camera driver fragile when other activity occurs.
  • Resource conflict (timers, LEDC channels) or USB/CDC config interfering with runtime when load increases.

Here’s a focused troubleshooting checklist and exact steps to test & fix it. I’ve also included an ARC JavaScript test you can run once the hardware/firmware side is stable.

  1. I can’t see photos - please post the exact board name or product link & the text printed on the board (e.g., "Freenove ESP32-S3 WROVER", vendor SKU). That lets me give pin-mapping & camera define specifics.

  2. Immediate checks (do these first)

  • Are the servos powered from the ESP32’s 5V/USB rail? If yes, stop that. Provide an external 5V servo power supply capable of the stall/peak current of all servos (estimate 1-2 A per small/medium servo under load). Connect servo V+ to that supply and connect the servo ground to the ESP32 ground (common GND). Add a 470 F - 1000 F electrolytic capacitor across the servo 5V and GND near the servos.
  • Use a separate power supply for servos and the ESP32. USB alone is often not enough and will cause brownouts that kill WiFi.
  • After changing power, test: camera on, then move a servo. If problem goes away, power was the culprit.
  1. Serial monitor logging (essential)
  • Connect the Freenove board to your PC via USB, open Arduino IDE (or PlatformIO) Serial Monitor at 115200, reboot board.
  • Start the camera stream in ARC and start moving the servo. Watch the serial log for:
    • Exceptions, panic messages, "Brownout detector" messages, WiFi disconnects, or camera init errors.
  • Paste (or copy) any error output here. That will tell us if the firmware crashed or WiFi dropped.
  1. Confirm correct camera define and PSRAM settings
  • For ESP32-S3 variants there are different camera models: CAMERA_MODEL_ESP32S3_EYE or CAMERA_MODEL_XIAO_ESP32S3 (and others). Which one to use depends exactly on the module wiring. If you don’t know:
    • Check the vendor product page or the silkscreen on the module.
    • If WROVER is printed (PSRAM present) try CAMERA_MODEL_WROVER_KIT (or ESP32S3 variant if S3-EYE is indicated).
  • If your module has PSRAM, ensure PSRAM is enabled in the Tools menu (PSRAM ON). If PSRAM is required by your chosen camera config but not enabled, behavior will be unstable.
  • If you changed flash/PSRAM/USB CDC options, revert to defaults recommended by the firmware page unless the board page requires the change. DJ’s working setup used a WROVER module with the v9 ESP32-CAM EZB firmware - try replicate those settings if you have a WROVER.
  1. Avoid camera pins for servos
  • The camera uses many GPIOs (D0-D7-like camera data lines plus PCLK/VSYNC/HREF/XCLK). On compact boards these overlap common IO. If you attached servos to a pin used by the camera it will crash when you toggle that pin.
  • Provide the list of pins you connected servos to. I’ll check for overlap. If you didn’t note them, move servos to tested "safe" pins (I can recommend safe ones once I know the exact board).
  • If possible, try the two-board approach (ESP32-CAM for camera; separate Esp32 devboard for servos). That avoids pin conflicts and is cheaper than an IO Tiny.
  1. Lower camera load as a test
  • Temporarily reduce camera resolution or FPS in the firmware/config (or stream URL parameters) and retry. If lower camera load makes the error go away it points to resource or power limit issues.
  1. Check USB CDC / console options
  • Some S3 dev settings like "Enable USB CDC on Boot" could change behavior. Try building/flashing with defaults recommended by the Synthiam ESP32-CAM firmware docs and the board vendor guide.
  1. Test script in ARC (one-line JS test)
  • After you have stable hardware, test with a simple ARC script. Example (use whichever d# port corresponds to your servo):
// Example ARC JavaScript test - move servo on d2
Servo.setPosition(d2, 90);
print("Moved d2 to 90");
sleep(1000);
Servo.setPosition(d2, 0);
print("Moved d2 to 0");

Run camera stream from Stream All The Video Sources and then run that script. If camera + servo are stable, good.

  1. Follow-ups I need from you
  • Exact board/product link or the exact silkscreen text printed on the board.
  • Which pins (GPIO numbers or ARC ports like d2,d12, etc.) you connected each servo to now.
  • How the servos are powered (USB, external 5V battery, bench PSU). Give voltage and amp rating.
  • Serial monitor log when the failure occurs (copy/paste). This is the most diagnostic item.
  • Which camera define you flashed (CAMERA_MODEL_ESP32S3_EYE or CAMERA_MODEL_XIAO_ESP32S3 or WROVER...), and whether you enabled PSRAM in tools.
  1. Quick recommended path for your Mecha Morphix (five servos)
  • Best: Two-board setup - ESP32-CAM for camera (streaming), separate ESP32 Dev for servos and IO. Both in WiFi client mode to the same router so you can control both simultaneously from ARC on any device (PC, iPad). That avoids AP switching. This gives the most reliable camera + servo performance.
  • If you must use single board, ensure:
    • Servos are powered externally with adequate current.
    • Servos use GPIOs not used by the camera/PSRAM.
    • Use the correct camera define and enable PSRAM if needed.

If you share the board link/text and the serial log, I’ll give the exact CAMERA_MODEL define you should use, a list of safe pins to move servos to on that board, and the specific upload/Tools settings to use. Want me to walk through serial log capture and interpretation step-by-step?


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
Canada
#94  

I found a lot of conflict with the camera on the original ESP32-CAM using the same GPIO ports.  I spent a fair amount of time going around the board testing all the GPIO ports to find the ones that don’t have a conflict. I eventually found 5 ports that worked. Maybe need to do a similar exercise with this one.

Author Avatar
PRO
Synthiam
#95   — Edited

If you're using Wrover board, why would you not use the Wrover camera settings? That's what I used because it's a Wrover board.

Author Avatar
PRO
Synthiam
#96   — Edited

Yeah i looked around and don't see why you'd select any other board setting than the one you're using. Not sure where you found that information but i'd stick with the settings for the Wrover and not use any other board settings.

PS, you can look in the camera_pins.h to see if the Wrover camera pins conflict with what's in the mapping list of the main file.

Such as... camera pins of wrover are

#define PWDN_GPIO_NUM  -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM  21
#define SIOD_GPIO_NUM  26
#define SIOC_GPIO_NUM  27

#define Y9_GPIO_NUM    35
#define Y8_GPIO_NUM    34
#define Y7_GPIO_NUM    39
#define Y6_GPIO_NUM    36
#define Y5_GPIO_NUM    19
#define Y4_GPIO_NUM    18
#define Y3_GPIO_NUM    5
#define Y2_GPIO_NUM    4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM  23
#define PCLK_GPIO_NUM  22

And the mapping is...

const uint8_t ARC_TO_ESP_DIGITAL_PIN_MAPPING[24] = {

  2,     // ARC port D0
  4,     // ARC port D1
  13,    // ARC port D2
  14,    // ARC port D3
  15,    // ARC port D4
  12,    // ARC port D5
  0xff,  // ARC port D6 (not used)
  0xff,  // ARC port D7 (not used)
  0xff,  // ARC port D8 (not used)
  0xff,  // ARC port D9 (not used)
  0xff,  // ARC port D10 (not used)
  0xff,  // ARC port D11 (not used)
  0xff,  // ARC port D12 (not used)
  0xff,  // ARC port D13 (not used)
  0xff,  // ARC port D14 (not used)
  0xff,  // ARC port D15 (not used)
  0xff,  // ARC port D16 (not used)
  0xff,  // ARC port D17 (not used)
  0xff,  // ARC port D18 (not used)
  0xff,  // ARC port D19 (not used)
  0xff,  // ARC port D20 (not used)
  0xff,  // ARC port D21 (not used)
  0xff,  // ARC port D22 (not used)
  0xff   // ARC port D23 (not used)
};

const uint8_t ARC_TO_ESP_SERVO_PIN_MAPPING[24] = {

  2,     // ARC port D0 (servo)
  4,     // ARC port D1 (servo)
  13,    // ARC port D2 (servo)
  14,    // ARC port D3 (servo)
  15,    // ARC port D4 (servo)
  12,    // ARC port D5 (servo)
  0xff,  // ARC port D6 (not used for servo)
  0xff,  // ARC port D7 (not used for servo)
  0xff,  // ARC port D8 (not used for servo)
  0xff,  // ARC port D9 (not used for servo)
  0xff,  // ARC port D10 (not used for servo)
  0xff,  // ARC port D11 (not used for servo)
  0xff,  // ARC port D12 (not used for servo)
  0xff,  // ARC port D13 (not used for servo)
  0xff,  // ARC port D14 (not used for servo)
  0xff,  // ARC port D15 (not used for servo)
  0xff,  // ARC port D16 (not used for servo)
  0xff,  // ARC port D17 (not used for servo)
  0xff,  // ARC port D18 (not used for servo)
  0xff,  // ARC port D19 (not used for servo)
  0xff,  // ARC port D20 (not used for servo)
  0xff,  // ARC port D21 (not used for servo)
  0xff,  // ARC port D22 (not used for servo)
  0xff   // ARC port D23 (not used for servo)
};

const uint8_t ARC_TO_ESP_ADC_PIN_MAPPING[8] = {

  0xff,  // ARC port ADC0 (not mapped)
  0xff,  // ARC port ADC1 (not mapped)
  0xff,  // ARC port ADC2 (not mapped)
  0xff,  // ARC port ADC3 (not mapped)
  0xff,  // ARC port ADC4 (not mapped)
  0xff,  // ARC port ADC5 (not mapped)
  0xff,  // ARC port ADC6 (not mapped)
  0xff   // ARC port ADC7 (not mapped)
};

Looks like D1 conflicts, so you'd want to change that and set it to 0xff so it's not used or move them or whatever...