Upon hearing about the new Particle Mesh contest, I wanted to create a novel project that made good use of the features of mesh networking. This could involve anything from a far-reaching network to a whole-home IoT solution, but I decided on swarm robots. Making robot swarms can be difficult, especially when it comes to communication between devices. The Particle Mesh platform makes this easy, as messages can be sent and received with ease via the built-in Particle Mesh API.
There was one more question I had to answer: What are the robots for? Playing multiplayer games with others via the Nintendo DSi LAN system was always fun. All someone needed was a client device. In the same way, I wanted to build three
identical robots that could be controlled via a simple webpage, letting anyone with a phone or laptop play with the robots.
I wanted there to be a way to score points and win the game. This led to the decision of using magnets and hall-effect sensors to detect hits. Each robot has a magnet in the front and a sensor in the back, so that when two robots collide, a point can be scored.
The user can set the maximum number of hits a robot can sustain before going “out”. Once two of the three robots have been disabled, the winner is announced and congratulated.
Designing a robot chassis from scratch and gathering the necessary components takes a long time and can become very costly. Rather, using a kit is a much faster and cheaper option. Elegoo reached out to me to sponsor this project, and they sent three of their Smart Car V3 Kits, which contain everything needed for a robotic car, including motors, a motor controller, rechargeable batteries, and a servo mount. The kit is solidly constructed from laser-cut acrylic panels and milled aluminum pieces.
For the controller board, all that is needed is a Particle Argon, which acts as an access point (AP) for the rest of the mesh network.
It handles external WiFi communication as well. Each robot car has a Particle Xenon, which are mesh network endpoints.
They mostly receive incoming data about movement or updated game states. They also control the rest of the robot’s IO, including motors, LEDs, servos, and the laser. An L298N motor driver is used to provide power to the motors. The module, along with the four motors, are included in the Smart Car Kit. DFRobot also reached out and provided me with three 128x64 OLED screens and three magnetic sensors. The screen is used to display data such as the name of the player and the hits that have been received, along with a game over/congratulations page.
Breadboards are great for fast prototyping, yet they take up a lot of space and require many jumper wires, creating a large mess. Protoboards are a bit better, as they need less space, but wiring a circuit on one can take ages to complete. That’s why I went with Printed Circuit Boards (PCBs) for each car’s circuitry. PCBs are very space efficient and can be easily designed and duplicated. PCBGOGO.com provided me with the PCBs for this project. While a PCB might cost about $10 on Oshpark.com, a PCB from PCBGOGO.com would cost about $0.50, and you get 3x more per order! After creating a schematic and board design with Eagle, I used their online gerber file viewer to check the validity of my CAM output files before sending them for fabrication.
After about two weeks, my 10 PCBs had arrived. I initially took my multimeter to check if there were any shorts present, and thankfully, there weren’t.
Next, I soldered on the WS2812b LED, along with the MOSFET, 5v regulator, and all of the pin headers. Before connecting anything, I check the output of the regulator, and to my surprise, it was incorrect, and the regulator was getting dangerously hot. This indicated a couple of pins were swapped. The part I used in the Eagle schematic had the wrong pinout, making GND go to 5v, VIN go to GND, and 5v going to VIN. It was then necessary to solder a wire onto each leg of the regulator and connect it to the correct pad on the PCB.
After taking one last measurement, it was time to plug everything in. Upon powering it on, the Xenon lit up and started searching for a mesh AP—success!
The Smart Car Kit arrived in a nicely packaged box, along with an instruction booklet and CD.
There were smaller boxes inside that contained various parts organized by function, such as one for hardware, one for electronics, and several others. I began by peeling of the protective paper from the acrylic panels.
Then I attached an aluminum plate to each motor housing and screwed it into the bottom acrylic piece.
Next was the line tracking module, which got attached upside-down with standoffs. The L298N motor driver module got stuck in the middle of the bottom plate and wired to each motor.
On the top portion, I joined the Li-ion battery housing to the back, as well as the frontal servo motor and my custom-designed and printed laser system.
Lastly, I put the whole thing together by using the included standoffs and screws, and also mounted the main PCB. The kit was a breeze to assemble, mostly due to its simplicity and the detailed instructions. I would recommend this kit for anyone who wants to get into robotics or is simply curious about the world of Arduino programming.
Going into this project, I knew the programming would be complex, but I had underestimated the level of complexity that a Mesh network communicating with a webpage brings. I started by breaking down the entire project into a logical flow chart:
Each car boots up with unique ID (UID)
User accesses webpage hosted on separate webserver and selects car
User can change name, LED color, and toggle laser/motors/servos
Argon runs webserver that handles requests from webpage
Argon sends commands to prospective robot
Robot handles commands and runs game when started
Robot handles hits and movements
Once hits > threshold, disable robot until winner
Breaking down a complex problem into simpler ideas and steps greatly helps in visualization and programming. It enables for there to be a greater level of focus and prevents you from getting overwhelmed at the task.
The mesh controller (Argon) runs a webserver and send commands to each robot. It also keeps track of the current game state, such as which cars are still enabled. For the webserver, I opted to use the Webduino webserver port for Particle. It is very simple to set up and run. A handler is defined at the start that gets called whenever the specified path is accessed, such as “192.168.0.2/test”. I settled on /cars as the main path.
If a POST request is sent there, the target UID, command, and value are parsed. Commands are sent as integers ranging from 1 to 8. The commands are as follows:
Name: Set new name to be displayed on OLED
Drive: Set motors to given value
Start: Start the match
End: End the match and reset the number of hits
Laser: Toggle laser on/off
Servo: Set servos to given values
Free: Start free mode
Color: Set and change RGB LED color
Once a command ID is parsed, it is then sent via the mesh network to the target robot. Each robot has a unique ID (UID), so calling Mesh.publish(UID, command_str) sends the necessary data.
The Argon also keeps track of the current game state. It stores which cars are still alive, their UIDs, and the total number still alive in a struct. Once a car goes out, it sends a mesh event called “OUT” with the data being its UID. That car’s state in the struct then gets changed to false, and the total number alive gets decremented by one. Once there is only one car remaining, and event called “GAME” get published with the winning car’s UID as the data. This causes the cars to display a message of congratulations to the winner.
Each robot runs the same code, with the only difference being the UID. In order to maintain clean code, I created a separate class called RoboCar, which handles everything from motor control to sensor reading.
It starts by initializing the pins, which are stored in a struct called pin definitions.
Next, the display and neopixel begin methods are called. Two timers are also initialized, one for the disabling the motors and the other for the hit cooldown. The name of the car is then printed onscreen, then the robot enters free mode, where it can move around freely but can’t participate in the game.
The RoboCar::run() method is called in each loop of the main program. It first calls Particle.process() to check and handle any new data from events.
Next, it checks if the car has been hit by reading the analog value from either the hall-effect sensor or magnet-activated switch. If a hit is detected, the number of hits is incremented. The motors are disabled, and the two timers are started. Once the motor disable timer expires, it re-enables the motors. After the cooldown timer expires, the car is able to register hits again. If the total number of hits goes over the maximum, the car is considered “out”, and it sends the event “OUT” to the Argon, which then registers the robot as having been disabled.
In the setup() function, a mesh event with a name of the car’s UID is subscribed to. It gets passed a handler that accepts the event name and any accompanying data. Then, it parses the command by converting the first two characters into an integer, which is then passed through a switch statement.
Based on the command, the remaining characters get parsed differently. For example, the command to change color (8), has characters 2 through 7 converted to an unsigned integer, which is then passed to the RGB LED.
I also created a config.h file that contains several adjustable parameters, such as cooldown durations and servo limits.
Instead of a physical controller or app, I went with a webpage. It contains all of the necessary elements to control the robot cars from a phone. On the top, there is a select element that allows the user to choose which car to send commands to.
Next to that, there is a color picker. Selecting a color with that and sending it to the robot sets the user color and changes the LED.
Underneath, a set of four buttons exist that handle mode switching and name changing. A name can be set by entering it into the textbox and then clicking “Change name”. The match can be started by clicking the second button from the left.
Below that, are two sets of buttons that emulate D-pads, along with a center button to toggle the laser.
On the left, the pan/tilt mechanism can be controlled by holding down a button to either increment or decrement the servo’s position. The servo’s x/y position is listed at the bottom of the page in degrees. The car is driven by holding down buttons on the right D-pad.
In order to prevent the Argon from becoming overloaded, I handled the button presses by creating and running an interval function that triggers every 250ms and gets cleared whenever the touchup or mouseup events are detected.
Playing the Game
To begin, I copied over the .html and .css files to my local Raspberry Pi webserver. Next, I accessed the page and selected which car I wanted to control. I then changed the name and color to something more suitable, in this case “ArduinoGuy” and a color of light blue. The RGB LED helps players to easily identify which vehicle is theirs while playing the game, since keeping track of an identical robot moving quickly can be difficult. On my command, each other player hit the “Start match” button, which enabled the robots to detect being hit. One-by-one, the cars went out, leaving a single winner, who was then promptly congratulated by the other cars.
Particle Mesh allows for some amazing stuff to be built. I enjoyed creating the robots and the game, as well as the webpage. It was interesting and at some points difficult to get an input from the webpage to be read by the mesh robots. I would like to thank Elegoo for sending their Smart Car Kits, as well as PCBGOGO.com for providing the PCBs, along with DFRobot, who sent me some of the necessary hardware.