Introduction: Arduino Wireless Programming With XBee Series 1 or 2
Hi. This Instructable will guide you through the process of wirelessly programming your Arduino using two XBees. I just finished designing a wireless EEG system with the XBee modules, so I've become quite fluent in their programming and have just now been able to accomplish this. It still amazes me how difficult it has been to try to wirelessly program the Arduino. On top of that no one has been able to do this with the series 2 XBees (that I know of... and I've looked hard). However I do not see why this method cannot be extended past the series 1 or 2 and used for the 900MHz series as well. You just need to make sure that the XBee is capable of acting as a transparent serial link.
Being able to wirlessly program your Arduino can come in immensly handy. This means you can set up your Arduino in a remote location that is hard to access and still be able to program it. For example, if you want to measure climate data in a harsh enviroment. This would require you to seal your device, and make it combursome to program. However, with this rig not only can you still program the Arduino inside from over 90m away, but also recieve data from your sensor wirelessly too.
Its my first Instructable so any feedback would be much appreciated!
In order for you to accomplish this you will need to:
1) Have two XBees. They can be any series I believe, but they have to be a pair of the same series
2) Have an appropriate method of connecting one XBee to your computer, and another to a circuit.
3) Build a small circuit that incorporates a Arduino. Can be a standard board such as the UNO or solely the microcontroller with accompanying crystal and capacitors.
4) Have an another Arduino bootloaded with the Duemilanove bootloader. This will be the Arduino that is programmed wirelessly.
For example, I used:
1) Two series 2 modules.
https://www.sparkfun.com/products/10414
https://www.sparkfun.com/products/10420
2) A USB explorer for connecting to my laptop, and a explorer regulated for connecting to my circuit.
https://www.sparkfun.com/products/8687
https://www.sparkfun.com/products/9132
3) A ATMEGA328p-pu microcontroller that was soldered onto a shield.
http://www.digikey.com/product-detail/en/ATMEGA328P-PU/ATMEGA328P-PU-ND/1914589
http://www.adafruit.com/products/51
4) A Arduino UNO board, but I re-burned the chip to have the Duemilanove bootloader instead.
https://www.sparkfun.com/products/11021
Step 1: Programming the XBees
Here we are going to program our XBees to the right communication settings for the project. I was using series 2 modules so as far as I know these steps work for series 2, but should be able to be adapted for any module. The end goal here is to setup a wirless transparent serial link operating at 57,600 buad.
1) Connect the XBee that is going to connect to your destination Arduino that is going to be wirelessly programmed, to your USB explorer and open up the XCTU program to program the XBee.
2) Program your XBee according to the "reciever" settings file I uploaded. Just load the file and click write. If you cannot access the file, then just program it as a Router in AT mode, and change the serial interface baud rate to 57,600. Remember to change your destination address accordingly. You want your detination address to be all zeros, indicating that you are transmitting to the cordinator.
3) Now connect your XBee that is going to stay connected to your computer to your USB explorer and open up XCTU again. This program can be found on the sparkfun link to the XBees I attached on the previous step.
4) Program your XBee according to the "transmitter" settings file I uploaded. Just load the file and click write. If you cannot access the file, then just program it as a Coordinator in AT mode, and change the serial interface baud rate to 57,600. Remember to change your destination address accordingly. You want your destination adddress to be the address of your reciever.
Now pop back your "reciever" XBee into your explorer regulated and wait for the next step to plug it into the circuit.
Step 2: Circuit and Code
This is the circuit that will handel the programming of the Arduino Duemilanove. Funny enough, its based on an Arduino microcontroller itself. I attached a picture of the schematic in case you cannot open the eagle file.
A background on the circuit:
The most unique thing about this circuit is probably the fact that it uses an interrupt on digital pin 2 that is connected to the RX pin of the destination Arduino (the Arduino that is destined to be programmed). This is to detect the first low bit of serial data, which will be the IDE trying to reset the arduino for a sketch upload. However, the IDE cannot reset the destination Arduino directly, but that is why I included the intermediary Arduino (The Arduino that will reset the destination Arduino). Once a interrupt is triggered a timer, really a delay function, will start that triggers a low to high pulse on D8. In turn, D8 is connected to the destination Arduino's reset line and will cause it to reset.
I found a good time to delay was almost 500ms, or 499500us to be exact. I arrived at this by monitioring the serial communcation and reset line of an Arduino that was connected VIA USB to my laptop while I uploaded a program to it, and trial and error. I posted a picture of the results into this step, it's the one with the Matlab program operating as an oscilloscope. This may be one point of improvement, because according to the picture I can shorten the delay to 100ms or 250ms from the first serial reset command. I stuck with 499500us because it worked and a half a second shorter upload was not worth another hour of debugging to me. You can see that 499500us is not a very genral number to arrive to. I had to try 490ms, 495ms, 499ms, 500ms, 501ms, 505ms, ... before I arrived to 499500us.
In order to keep the interrupt from reseting the destination Arduino on every recieved serial tranmission while uploading I included a timeout of 60s. Which seems to be how long it would take to upload even a ~30kb program; the maximum size possible. However the time to upload a 1,100 byte program is about 5s so I included another interrupt that will stop the timeout if a high voltage is detected on the A0 pin of the destination Arduino. Therefore, if you include a few lines of code that pulse a high level on the A0 pin in the setup() routine of your destination Arduino you will significantly shorten the time between uploads for your small sketches. I programmed a blue LED to light on when the timeout is active. Indicating that you are uploading, and nothing else can be transmitted at the time.
One last note for this step. I highly recommend putting this circuit on a shield, and using the female headers to mount the XBee. This will not only make your circuit much sturdier, a work of art, not permanently comission an XBee, but also speed up your prototyping as well; which is probably what your doing when your uploading code often enough to benift from doing it wirelessly. If you're not ready not solder, though, or dont belive me lol, you can always breadboard the ciruit and use it like that. Which is what I did when I was prototyping this circuit.
For some reason I cannot attach my code here, do you know why? I've tried Chrome and Explorer. So I pasted it below.
/*
This sketch is meant to be mounted on a Arduino(I used a UNO 5v) that is going to be used
to reset a Arduino Duemilanove that is meant to wirelessly programmed. It has one
interrupt on pin 2(tied to RX on destination Arduino to know when a upload
is attempted and therefore reset the destination Arduino at the approriate time.
Another interrupt exists on pin 3(tied to A0 on destination Arduino) that is used
as a signaling pin by the programmed Arduino to tell this Arduino that the
programming process has concluded. An example of such a signaling routine is shown
below. For best practice, include it as the first line in your setup() routine of your
programmed Arduino.
pinMode(A0, OUTPUT);
digitalWrite(A0, LOW);
delay(1);
digitalWrite(A0, HIGH);
delay(1);
digitalWrite(A0, LOW);
pinMode(A0, INPUT);
However this is not necessary, because this program includes a 60s timeout after
which you can again program this chip. The afore mentioned code simply stops the
timeout, allowing you to upload code immeadelty after your previous upload. In any
case you cannot upload until the blue LED on D4 turns off.
*/
volatile boolean startup=false;
volatile boolean done=false;
static byte resetpin=8;
static byte blueledpin=4;
void setup()
{
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(blueledpin,OUTPUT);
pinMode(resetpin,OUTPUT);
//pinMode(13,OUTPUT);
digitalWrite(blueledpin,LOW);
digitalWrite(resetpin,HIGH);
attachInterrupt(0, resetter, LOW); //this pin is attached to the RX line of the other Arduino
attachInterrupt(1, stopignore, HIGH); //this pin is attached to A0 of the other Arduino
detachInterrupt(1); //However this interrupt is only necessary when the first one has triggered
}
void loop()
{
if(startup)
{
detachInterrupt(0); //so we do not reset again in the middle of the upload
digitalWrite(resetpin,LOW);
delayMicroseconds(499500); //499500us worked well
digitalWrite(blueledpin,HIGH);
digitalWrite(resetpin,HIGH); //bring high to stop reseting the Arduino
//maybe insert a small delay here
attachInterrupt(1, stopignore, HIGH);
startup=false;
for(unsigned int i=0; i<60000; i=i+50) //delay a total of 60s unless "done" is true
{
//digitalWrite(blueledpin,LOW);
delay(25);
//digitalWrite(blueledpin,HIGH);
delay(25);
if(done) //then stop timeout because upload has finished
{
i=60000;
break;
}
}
//reset for the next code upload
attachInterrupt(0, resetter, LOW);
detachInterrupt(1);
done=false;
digitalWrite(blueledpin,LOW);
}
}
void resetter() //triggered only at the start of an upload. E.G. first low byte of an upload
{
startup=true;
digitalWrite(blueledpin,HIGH);
}
void stopignore()
{
done=true;
}
Attachments
Step 3: Burning Bootloader
Your target Arduino, the one being wirelessly programmed, needs to have the Duemilanove bootloader. This makes it easier to upload code to since the timing of the reset signal does not have to be so percise. If your chip doesnt have the Duemilanove bootloader then you can use your Arduino as an ISP programmer and burn the bootloader using the Arduino IDE. If you do not know how to do this, then I recommend checking out Arduino's tutorial on it at http://arduino.cc/en/Tutorial/ArduinoISP.
What I did was take a blank ATMEGA328p-pu chip I had on hand and burned it with the Duemilanove bootloader using my Arduino Uno as an ISP. Since I only have UNO Arduino boards i just popped the newly burned chip into my UNO board and treated it like it was a Arduino Duemilanove board.
Step 4: Uploading Wirelessly
I attached a video so you can see how the whole process works. I used a modified blink sketch as the sketch to upload for demonstation purposes. It only takes up 1,100 bytes of memory, but this method should also work for the maximum file size. It has been tested with up to a 25kb sketch (A CNC program I wrote last year).
Thanks for viewing.
Step 5: Future
So now that I have shown you a simple and effective wireless programming method using XBees S2. Maybe you guys can help improve it?
Below I've noted some areas for improvement:
*As mentioned in step 2, the delay between recieving a reset command and actually reseting the chip could probably be shorted to 100ms or less.
*Secondly, my note I left in the schematic of step 2. That chip you see is a multiplexer. I was wondering if the Arduino could still retain serial recieve capabilities to gather information from another device. So far it can transmit just fine, but any time it recieves something over the RX line it will reset. Maybe code could be written that controls the multiplexer to switch lines between the D0RX pin and the XBee or another periphiral?
*Most importantly, maybe code could be written that actually makes the shielded Arduino read in serial data upon interrupt, and determines if the IDE is trying to program the other Arduino. Based on some serial data I aquired, it seems the code to look for a 3 byte line "0x14 0x10 0x14". For example, if the shielded Arduino recieves this line it will reset the destination Arduino. This would allow you to transmit to the destination Arduino from a serial window without reseting it everytime you transmitted; Of course, as long as your transmission does not start with the reset code.
Take care and thanks for viewing. It will be interesting to see where this project goes from here.

