ESP32-CAM RC Car with Camera and Mobile Phone Controller

ESP32-CAM RC Car With Camera

Retro-fitting a toy radio control car with an ESP32-CAM to enable Wi-Fi control and video streaming on a mobile phone

This tutorial is fairly advanced and more of an experiment than a finished project. Hopefully there are some ideas and code to learn from that might help with a similar projects.

I bought a cheap radio control car from a local toy shop with the intention of converting the normal radio control elements to a system using an ESP32 micro-controller communicating over WiFi. The ESP32-CAM used in this tutorial features WiFi and a camera so a video stream can be sent from the car.

Unfortunately the ESP32-CAM suffers from a lack of usable pins. I have only found two pins that can be used as outputs so some workarounds and compromises have been made in the design. One pin is used for steering and the other for forward speed control.

Conventionally to control an RC car you need to be able to set four different things, steer left, steer right, go forward, go reverse. The RC car I used doesn’t have analogue steering, it’s just left or right so I used servo motor to push limit switches to turn current on and off to the steering motor.

A motor controller needs two free pins so a reverse signal can be sent in addition to a PWM signal to control speed. However after using one pin for steering there is just one pin left on the ESP32-CAM so while the forward speed can be controlled there’s no way to tell the motor to go the opposite direction.

A possible solution that I haven’t investigated is to add another micro-controller to the system. This could receive data from the ESP32-CAM via the two available pins and parse this data in another Sketch that outputs over multiple pins . For example the ESP32-CAM could output data on a pin in the range 0 to 100, a Sketch on the second microcontroller would interpret the data in the range 0 to 50 to be reverse speeds and 51 – 100 to be forward speeds and activate output pins appropriately.

RC Car Hardware Components

These are the components installed in the RC car. I used 3.3v volts to power the ESP32 with a step down module to make the voltage from the 4 AA cells more stable . The steering is controlled by the two limit switches which make one or other side of the motor live when activated. The limit switches are pushed closed by a servo motor. The motor controller receives a PWM signal from the ESP32 and controls the motor speed.

3.3v Step Down
3.3v Step Down
Motor Controller
Motor Controller
Servo Motor
Servo Motor
Limit Switches
Limit Switches

A closer view of the steering system with the servo and limit switches. When the switches are in the position below, both sides of the steering motor are connected to negative side of the battery. When the servo pushes a limit switch closed, that side of the steering motor is connected to the positive side of the battery.

Servo and Limit Switches

I used a fish-eye lens with a longer cable for the camera. There are various replacement cameras available from here:

Longer Camera Cable
Fish-Eye Camera in Hood

This is how it looks assembled. The red and black wires top left are normally connected to the power connector block next to the steering motor.

RC Car Internals Labelled

This is how I wired it all together:

ESP32-CAM WiFi RC Car Wiring Diagram

The car’s speed and steering are controlled using a touch interface on a mobile phone or tablet. Below the the touch interface is a live view from the camera.

Wi-Fi Car Touch Interface

RC Car Sketch

If you’ve not used the ESP32-CAM before you will need to read through this tutorial first – to get familiar with it.

The ArduinoWebsockets and ESPAsyncWebServer libraries need to be installed for this Sketch…

Library Manager ArduinoWebsockets

ESPAsyncWebServer: I’m not sure whether this library has to be used but during the process of developing this project I appeared to have problems with other web server libraries so I ended up with this one. You have to install it manually by copying it to the Arduino libraries folder.

Download the code from Github:

The index_html_gz variable in the code is for the controller interface. If you want to edit this code see this tutorial:

The code uses Web Sockets to stream the camera data to the browser:

client.sendBinary((const char *)fb->buf, fb->len)

and also receive control data from the touch interface on the mobile or tablet:

