Multimedia
Categories: Arduino, Radio, Technology
Arduino Wifly Mini
Posted on April 20, 2012, at 3:31 pm

I offer my sincerest thanks to all who so kindly took the time to write about this project on their blogs and websites. I’m honoured! I’ve added a section below, titled “Mentions” to list and say thanks to you by name. If I somehow missed you, please let me know!

Introduction

Since I was a kid I’ve been captivated by remote control vehicles. The R/C cars of Toys’R'Us can be fun, but what I’ve always been enthralled by are remotely operated vehicles (ROVs) such as the kind used to explore sunken ships. Or the type police forces use to disarm or explode a bomb. In my early teens I made my first attempt at an ROV by modifying a toy R/C car and mounting a small camera in its body. Technology has come a long way since then.

A few months ago a friend of mine reminded me of Arduino. I was in university when I first heard of it, but had been under the impression it was a special device musicians employed to make peculiar noises when sticks were bashed on dinner-plates. My friend told me Arduino was much more than that. He showed me Matt Richardson’s “Enough Already,” and that’s when I got an inkling of Arduino’s potential.

I picked up an Arduino UNO and began experimenting. At first I got a feel for the platform and attempted a modified version of Richardson’s “Arduino High Speed Photography Trigger.” Naturally, this tinkering evolved into a desire to build an ROV operated by a PS3 or XBOX 360 controller, or a Logitech G27 steering wheel, with communication done over WiFi, and with a First-Person-View (FPV), and Force Feedback.

The Arduino and FPV R/C communities are vast and full of extraordinarily talented people. So it was no surprise, once I had begun investigating the viability of my project, to discover that others had already done similar things. Someone already made a Logitech steering wheel control an R/C car, and a commenter on a blog relating to that project suggested adding force feedback. Another person got an XBOX 360 controller to direct an R/C vehicle; another did the same with a PS3 controller. There’s even a project called ‘Force Fly,’ where the pilot receives force feedback from an aircraft. And my at-present favourite R/C video, “Tonka Summit Too,” features a fantastic head-tracking FPV setup. But nothing I saw was exactly what I wanted: a ground based vehicle that could move at high speed, with very little response delay and could therefore be operated in real time over WiFi – and provide force feedback. And I wanted it to be expandable. And built by me. So I got to work.

Parts List

The following is a list of components used in the assembly and operation of the Arduino Wifly Mini:

  • Tamiya Mini M05, and using stock Motor and ESC
  • On-Road Tuned Spring Set, Blue on Rear Shocks, Green On Front. (To support the extra weight at the rear of the vehicle.)
  • One Dynamite 7.4v 4500 mAh NiMH Battery, for Tamiya’s ESC.
  • Arduino UNO
  • Wifly Shield
  • One plastic housing component salvaged from another R/C vehicle for mounting the UNO and Wifly
  • One 750mAh 7.4v Battery for Arduino and Wifly shield.
  • Two Standard-Size metal-gear servos, one for steering and the other for camera panning.
  • One 6v 1500mAh battery for servo power. (Lots of batteries. The stock ESC’s power output is too high for the servos, at 7 volts).
  • One 4.7k Ohm Potentiometer
  • One Triple Axis Accelerometer, ADXL335, for Force Feedback
  • Some ‘arts and crafts’ wood slats to aid in mounting the pot.
  • Several ball links and 4-40 rods for steering linkage and potentiometer apparatus, and other components.
  • Two pieces of plastic cut from the lid of a cheap container: these are used as debris shields to protect the camera’s lens.
  • One GoPro HERO 2 Video camera, for FPV. These cameras are excellent.
  • One 300 mW 1.3gHz video transmitter with appropriate cables and connectors, and stock antenna.
  • One 3s 11.1v 1100mAh LiPo for Video TX power.
  • One 1.3GHz Low-pass antenna filter, to reduce interference from the video transmitter. (In my case this was not optional.)
  • Several ferrite rings, to mitigate interference from electronic equipment. Without the low-pass filter and the ferrite rings, the Wifly can’t hear the base station when the video transmitter is powered-on. Don’t underestimate the effectiveness of the ferrite ring! They’re worth having.
  • One 1.3gHz video receiver
  • One 8dBi patch antenna for receiver.
  • A couple of 12volt deep cycle batteries, a Pure-Sine Wave inverter, and a regular monitor for FPV viewing when in the field. Bulky!
  • WRT54GL Router for base station. Excellent router when paired with DD-WRT Firmware, as I have.
  • 2.4 GHz Yagi (12dBi) and Patch antenna (14dBi) for base station, both from a local electronics store.
  • Tripod Stand for Mounting antennas.
  • Various connecting cables for base station (RP-SMA, TNC, N-Type, Cat-5, Etc).
  • Macbook, for base station.
  • Controllers (so far): Xbox360, PS3, G27 Steering Wheel, F510 rumblepad.

Choosing a Vehicle

My first choice of vehicle was a Jeep Rubicon ‘replica’ from Toys’R'Us. I bought it because it was inexpensive and seemed to be a good platform for the equipment I’d be mounting in it. Wouldn’t it be neat to turn a cheap R/C toy into something far more?

Toy Jeep Rubicon, Wifly Project’s First Vehicular Candidate

This idea turned out to be false economy. Modifications proved much more difficult than I anticipated. For example, I was not content on having a vehicle that could turn only left or right, with nothing in between. What good is a car without finite or gradual steering capability? (Other than guaranteed to flip at high speed…) Adding a servo-driven steering system to the existing body proved to be the breaking point for this vehicle’s inclusion in the project. And there were other problems: The motor mount in this vehicle is totally custom and can accept only one size of generic, low-quality motor. I ended up purchasing an ESC (Electronic Speed Control) to govern the forward and reverse directions, since building an H-bridge to do the same thing was a bit too granular, too close to the building blocks, for the type of project I wanted this to be. And the wheels are not easily replaceable, and same goes for most other critical components. And I don’t have much confidence the parts can be ordered separately, or for very long after the vehicle is discontinued, which probably it already is. If you decide on trying this project yourself, I recommend you get a remote control vehicle from a reputable manufacturer like Tamiya or Traxxas. You’ll save yourself a lot of time and money in the long run. Of course, you could build a custom vehicle if you wished. If so, remember it is a highly skilled business if attempting to make something robust and reliable.