Participated in the
SciStarter Citizen Science Contest

Participated in the
Instructables Design Competition
16 Comments
5 years ago
please share the details of how to program the transmitter, is it from arduino ide,in such case i've connected xbee to my computer and trying to load the code, it gives an error
avrdude: stk500_getsync(): not in sync: resp=0x00
Dear,
Does it support wireless programming XBee series 2?
7 years ago
Does it support in arduino Uno bootloader?
Reply 5 years ago
My name is Mustafa Shakur and I agree 101% with you my friend. I hope you have very good time with uno adapter my son.
7 years ago
I have xb24-z7-004 xbee its not detecting on xctu can help me
7 years ago
I have a Xbee S1 and a Xbee s2. How can I establish a wireless communication between a PC and an Arduino with these bees?
7 years ago
does anyone know how to send a value in terms of floating point from one arduino to another arduino using xbee series 2...i want to complete this project within this month... please anyone help me..if u know the code please send it to krishnansadasivam96@gmail.com
Reply 7 years ago
the float which you want to send multiply with 10,100 or 1000 based on your requirement now it in integer form transmit via xbee after receiving at receiver in your programming divide it with same number 10,100 or 1000
ex : float a=98.67
int b = a*100
now b=9867
xbee.print(b)
at receiver int a= xbee.read()-'0'
float b= a/100
now b= 98.67
but you should have idea on transmit and receive program
Reply 7 years ago
hey could you help me
I have to send 3 sensor values (temp,humidity,Ldr) via xbee series 2 and receive them at other arduino-xbee
7 years ago
Can i transmit and receive voice signal by xbee module ...!?
8 years ago on Introduction
what is the wiring and layout of the shield, what program that made https://www.instructables.com/files/orig/FP2/4Y1R/HAQ3217E/FP24Y1RHAQ3217E.sch i can't find the program that made it.
thanks
keith
8 years ago on Introduction
hye bro .. this project need one or two xbee wireless ?
8 years ago on Introduction
Great project. Thank you for sharing.
9 years ago on Step 3
let me know your EEG project with XBEE??
can you share link for your project above
9 years ago on Introduction
hi there ..
i'm new to RF , could anybody help me with Xtenda 900 40 miles range , how to hook it to Arduino Uno
i couldn't find any tutorial or video
10 years ago on Introduction
A wonderful guide to start working with Arduino Uno. As you can see I add a link in my article where is an impressive collection of guides and tutorials to start working with Uno.
10 years ago on Step 2
I've been trying to figure this out for a while. If it still doesn't work. I may have to try your method. I've been reading about people using the RST or DTR lines on the FTDI chip to reset the Arduino. for example http://letsmakerobots.com/node/23869 and http://www.ladyada.net/make/xbee/arduino.html. I've tried relentlessly, with different combinations of high to low transitions from my xbee, but I still can't quite seem to get the timing right. Do you think you could check out these articles and maybe scope the DTR and RST pins on the Xbee Explorer to help me figure this out? I think it could be easier than using another chip, but I can't seem to get it to work. I also think they are using various sized capacitors to get the timing, but I can't be sure if that actually changes anything.