void handle_message(WebsocketsMessage msg) { // do stuff}

Project Demonstration Video

In there’s a lot of interest in this project (coffees!) I’ll work on a simpler version with a 3D printed chassis with servo control for steering and foreward/reverse and space for the ESP32-CAM to be located without bending pins etc.

You can also find this project on YouTube here:


Touch Interface:

45 Replies to “ESP32-CAM RC Car with Camera and Mobile Phone Controller”

  1. rob says:

    Nice project. Have you ever tried the DRV8871 DC motor drivers? They are MOSFET based and have a lower voltage drop and better performance , price wise very similar.

    1. WordBot says:

      Maybe for another project but it looks like the DRV8871 needs a minimum of 6.5v. The ones I used are a quarter of the price and work from 2v –

      1. rob says:

        Ahh. Yes, you are right about that, there is also a low voltage dual channel version , DRV8833.
        Thanks for the great write up.

  2. Anderson F says:

    Very nice project. I just would like to see the code responsible to send commands when we move the button. Could you tell where I can found it ?

    Or you just uploaded the and verything started to works ?


    1. WordBot says:

      The HTML etc for the interface? It’s in this variable index_html_gz in the code. There’s a little explanation in the tutorial. You can also view source in the browser to view it.

  3. Francisco Valladares says:

    I want to congratulate you on your work, you can share the html, since I would like to modify something in the code, I am thinking of implementing it in an ESP32 wrover without a camera, sorry for the translation, my English is not very good

  4. Yigit says:

    This website you gave shows how to edit the html for your own file but you didnt give us the code you used which has the joystick.

    Can you upload that too?

    Very nice tutorial btw.

  5. Enn says:

    Nice work send you some coffe 🙂
    Modfied html and triyng to understand the code!
    Q: What is the number 8191

    1. WordBot says:

      Thanks for the coffee! That part of the code comes from here: you can see where the number comes from. I don’t 100% understand it all through.

  6. Francesco says:

    Nice project.
    I have tested on ipdad, iphone and 2 android tablets.
    in the iPAD it’s very fast
    on my iPhone 6S I can’t see the video… I’m not sure why ? What do you think it could be?
    on the Android Tablet, there is a Lag (not from the video) but from the commands. it looks like every 4-5 seconds there is a delay.
    What do you think could be?

    Thanks! excellent work!

    1. WordBot says:

      The lag might be Wi-Fi related. I sometimes had a problem with the video framerate or the video dropping on this project. On others the control was sometimes laggy. If there’s a delay every x number of seconds it could also be the websocket data is being sent too fast and the buffer fills up.

      The video not showing on the 6s.. maybe this is a CSS layout problem and the video panel is hidden somewhere.

  7. Rafik24 says:

    Great work !

    In order to overcome the pins limitation I used an arduino nano and talked to it over serial then you can use all the nano ports do add FPV camera and many more.

    1. WordBot says:

      Thanks! I have another project planned where I intend to do something like that.

  8. John York says:

    Thanks for the project. It works fine. My only problem is that every time I power up the ESP32 cam module I have to manually press the onboard reset switch to start video streaming. Is there a workaround? Thanks for all the hard work and Merry Christmas.

    1. WordBot says:

      That’s a bit odd. Connecting the power and pressing the reset should do the same thing – start the sketch up. Maybe it’s a power thing somewhere on the board.

  9. Mike D says:

    Great project.. trying to put together a micro crawler with it but having trouble trying to figure out how to rotate that video feed and center the motor as my fwd/rev is around 140 on the controller and not at 0. Any suggestions? Thanks

    1. WordBot says:

      I don’t think the feed can rotated 90 degrees on the camera but possibly in CSS in the HTML. Can you do some maths in the code? Or change the map values? – forwardValue = map(forwardValue, 0, -90, 500, 2000);

  10. tangzhiwei says:

    I modified your html code to meet my needs.
    But I don’t know how to convert HTML code to Hex.
    Could you please tell me how to convert HTML to Hex.

  11. Perry Mole says:

    You might consider a continuous rotation server for the drive system.
    You would get forward/reverse and speed control.
    Real problem in physical interface though…

    1. WordBot says:

      Apparently other pins are usable but I’ve not tried yet. If the SD card is put into 1-line mode supposedly 4 and 13 also become available. I need to test.

  12. IntelliGads says:

    Any way to stream to a Windows 10 PC?

    1. WordBot says:

      You can stream to any browser on any OS.

  13. Raj says:

    Is it possible to integrate with AutoConnect or WiFimanager so the WiFi credentials need not have to be hard-coded?

    1. WordBot says:

      Should be possible. Or checkout the this tutorial to use Bluetooth to set the Wi-Fi credentials –

  14. Raj says:

    Thats cool.. thanks..
    How do I integrate it with by sketch?

    1. WordBot says:

      Ah.. you have to work it out yourself! Shouldn’t be too hard to cut and paste something together.

  15. Fra says:

    ESPAsyncWebServer.h:210:5: error: ‘AsyncClient’ does not name a type

    And it’s the same for all the examples in the library ESPAsyncWebServer
    How to get out of it?

    1. WordBot says:

      How did you install the ESPA library?

  16. Dave says:

    Thanks, it’s a good project.
    I am modifying the html code to add a button to turn on/off LED but I am still struggling.
    Could you help please.

    1. WordBot says:

      Do you need help with the HTML part? Should just be a case of copying the code for one of the existing buttons to make a new one. In the JavaScript part as well.

  17. OrakelKSL says:

    Some Hardware-hints:
    To drive up to 16 servos /ESC/ LEDs / solenoids (mixed) with only 2 ESP32 port-pins, you can use . It’s cheap, easy to get from nearly all well-known suppliers, and more precise.
    If you decide to use a brushed DC-Motor (including LEGO Technic) search for “20A brushed mini esc car”, easy to get from nearly all well-known suppliers. Both directions and a switch selectable brake. Advantage: More speed variations by gear-ratio and more reliable than a pimped servo (bad experience with the rubbish MG946 clones which burned after minutes) . You can it also connect to the PCA9685. With 2 of them, you can control tanks. Think: If you decide to use stronger ESC or brushless Motors with ESC, only CAR-type provides both directions. Planes fly only foreward and neither have reverse direction nor brake.

    1. WordBot says:

      Ah cool! I was vaguely aware of the servo drivers but hadn’t researched them. I’ve got more motor projects in the pipeline so I’ll take a look.

  18. OrakelKSL says:

    You can also control up to 8 Servos / ESC with only one Portpin (output) by using a PPM (Standard output of all older RC-Systems) to PWM decoder. You need only 4 easy available and cheep devices: A Resistor, a Diode, a capacitor and a decade-Counter 4017.
    (R1 220Ohms on the schematic goes to VCC Pin 16 and is not needed (EMC-Reasons for the 27MHz receiver).
    Advantage: You can use every standard RC-Device as servo, ESC, Switches… and a loss of PPM leads to a standstill of the ESC. Some kind of “fail-safe” 🙂
    I use this simple device very often because you can encode, transmit and decode the serial PPM very simple (AM, FM, SSB, CW..) and then feed the Reciver-signal to the decade counter.
    Hint: If the Output has problems to discharge the 22nF Capacitor, use 470k/10nF instead for Reset.

  19. OrakelKSL says:

    Addition: Some ESC provide a 5V BEC (Battery eliminating circuit) , so you can feed the ESP32 directly with 5V from the ESC.

    Don’t belive the 320A 🙂 1/10 is more than enough for the ESC but should be enough for a normal project.

  20. Leon says:

    i have a question is there a way to make it standalone like controlling it directly from my phone without in need of wifi outer connection and as i know esp32 cam has Bluetooth so maybe a Bluetooth vitiation

    1. WordBot says:

      Easiest way would be to change the Wi-Fi code on the ESP32 to be an access point (AP) so you connect straight to the ESP32 without using a router.

  21. butch says:

    Suggestion for tutorial: An “on screen display” or “heads up display” for the ESP-32 camera dev. board.

    Could display GPS info, voltages, and other data overlaid on the Web app.

    Has anyone seen anything like this?

    1. WordBot says:

      It’s possible to add text overlays to the stream – the CameraWebServer example does this. If you want graphical data you would have to overlay the JPEG data somehow before it’s sent. Maybe I’ll do a tutorial for this. (Make sure you subscribe to the newsletter to get an email for new projects.)

  22. Jozef says:

    I have a problem with compilation of project to esp32 dev module. Do you know solution of this problem, because I have tried several settings but it didn’t work. Can you help me please?

    1. WordBot says:

      Hi, What error do you see when it fails to compile?

  23. M.Zeeshan says:

    Hello Dear, where is the source code?
    Can not see a link for the souce code. Can you plaese the source code

    1. WordBot says:

      Hi code was in the article but I’ve moved it to Github for better formatting:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

scroll to top