I ended up buying a Tamiya Mini with an MO5 chassis. It wasn’t much more expensive than the Rubicon. It was a “build kit,” which means all the pieces had to be put together one screw at a time. That wasn’t a problem for me. The process was long but enjoyable and informative. If something goes wrong with the vehicle I have a much better chance of successfully diagnosing the problem, and obtaining the necessary parts to fix it.

Tamiya Mini with M05 Chassis (Front-Wheel Drive). Before Modifications.

From the get-go, this model was far more promising. It has graded steering thanks to the steering servo, and maintenance is possible if only sometimes a bit of a hassle. And it is much, much faster than the Rubicon.

Means of Communication

This section deals with the methods of communication employed in the Arduino Wifly Mini project.

General Communication

The electrical components of an R/C vehicle are typically controlled by a small onboard receiver. The receiver gets its instructions from the transmitter, usually held in the driver’s hands. Most receivers don’t send information back to the transmitter, and those that do don’t have the required capabilities: Since an Arduino will be controlling the vehicle’s components and measuring sensor inputs, I needed something that was not only compatible with the Arduino and could receive information wirelessly, but could also send specific information back. That’s where the Wifly comes in.

The Wifly Module, Freshly Soldered. Not bad for my first soldering job in years. And for having learned from a YouTube video!

The Wifly module allows the Arduino to send and receive information over a WiFi network. It sits on top of an UNO board that runs the vehicle’s software. The Arduino initiates a serial connection with the Wifly, and the two devices exchange information through this link. The Wifly module talks with the WiFi access point specified in its configuration.

In this project my controllers are connected to a computer running Processing, utilizing a library known as “ProControll” to read the controller inputs and initiate force feedback. The Arduino Wifly and Processing exchange information in UDP (User Datagram Protocol) packet form. It is not as reliable as TCP, but it is faster. It is not hard to see why a small response delay is desirable when manoeuvring at high-speed.

Video Transmission

The video feed from the Arduino Wifly Mini is sent via a 1.3GHz 300mW video transmitter. (The battery for this device can be seen on top of the vehicle.) A low-pass filter and ferrite rings were required to reduce interference with the Wifly module. The on-board camera is a GoPro Hero 2. It is an excellent camera and it has many more uses than just FPVing.

When driving at high speed, you need a low-latency video transmission method. The video transmitter I’m using provides this. Typically, the video feed from a webcam is not fast enough to make safe driving possible. However, the benefits of a WiFi-connected camera that is fast enough are plain to see; wherever you had a WiFi connection, you could see through the ‘eye’ of your vehicle. I have my sights set on a product that at the time of writing is yet to be released by GoPro: the WiFi BacPac. It was supposed to come out in March of this year but the release date has been repeatedly pushed back. They now say it will be released in ‘Summer 2012′. Well, when it does come out, I plan to acquire one, and if I do I will give it a test and let you know if it works well enough to use safely with this project. Even if it doesn’t send images in real-time (or close to it), I’m sure the WiFi BacPac could be used to provide a video feed for projects that didn’t involve vehicles moving at such high speed.

Force Feedback Sensors

If sending ‘force feedback’ from the vehicle, one must decide exactly what force will be sent. I decided to try a couple of possibilities. For reasons described below, and for memory issues, the current version of the software running on the Arduino Wifly Mini does not observe potentiometer values. Also, the G27 steering wheel and F510 rumblepad are currently the only controllers that rumble when instructed by Processing.

The Potentiometer

I mounted a potentiometer to the body of the vehicle and attached it to the steering linkage. At runtime, the value of the potentiometer at each stage of the steering servo’s movement, from hard left to hard right, is recorded. Knowing these values gives us a reference to compare values read later, when driving. A discrepancy in expected and actual values would indicate a force on the wheels in a certain direction. A small discrepancy would be a weak force; a large discrepancy would represent a strong force.

View of the steering potentiometer installed in the vehicle. Also in this picture: To the right, the Arduino and Wifly mounted between body posts. On either side of the steering linkage and potentiometer, above the motor and wheels, are ‘debris shields’ I devised to deflect flying matter away from the camera lens.

This approach, it turns out, is not reliable. In a controlled setting, with the vehicle sitting on my desk, I had good results when pushing on the wheels. But when driving, the feedback is inconsistent such that it serves to confuse rather than augment the driving experience. I suspect several issues are responsible for this. The Arduino compares stored pot values to present ones. How does it know which recorded value it needs to compare to the present one? It uses the current servo setting. The problem with this is the servo setting isn’t necessarily where the servo is. This is because it takes time to move the servo horn from one position to another. And under the varying conditions of driving, the time it takes isn’t always the same. My code estimates the movement delay, but as you can imagine, it is very difficult to produce an acceptably small margin of error. Also, the Mini has a fairly good suspension system, which dampens forces on the steering linkage. Anyway, I’m not driving the vehicle over many large bumps and nothing in the terrain should cause too much of a force in one direction or another. If I were using a rock crawler with this potentiometer system, and the steering servo was equipped to report its current position, and I was able to control the direction of force feedback in the steering wheel controller, this approach would probably work well when a tire got jammed on terrain. Otherwise, the potentiometer-as-force-feedback-sensor isn’t worthwhile. At least not in this configuration.

The Accelerometer

I mounted a triple-axis accelerometer at the front of the vehicle. I programmed the Arduino to observe this sensor and take the average reading of both the Y (forward & backward) and Z (up & down) axis, over a short period. Deviations in these averages represent a change in acceleration. Detected changes are sent back to Processing, where they’re converted into a force feedback representation in the controller.

Triple Axis Accelerometer

This approach offers much more reliable and predictable – and generally more usable – information. Testing on my desk and while driving produces results you’d expect: driving over bumpy terrain makes the controller shake, and so will hard acceleration and braking. The amplitude of these forces is mirrored in the strength of the controller’s rumble. As stated above, memory issues with the Arduino UNO keep me from implementing both the potentiometer and accelerometer sensors, and the latter is superior anyway, so I just run the accelerometer code.

