Taking your nodebot wifi
Controlling your nodebot using a USB cable is great and all, and obviously you could shell out and grab a sparkcore or some other dedicated controller but what if you've got a standard arduino and you want to take an existing nodebot wireless?
Bluetooth is an option and there's this excellent JohnnyFive wiki entry that will help you there. Bluetooth can be a bit flaky though and it's range is pretty lousy. You can also look at things like XBees and what not using point to point serial, but these are expensive and very fiddly to get working.
Really, what we want is a method of transferring data over a nice, simple, standard method, requiring little configuration, low cost and we can utilise a whole stack of the code we've already produced.
Enter the WiFi232 module. These little beauties are available from AliExpress for $12 each. Basically they are a standard WiFi b/g/n modules with a simple ttl serial interface. In addition, the wifi module has the ability to work in both Access Point (AP) mode as well as station mode at the same time. This means you can have it connect to your wider wireless LAN as well as create it's only little access point for configuration and discoverability. The full data sheet gives you a lot more information about things you can do with them (including running PWM modules directly using the onboard GPIO).
What we're going to do is use this to remove the USB cable between our computer and our nodebot.
Assuming you have the modules get familiar with them. Note that they use 2mm pitch headers which is a pain but if you have an XBee breakout board laying about you can use one side of it and plug the module into a breadboard. Just don't use a powered one (eg Xbee Explorer USB) as the pinout is definitely not the same and you'll probably blow it up.
Pinout is like this:
WiFi232 Pin 1 <--------> GND
WiFi232 Pin 2 <--------> VCC (3.3v) - IMPORTANT - don't plug this into 5V on an arduino!
WIFI232 Pin 5 (RX) <---> Arduino (TX) Pin 1
WiFi232 Pin 6 (TX) <---> Arduino (RX) Pin 0
Check, check and triple check this set up and refer to the data sheet and check again. There's no reverse or over-current protection on these modules and applying power with too much voltage or GND & VCC back to front will toast your module very rapidly.
Seriously, check your wiring again before you plug it in.
Note that as you're using the Arduino hardware serial port if you need to flash your arduio then you'll need to remove the wires so you can talk to the arduino using USB. If you get an stk_500 sync error it's probably because you forgot to unplug the serial wires.
Also make sure you use your antenna - it's fiddly to attach, but attach it. These modules are designed to take an antenna and don't have a chip antenna on them so your range will be drastically reduced if you don't use it (I couldn't get one to work on the other side of a table about 1m away from my computer).
What we end up with is this:
WIFI232 Serial Interface <---> Arduino Serial Interface
Testing the module
Once you have some power applied, the WiFi module will power up. By default it will be in AP mode. Give it 10-15 seconds and then in your WiFi networks on your computer you should see the SSID "USR-WIFI232-T". Connect to this network and once connected you can then try two things to see if it's all working.
The module IP address is 10.10.100.254 and it has a DHCP server so it should assign you something in that range once you connect. Test pinging that IP address and if you're getting responses, move to the next step. If not, diagnose your network interface and make sure you're not using a static IP or have dodgy routing or something.
Now you can see the module, fire up a web browser and point it at 10.10.100.254. Username and password by default are "admin". In here you can configure the common aspects of the module itself. I have set mine to operate in STA+A mode which means it operates as a WiFi station (sits on your wifi network) but also operates as an access point. The benefit of this is that if I'm in a place for a long time (eg home or work) I can put it on that network and access it from any device but if I move or I'm in the park or somewhere without infrastructure networking I can just use the module as an access point - best of both worlds!
If you've ever configured a home wifi router everything will look pretty familiar. The only other thing to look at is the TCP timeout. I've reduced mine to 90 seconds from 300 which is a nice balance of quick to time out but long enough to maintain the connection if you aren't sending messages (especially when you're doing it by hand).
Wireless not working?
If you can't get to the wireless module using the methods above for some reason, try connecting over serial directly. Basically you'll need something like an FTDI or other serial ttl USB cable. Plug it in then connect using a serial console at 115200 baud rate.
The user guide has more details but if you enter "+++" and nothing else you should get an "a" sent by the module. Reply with an "a" and you'll be in an AT command console. Use AT+H to get a list of commands and refer to the docs for more on the AT command console. If you're here then you'll be able to debug what's going on with the various GET AT commands.
Arduino set up
This is super easy. Just use your standard firmata sketch with one change. Do a find for the line that says
and change it to:
This will tell firmata to use a higher baudrate so it can talk to the WiFi232 over serial at the same speed.
That's it, compile and upload the sketch to your arduino.
Testing comms is working
The next step is to make sure communucation is occuring before we start trying to play with Johnny Five.
The nice thing about the WIFI232 module is that exposes a TCP port (8899 default, unless you changed it) and whatever is sent to and from the serial connection is sent through that TCP port. Thus:
PC <---> WiFi Network Interface (TCP 8899) <---> WIFI232 Netork Interface (TCP 8899) <---> WIFI232 Serial Interface <---> Arduino Serial Interface
So if we open a telnet connection to the module we should be able to see serial messages coming from the Arduino. Whilst most of firmata data is encoded byte instructions, one message that is in clear text is that it sends the name of the firmata sketch being used to the receiver as part of the start up messages.
On my network, the module is using IP: 10.0.1.12 so I telnet there.
telnet 10.0.1.12 8899
And I get the following response:
Trying 10.0.1.12... Connected to 10.0.1.12. Escape character is '^]'.
That's good, now we're connected. Let's see if we can get a message. Hit the reset button on your arduino so the sketch restarts. You should see the tell tale Pin 13 LED blink sequence and withing a few seconds something like this:
Trying 10.0.1.12... Connected to 10.0.1.12. Escape character is '^]'. ����y��SimpleBotFirmata.ino
Success! We've just received a message from firmata onto our PC running node. Note that my message says "SimpleBotFirmata.ino" because I use a custom firmata. Yours will say something like "StandardFirmata.ino".
Quit out of telnet (ctrl+5 then type quit on most machines). We're ready for the last step.
Johnny Five set up
Now we've got firmata messages travelling over the network all we have to do is get Johnny-Five to read and write them and we've got a wireless NodeBot. The problem is JohnnyFive by default assumes you have a Serial device that you're connecting to "/dev/ttyUSB0 or /dev/tty.USBSerial". What we have instead is a network socket. Now we could go and write an IO interface for Johnny-Five but that's a bit of overkill for a simple socket and it's not like we're writing a new messaging protocol, we're just sending messages via the magic of WiFi not over a pair of wires.
Socat to the rescue (Mac / Linux)
Socat is a great little *nix program for arbitrarily creating relays between two otherwise independent data channels (for the nodey amongst you - think a relay between two independent streams). Knowing this we can exploit another *nix feature - pseudo terminals - which allows us to "fake" a serial terminal.
A "faked" serial terminal sounds awfully like something Node Serialport and thus Johnny Five could use natively without any changes doesn't it?
Using both these things together what we're going to do is make a relay between a pseudo terminal that looks like a serial port and connect that to the TCP socket used to talk to the WIFI232 module.
PC <---> Pseudo terminal (~/dev/ttyV0) <---> TCP Socket (10.0.1.12:8899)
To do that we use this command:
socat -d -d pty,nonblock,link=$HOME/dev/ttyV0 tcp:10.0.1.12:8899
The -d switch is a debugging parameter, remove if if you don't want details, and use it up to 4x for LOTS of messages.
We tell socat to create a pseudo terminal (pty), don't block it (we can use it from other processes then) and link it to $HOME/dev/ttyVO (in my case that puts it at "/home/ajfisher/dev/ttyV0" but put it wherever you fancy but I tend to not put psuedo things in the actual /dev device space. We're then connecting that to a tcp connection to 10.0.1.12 on port 8899.
Assuming socat doesn't report any errors then create another terminal window and use a terminal emulator to connect to ~/dev/ttyV0:
Again do the trick with resetting the arduino and you should see your firmata sketch name. If that all works then you're ready to wireless your nodebot.
The file attached in this gist, blink.js is a simple J5 blink script that takes the port name as a parameter. Execute it like this:
node blink.js ~/dev/ttyV0
Obviously, substituting the port for the one you made if it was called something else.
At this point you should have a nice, blinking LED on pin 13.
VSPE to the rescue (Windows)
On windows, there is a bit of software that will do what we want called Virtual Serial Ports Emulator. VSPE allows you to define a COM port and then create mappings for other end points such as to network services - like we did above with socat.
So what we'll end up with is something like this:
PC <---> Virtual COM Port (COM10) <---> Bridge <---> TCP Client (10.0.1.12:8899)
Download and install the software (you may be prompted for a licence which you don't strictly need but obviously support the developer if you're using this a lot).
Once you have it open we'll create two devices:
The first one create as a "Connector" from New Devices and set it to be COM10 - this creates a COM port for Windows to talk to and thus for our node script to look at.
The next one we create will be a "Bridge" type which bridges between two data streams.
Stream 1 should be set up as:
- TCP Client
- Host: 10.0.1.12 (or whatever yours WIFI232 IP is)
- Port: 8899
Stream 2 should be set up as:
- Serial port
- Port: COM10 (type it in - it won't be in the drop down as it's not "real")
- Speed: 57600
Once you have that save it all and press the play button to get it all running. Any errors should be fairly obvious in terms of what you need to do to fix it.
You should now be able to run the blink.js file in this gist like this from your command line:
node blink.js COM10
And you should see your blinking LED.
Bear in mind that there are some timing sensitivities to all of this so give it a good 20 seconds to connect. There are timeouts in node firmata and johnny five that try to reset firmata if they don't hear anything so be patient, it's not as immediate as with a physical wire.
If you get an error, your tcp connection has probably timed out, restart socat and try again.
With a cheap and simple module that's readily accessible and a bit of *nixy goodness you now have a wireless nodebot. I can fairly reliably drive my SimpleBot around the house without too much trouble all the while it's in good wifi coverage. I leave it as an exercise for the reader to control a few of these and drive them around from the same node process - Swarm SumoBots v Swarm SimpleBots anyone? I bet @makenai will be up for that.
Now you're running wirelessly you're going to run into all sorts of other wonderful problems - mostly around power considerations and what happens when everything is running off a battery (hint motors + ICs don't mix well).
Have fun with your newly wireless nodebot and post a comment to show a link to what you've built.