Close
0%
0%

$10 Robot!

A super cheap educational robotics platform. Everything you need to build and program a simple robot.

Public Chat
Similar projects worth following
I run a robotics club in a school, for students aged 11 – 14. We generally use a Raspberry Pi for the brains in our robots, but by the time you've added on motor controllers, voltage converters, wireless controllers etc... to the price of the Pi – It all starts to get rather expensive!


You can even buy my own robot controller board – The RedBoard+, over on Tindie. www.tindie.com/stores/redrobotics/


This time I wanted to make an all in one simple robotics controller, that was cheap enough to give to each of the students to keep, so once they had built their robots they could take them home to continue tinkering.

Here are the features I wanted to include on the board:

1. Dual H-Bridge – to drive 2 DC cheap TT motors, so nothing too fancy.

2. DC/DC converter – with an input voltage range of 6-12V, so you can use different types of batteries.

3. Reverse polarity protection – the students are definitely going to plug the battery in the wrong way around!

4.Enough spare input/output pins to drive a few servos or read a few sensors etc...

5. A micro controller with built in wireless communication. Preferably programmable in Micro/Circuit Python. Controllable from a mobile phone or website, so you don't need a physical controller to get started. But also with bluetooth, to connect to Playstation controllers, as we already use these for our other robots.

6. Cheap!

Nice, but not essential:

7. Through hole components – I want the students to assemble the boards themselves, so they can learn to solder, and have a better understanding of what the different parts on the board do.

8. Raspberry Pi Zero sized – so it can replace the PI Zero's in our existing robots.

This project was started back in 2022 when electronic components were still hard to get hold of. So I looked around in my parts box so see if there was anything I could use and believe it or not, I found a load of dual H-bridge modules, DC-DC converters and micro controllers.

Having a quick check on AliExpress I got an idea of the costs:

2 x Yellow TT motors = $2.00

DC/DC Converter = $0.45

Dual H-Bridge Module = $0.50

MOSFET = $0.45

ESP32 = $3.00

PCB = $0.40

Screw Terminals = $0.10

Header Pins = $0.10

6 x AA Battery holder (not including batteries) = $1.00

Total components = $8.00

These are of course subject to change but It's a good starting point.

This leaves $2.00 for materials for laser cutting or 3D printing to make a chassis – I think this is possible!

ESP32_GamePad_v0-1_Gerber.zip

Gerber files for the ESP32 Gamepad.

x-zip-compressed - 206.78 kB - 10/10/2023 at 11:20

Download

10_Dollar_Robot_30_Pin_Gerber.zip

Gerber files for the $10Robot! Robot control board. ESP32 30Pin Version.

x-zip-compressed - 420.06 kB - 10/10/2023 at 11:19

Download

10_Dollar_Robot_Laser_Parts_V1.dxf

Chassis parts to be laser cut. Use 3mm MDF, PLY or Acrylic.

AutoCAD DXF - 47.54 kB - 10/09/2023 at 12:23

Download

Yellow_TT_Rear_Wheel.stl

Rear wheel for yellow TT motor.

Standard Tesselated Geometry - 1.14 MB - 10/09/2023 at 13:14

Download

Standard Tesselated Geometry - 363.07 kB - 10/09/2023 at 12:45

Download

View all 7 files