The accelerometer is located in the front bumper of the vehicle. The sensor’s wires, leading to the Arduino, are visible between the shocks.

More Features Worth Mentioning

The beauty of Arduino is its… everything. It is a diverse platform. You can do so much with it. I’m only starting, and I want to squeeze as much out of it as I possibly can.

The ESC Switch

Using an opto-isolator chip connected to the Arduino, I can control remotely the power-state of the ESC. I did this primarily for safety reasons. If my code detects an error, such as multiple instructions received without a proper terminating character between each (a feature of an older version of the code, no longer posted), or the absence of a heartbeat character for a set period of time, the car performs a “take-no-chances” three-second full reverse (only if in forward throttle) and then cuts power to the ESC. This is to prevent a runaway, which of course could lead to an ‘obliterated vehicle’ situation. Or in the worst-case, somebody could get hurt. Both scenarios are highly undesirable.

Opto-Isolator Chip with Current Limiting Resistor, for remote ESC power-state control. It does what its name suggests. The voltage of the ESC is separated from the voltage of the Arduino’s PWM output by means of an optically sensitive switch and an LED, all inside this little unit.

The Camera-Panning Servo

The limitations of a static camera will become apparent very soon after you start driving an FPV vehicle. Enthusiasts have created an array of solutions for this, and I’ve noticed they’re often custom. This is because everybody’s situation usually differs somewhat in terms of hardware or goals or both. The Mini is so small that a tilting camera was not really an option, at least not with the equipment I have, and it wasn’t within the limited scope of this phase of the project. But a panning camera seemed like a must. I made some modifications to the body to accomodate a servo. It had to go on the roof. I suppose I could have finagled some kind of mount that attached to the chassis, but there is a lot more equipment to be added when implementing FPV than just a servo and a camera (transmitter, battery, connecting cables, ferrite rings, low-pass filter), and I wanted some degree of modularity. The only thing I lamented was the look of the car, but I got over that pretty quickly. I will focus on looks for the project’s next phases.

Panning servo mounted in the roof of the Wifly Mini. You can also see I’ve cut out the front windshield for better visibility.

A Note on Wifly Configuration

If you’re like me, you’ll sometimes be frustrated when confronted with obstacles that are to you totally opaque but, to experienced individuals, so transparent it isn’t worth mentioning. I ran into this when attempting to configure the Wifly module.

The Wifly is a wonderful device that is highly configurable. I recommend you download the manual and familiarize yourself with the various commands. Don’t skip this step, as time consuming as it might seem. You’ll save yourself some hassle and probably discover information you’ll find useful later on. Once you’ve done this and you have the Wifly module attached to the Arduino (which should be connected to your computer), make sure you have the Wifly library loaded and accessible to the Arduino development tool. If done properly, you should see an example sketch titled SpiUartTerminal. Load that onto the Arduino. In the serial monitor, if you reboot the Arduino board you’ll see a line that reads something like, ‘press $$$ to enter commands.’ In my initial experimentation, I could enter command mode but I could not issue commands. This is because, it turns out, the version of Arduino I’m using doesn’t send a carriage return even when you press the return key! The Wifly recognizes, in its default state at least, the carriage return as the end of a command and a request from the user to execute it. So in order to issue commands I needed to connect to the Arduino through the ‘Terminal’ program on my mac. To do this, your Arduino should be plugged in via USB to your Mac just like it would be when loading a program, except you’ll be using Terminal (or some equivalent in Windows) to open a serial connection instead of the Arduino IDE. You’ll have to enter the following into the Terminal prompt (your location, i.e. ‘usbmodem621′ as seen below, will probably differ slightly. It could be usbmodem2201 or usbmodem323, or something like that):

1
screen /dev/tty.usbmodem621 9600

When you hit enter, the Terminal should connect to the Arduino (make sure you have that SpiUartTerminal sketch loaded!) and you’ll be able to enter ‘$$$’ to start issuing commands. This project requires the Wifly be set to UDP or combo mode.

The Code

The code for this project is a wild beast. This is practically my first (but literally my second) Arduino project and before this I had never programmed in C. Gradually, I will add highlights from the code below. There are still many improvements to be made to this code.

I want to learn how to make C classes, and soon! ;)

Soon after I finished the first phase of the Arduino Wifly Mini project, I started learning about PPM signals. I have now realized that my method of sending data back and forth from the Arduino is flawed: instead of sending packets with each instruction, I should be putting a series of instructions (steering, throttle, camera, etc) into one packet, so the method more greatly resembles a PPM stream. I will be making this modification to the code and will update it here when finished. This update has now been made to the code.

Permissions

I’ve been asked if the code can be used, modified, and republished. The answer is yes! Feel free to use the code however you like. My only request is this: if you use the code verbatim or you found it helped you substantially, please just make a note of it somewhere in your published project. Thanks! And have fun. :)

Libraries

Between Processing and Arduino, there are a few (that’s not to say many) libraries in use. Check the import statements in the full code to see them all. Of note are the following. On the Processing side is Hypermedia NET (for UDP communication) and ProControll, a great little library that’ll read the inputs of a wide range of devices. Though I wish it would handle controller rumbling better: that way we could have the XBOX360 controller shaking. On the Arduino side, we need the standard WiFly library in order to use the SpiSerial object.

Arduino Code

I have placed the whole Arduino code within it’s own post to keep this page a reasonable length and make updates easier. Click here to see the Arduino sketch.

Sending Packets from the Arduino Wifly

One of the larger initial puzzles I faced was how to send packets from the Arduino/Wifly to the computer running Processing. I was able to do it the other way around fairly easily. I could find nothing that explained how to send packets from the Wifly. I found a thread on SparkFun that explained how to put the Wifly into UDP mode, and a few people commented they were able to send UDP packets from the Wifly, but didn’t say exactly how. I decided to scour the Wifly’s manual. And whatd’ya know? The answers were there.

Like the SparkFun forum thread indicated, the Wifly has to be put into UDP packet mode using the SPI-UART Terminal Sketch, or similar method. (This only has to happen once.) I figured out that you then have to write information to the SPI register/buffer on the Wifly. When you’re ready to send the packet, the buffer needs to be ‘flushed.’ Here is a simplified version of the code I use to do this:

