Go Down

Topic: Wireless upload with bluetooth module (or uploade code without DTR/RTS to reset) (Read 3258 times) previous topic - next topic

brewmonkey

Hi!

First post, please be nice...  :)
Ok, so first let me state that I'm not looking for help, but I have been trying to get wireless upload via a cheap bluetooth module to work. I have myself been searching for info on this, and found some scattered about but not all I needed to really get it working. I have now gotten to a point where I am very satisfied with the result, so I thought I'd post how I solved it.

First some background, what I am trying to do is set up a controller for a fridge used to ferment beer at the correct temperature. For this there is an excellent project, BrewPi. However, I don't want all the fancy stuff (i.e. the Pi part), I just want a small uC that will fit inside the fridge and keep my desired temperature (or follow a schedule/profile). For interacting with the uC i bought a cheap JY-MCU (somtimes referred to as HC05 i believe), bluetooth - serial adapter, that I plan to connect to from my Android phone.
Now, since I'll be hacking at the controller part some myself also, I want to be able to upload code and preferably over bluetooth (I intend to implement enough of STK500v1 protocol in my app, to be able to upload from my phone).

So here is what I have done:
First I needed to make sure bootloader and application communicates at same baudrate. I chose 115200 as that is the original speed of the optiboot bootloader, so no changes are needed in the IDE/avrdude for upload. The JY-MCU I had was using 9600bps per default, but I found the information on how to use SoftwareSerial example sketch to send AT commands to the device to change baudrate.
When I set baudrate to 115200 I received garbage back from the module and got really nervous. Turns out that SoftwareSerial did not receive well enough at the breakneck speed of 115kbps. Switching to using the hardware UART the device works excellent.
Now, there is no way to upload new code without some really well timed push of the resetbutton, as the control signals are lacking on the module (DTR/RTS). This is in fact nice I think, because I dont want any problems with resets when I connect.
My plan was to reset in software when I receive reset command over serial, only way to do software reset is a watchdog reset. Unfortunately the fastboot mod stuff in Optiboot makes this not possible, so I needed to hack the bootloader as well.
Simplest way I could find to allow bootloading after a watchdog reset, was to add a 16-bit global variable in the .noinit section for the bootloader. After a watchdog reset I check to see if it has my magic number, if not I set it and run bootloader code. When bootloader is done, another watchdog reset occurs, but this time the magic number is present and it jumps to application code.
Since I was modifying bootloader anyway, I also increased the delay, so if bad code make it to my app and reset from software fails. I can at least power cycle hard and still manage to an upload in time.
Now for the final piece of trickery. In my application code, the part that handles incoming commands over serial. I made the command for resetting (using wdt_enable and while(1) loop), 0x30 and 0x20 in succession (ASCII '0' and ' '). This is in the STK500v1 protocol the GET_SYNC command and CRC_EOP, which is what Avrdude will send. This allows me to upload code, using the IDE/Avrdude completely unmodified, just press the button as if I was uploading with regular USB connection :) The arduino will reset and jump to bootloader before avrdude gives up and then continue uploading the code.

Hope this info can be of help to others in a similar situation.
Cheers!


Go Up