Programming Arduino via bluetooth
I finally figured out how to program my Arduino controlled "Start Here Robot" clone without leaving my chair using bluetooth. Unfortunately it still only works when the Arduino IDE is running on a Linux box.
I ordered an other $6.49 bluetooth module on ebay, this time I payed attention on getting the right type, HC-05 to be precise. See my other bluetooth post to understand why I'm emphasize this.. (http://letsmakerobots.com/node/30345) The HC-05 is well documented, i easily found several PDF's in the Internet, which described the module in great detail.
The module is quite small, 13x27mm which is a little more than 1/2x1 inch. And it features 34 terminals around. I mounted the module on a piece veroboard with a double sided sticky foam thingy. Then soldered thin wires between the 8 terminals needed and the veroboard. Also on the veroboard i have level shifters, 3.3v regulator and a reset circuit to trigger the Arduino bootloader. All in all I have build this:
Now I put a jumper on the mode pins to enable the onboard command processor, and then I connected the transmit and receive pins to my level shifter cable described here http://letsmakerobots.com/node/29207 and fired up putty on my linux. Initially the module communicates at 38400 baud
Connected to the port where I put the cable and typed AT. The module went berserk, spraying ERROR all over my terminal. It seems that my putty is sending carriage return when I hit enter nut the module wants a line feed as well. A little reconfigure in putty fixed this.
Ok, now that I have established communication to the command processor on the bluetooth module it's time for the initial configuration. I sent the following list of commands to the module:
Some of these needs a little explanation. ORGL is a factory reset, ROLE is enter slave mode, POLAR configures pin32 to shift from high to low when link is established, UART sets the line speed to 57600 BAUD (but first when module is reset next time), INIT and INQ makes the module listen for incoming connections.
Now I reset the module and reconfigured putty to 57600 BAUD and checkedthat AT still responded with an OK. Leave the putty online, connected to the module via the serial link.
Now scan the ether for your module. On linux its hcitool scan which responds with the address of the module. My module has the address 00:11:11:28:06:25 which is the address you will need for the connection. The command sudo rfcomm bind 3 00:11:11:28:06:25 makes the linux "prepare" the connection. At this point the kernel prepares the device file /dev/rfcomm3, but no connection is established yet. Now fire up another putty and this time make a serial connection to the /dev/rcfomm3. If everything goes well your bluetooth manager will pop-up and request you a pin code. for the HC-05 it defaults to 1234. After you have entered the pin, the two puttys are connected, and I were able to send data from the one to the other.
Now, disconnect the serial cable and connect the bluetooth interface to your Arduino. Pin numbers are on the schematic. It helps if you have a program on the Arduino which slowly counts and outputs the result on the serial link. Something like this:
static int i;
Now you should see the output of your program in the putty connected to /dev/rfcomm3. And when you close the putty and open it again it should trigger a reset, making the counter starting over.
Now its time for tweaking the Arduino IDE to program through the bluetooth link. This requires a little hack to the IDE, which I were not able to get working on the windows side, which is why this guide is considered linux only.Btw. I'm working in version 0022 of the IDE. I still don't like the new version 1 thing!
A little background info may be needed here. Then the OS, linux or windows, opens the bluetooth interface, the lower stuff in the system establishes the actual link. This is an automatic process. This also happens if the Arduino IDE opens the interface. Sounds good, but its not. Problem is that the IDE scans all serial ports on the system, and it does this by opening them. Just a fast open-close, but this is enough to trigger the automatic establish bluetooth link process, which takes a second or two. And since the scan is way faster than this it often clutters up the link.
On windows the bluetooth interface gets a serial port name, eg. COM21. and this gets detected, and smashed by the IDE. On linux the devices (thats what we call interfaces there) gets named /dev/rfcomm3, which the Arduino IDE DOES not find and hence wont smash! Perfect! Ok the IDE cannot select the port, how does I then actually program my Arduino though a port thats not visible in the IDE?? Hey its linux, it hackable!
I located the version of avrdude shipped with my Arduino IDE, it's under $ARDUINO_HOME/hardware/tools/avrdude. here I renamed the avrdude program to to avrdude-real and then put a little perl program there instead:
my @cmd = ("$0-real", @ARGV);
printf "Programming %s\n", $? ? 'FAILED' : 'SUCCESS'
Pay attention the the regexp substitute there. I replace the device /dev/ttyS0 with my bluetooth devicde. Now I simply tell my IDE to program an Arduino on /dev/ttyS0, the my wrapper program translates this to /dev/rfcomm3 and avrdude programs away.
Now what about the automatic reset triggering? Yes it woks. When avrdude opens the device, it gets blocked until the link is established, typically 1.2 second. And when link is ready, the bluetooth module lowers pin32, which through the cap triggers the reset pin on the Arduino. with 1uF, the timing seems to be just right!
Ok, the using a different port to keep the IDE from breakign everything is an ugly hack, but I have not been able to locate a better solution, and nor make it work in windows.
I see a few options here
- Fixing the IDE to not probing everything but taking the port to be used as a configuration parameter. Requires a JAVA hacker, which it NOT me!
- Using an other IDE than the official Arduino one. It have been done, but its not beginner friendly.
- Using Linux. Oh yes, thats the way to go anyway. ( yes, I'm a fanboy, I admit it!)