1
2
3
4
5
6
7
8
9
10
11
12
void ptb(char c)
{
  //prints to SpiSerial (fills up the buffer).
  SpiSerial.print(c, BYTE);
}
void fb()
{
  //FLUSH BUFFER (sends buffer contents to host).
  //a carriage return character (hex 0xd) flushes the WIFLYs buffer and sends the msg
  //where FBC is defined as: char FBC = 0xd;  //carriage return.
  SpiSerial.print(FBC, BYTE);
}

The Wifly then forms a proper UDP packet with the payload set as whatever you printed to the SPISerial before issuing the Flush command. Voila! Remember, you have to begin the serial connection in order to use the SpiSerial object, just like you’d have to begin a regular Serial connection between the Arduino and your computer. It looks like this, and is placed in your setup function:

1
SpiSerial.begin();

If you want, you can set the Wifly to ‘flush’ the buffer once it fills with a certain amount of data. Or you can disable that feature and flush the buffer when the Wifly sees a specified character. (The flush command should work even if you have a buffer limit set). I believe the default character is a carriage return.

Processing Code

Same as Arduino code. Click here to see the whole Processing sketch.

UDP Packet Listening

To listen for packets in Processing on a specific port, you need the following code in your setup function:

1
2
udp = new UDP( this, listenPort );  //port 6000
udp.listen( true );

Then, somewhere in your code you’ll need a read function. This is what mine looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void receive( byte[] data ) {
  //void receive( byte[] data, String ip, int port ) {   // <-- extended handler
  char[] mrTdata = new char[data.length]; //FOR CONVERTING BYTE TO CHAR. here is stored information coming from the arduino.
  String incomingDataString = ""; //makes a whole string out of data presently being received...
  String firstChar = "";
  String currentChar = "";
 
 
  for (int i=0; i < data.length; i++) {
    mrTdata[i] = char(data[i]);   //BYTE TO CHAR.
    incomingDataString = incomingDataString + mrTdata[i];  //added to whole string used for reference.
    firstChar = "" + mrTdata[0];   //store the first char for reference... "" appears to be necessary to force conversion from CHAR to STRING
    currentChar = "" + mrTdata[i];
 
    if(!currentChar.equals("1") && !currentChar.equals("2") && !currentChar.equals("3") && !currentChar.equals("4") && !currentChar.equals("5") && !currentChar.equals("6") && !currentChar.equals("7") && !currentChar.equals("8") && !currentChar.equals("9") && !currentChar.equals("0") && !currentChar.equals(".")) { 
      //the character is not a number, not a value to go along with a command,
      //so it is probably a command.
      if(instructionDataString != "") {
        aCommandVal = Integer.parseInt(instructionDataString);
      }
      if(aCommand != "") {
        delegate();
      }
      aCommand = currentChar;
      instructionDataString = "";
    } else {
      //in this case, we're probably receiving a command value.
      //store it
      instructionDataString = instructionDataString + currentChar;
    }
 
  }
}

When data is received, the above function looks at it one character at a time. The function determines if the character is a command or data. Anything that’s a number or a decimal is stored in string format as a ‘command value.’ Anything else is stored as a command. When another character that isn’t a number or decimal is received the function throws the stored command and (if applicable) accompanying value at the delegate function.

Controller-Map Example

Here is an example of a controller map, for the PS3 controller in this instance. My processing code utilizes the information set within this function in conjunction with the ProControll library. The code then makes use of the various inputs from the controller through a large series of functions. To understand the basics of using a controller with ProControll I recommend reading through the examples offered by the library’s authors. If you’d like to see how my code makes use of the various controllers, I recommend viewing the entire Processing sketch and following the trail from the main draw() function. You’ll see the readControlDevice() function calls a set of more functions (sliderHandling(), buttonHandling(), etc) that watch – you guessed it – each slider and button on the controller, and those functions call more functions (shClutch(), shCamera(), shThrottle, etc) depending on what the controller readings are.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
void mapPS3mac()
{
  controlDevice = controll.getDevice("PLAYSTATION(R)3 Controller");
  printDeviceItems();   //prints a list of available controls.
  controlDevice.setTolerance(0.05f);  //was 0.5f.
  wheelMovementMin = 0.001;  //wheel has to be moved this much in order to calculate new value.
  wheelStickDeadZone = 0.01;    //stick neutral deadzone. If stick reading is within + or - this value, it's as good as in the centre.
  wheelHardValue = 0.93;  //if the stick is moved to the right or left this amplitude then we consider it moved left or right 100%
  wheelPOW = 1.0;  //I haven't developed this fully, tinker with caution. It is intended to add progressive steering.
  throttleStickDeadzone = 0.05; //throttle neutral deadzone.
  pedalDeadZone = 0.004;  //if the pedal reading is under this value then we consider it not-activated.
  pedalMovementMin = 0.004;  //minimim distance pedal must be moved to calculate a new value
  pedalHardValue = 0.95;    //if pedal is depressed more than this amount then we consider it fully activated...
  cameraMoveInterval = 6; //milliseconds between camera steps.
  cameraMovementMin = 0.01; //if camera movement is controlled by a stick, the stick has to be moved this much to calculate a new value.
  cameraStickDeadZone = 0.07;
  cameraHardValue = 0.90;
  cameraMaxStep = 7;
  cameraMinStep = 4; 
  hasCoolieHat = true;    //the controller has a cooliehat.
  coolieIsCoolie = false;  //the cooliehat is broken into buttons.
  clutchForGears = true;  //does the clutch need to be depressed to change gears?
  hasSlidingClutch = false;
  hasForRevGear = false;  //false. used to determine if we should pay attention to "direction".
  oneSliderForThrottle = true; //one stick, on the left, signifies both directions...
  hasReversePedal = false; //this controller does not have a dedicated reverse pedal.
  wheelIsStick = true;    //steering is controlled by a stick. (as opposed to a wheel, like the G27)
  throttleIsStick = true; //make sure you use stick deadzones.
  hasCameraStick = false;   //is camera control a stick on this controller?
  hasCameraButtons = true;
  hasCameraCentreButton = true;
  hasRumblers = 2;  //controller has rumblers, though I can't get them to work yet for the PS3 or Xbox360 controller.
  maxRumbleIntensity = 1.0;  //max rumble intensity...
  throttleBase = 2;  //0 = -1 to 1, rests at 0. 1 = -1 to 1, rests at -1. 2= SPLIT across two padels, rests at 0, range: 1 to -1.
  reverseBase = 0;
  clutchBase = 0;
  //sliders
  sliderWheel = controlDevice.getSlider(2);
  sliderThrottle = controlDevice.getSlider(1);
  //sliderCameraX = controlDevice.getSlider(1);
  //buttons
  buttonStart = controlDevice.getButton(3);      //START BUTTON
  buttonESC = controlDevice.getButton(0);     //SELECT BUTTON
  buttonSendSettings = controlDevice.getButton(3);      //START BUTTON, clutch must be in.
  buttonResetOnFlatline = controlDevice.getButton(0);      //SELECT BUTTON (clutch must be in for this one to work).
 
  buttonGEARDOWN = controlDevice.getButton(10);       //LTB
  buttonGEARUP = controlDevice.getButton(11);        //RTB
  buttonCLUTCH = controlDevice.getButton(2);    //RJD
 
  buttonCentreCamera = controlDevice.getButton(1);    //LJD (depress to adjust camera trim).
  buttonAutoCamera = controlDevice.getButton(14);    //X. autoCamera ON/OFF
  buttonCameraMoveLeft = controlDevice.getButton(8);       //LEFT PADDLE
  buttonCameraMoveRight = controlDevice.getButton(9);        //RIGHT PADDLE
 
  buttonCalibrateSensors = controlDevice.getButton(12);        //TRIANGLE  (clutch must be in. calibrates sensors. Vehicle should be stopped!!)
  buttonSendFFaccels = controlDevice.getButton(12);        //TRIANGLE (when clutch is NOT in).
 
  //cooliehat
  //broken into buttons for this controller.
  //(left arrow pad)
  coolieUP = controlDevice.getButton(4);    //cooliehat UP
  coolieDOWN = controlDevice.getButton(6);    //cooliehat DOWN
  coolieLEFT = controlDevice.getButton(7);    //cooliehat LEFT
  coolieRIGHT = controlDevice.getButton(5);    //cooliehat RIGHT 
}

