Introduction
There is something about robots that have captured my imagination as long as I can remember. They are my comfort zone whenever I embark on new Maker adventures; as soon as I get past the “blinking LED” project, a basic robot is always my go to project when learning a new platform or technology. And so, when I decided to give Windows IoT Core a try, this project was naturally my starting point. The Rover is a simple robot so it’s a good place to start but it’s also infinitely expandable.
This initial
Rover project creates a little robot that runs around your living room on its
own. It just drives straight ahead until it detects an object blocking its
path. At which point, it turns until it can find a clear path and then its full
speed ahead again. The heart of the Rover is a Raspberry Pi running Window 10
IoT Core. The two motors are driven via a dual H-bridge motor controller and an
ultrasonic distance sensor is used to detect obstacles. The Rover can be built on any rolling chassis; I selected a low cost one that is readily available from
a variety of retailers around the world.
This is a beginner project and no advanced software or hardware skills are required. Excluding the pre-requisites, this project can be completed in 1.5 to 2 hours if you have any Arduino or similar microcontroller experience. If this is your very first electronics project, I recommend that you spend a couple hours watching a few introductory Arduino and Raspberry Pi videos prior to getting started.
I have a few enhancements still to make:
Light dependent resistor and LEDs for headlights.
Code to mimic a PWM signal on the digital GPIO pins to adjust the Rover’s speed.
3D print a body to hide all the electronics (maybe print a chassis as well).
If you try any of these enhancements or any others you come up with, please leave a comment and let me know how it went.
Here are some online resources that I found very helpful throughout the course of this project:
Microsoft Windows Dev Center for IoT has a very good step-by-step guide to get started with Windows 10 IoT Core.
ModMyPi blog post on using an ultrasonic distance sensor with the Raspberry Pi
Pre-Requisites
Get Windows 10 IoT Core running on your Raspberry Pi 2 (instructions here).
Get Windows 10 and Visual Studio 2015 running on your PC (instructions here).
Deploy a simple Windows app to the Raspberry Pi to ensure everything is working (instructions here).
Note: It will take 2-3 hours to complete the pre-requisites but most of that time is unattended.
What You’ll Need
Parts:
- Raspberry Pi 2 and standard accessories: 5v 2A power supply, 8GB class 10 micro SD card, case, and network cable
- Jumper wires – both male/male and male/female
- Mini breadboard
- Robot
car chassis kit which includes a base, motors, and wheels
- L298N motor controller
- HC-SR04 ultrasonic distance sensor
- 1k and 2.2k Ohm resistor
- LM2577 DC-DC adjustable step up power converter module
- 3 x 1.5v AA battery holder
- Optional: 4 x 1.5v AA battery holder with on/off switch and cover
- Optional: Double sided tape or Velcro or rubber bands
Tools:
#1 Phillips head screwdriver
small needle nose pliers
Optional: wire stripper
Optional: soldering iron
- Optional: electrical tape
References:
Project Instructions
Step 1: Assemble the robot chassis
Time: 30 minutes
Tools: #1 phillips head screwdriver; soldering iron or electrical tape; optional wire stripper
Parts: robot chassis kit; optional 4 x AA battery holder with on/off switch
There are several robot kits on the market that will work with this project. You just need a kit with two driven wheels and a third for balance. Follow the instructions which came with your robot chassis kit to assemble the base plate, motors, and wheels. I found a YouTube video showing the assembly of a robot kit very similar to the one I used.
If you have a soldering iron, go ahead and solder the included wires to the motors. If you don’t have a soldering iron, you can just bend the exposed wire ends and hook them on to the motor terminals and then wrap electrical tape around both wire / terminal connections on the motor to secure them.
Tip: I route the motor wires up through holes in the base to keep them from getting caught by the wheels.
Instead of using the 4 x AA battery holder that came with the robot kit, I used a different one with a cover and an On/Off switch. This is an optional substitution as it doesn’t change the performance or functionality of the robot at all. I just like the convenience of easily turning off the power to the motors using the switch built into the battery holder. Since I mount the Raspberry Pi directly on top of the battery holder, it’s a little more difficult to remove a battery to cut power to the motors.
The battery case can be mounted to the base in a number of ways. If the robot base has holes that align with the holes in the battery case and you have the right size screws, you can screw the case to the base. Otherwise, use Velcro, double sided tape, or rubber bands. I used rubber bands and they worked fine. I mounted the case in the middle of the base to keep the center of gravity close to the midpoint of the base.
Step 2: Wiring the L298N motor driver
Time: 20 minutes
Tools: #1 phillips head screwdriver; small needle nose pliers
Parts: L298N motor driver; jumper wires
The L298N motor driver allows you to spin the motors forwards AND backwards using a handful of GPIO pins. First, connect the two wires you secured to each motor in the prior step to a pair of motor terminals – the red and black wire from one motor to ‘Motor A’ and the red and black wire from the other motor to ‘Motor B’. Polarity isn’t important and you can always switch the order of the wires later if your motor ends up spinning the wrong way when you deploy your code. Next, connect the wires from the 4 x AA battery holder to the power terminals – red to +12v input and black to Ground; the 4 AA batteries are the power source for the motors. Also be sure to run a wire from the Ground terminal on the L298N to a GND GPIO pin on the Raspberry Pi (pin 6).
The L298N was designed to support a single power source for both the motors and the microcontroller / computer. The full voltage from the power source is routed to the motors. At the same time, the voltage from the power source is converted and regulated to 5v for the microcontroller / computer and is supplied via the +5v terminal on the power block. However, through past motor oriented projects, I found too much variability in the power from the L298N’s 5v supply – i.e. when a motor stalls, there is a large voltage drop in the 5v output (large enough to reset the Raspberry Pi). Additionally, even without the motors running, I measured only 4.35v of output from the 5v supply. While in reality, that was enough to power the Raspberry Pi (even though the Raspberry Pi’s specification state that it is below the minimum voltage required), I didn’t want to take any chances – it’s no fun chasing inconsistent behavior in the Raspberry Pi especially when it might be due to very minor voltage changes. Therefore, for this project, I decided to use two power sources – one for the motors and one for the Raspberry Pi. Earlier in this step, we connected the 4 AA batteries to the +12v terminal to power the motors. In the next step, we’ll connect the 3 AA batteries to power the Raspberry Pi.
But while we are setting up the L298N, we’ll go ahead and link the power from the Raspberry Pi to the L298N. First, remove the physical jumper – labeled ‘5v enable’ in the photo – from the L298N. This sets the motor controller logic to be powered by the Raspberry Pi via the +5v terminal on the power block rather than from the power source connected to the +12v terminal.
Important: Make sure you remove the physical 5v enable jumper on the L298N. If you don’t, then the L298N will output a variable 4-5v via the +5v terminal which may cause performance issues with the Raspberry Pi.
Unfortunately, the Raspberry Pi only has two 5v pins and I need three for this project. So, I decided to create a power rail on my breadboard – use the interconnected row on the breadboard to distribute power from the Raspberry Pi. To create the power rail, connect a female / male jumper wire from the Raspberry Pi’s pin 2 (a 5v pin) to any unused row on the breadboard (I usually use the first or last row). Now, the 5v from the Raspberry Pi can be distributed across the project by plugging into the same row on the breadboard. Use a male / male jumper wire to connect the +5v terminal on the L298N to the power rail.
The last connections required are to connect 4 GPIO pins from the Raspberry Pi to the 4 motor input pins on the L298N. IN1 and IN2 control the direction of motor A and IN3 and IN4 control the direction of motor B. Leave the jumpers on the L298N attached to the two sets of motor enable pins - ENA and ENB - in place. My connections are as follows:
IN1 -> GPIO 27 / physical 13
IN2 -> GPIO 22 / physical 15
IN3 -> GPIO 5 / physical 29
IN4 -> GPIO 6 / physical 31
Now, your connections should match this diagram:
Step 3: Wiring the DC-DC step up power converter
Time: 20 minutes
Tools: multimeter; soldering iron or electrical tape; optional wire stripper
Parts: DC-DC step up power converter; 3 x AA battery holder; jumper wires
As mentioned in Step 2, I decided to use separate power sources for the Raspberry Pi and the motors. Unfortunately, the Raspberry Pi doesn’t support a wide range of input power – 3 AA batteries would not be enough and 4 would be too much – so you need to use something between your battery pack and the Raspberry Pi to output a steady 5v. In the interest of trying to lighten the load where possible, I chose to go with 3 AA batteries rather than 4. The DC-DC step up converter can take the 4.5v input from the 3 AA batteries and can output 5v for the Raspberry Pi.
Either solder the red and black wires from the 3 x AA battery holder to the In+ and In- solder pads respectively on the DC converter or, for those without a soldering iron, hook the ends of the wires into the solder pads – labeled ‘Power input from battery’ in the photo – and wrap the electrical tape around them a few times. Put three batteries into the holder and use your mutlimeter to measure the DC voltage out from the DC converter. Use the converter’s built in potentiometer to “dial-in” an output of 5v.
Important: Make sure you set the DC converter’s output to 5v before connecting it to the Raspberry Pi. Out of the box, the converter’s power output is usually much higher – high enough to damage the Raspberry Pi.
Lastly, connect the output of the DC converter to the Raspberry Pi. Using the wire strippers, I cut the male ends off two male / female jumpers, stripped a little insulation off, tinned the exposed wire, and soldered them to the Out+ (red jumper) and Out- (black jumper). Alternatively, twist the exposed wire strands, hook them on the solder pads on the DC converter, and tape. Connect the female ends of the jumpers to a 5v pin (red wire to pin 4) and GND pin (black wire to pin 14) on the Raspberry Pi.
Step 4: Connecting the ultrasonic distance sensor
Time: 20 minutes
Tools: N/A
Parts: HC-SR04 ultrasonic distance sensor; mini breadboard; 1k and 2.2k ohm resistors; jumper wires
The HC-SR04 has 4 pins – VCC, Trig, Echo, and GND. I mounted the sensor into a mini breadboard to steady it on the robot as well as to simplify all the necessary connections. VCC on the sensor should be connected to 5v so use a male / male jumper to connect the distance sensor’s VCC to the power rail on the breadboard which was created in Step 2.
As an aside, here is a chart to help you read the color bands on a resistor for future reference. You'll use it more often than you think.
Now that there is power to the sensor, let’s complete the connections to the other three pins. Connect a female / male jumper wire from a GPIO pin on the Raspberry Pi to the sensor’s Trig pin – in my project, I use the Raspberry Pi’s GPIO 23 / physical pin 16. Do the same for the Echo pin but first put a 1K ohm resistor in between the sensor’s echo pin and the Raspberry Pi’s GPIO pin – in my project I connected the Raspberry Pi’s GPIO 24 / physical pin 18 to the resistor and then the resistor to the sensor’s echo pin. Connect a second resistor – 2.2k ohm – to the jumper from GPIO 24 and to the sensor’s GND Pin. Run another jumper from the sensor’s GND pin to a ground pin in the Raspberry Pi – i.e. pin 20. (The sensor will deliver 5v over the echo pin but the RPi only likes 3.3v on the GPIO pins so we need to divide the voltage.)
Step 5: Mount the components to the robot chassis
Time: 20 minutes
Tools: N/A
Parts: optional rubber bands or double sided tape or Velcro
There are a variety of layouts available and it, of course, depends on the robot kit you selected. For mine, I placed the 4 cell battery pack in the middle of the chassis, the Raspberry Pi in its case on top of the battery pack, and the L298N on top of the Raspberry Pi – all secured with rubber bands. The DC-DC step up converter is placed on the chassis next to the 4 cell battery pack and is held in place by the rubber band holding down the battery pack, Raspberry Pi, and motor controller. The 3 cell battery pack is behind that stack.
Step 6: Download and deploy the code
Time: 20 minutes
Tools: Visual Studio 2015 Community Edition
Parts: completed Rover
Download the source code from GitHub and load the project into Visual Studio. The main part of the program is straight forward - just two while loops. As long as the GPIO pins initialized properly, the first while loop drives the robot forward indefinitely. Nested within is a second while loop which simply turns the robot to alter its course as long as an obstacle is in its way.
Since we left the jumpers in the motor enable pins on the L298N, the motors are always enabled. You can drive them forward, stop them, and drive them in reverse with the input pins (2 pins for each motor). If you set both pins to low, the motor stops. If you set one pin to high and one to low, the motor spins; reverse the high / low setting on both input pins to spin the motor in the opposite direction.
Tip: If a motor is spinning in the wrong direction, either swap the pin settings in the code or swap the physical wires from the motor in the terminal block.
This initial project only required forward, right turn, and stop. However, in the code, you will see subroutines for reverse and left turn as well. That functionality is commented out for now; I left it in as it will soon be needed as I expand my project.
The ObstacleDetected subroutine simply compares the robots distance to a detected object and determines whether the robot is close enough to warrant a course change. The specs for the distance sensor state that it can measure distances up to few hundred centimeters. Just because the wall on the other side of the room is a 300 cm away doesn’t mean that it’s currently an obstacle and that the robot needs to make a course correction. Therefore, I arbitrarily picked a distance of 30 cm – any object less than 30 cm in front of the robot is considered an obstacle and therefore, will need to be avoided via a course correction.
The DistanceReading subroutine controls the distance sensor to take a reading. The process for getting a distance reading is as follows:
Ensure that the trigger is off and give it some time to settle.
Turn on the trigger for 10 microseconds
Wait until the echo is turned on
As soon as the echo is on, then start the stop watch
Wait until the echo is turned off
As soon as the echo is off, then stop the stop watch
Calculate the distance to the object based on the recorded time
After everything is running perfectly, you can set the program to run at start up so that you don’t need to manually start the program; instructions can be found here on how to set the program as the startup app.
Comments