Pan and Tilt Control for an ESP32-CAM

Pan-and-Tilt-ESP32.jpg

Mounting an ESP32-CAM into a pan and tilt platform with a mobile phone touch interface to control and view the video stream.

This servo part of this project was much harder to make work than with other ESP32 modules. The ESP32-CAM has limited resources available and at every turn it presented a new problem!

With a standard ESP32, controlling servo motors is easy using the ESP32Servo library. For example this pan and tilt sketch controls the 3D printed pan and tilt platform below. You can even power the servos from the 5v pin of the micro-controller.

Lolin ESP32 Pan and Tilt

Attempting to use this library with the ESP32-CAM however led to instant hangs. From my experiments it appears there is a clash on the channels. I found some different code that allows the channels to be chosen and after a few tests I found I could use channels 2 and 4 with the ESP32-CAM.

Mounting the ESP32-CAM in a pan and tilt platform was also a bit tricky. In the end I 3D printed some parts and glued and bolted it together. It doesn’t look great and could do with being designed from the ground up but this is just a proof of concept for later projects so it doesn’t matter

ESP32-CAM Pan and Tilt Platform

I also tried various web server libraries and the ESPAsyncServer library seemed to work the best. I also moved to WebSockets for the data transfer because it seemed to be more efficient and not queue up requests from the mobile phone.

ESP32-CAM Pan and Tilt Wiring Diagram

ESP32-CAM Pan Tilt Code

If you need help with the ArduinoWebSockets or ESPAsyncWebServer libraries please see this tutorial: https://robotzero.one/esp32-cam-rc-car/

Demonstration Video

I got variable results from the ESP32-CAM. Sometimes it was as fluid as the Lolin in the video below and other times it was quite jerky. I don’t know if this is an issue with (my) Wi-Fi or if the data transfer from the video overwhelms the web socket servo control data.

References

Lolin32 Pan and Tilt Platform: https://www.thingiverse.com/thing:708819
ESP32-CAM Pan Tilt with Servos: https://www.ebay.es/itm/201544779605
Touch Interface: https://www.kirupa.com/html5/drag.htm

