Last time, I talked about how my storage situation and my cheap nature led me to build an RC joystick controller with a cell phone app and an ESP8266. The key to making this easy was to use the GUI builder called Blynk to make a user interface for an Android or Apple phone. Blynk can communicate with the ESP8266 and makes the project relatively simple.
ESP8266 and Arduino IDE
The ESP8266 Blynk code is straightforward. You do need to set up the Arduino IDE to build for the ESP8266. That can vary by board, but here’s the instructions for the board I was using (from Adafruit; see below).
Depending on the type of ESP8266 device you are using, you may need a 3.3 V serial cable or some other means of getting the firmware into the device. For the Adafruit device I had, it has a 5 V-tolerant serial connection so a standard USB to serial dongle plugs right in. There’s also two switches on my device. To get into bootload mode, you have to push the one button down, hold it, and then press the reset button. Once you release the reset button you can release the other button. The red LED half-glows and the device is then waiting for a download.
Otherwise, things are just like usual with the Arduino IDE. You do have to be aware of what objects are available on the ESP8266 as opposed to a regular Arduino. There are some subtle differences, too. For example, the EEPROM object has some extra methods because the ESP8266 emulates an EEPROM (more on that later).
Virtual Pins and Processing
If you are getting started, you can just make a simple user interface with a push button and wire it to an LED on the board. That’s the Blynk “hello world” program. But for the joystick there are a few other considerations.
Instead of wiring a widget to a physical pin, you can use a virtual pin. Your program can then read and write these virtual pins easily. A “pin” in this context could be a bit, a number, or even a string.
To handle a virtual pin write (for example, a button push or a slider changing value), you write a function using the BLYNK_WRITE macro. For example:
// Flip S1
if (!param.asInt()) return;
The framework will call this code when the associated virtual pin (V5) changes. One word of caution: a button press gets two calls; one for the press and one for the release. You need to test the value if you want to only act on one or the other. That’s why the first line tests for the parameter value of zero and returns, thus ignoring the button release.
In addition to asInt() you can convert the parameter to other types, including float (asFLoat), double (asDouble), and string (asStr).
The BLYNK_READ macro lets you provide code that will run with the framework wants to read a virtual pin (that is, send data from the embedded system back to the phone). You can also call Blynk.virtualWrite to immediately update the value of a virtual pin.
You can find the code on GitHub. It is quite straightforward: Two Servo objects control the pulse output. Their duration is set by virtual pins from Blynk. Because the joystick is set to output the microsecond count directly, there’s not much to that.
To make things more interesting, I arranged for buttons that could flip the X and Y axis and also reflect either axis (that is, invert the axis so instead of reading 1000-2000, it reads 2000-1000). Each of those is just a button push that calls a BLYNK_WRITE function. There’s a line of code that makes the buttons only operate on one of the two events you get from a button push and release.
Of course, once you can configure the joystick (including a recenter option), it is a pain to lose the configuration on each restart. So I decided to allow writing the configuration to EEPROM. That was the start of a lot of trouble.
The ESP8266 doesn’t have a true EEPROM. But the Arduino software emulates it with flash. When you want to use the EEPROM you have to inform the library how much memory you will use. It reads that memory from flash into a buffer. From that point on, all your EEPROM changes occur in the buffer. When you are done, you call end or commit and the library determines if you made changes. If you did, an entire flash page is erased and rewritten. If you call commit, you can make more changes (which then need to be written). If you call end, you are done.
By itself, that wouldn’t be a problem. However, watching the output on a scope, I noticed that when I would change configuration, sometimes–and only sometimes–the servo outputs would stall. The ESP8266 was still operating because the buttons that light LEDs would still work. I finally realized that any button that called for a EEPROM commit might hang the servo output. It wasn’t all the time, or even most of the time, but it was often enough to be annoying.
I tried a lot of things. Nothing completely fixed it. I finally resolved to have a “save” button so at least you know you might crash when you press it. Searching the Internet, this is a common problem. Since the simple code works, it seems as though the EEPROM code is disabling whatever timer interrupt the Servo object uses or not resetting the servo timer.
In the end, it mostly works, but any time you hit the save button, there’s a risk the servo output will die until the watchdog timer kicks in and resets the device.
Of course, the ESP8266 has my local WiFi SSID and password plugged into it. You can set one up to act like a lot of modern devices where if it can’t connect it acts as its own access point so you can configure it. You could also just set it up as an AP and connect to it, assuming you can work out the Internet routing to get to the Blynk servers.
The problem is, I took the device into the office to show it off and realized that while my phone could connect to the corporate network, the ESP8266 wasn’t set up for it. I wasn’t carrying enough stuff to reprogram the device, but a solution dawned on me: I configured the hotspot on my phone to mimic the WiFi at home. With the same SSID and password, the joystick connected. Granted it was a little circuitous for the Blynk app to send data to the remote server, which sent it back to the phone which then routed it to the joystick, but it did work.
Overall, using Blynk was pretty easy and worked pretty well. The EEPROM glitch didn’t seem to be a Blynk issue, so I can’t fault it for that. There were a few rough edges, though. For example, the LED buttons were inverted, but there was no simple way I could find to invert the operation of the buttons. That is, the buttons were on to send a high even thought that extinguishes the LEDs.
Using their server introduces some lag, but not nearly like I feared. If you have security concerns, you can run your own server, although I have not tried that. You still need “energy” for the app, though. I couldn’t decide how I felt about that. I understand that one has to make a living, and the joystick project fit in the free limits after all.
Speaking of which, you can field the Blynk embedded side into a lot of devices ranging from Arduinos, to MBed boards, to Raspberry PIs. You can connect via Ethernet, WiFi, Bluetooth, USB, and you can add your own connection methods.
This project didn’t even scratch the surface of the widgets you can use with Blynk. You can send e-mail, show video from a streaming server (like a web camera), or post to Twitter. There are gauges and sliders and lots of other things I didn’t need for the joystick.
If you don’t like Blynk, there are other options, although none of them struck me as quite as complete. For example, a quick scan of the Google Play Store shows quite a few similar apps. If you start weeding out the ones that won’t run on all the different platforms or work with Apple phones, you get a much shorter list. If you have experience–good or bad–with a different app, post in the comments.
Of course, you can always build your own phone app and communicate via standard networking. That’s actually not as hard as it sounds, but it isn’t as easy as using a tool like Blynk, either. Custom code can optimize what you are most worried about and will do exactly what you want. On the other hand, it would be a lot of work to support many different platforms, work on Google and Apple phones, and so on. For your application, though, that might not be as important as the control over the functions. That’s your call.
Filed under: Arduino Hacks
, phone hacks