Notes and Ideas

Overall Performance

The performance of the Wifly Mini has exceeded my expectations. Steering, throttle, camera servo and force feedback are all fast and responsive under ideal conditions. (In my house.)

Bulk

The system is extremely bulky. (I’m talking about all the components needed to run the vehicle). I put this down mostly to the project being in its very early stages. At present I’m spending nearly an hour to set up in the field, which in the long run will be a total buzz-kill. It would be nice to be able to eliminate the computer and have an Arduino with, say, a USB host shield handle the the controller of choice. I believe this will be possible but isn’t planned for the near future. I have found an incredible project that would help me cut out the laptop. It’s called USB2PPM. If I can find more information about it, I will implement it into a new version of the Arduino Mini. This would be a major change to the project, since it would cut out the Wifly, but might be necessary if I want long-range communication (which I do). I will probably end up building my own version of USB2PPM and sharing the details on my site.

Range

I range test the Mini. Can you spot me?

I’ve been able to take the car out a few times to a track and a large parking lot for range testing. When the model is close (under 75 metres away), it performs very well. But anything beyond that and things start to get very glitchy. This is despite having a signal amplifier on my router and directional antennas. One of the major components of the next phase of this project is to improve range: I intend to build an antenna tracker and fiddle with the DD-WRT firmware on my WRT54GL router. I’ll try turning off ACK timing and playing with other relevant settings.

A Closer Look: There I am!

When the car was on the ground, I could only achieve about 100 metres distance from the base station. But when picked up, the range improved dramatically. I suspect this has something to do with the ground somehow attenuating the signal. I’m not sure at the time of writing. I am going to try to get the Arduino Wifly Mini’s antenna further off the ground.

Signal Strength at Several-Hundred Meters Distance

Changing Frequencies

With all the research I’ve done on 2.4GHz (the frequency in which most WiFi operates), I’ve learned that it is highly vulnerable to signal attenuation, particularly as a result of uneven and obstructive terrain. So after a bit of research I suspect 433MHz might be the way to go for long range control. Specifically I have my eyes on EzUHF and OpenLRS: both seem promising. The longer wavelength will mean less bandwidth, but telemetry and force feedback (at least in the form I’ve concocted) aren’t very bandwidth-heavy. So this would constitute an Arduino Ham Mini. Babe could be the mascot!

Jessica stands over the Wifly Mini during range testing. 2.4 GHz directional antennas are aimed at the car. In this shot, the connection had been already lost. The Wifly has a hard time hearing signals from the base station when its antennas are close to the ground.

Platform Size

In the next phases of the project I will be moving to something larger. The Mini M05 is simply too small for what I want to do. (The cement lip of a driveway is an impassable obstacle.) It is fun to drive around the house on a single level, but the scenery quickly becomes repetetive. And outside, the Mini is confined to clean parking lots or tracks, both of which often have many people and cars to accidentally drive a prototype into… or under. Besides, I want to add a lot more sensors to the vehicle, such as a GPS module. I’d also like to add in a true brake to make the pedal on the G27 wheel behave more as one would expect. And with more than one transmission frequency in the mix, the proximity of radio devices onboard makes it hard to keep interference down. Suddenly I’ve had an idea…

Monster Mini! Raaaaaa!!

Communication Through Cellular Broadband

I was able to associate the Wifly with my iPhone hotspot, and with some adjustments to my home firewall I was able to exchange some packets, but none of this worked in the way we might wish. I was not able to send packets to my cell phone and then to the Wifly module. Rather, when my computer – the one running processing – was associated with the cell phone’s hotspot, I was able to send packets to my home network and control the Wifly there. This state of affairs is the wrong way around, as you doubtless see if you consider I’m after long range control from a base station. Another thing: there was far too much latency to make safe driving a reality even if the cell phone could receive and route packets from external sources. However, my cell phone has only 3G connectivity, and it is a member of the walled-garden iPhone variety after all. So I have high hopes for LTE and Android phones, where one might be able to devise a custom and open source program to exchange UDP packets at high speed. Imagine an R/C car operated remotely through an LTE network in real time with a video uplink. Theoretically you could drive across Canada, given adequate cell coverage and a lot of helpful hobbyists…