View all 16 components

  • Boards Available from PCBWay.

    Neil Lambeth10/05/2023 at 19:58 0 comments

    The bare PCB's for the $10Robot! are now available from PCBWay.

    There's also a $5 Discount for new users.

    Here are the links:

    $10Robot! 30 Pin PCB

    Robot Controller

  • ESP-NOW Controller

    Neil Lambeth10/04/2023 at 13:11 0 comments

    I heard about the ESP-NOW wireless protocol a while ago and I thought a custom controller would make a good addition to this project. This will not be included in the original budget of $10, but it will still be very cheap to make at around $5, and much cheaper than buying a PlayStation (or other) controller.  

    Here's the first iteration. It uses the 30 pin ESP Devkit, as this was the cheapest option if you buy them in packs. It has a joystick with 2 analogue axis and 9 buttons, It's powered by 2 AAA batteries.

     I wanted to use MicroPython, but ESP-NOW is not included in the main MicroPython firmware. You have to use the nightly build, you can download it here: MicroPython_ESP32

    Make sure you download the nightly build:

    You can upload the new firmware to your ESP32 device using Thonny (as detailed in a previous log).

    Once you have the firmware installed, you need to get the MAC address of the receiving device, in this case our robot. Run the following code on the ESP32 device in your $10Robot!

    import network
    import ubinascii
    
    wlan_sta = network.WLAN(network.STA_IF)
    wlan_sta.active(True)
    
    #  https://stackoverflow.com/questions/71902740/how-to-retrieve-and-format-wifi-mac-address-in-micropython-on-esp32     
    print(ubinascii.hexlify(wlan_sta.config('mac'),':').decode().upper())
    

    You should see the MAC address in the output window.

    Make a note of the MAC address as you'll need it in your controller code. It's also worth writing it on a little sticky label and sticking it on the robot. 

    Now load the following code onto the ESP32 in the controller. 

    import network
    import espnow
    from machine import Pin, ADC
    from time import sleep
    
    Y_Pot = ADC(Pin(36))
    Y_Pot.atten(ADC.ATTN_11DB) #  0 - 3.3V range
    Y_Pot.width(ADC.WIDTH_9BIT)
    X_Pot = ADC(Pin(39))
    X_Pot.atten(ADC.ATTN_11DB) #  0 - 3.3V range
    X_Pot.width(ADC.WIDTH_9BIT)
    
    UP = Pin(5, Pin.IN, Pin.PULL_UP)
    DOWN = Pin(15, Pin.IN, Pin.PULL_UP)
    LEFT = Pin(16, Pin.IN, Pin.PULL_UP)
    RIGHT = Pin(4, Pin.IN, Pin.PULL_UP)
    
    L1 = Pin(32, Pin.IN, Pin.PULL_UP)
    R1 = Pin(23, Pin.IN, Pin.PULL_UP)
    L2 = Pin(33, Pin.IN, Pin.PULL_UP)
    
    START = Pin(14, Pin.IN, Pin.PULL_UP)
    SELECT = Pin(13, Pin.IN, Pin.PULL_UP)
    
    # A WLAN interface must be active to send()/recv()
    sta = network.WLAN(network.STA_IF)  # Or network.AP_IF
    sta.active(True)
    #sta.disconnect()      # For ESP8266
    
    e = espnow.ESPNow()
    e.active(True)
    peer = b'\x0A\x0B\x0C\x0D\x0E\x0F'   # MAC address of peer's wifi interface
    e.add_peer(peer)      # Must add_peer() before send()
    print("Start")
    
    while True:
        Y_Raw = Y_Pot.read()
        X_Raw = X_Pot.read()
        Y = int(Y_Raw/2) # Convert to 8bit
        X = int(X_Raw/2) # Convert to 8bit
        
        e.send(peer, b'start', True)
        
        e.send(peer, str(Y), True)
        e.send(peer, str(X), True)
        
        e.send(peer, str(UP.value()), True)
        e.send(peer, str(DOWN.value()), True)
        e.send(peer, str(LEFT.value()), True)
        e.send(peer, str(RIGHT.value()), True)
        
        e.send(peer, str(L1.value()), True)
        e.send(peer, str(R1.value()), True)
        e.send(peer, str(L2.value()), True)
        e.send(peer, str(START.value()), True)
        e.send(peer, str(SELECT.value()), True)
    

     Remember to change the peer MAC address on line 32 to match the one in your robot.

    Now load the following code onto the ESP32 in your robot.

    import network
    import espnow
    import ubinascii
    import time
    from machine import Pin
    
    # A WLAN interface must be active to send()/recv()
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
    #sta.disconnect()   # Because ESP8266 auto-connects to last Access Point
    
    e = espnow.ESPNow()
    e.active(True)
    
    # Set up motors
    M1a = Pin(18, Pin.OUT)
    M1b = Pin(19, Pin.OUT)
    
    M2a = Pin(25, Pin.OUT)
    M2b = Pin(26, Pin.OUT)
    
    
    data =[0,0,0,0,0,0,0,0,0,0,0,0] # List to store controller data
    count = 0
    UP = 0
    DOWN = 0
    LEFT = 0
    RIGHT = 0
    
    print("Press CTRL-C now to stop program")
    time.sleep(2)
    print("Start")
    
    while True:
        host, msg = e.recv()
        if msg:             # msg == None if timeout in recv()
            if msg == b'start': # Look for the start of the message and reset the count
     count...
    Read more »

  • PS3/4 Controller

    Neil Lambeth10/03/2023 at 10:36 0 comments

    We already use Playstation controllers for the other robots that we use in our club, there's also a prety good chance that the students will have them at home. So It makes sense to use them with the $10Robot! as well.

    A quick bit of googling lead me to an Arduino library: PS4-esp32 (there's also a library available for PS3 controllers).

    The first thing you have to do it get the MAC address of your controller. You can do this by using the Sixaxis Pair Tool, I used this one.  Just install it then plug in your controller with a USB cable and it will show you the MAC address. Make a note of it as you'll need it in your Arduino program.

    After installing the Arduino library, it was pretty easy to get up and running, as there are a number of example programs included. I used PS4ReceiveData as my starting point. It doesn't control a robot yet, it just shows the button presses in the serial monitor.  I modified the original code a little, just so that it makes the serial output a bit easier to read. 

    #include <PS4Controller.h>
    
    //Set up variables
    int LX = 0;
    int LY = 0;
    int R_X = 0;
    int RY = 0;
    
    int LX_old = 0;
    int LY_old = 0;
    int RX_old = 0;
    int RY_old = 0;
    int deadBand = 8;
    bool connected = 0;
    
    void setup() {
      Serial.begin(115200);
      PS4.begin("0a:0b:0c:0d:oe:0f"); // Enter your MAC address here.
      Serial.println("Ready.");
      delay(200);
    }
    
    void loop() {
      if ((PS4.isConnected()) && (connected != 1)) {
        Serial.println("Connected!");
        Serial.printf("Battery Level : %d\n", PS4.Battery());
        connected = 1;  
      }  
    
      // Below has all accessible outputs from the controller
      if (PS4.isConnected()) {
        if (PS4.Right()) Serial.println("Right Button");
        if (PS4.Down()) Serial.println("Down Button");
        if (PS4.Up()) Serial.println("Up Button");
        if (PS4.Left()) Serial.println("Left Button");
    
        if (PS4.Square()) Serial.println("Square Button");
        if (PS4.Cross()) Serial.println("Cross Button");
        if (PS4.Circle()) Serial.println("Circle Button");
        if (PS4.Triangle()) Serial.println("Triangle Button");
    
        if (PS4.UpRight()) Serial.println("Up Right");
        if (PS4.DownRight()) Serial.println("Down Right");
        if (PS4.UpLeft()) Serial.println("Up Left");
        if (PS4.DownLeft()) Serial.println("Down Left");
    
        if (PS4.L1()) Serial.println("L1 Button");
        if (PS4.R1()) Serial.println("R1 Button");
    
        if (PS4.Share()) Serial.println("Share Button");
        if (PS4.Options()) Serial.println("Options Button");
        if (PS4.L3()) Serial.println("L3 Button");
        if (PS4.R3()) Serial.println("R3 Button");
    
        if (PS4.PSButton()) Serial.println("PS Button");
        if (PS4.Touchpad()) Serial.println("Touch Pad Button");
    
        if (PS4.L2()) {
          Serial.printf("L2 button at %d\n", PS4.L2Value());
        }
        if (PS4.R2()) {
          Serial.printf("R2 button at %d\n", PS4.R2Value());
        }
    
        if (PS4.LStickX()) {
          LX = PS4.LStickX();
          //Serial.printf("Left Stick x at %d\n", PS4.LStickX());
          
          // Use the deadband to make sure the value goes back to zero when you let go of the stick.
          if ((LX < deadBand) && (LX > -deadBand)) {
            LX = 0;
          }
        }
        
    
        if (PS4.LStickY()) {
          LY = PS4.LStickY();
          //Serial.printf("Left Stick x at %d\n", PS4.LStickX());
          
          // Use the deadband to make sure the value goes back to zero when you let go of the stick.
          if ((LY < deadBand) && (LY > -deadBand)) {
            LY = 0;
          }
        }
    
    
        if (PS4.RStickX()) {
          R_X = PS4.RStickX();
          //Serial.printf("Left Stick x at %d\n", PS4.LStickX());
          
          // Use the deadband to make sure the value goes back to zero when you let go of the stick.
          if ((R_X < deadBand) && (R_X > -deadBand)) {
            R_X = 0;
          }  
        }
    
    
        if (PS4.RStickY()) {
        RY = PS4.RStickY();
          //Serial.printf("Left Stick x at %d\n", PS4.LStickX());
          
          // Use the deadband to make sure the value goes back to zero when you let go of the stick.
          if ((RY < deadBand) && (RY > -deadBand)) {
            RY = 0;
          } 
        }
    
    
        // Only print the values if they have changed
        if ((LX != LX_old) || (LY != LY_old) || (R_X != RX_old) || (RY != RY_old)) {
          Serial.printf("LX = %04d, LY = %04d, RX = %04d, RY = %04d\n", LX, LY, R_X,...
    Read more »

  • Create an App with Blynk

    Neil Lambeth09/29/2023 at 15:16 0 comments

    Now it's time to get programming. When introducing young students to programming, you'd normally start by blinking an LED, so let's do that but we'll do it controlled over the internet by an app on your phone. Then we'll make the app control your robot! 

    To do this we'll use blynk.io

    Blynk is a low code Internet of Things framework. It works very well with the ESP32 and Arduino. There's a free plan with enough features to create our app for controlling a robot.

    Blynk has got some great examples to get you going, we'll use one of those but we'll modify it for our needs. After you have created a free account, go to you dashboard then click on Templates on the left hand side, then click on + New Template.

    Give your new template a name, I called mine 'Robot Controller'. The hardware should be ESP32 and the connection should be WiFi.

    Click on Datastreams, then + New Datastream.

    Select Virtual Pin, then click on Create

    Repeate this 6 more times, your datastreams should look like this:

     Click on save in the top right corner.

    Click on the lifebuoy icon in the bottom left of the screen, then select Quickstart. 

    Click on Let's Go! Then select ESP32 as your hardware. Follow the instructions to install the Blynk library for Arduino.

    You'll be presented with some example code, but we are going to use a different example.

    Click on the other examples at the bottom of the screen.

    Select the Blynk Blink example from the drop down box on the Left.

    Also change the Template Name to match what you called the template you created earlier.

    Now click on Copy Example on the right hand side of the screen.

    Open the Arduino IDE and paste in the copied sketch.

    Change the WiFi credentials to match your own network.

    We'll now add the code to flash an LED. At the bottom of the void setup() section of code, add the following line:

    pinMode(2, OUTPUT); // LED

     So it should look like this:

    Now just after your WiFi credentials, add the following code:

    BLYNK_WRITE(V0)
    {
      // Set incoming value from pin V0 to a variable
      int value = param.asInt();
      
      if (value== 1)
      {
        Serial.println("LED On");
        digitalWrite(2, HIGH);
      }
    
      if (value== 0)
      {
        Serial.println("LED Off");
        digitalWrite(2, LOW);
      }
    
      // Update state
      Blynk.virtualWrite(V1, value);
    
    }

    It should look like this:

    Upload the code to your ESP32 device. Turn on the Serial Monitor and change the Baud Rate to 115200. If everything is correct it should connect to your WiFI and you should see some output like this:

    Now open the Blynk app on your phone. This has got a drag and drop interface to easily create your app. Click on the + symbol at the top right of the screen to Add a New Device. Then select Manually from template.

    Select the template you created earlier, then click on Create. Now click on the spanner icon at the bottom of the screen to enter Developer Mode.

    Now you can start adding buttons and other controls for your app. Click on the screen, then from the menu that appears, add a Button. Repeat the process to add an LED.  Long press on the items you have just added and drag them around the screen to reposition them.

    Arrange the button and LED like this:

    Tap on the button  to change it's properties. Tap on Datastreams then select the entry at the top of the list, this should be IntegerV0

    Next change the Mode to Switch, as shown here:

    Next, tap on the LED and change it's Datastream to IntegerV1. Tap the back arrow at the top of the screen to exit Developer Mode.

    If everything has worked correctly, when you tap the button on the screen, the LED on the ESP32 should light up!

    You should also see the output change in the Serial Monitor window.

    Now we have our LED flashing, it's time to make our robot move.

    In the Blynk app on your mobile, select your Robot Controller App. Enter developer mode by tapping the spanner at the bottom...

    Read more »

  • TPU Tracks

    Neil Lambeth09/28/2023 at 13:59 0 comments

    A s mentioned in my previous log, my chassis design was based around some cheap tank tracks I found on Aliexpress, these came in at about $2.85 for the pair. I hadn't included these in my original costing so I need a cheaper alternative.

    I had a roll of TPU filament lying around but hadn't had much need for it. So this was a perfect opportunity to try it out properly.

    I set about designing a version of the tracks in FreeCAD.

    It turns out that it actually prints pretty easily, I just used the default settings and they came out well. There's a little bit of stringing on the inside lugs but nothing I can't live with.

    Having a quick look on Amazon, I can get a 1kg roll of TPU for around $24. I weighed the tracks and together they came in at 19 grams. That works out at just under $0.5 for the pair. That will get me back on budget.

  • Laser Cut Chassis

    Neil Lambeth09/28/2023 at 13:30 0 comments

    The overall size of the chassis was determined by the size of the tracks I could get. I found these Lego compatible ones on aliexpress

     I also wanted to make sure I could fit different types of battery pack inside, mainly a pack of 6 x AA, like this:

    AA batteries are cheap and easy to get hold of and there's a good chance that the students will already have some at home that they can use. Hopefully they would have some rechargeable ones, which of course would keep the cost down.

    I also wanted the option to use Lipo batteries for more advanced users.    

    Here's the first laser cut prototype of the chassis.

    The top cover has a tool-less quick release mechanism so you have easy access to the electronics inside.  

    The mounting plate inside has lots of options for different development boards.

    Here's my Pi Zero sized board:

    And here's the A+ sized board:

    The underside with the bottom panel removed with space for  6 x AA's of a 3s Lipo.

  • A+ +

    Neil Lambeth09/28/2023 at 11:47 0 comments

    After researching the different types of ESP32 Devkits I redesigned the A+ sized board. I was hoping to make one board that would accept all the different devkits but in the end I designed two new boards. One to for the 38pin versions and one for the 30pin version.

    The 38 pin version was pretty easy as I just added another row of pads so the board could  accommodate both the wide and narrow versions.

    As there was some space under where the Devkit would go I also added some pads to solder in a capacitor which would help if you are driving more powerful motors. 

    The pinout for the 30 pin version was quite different so It needed it's own board. I wanted to be able to use this version of the Devkit as it's available in bulk, so it works out to be the cheaper option.

  • WebREPL and Wireless Programming

    Neil Lambeth09/26/2023 at 09:00 0 comments

    One of the thing I liked about the M5 Stamp was that you could program them wirelessly with minimal effort. This is a great feature for working with robots as you don't need to keep picking them up to reprogram them. This relied on M5's UiFlow software but I was wondering if there was a way to make this work with generic ESP32 modules. 

    As it turns out, Hackaday had the answer with this article: Wireless micropython programming with thonny.   

    I then found out more about WebREPL and ESP's with this article from Adafruit: ESP8266 WebREPL

    Some of the details seem to have changed or it's different for the ESP32 as mine didn't automatically create it's own access point, so to create one I followed this guide from Random Nerd Tutorials: ESP32 Access Point

    We only need the first part of the code from that tutorial as we don't need to create the Web Page.

    Here's a run down of the procedure:

    1. Install Thonny, It's a great Python IDE especially for use in education.

    2. Upload the Micro Python firmware to your ESP32 board. You can do this from within the Thonny IDE, your board has to be connected via USB. Just click on the info tray at the bottom right of the Thonny window, then click on Configure interpreter.

    Next click on Install or update MicroPython (esptool). 

    Then select your ESP32 board and version from the drop down boxes and finally click on install.

    In the Shell window at the bottom of the Thonny screen, type:

    import webrepl_setup

    Enter E.

    Then enter a password (use a better one than I did!).

    Then enter y to reboot.

    Now enter the following code, then from the file menu select Save As, then select MicroPython Device. Save the file as boot.py (overwrite the exsisting boot.py file). 

    # This file is executed on every boot (including wake-boot from deepsleep)
    #import esp
    #esp.osdebug(None)
    import time
    import network
    import webrepl
    webrepl.start()
    
    #Set up ESP32 as access point
    ssid = 'MP_AP'
    password = '123456789'
    
    ap = network.WLAN(network.AP_IF);
    ap.active(True);
    ap.config(essid=ssid,authmode=network.AUTH_WPA_WPA2_PSK, password=password)
    print(ap.ifconfig())

    Reboot your ESP32 by pressing the EN button on the Devkits or disconnecting then reconnecting the USB cable.   

    The ESP32 access point should show up in your list of WiFi networks.

    In Thonny, select configure Interpreter again.

    From the Port or WebREPL drop down box, choose <WebREPL>.

    Enter the password that you entered for the WebREPL setup (not the access point password in the Python code!). 

    Click OK. The shell window in Thonny will now disconnect as it's now trying to connect over WiFi not USB.

    Go to your WiFi settings and connect to the MP_AP access point.

    It will report that's there's no internet connection, so your computer will go offline (unless you have a wired connection as well).

     Click on Stop/Restart backend in Thonny, and the Shell window will reconnect. But this time it will be connected over WiFi, not USB!

     It may be a little slower but you can now do everything that you could do over a wired connection.

  • Which ESP?

    Neil Lambeth09/21/2023 at 20:29 0 comments

    After designing the last board with a ESP32 Devkit, I found there were a few different versions with different pinouts. 

    I bought a some of the different boards to try to work out what was what. This is what I found:

    Starting on the left, is the basic ESP32 surface mount module.

    Next is the 30pin DevKit, this only seams to come with one choice of ESP32 module with the onboard antenna.

    Then we have 2 38pin boards in a narrow format, these are available with different ESP32 modules.

    On the right there are 2 38pin boards in a wide format, these are also available with ESP32 modules. 

    The 38pin boards have the pins in the same order but the different widths means they are not compatible.

    The 30pin board has a different pinout. The 8 missing pins are for the Internal flash chip and are not needed.

     The 30pin board are available in bulk packs and so are a bit cheaper than the others at about $2.70 each. 

    I'll see if I can design a board which can accept any of these board for maximum flexibility.    

  • A+

    Neil Lambeth09/21/2023 at 20:25 0 comments

    I originally wanted to board to be the same size as a Pi Zero. This was possible using the basic ESP32 module, but it was lacking a USB port which meant you needed a separate programmer to upload code. I had some of the ESP32 Devkits in my parts box so I set about designing a board using one of these. These boards are quite a bit bigger than the ESP32 modules so this design would have to be bigger than a Pi Zero. I though about designing a slightly bigger board with a different mounting hole pattern but I then decided against this as I wanted these boards to be drop in replacements for the RPi's that we already use in our robots. The next size board I looked at was the Pi A+, this was a pretty good fit for the ESP32 Devkit. 

    Here's the first board I designed using this shape. It uses the 38pin Wide Devkit as I already had some of these to hand.

    A bonus of this sized board is that it breaks out all of the GPIO pins, so you have the option of making more complicated robots.

View all 14 project logs

  • 1
    Gather all of the components.

    Some of them are optional, you don't necessarily need the header sockets as the ESP32 module can be soldered directly to the board for a more low profile look. You also don't need the GPIO pin headers on the left hand side unless you want to control servos or read sensors etc.

  • 2
    DC/DC Converter

    Flip the board over and insert the PCB pins for the DC/DC Converter.

    Use a bit of masking tape to hold them in place.

     Look at the underside of the DC/DC converter and make sure the arrows are pointing in the same direction.

    Flip the DC/DC Converter the right way up, place it over the PCB pins, then solder the pins on the top side first. When all 4 pins are done, flip the whole PCB over, remove the masking tape and solder the 4 pins on the underside. 

  • 3
    Dual H-Bridge

    Insert the 2 6-way header pins for the Dual H-Bridge.

    Flip the board over and solder the pins on the underside. Make a note of the position of the symbol of the LED as you'll use this to orientate the Dual H-Bridge. 

    Flip the board back over, insert the Dual H-Bridge then solder the pins.

View all 13 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates