Software apps and online services
The goal of this project is to create an outdoor rover, capable of autonomous navigation using GPS and sonar sensors, but which can also be controlled and tracked over WiFi. Of course, there are dozens of similar projects (some under the name "smart car"). Here are some features which set this project apart:
- We use NodeMCU microcontroller and Blynk app to control the rover using a cellphone
- It is intended for outdoor, off-the-road navigation. To achieve it, we use tank chassis with 12 V motors - more powerful than typical smart car project
- To prevent motor burnout, we use motor drivers with current limiting
- To avoid nest of wires, we use custom-made PCB (schematics and Eagle files are included with this project). We also use a custom-made plastic cover for nice appearance
- For increased accuracy, we use GPS receiver based on a newer u-blox M8N chip, which use both GPS (USA) and GLONASS (Russia) navigation systems at the same time.
This tutorial contain full instructions; in the attachments you will find Bill of Materials (in CAD and custom parts section), schematics, and sample code.
This projects was created for robotics lab at SigmaCamp, a science summer camp.
Please leave your comments!
For chassis, we use TS100 tank chassis by Chinese company DoIT (http://en.doit.am/ ). The chassis can be bought from their AliExpress shop; there are several versions - choose the one with 12V motors. As of time of this writing, total cost (including shipping to USA) is $89, and shipping was fast.
The chassis is very well made, with miniature ball bearings for axles. The chassis can be assembled in several configurations; we used more narrow one, and put both motors in front (see images above). The only change we made was replacing regular M4 nuts by locknuts and drilling extra holes for mounting the electronics. We also soldered 18 gauge cables to motors.
Finally, after attaching all electronics and sensors, we cover the rover with a shell made from 1/16" ABS plastic; we use heat gun to bend it to shape. It is mounted using four 2-inch aluminum standoffs. The power switch and sonar sensors, described below, are mounted on the shell.
We used 3000 mAh 12V NiMh battery (such as this one from ServoCity) - just because we had a bunch of them from FTC competitions. They are not cheap - feel free to use any 9-15 V battery source of your choice. We attached the battery under the rover, using zipties; low center of gravity helps stabilize the robot.
We also used an illuminated 12V rocker switch - any generic one will do (choose round to make it easier to install). The wiring uses 18 gauge cable (speaker wire is probably the easiest choice).
All motor and power wires going into the screw terminal of the control board were terminated with wire sleeves (ferrules). Another option is tinning the wire ends, but it is less reliable and not recommended (see, e.g., discussion here).
This is the core of the car. It consists of a custom-designed PCB (eagle files are attached), on which we mount the following components:
- two rows of 15-pin female headers - for NodeMCU microcontroller (version 1.0)
- an 8-pin DIP socket, for slave ATtiny85 processor, used to control the sonar sensors (see section on Sonars) and two 3.3k resistors, used as pull-up resistors on I2C bus
- L7805 voltage regulator with a heatsink
- two DRV8871 motor drivers made by TI. These drivers are relatively expensive ($2.44/piece), but they provide features not available from cheaper drivers: high efficiency, capable of continuous current of 2A at up to 45V, and, most importantly, current limiting - so even when the motor is stalled, the current provided by the driver will not go over certain limit (determined by a resistor; we use 22k resistors, which limit the current to 2.9 A). This helps prevent motor burnout.
- A ceramic 0.1mF and electrolytic 100mF capacitors, for stabilizing the input power, as described in DRV8871 datasheet (datasheet suggests one of each capacitors for each of the drivers; in our circuit, the drivers share the capacitors)
- A P-channel MOSFET, used for reverse polarity protection of input (as described in this note).
- 6 position terminal block. We used a high-quality one (rising cage type) by Amphenol
- male headers for connecting sensors:
- two 4-pin headers for HC-SR04 sonar sensors
- a 6-pin header for GPS/compass sensor
- a 4-pin I2C header (not used currently - for future extensions)
We had the PCB manufactured by SeeedStudio Fusion service; total cost for manufacturing and shipping 10 boards was about $20 (with two-week delivery to US; for extra $20, you can get expedited shipping and receive your boards within 3 days). Here is the direct link to the board design in SeeedStudio gallery for easy ordering. Alternatively, you can use eagle files attached to the project, modify them as you like, and order your own copy from any PCB manufacturer.
Note that DRV8871 are only available in surface-mounted package (and the polarity protection MOSFET we use is also surface-mounted), so soldering the board requires SMD soldering skills.
The board has 4 mounting holes (for M3 screws) using the same pattern as Raspberry Pi board: 49 mm x 58 mm rectangle.
To make it easy to upload new code to NodeMCU, we use a USB extension cable (microUSB male to microUSB female). One end is permanently plugged into the NodeMCU, the other is ziptied at the rear of the rover for easy access. This also reduces the wear on NodeMCU microUSB port.
We use two HC-SR04 sonar sensors for obstacle detection. To free the resources of the NodeMCU microprocessor, we use a separate MCU, ATtiny85, for controlling the sonars. NodeMCU and ATtiny85 communicate using I2C protocol. This also takes care of differing logic voltage levels (5V for HC-SR04 and ATtiny85, 3.3 V for NodeMCU): ATtiny85 and NodeMCU easily communicate over I2C bus, with pull-up voltage of 3.3V.
We use DualSonar library for programming the ATtiny85; please see the README file for installation instructions (you will need an Arduino Uno to serve as a programmer for ATtiny85).
We use a GPS+compass combination sensor; such sensors are commonly used for drones/quadcopters. These sensors combine two chips: a GPS chip (usually made by u-blox) and magnetometer (compass) chip, usually Honeywell HMC5883 magnetometer. They are available from a number of vendors (usually Chinese no-name vendors). We had bought our sensor on eBay, but you can choose any vendor; you can find one under $20 (including mount). We recommend using a sensor based on newer u-blox NEO-M8N chip, which provides increased accuracy compared to older NEO-6 and NEO-7 series chips, by using concurrently GPS (US) and GLONASS (Russia) navigation systems (it is also capable of tracking Chinese BeiDou and recently launched European Galileo satellites). However, it also requires extra work when programming (see Software installation section below).
Such sensors typically come with connectors either for APM 2.6/2.8 (a 4-pin DF13 connector plus a 5-pin DF13 connector) or Pixhawk (a 4-pin plus 6-pin DF13 connectors) flight control boards. It doesn't matter which one you buy - you will need to cut off the connectors and solder instead a 6-pin female header (obtained by cutting in half a 6-pin jumper wire from SparkFun, see Bill of Materials).
Note that GPS and compass chips use different protocols for communication. GPS chip uses serial interface; we use software serial to read it, leaving hardware serial for communication with computer. Compass chip uses I2C protocol and shares I2C bus with the ATtiny85 controlling sonars.
List of pin assignments and connections, needed for programming, is given in attached spreadsheet.
Note that in this spreadsheet, serial interface for GPS sensor is labeled from the point of view of the sensor: "TX" means "pin which connects to sensor's TX".
Note also that if you duplicate this project and are looking to change pin assignments, it is trickier than you might expect. For example, during normal startup of NodeMCU, GPIO 15 must be held low, which means that you can not use it for I2C (which is normally held high).
We program the rover using Arduino IDE. To do that, one needs to install the following extra components:
- Support for ESP8266-based boards (including NodeMCU)
- TinyGPS++ library (which needs to be patched, see below)
- Adafruit unified sensor library (Adafruit_Sensor) and Adafruit HMC5883 library, for accessing the compass data. Both can be downloaded here.
- DualSonar library (for communicating with ATtiny85, which controls the sonars)
- Blynk, BlynkESP8266_Lib, and SimpleTimer, all parts of Blynk project
General instructions for installing Arduino IDE libraries can be found here: https://www.arduino.cc/en/Guide/Libraries
We had some thorny issues using these libraries:
- Official TinyGPS++ library doesn't work with ublox NEO-M8N chip. The reason is that because M8N uses more than one navigation system, it outputs the data in slightly different format (if you are curious, it uses GN*** NMEA sequences instead of GP***, see e.g. here or here) . To fix this, we need to make some changes to TinyGPS++ library. Such a patched version of TinyGPS++ library is included as a zip file with the project - so you can just install it instead of the original library. If you are using older NEO7 or NEO6 series GPS receiver, you can use the patched version or the original TinyGPS++ - either one would work.
- For reasons unknown, the measurements of magnetic field returned by the magnetometer (compass) sensor have some offset, which differed from one sensor to another (we tested 4 of them). For example, one sensor would return x- component measurements ranging from -27 to +13 uT (expected behavior is that range be symmetric: turning the sensor 180 degrees should replace value x by -x). We do not know why it happens, but a workaround is to find the offset and subtract it. See
Rover-compasstestsketch for details. Once you found the offset, use it in all your sketches.
Finally, you need to install Blynk app (available for Android and iPhone) on your cell phone, and you need to have a WiFi network - usual household router would do for indoor tests. For using the rover outdoors, see section on Blynk local server below.
Attached to this tutorial is a zip file with sample sketches:
Rover-motortest: the simplest test, to verify that the control board and motors are working as expected.
Rover-compasstest: test the compass and print the output to serial terminal (start serial terminal at 9600 baud)
Rover-sonartest: test the sonars and print the output to serial terminal (start serial terminal at 9600 baud)
Rover-gpstest: test the gps and print the output to serial terminal (start serial terminal at 9600 baud)
Rover-blynktest: drive the rover using joystick widget in Blynk. Requires that you also create a Blynk project on your cellphone, with matching widgets. The easiest way to do it is by scanning the QR code below to clone a project (see Blynk documentation)
Rover-full: combines the previous ones. Drive the rover using Blynk joystick, follow its path on the map, and see the data from sonars and compass.
Rover-autonomous: rover drives autonomously to a given target location. In this sketch, the target location is hardcoded.
For using rover outdoors, far from any infrastructure, we made our own portable Blynk server, consisting of
- Raspberry Pi 3 running Blynk local server software (see https://github.com/blynkkk/blynk-server#blynk-server )
- portable router. We used TP-Link N300 router
- Portable power bank, used to power both Raspberry Pi and the router, such as this one by Jackery. Make sure to choose one that has two USB ports outputs, and that the USB port used by Raspberry Pi can provide at least 2 Amp.