Mentions

Thank you to everyone who so kindly took the time to write about this project or link to it, and thanks for all the kind things you’ve said about it. Here is a list of those I’ve known to have written about my project, or mentioned it. If you’re missing from this list, please let me know. The fastest way would be to post a comment below or through Twitter. Also, thanks to all of you on YouTube for your generous comments. It means a lot to me.

Matt Richardson of MAKEzine
Mike Szczys of Hack-a-Day
Luke Plunkett of Kotaku
Mike of Mini Cooper Orange County
Lambert Varias of Technabob
Andrew Angus on Scoop.it
David Deloney of Walyou
Sven Wernicke of neuerdings.com. (In German.)
Julian Horsey of Geeky Gadgets
Alan Parekh of Hacked Gadgets

‘Organic’ is a word that might apply to the internet. Things change frequently. I’ve taken screencaps over the months of coverage of the Arduino Wifly Mini. They are provided in gallery form below.

Update History

August 15, 2012: Added “Mentions” section.
April 30, 2012: Added Controller-Map Example to Processing Code section.
April 29, 2012: Added ‘Video Transmission’ section to writeup under Means of Communication. Just to be clear on how the VTX is presently being done.
April 28, 2012: Updated Processing and Arduino code. Removed complicated braking functions. Simplified packet communications (both directions); payloads now more resemble PPM-style configuration, instead of the one-command-per-packet method I was using. Also simplified accelerometer/force-feedback functions.
April 22, 2012: Added ‘Permissions’ to code section.
April 21, 2012: Added parts list.

  • http://blairkelly.ca/ Blair Kelly

    Hello Jose! Thanks for saying so. The Wifly can receive UDP packets and I go into a bit of detail on this post about how to do that. As for commands – that is, telling the Wifly to do something using some kind of pre-existing command framework found on other platforms (like servers), I’m not sure. I’ve not tried it or looked into it. It might be able to! What is it exactly you wanted to do? :)

  • guest

    Does this software work on Microsoft Windows NT?  I would really like to use Microsoft Windows NT for my project.

  • http://blairkelly.ca/ Blair Kelly

    Hi there. Which software? Processing or Arduino IDE? I’m not sure if they’re supported! They might be. I would try downloading, installing, running, and then testing the programs to see if it’d work.

  • Vannieuwkoop

    Blair, hey Max, Enya and I watched your video. Wow, how incredibly cool is that! Man, just super. You are a wizard!

    We are all exited about your achievements and are thrilled to meet you and see you again next weekend.

    Best
    Aldert, Enya and Max

  • http://blairkelly.ca/ Blair Kelly

    Hey Aldert, Max, and Enya: I’m very glad you liked it, and thanks for watching. It was a pleasure meeting all of you and I look forward to seeing you again next weekend. Hopefully I’ll have enough time to ready & bring some stuff to show off then. 

    All the best,Blair.

  • Ronald Patino

    Hi Blaire, thanks a lot for sharing this info, I’ve got one question, does the wifly module operates using  3.3 v or 5v from the arduino power source?

  • http://blairkelly.ca/ Blair Kelly

    It’s my pleasure, Ronald! From the Wifly product page: “Power is taken from the Vin pin of your Arduino, regulated to 3.3V ”  :)

  • Nord

    Bravo, man. I working almost on the same project. 

  • http://www.facebook.com/ouday.khaled.9 Ouday Khaled

    hi, i am computer engineering student, and i need a quick help…
    Can you please tell me how to receive a simple UDP packet in arduino?
    For example i send a UDP packet containing “1″ as a string and i will received it on arduino. Please send me the code as faster as you can…
    The code of this project is very complicated, so i can’t learn from it …

    email
    ouday.khaled@gmail:disqus .com
     Thank you very much :)

  • http://blairkelly.ca/ Blair Kelly

    Hey thanks! What’s your project like?

  • http://blairkelly.ca/ Blair Kelly

    Hi Ouday, above I have a section titled “Sending Packets from the Arduino Wifly”. It goes through the major points of setting up the Wifly for UDP communication (necessary before packets can be exchanged). I suggest you attempt to do that with Processing. Once you do, try to send a packet the other way. I took this bit of code from the whole Arduino sketch (linked-to above):

    char c;
    char w[8];
    while(SpiSerial.available() > 0) {
    c = SpiSerial.read();
    if((i>=iStart) && (i<=iEnd)) {
    w[ii] = c;
    ii++;
    }
    i++;
    }

    That's how I got commands into the Arduino. You'll notice it's sort-of the reverse of "SpiSerial.print" which I use to prepare UDP packets to be sent from the Arduino Wifly.

    I might write a detailed tutorial about the very basics of UDP communication between Processing and the Arduino Wifly. But that will take me a few days.

    Best of luck!

  • Henry

    Hi Dude.

    Super awesome project. It literally made me want to start coding with the procontroll library. I am having a problem though and I thought you could help me. I am using the procontroll_printDevices example found in the procontroll library to see the devices that get recognized by processing. I have a joystick that is connected but does not get recognized (no number for the joystick). I was wondering if you had that problem and how you solved it.

    Thanks.

  • http://blairkelly.ca/ Blair Kelly

    Hi Henry! Thanks for the compliment. I am sorry to say I didn’t come up against that problem myself. What kind of joystick are you using? Is it a USB joystick or does it use a gameport?

  • Henry

     Hi man,

    Answering your question. The joystick is the avb top shot pegasus force feedback joystick. The joystick has actually the USB and an rs232 connection. When I plug the it gets recognized by windows OS. When I run the example in the library it does not recognize any other device other than the mouse and keyboard.

    Anyways, since you used the PS3 controller can you explain the initial setup and by that I mean what programs did you use to install the ps3 driver for pc.

    Thanks for the help.

  • http://blairkelly.ca/ Blair Kelly

    Hey Henry, no problem, I just wish I could help you more. I’m at a loss as to what to do with the Pegasus FFB joystick. All of my devices were recognized by ProControll in Processing without trouble; the only snags came in the form of limited functionality. I just googled the Pegasus. I see it has a separate lead, or an extended lead/adapter in USB form. I have a feeling that device is geared more toward serial communication. A really neat thing you could try is making your own Arduino controller for the device, then you’d have complete control over everything the joystick could do. The problem, of course, is finding a way to enumerate what commands you have to send the joystick for proper FFB, and what the info looks like coming from the device. But if you did manage to do that, you’d have a pretty versatile DIY controller…

    As for the PS3 controllers, unfortunately I only ever got it to work through the Mac, and not entirely well either (no FFB and if I recall correctly the paddles didn’t work properly). I had much more success with the XBOX 360 controller in this regard; it works well on both PC and Mac. This is the location of the very primitive driver I used for the PS3 controller on the Mac: http://tattiebogle.net/index.php/ProjectRoot/Ps3Controller

  • Speedracer98

    Is there one for the auto wiring diagram and a file with all programs for pc and Arduino

  • Speedracer98

    Is there a car for a wiring diagram and a file containing all programs for PC and Arduino

  • Alex Merrill

    Hi blair, i am really serious about making this and the one thing that keeps me wondering if you don’t mind me asking is in the end what was the total price

    thanks

  • http://blairkelly.ca/ Blair Kelly

    It was under a thousand dollars. However, one of the more expensive components in use is the GoPro Hero 2: you could probably cut down on cost by using different components.

  • :)

    how did u connect the ps3 controller to it ?

  • marshmallow

    Hi there. I am just wondering does the video transmitter you use in this project send video through the wifly module or is the video sent from the transmitter straight to some sort of receiver? 

  • http://blairkelly.ca/ Blair Kelly

    With a processing sketch running on my pc. Though now there are better methods to do this, for example, using a USB Shield.

  • http://blairkelly.ca/ Blair Kelly

    Yes, video transmitter separate from the WiFi. I go into a bit of detail on that here: http://www.blairkelly.ca/2012/04/20/arduino-wifly-mini/#awm-vtx

  • http://www.facebook.com/duncan.woodward Duncan Woodward

    Hey there, I came across your project while doing research for one I’m considering embarking upon. If I can say one thing, you’ve made it very clear just how much work is involved in this sort of thing. 
    The good news is that what seems to be one of your biggest complaints, the range, is a non issue for me, as I really only want to build something for cruising around the house. 
    I do, however, have a couple questions for you.
    As cool as it is, how integral is force feedback to the system. Were I to use your code and setup, minus the accelerameter and it’s various wiring, would it still function?
    The main reason I’m not interested in FF is because I don’t plan on using a computer to control the vehicle. I’m hoping to try and write an app for android and control the device through this: http://www.archos.com/products/gamepad/index.html?country=us&lang=en&slider
    It doesn’t have a vibrator or anything, so FF is basically useless. What’s cool is that it has physical controls (and the analog sticks are truly analog, no binary controls there!) and it has a relatively large screen for viewing the POV cam. 
    Anyways, let me know what you think. I’ll keep window-shopping the net for the various parts I might need, but I look forward to hearing from someone who understands my need to tinker with things like this.
    Good luck on future projects!

  • http://blairkelly.ca/ Blair Kelly

    Hi Duncan! You can say anything you like. It was a lot of work, but worth it. The force feedback is not integral to the system. While it does enhance the experience considerably, the vehicle can be driven without it. If you were to use my exact setup minus the accelerometer, it would still function. If in this case you did not disable the force feedback feature and accidently flipped it out of its default off-state while driving, the wifly might (probably would) start sending erratic messages rapidly to processing, which would spit errors at you because it can’t deliver rumble commands to the controller you’re using. It might crash or just stop working. That GamePad looks pretty sharp. I have no doubt in my mind you could write an app to drive an RC car with it. I have a question for you: how do you plan to get the video signal to the screen on your gamepad? I got asked a lot about the video TX system in the Wifly Mini. I wanted to try to send video directly from the GoPro, through WiFi, to my PC screen. Unfortunately the GoPro WiFi bacpac didn’t become available during the course of this project and I relied on a separate analog video transmission system (it’s all documented above, you might have seen it already). Not ideal, but it worked. The WiFi BacPac has since come out and it allows for live streaming. My initial tests have been predictably disappointing: very laggy and choppy. Mind you, I’m transmitting directly from the GoPro to my iPad 1, which might account for some of the delay. Anyway, I know you have your work cut out for you, and I hope you decide to blog a bit about your project. I’d love to see it. And best of luck with it!

  • http://www.facebook.com/duncan.woodward Duncan Woodward

    I actually hadn’t thought about that, I’ve done a bit of programming in the past and have taken a few engineering classes, and those had a bit about electrical engineering, so I’m hoping to combine that with help/stealing ideas from wonderful people like you. I’ve understood from the beginning though that video is the hardest part, hell, they have devices that plug into the sound jack and transmit IR signals to the little SYMA helicopters, I’m sure you could rig up something similar with the standard radio frequencies used by most R/C vehicles and simply right an app to transmit. But that’s only one way, so no video. Perhaps a combination of that and something else for streaming? I’m not sure yet, but I’ll keep poking around, and if something ever comes of this, I’ll be sure to share it with you!

  • Gordont

     Hi Dustin ,
    Did you have have any success with the xbee modules ?and what range did you get from them?Thanks

  • Gordon Tricker

    Hi Blair ,
    Excellent project and details well described .
    However I would like to contact you so as to ask some technical details which I am sure you will be able to assist .Please let me know how to contact you .Thanks

  • http://blairkelly.ca/ Blair Kelly

    Hi Gordon! Thanks for the kind words! This is a good place to talk to me about technical details of the Arduino Wifly Mini, because then anybody visiting, should they have the same technical questions as you, will be able to learn from our correspondence. What can I help you with?

  • Gordon Tricker

     Hi Blair ,
    Thanks for the reply it is greatly appreciated.
    The questions I have  are
     1) How did you set up the wifly with the router and then how did you get it to link from the control point .I as looking at the xbee boards but they are line of sight.I think the wifly is the answer.
    2) do you perhaps have any rough sketches /diagrams of the complete configuration?
    3) I have a Dlink 3G Broadband router which I want to link to the wifly,How will I have to set this configuration ( protocol ) for communication?
    4) How are you transmitting the video signals from the vehicle to the control point .Are you using the same router  but different channel ?
    Your advice or suggestions would be most welcome
    Best Regards
    Gordon

  • Abishai Singh

    Hey Blair Kelly, very nice work. I really appreciate your work which seems really skillful.  I am planning to control my arduino board from any android phone or tablet. In beginning I want to control the blink of an led through android phone or tablet. I googled and found your blog. Can you please tell me where should I start? and which wi-fi shield should I use.

    Thank you

  • http://blairkelly.ca/ Blair Kelly

    Thanks Abishai! There are a number of ways, as far as I’ve heard, to make your Android phone capable of controlling an LED. I haven’t done it myself. If you want to control your Arduino project using a Wifly shield, I’m very confident that could be done. You could write a native application for the Android device that sends packets over WiFi to the Wifly shield. Or you could have some sort of server running on the Wifly (cool example here: http://www.sparkfun.com/tutorials/158 ) Using that method, you could have any device with a web browser on your network control the LED. :)

  • http://blairkelly.ca/ Blair Kelly

    Hey Gordon! To set up the Wifly with the router, you need the Wifly shield mounted on an Arduino, then you need to connect to the Arduino with a terminal window and issue all the proper commands. The commands will be in the manual (I really recommend reading it or skimming it carefully if you get a Wifly shield, it’ll help a lot). There are some more notes on that above. I never kept any diagrams of the complete wiring configuration. This is something I could put together and probably should. It was my first real Arduino project and I didn’t think that people would be interested in the wiring diagrams. (I was wrong!) Maybe I’ll put one together sometime. If your DLINK 3G Broadband Router can be used like any other regular household router, then connecting the Wifly to it should be fairly straightforward. As for video transmission, check this out:

    http://www.blairkelly.ca/2012/04/20/arduino-wifly-mini/#awm-vtx

  • Romarshmallow

    Hi there, i am doing a similar project and i was having difficulty identifying the ports. How did you go about finding these, for instance is the sending port in the arduino code from the ip address after you type “get ip” and how do you obtain the listening port?

  • Giant Rainbow

    I am using the wifly to receive udp packets in my project. I am wondering, how is your arduino code receiving the udp packets. From what i can understand, your listenForCommands function checks if there is data available in the wifly and if so, to read and interpret it. So does this mean that the udp data should automatically exist within the wifly after sending it from processing? E.g you dont use a specific command for reading udp like udp.receive?

  • Derek

    The UPD.zip library is no longer available from Processing.  The link does not work and no one seems to have it to download without registering for some spam email, at least.  Is there any way you could post it to be downloaded from here?  I am trying to do a similar project with my high school students and need to get it up an running.

  • http://blairkelly.ca/ Blair Kelly

    Hi there! The packets sit in a buffer in the Wifly, and the Arduino reads them. So you’re right, the Wifly handles listening for UDP packets. You’ve just got to tell the Arduino to check the Wifly for available data, with SpiSerial.available() 

  • http://blairkelly.ca/ Blair Kelly

    Hi Giant Rainbow, sorry I didn’t respond sooner to this message! You actually set the ports that you want to use. You configure the Wifly itself. And in processing it’s a little more straightforward to specify which ports you want for listening/sending.

  • http://blairkelly.ca/ Blair Kelly

    Hey there! I was actually able to download the library from here:

    http://ubaa.net/shared/processing/udp/  
    (that’s the site). The actual zip location is:
    http://ubaa.net/shared/processing/udp/udp.zip

    Let me know if you still have problems, and good luck with your project! I bet your students will love it!

  • Derek

    Thank you.  Knowing that it just worked for you made me think outside the box.  I wasn’t getting the usual web error, but it still turned out that my school server was blocking the site.  I was able to download it on my phone and email it to myself.  Project back on track!!  Thanks again.

  • Derek

    How did you define the settings for the Wifly Communication?  Did you have to run an Arduino code to first program the Wifly to define its IP, DNS, etc. and then create the main code?  I saw some of the settings in the Arduino code, but nothing that defined everything that the normal Wifly settup requires.  This part is confusing me a bit.  Thanks.

  • Derek

    I see from other posts that you already answered this question.  Should have looked before asking.  Feel free to delete this thread. Thanks again and cool project.

  • http://blairkelly.ca/ Blair Kelly

    Hey Derek, sorry I didn’t reply sooner. Work’s been very busy! The code is really bloated so I’m not surprised you found it difficult to pick through. I hope you got everything sorted out!

  • jonathan caughron

    I am looking to complete a less complicated version of this project for my senior design. I was wondering if it is possible without a rc car. I have a rover that uses a wifi shield and arduino mega chip to communicate wirelessly. I am wanting to implement a ps3 or xbox controller to control the robot. I am curious as to how you got the controllers to communicate and relay to the mini? Any help would be appreciated. I am using windows 7.

  • أبو شهاب الإماراتي

    Super Amazing,

    I would like to know if there’s a chance to buy an assembled piece from you, or if you have that offered somewhere where I can buy from ?

    pls. email me if you would do that. thanks

More Updates...
  • Klick Holiday Video I’ve only been with Klick for a short time but it’s been a great place to work. We put together this video for the holiday season. It’s the best yet!
  • Martin Amis on the nervous breakdown of the GOP
  • “Communicating with James was difficult.” New York Times profile of a deeply troubled man.
  • Bill Nye on Creationism: It’s not appropriate for children!
  • How to Suck at Your Religion A cartoon by The Oatmeal
  • Texas claims abandoned Walmart and turns it into an award-winning library.
  • Beer Cocktails. Learn a bit of history about the Shandygaff!
  • In Mumbai, a man points out people are drinking sewage water. He now faces charges and arrest.
  • See more...
    © 2013 Blair Kelly