24 Replies to “Pan and Tilt Control for an ESP32-CAM”

  1. rob says:

    Do you think it would be possible to overlay the pan tilt control on top of the camera image, a bit like this
    https://youtu.be/NSowf_ctzAw?t=12

    1. WordBot says:

      I looked at the Github quickly and it looks like he’s using HTML Canvas https://www.w3schools.com/html/html5_canvas.asp to draw the interface on top of the video. This could be one approach. It might also work using CSS Z-Index to layer the control with a transparent background on top of the video.

  2. Enn Ellandi says:

    I made a little investigation abd foun out that this part on ESP32 Cam code is preventing Servo library to work:

    // camera init
    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK) {
    Serial.printf(“Kaamera init viga 0x%x”, err);
    return;
    }

    sensor_t * s = esp_camera_sensor_get();
    s->set_framesize(s, FRAMESIZE_SVGA);

    1. WordBot says:

      It should be OK. Which camera are you using?

  3. Petko Petkov says:

    Hello my friend!!!
    I am quite a beginner and I would very much like to carry out your project. Can you send me screenshots of Arduino ID to learn out which sketch you use, which board, which file (.in) because this one is here (.cpp) and only I can’t add it.
    I apologize for my bad English !!!
    Thank you very much !!!

    1. WordBot says:

      Hi, everything is in the tutorial. You can use any ESP32 board. The code in the tutorial is an .ino file so you just paste it into a new Sketch in the Arduino IDE.

  4. Petko Petkov says:

    It worked….. 🙂 Supeeeerrrrrr !!!
    Thank you so much!!!

  5. CaptainJ says:

    Hi, and thank you for this useful tutorial. It works fine to me.
    In my case, I want to pan and tilt an ESP32-CAM as a surveillance camera through internet.
    Using NO-IP services I can use Dynamic DNS (I did it in another application).
    For security reasons, I want to change ports 80 and 82 you are using in your program, which I will port forward in my router. So far I haven’t had any success. It seems to work only with 80 and 82 ports. How can I do it?
    Please help me. Thank you.

    1. WordBot says:

      Hi, Did you you change the ports in the HTML? See this tutorial for help with this – https://robotzero.one/esp32-cam-custom-html/

  6. Token says:

    Hello Fellow Maker,

    Great tutorial, I am doing something very similar and wanted get your opinion/advice on the following.

    Currently I have an application that is sending polar coordinates (magnitude, theta) and wanted to know what would you suggest to map the panValue & tiltValue so that it can handle the conversion.

    I’m thinking that magnitude could be used as the “speed” or “power” of the servo and convert the theta into some useable mapping angle value.

    Magnitude = 0 to 1
    Theta = 0 to 359.99

    I’m having a bit of trouble with the logic and trying to use your example as a base when handling the WebSockets on the ESP32 Cam

    panValue = map(panValue, -90, 90, 0, 180); // 0-180
    tiltValue = map(tiltValue, -90, 90, 180, 0); // 0-180 reversed

    any advice is greatly appreciated 🙂

    1. WordBot says:

      Hi, I’m not really sure but one thing to note is map is only for integers so you need to multiple the numbers to get whole numbers first. For example magnitude should be 0 to 100 to map it. With map you start with the values you get from your sensor or whatever and ‘map’ them to a range of values you need for the function (servo in this case). If you need help with more maths stuff this site is great: https://math.stackexchange.com/

  7. CaptainJ says:

    Hi again, and thank you for your reply.
    Studding your tutorial you mention above, and using CyberChef, I converted hex to html. The only point I can change port is in line const WS_URL = “ws://” + window.location.host + “:82”;
    I changed 82 with 8084.
    I converted html to hex again and correct the index_html_gz length to 1744 in camera code.
    Also in camera code, I changed line 120, the WSserver.listen(82); to WSserver.listen(8084);
    and the line 38, the AsyncWebServer webserver(80); to AsyncWebServer webserver(8082);
    After uploading code, removing GND from IO0, pressing RESET button, in browser look for 192.168.x.x:8082.
    The only I can see in browser, is the touch interface in the upper portion of screen, with the yellow spot in the middle, but I cannot move it to any direction. No image at all, no servo movement.
    Probably I miss something. Have you any advice to give me?
    Thank you.

    1. WordBot says:

      Hi. Sounds like you are doing well following the tutorial. Can you press F12 in the browser can take a look in the Console tab at the moment. It sounds like the Javascript isn’t loading.

  8. CaptainJ says:

    Hi again.
    I followed your advice (Console tab using F12). A Syntax Error appeared:

    “SyntaxError: An invalid or illegal string was specified 192.168.1.7:8082:71
    http://192.168.1.7:8082/:71”

    What is that :71 ? There is neither in code nor html.
    Also I changed the 8082 and 8084 ports with 2 digit number (p.s. 90 and 92) but the same error appeared.
    That error is not appearing when using 80 and 82 ports.
    Have you any suggestion?
    Thank again for your time.

    1. WordBot says:

      Hi, Can you post the HTML and sketch into two pastes here: https://pastebin.com/ and I’ll take a look.

  9. CaptainJ says:

    OK I made registration to Pastebin and I made two pastes.
    I am not familiar with Pastebin.
    Now how do you will see them?

    1. WordBot says:

      Ah.. I need the link to the pastes. When you save them, just copy the URL into a comment here.

  10. CaptainJ says:

    Wednesday 25th of March 2020 04:19:49 PM CDT (My registration)
    Postes, a few minutes later…

    1. WordBot says:

      Hi, When you copy and paste into Pastebin and save, you can just copy the URL of the page and paste it here.

    1. WordBot says:

      I think I’ve sussed it. Try:
      const WS_URL = "ws://" + window.location.hostname + ":8084";

      host includes the port number. I didn’t know this before.

  11. Captainj56 says:

    IT IS WORKING !!!!!!
    THANK YOU VERY MUCH…
    I appreciate your help.
    Thanks again !!!

  12. Injee says:

    Hi will be great if you can post the working program with the port set for 8084.
    I am trying the same and not able to get it to work.

    1. WordBot says:

      IF you check this comment (with the two examples) and my correction below it should work: https://robotzero.one/pan-and-tilt-control-for-an-esp32-cam/#comment-45254

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