├── TODO ├── xbeeconfigure ├── data │ └── configure.txt └── xbeeconfigure.pde ├── README └── examples ├── XBeeSerialEcho └── XBeeSerialEcho.pde └── XBeeCableReplacement └── XBeeCableReplacement.pde /TODO: -------------------------------------------------------------------------------- 1 | 2 | * Display success or failure in GUI. 3 | 4 | * Provide a "Reset to defaults" option. 5 | 6 | -------------------------------------------------------------------------------- /xbeeconfigure/data/configure.txt: -------------------------------------------------------------------------------- 1 | # This configuration is for wireless uploading 2 | [Common] 3 | BD 4 4 | RO 10 5 | 6 | [Transmitter] 7 | NI Transmitter 8 | D3 3 9 | IC FF 10 | 11 | [Receiver] 12 | NI Receiver 13 | D3 5 14 | IU 0 15 | IA FFFF 16 | 17 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | xbeeconfigure -- a tool to configure XBee modules 2 | 3 | Requirements 4 | ------------ 5 | 6 | * "GUI for Processing" 7 | This needs to be installed if you are running the tool 8 | from within Processing. 9 | 10 | 11 | Features 12 | -------- 13 | 14 | * Auto-detect baud rate -- If an XBee module has been configured at 15 | 1200, 2400, 4800, 9600, 19200, 38400, 57600 or 115200 this tool 16 | will determine the correct speed to communicate at in order to 17 | reconfigure it. (It checks them in rough order of likely use so it's 18 | not much slower than specifying it directly and it means you don't 19 | have to remember/know the existing baud rate.) 20 | 21 | * Configuration settings file -- 22 | 23 | Usage 24 | ----- 25 | 26 | Connect your XBee module to the SparkFun USB Explorer board and then 27 | connect the board to your computer. (If you do not connect the board 28 | before running the tool the serial port will not appear in the pop-up 29 | list.) 30 | 31 | Now run the xbeeconfigure tool. 32 | 33 | 34 | = How to: Reset to default configuration = 35 | 36 | * Select the correct serial port from the pop-up menu. 37 | 38 | * Click on the "Configure as Receiver" button and wait for it to turn 39 | from yellow back to blue. 40 | 41 | * Hopefully the configuration will have been successful. The Processing 42 | console (or possibly system log) will contain a message if it was not 43 | successful. 44 | 45 | 46 | = How to: Change the communication speed (baud rate) = 47 | 48 | (Note that this preserves all the other existing configuration 49 | settings.) 50 | 51 | * Select the correct serial port from the pop-up menu. 52 | 53 | * Select the desired baud rate from the pop-up menu below the "Set 54 | baud rate button". 55 | 56 | * Click on the "Set baud rate button" button and wait for it to turn 57 | from yellow back to blue. 58 | 59 | * Hopefully the configuration will have been successful. The Processing 60 | console (or possibly system log) will contain a message if it was not 61 | successful. 62 | 63 | 64 | = How to: Configure for Wireless Bootloading = 65 | 66 | * Select the correct serial port from the pop-up menu. 67 | 68 | * The configuration that ships with the script is designed to be used 69 | for wireless bootloading. This means one XBee needs to be configured 70 | as a "Transmitter" and the other as a "Receiver". This will allow the 71 | Arduino reset signal to be sent to the Arduino. 72 | 73 | * Click on the "Configure as Transmitter" or "Configure as Receiver" button 74 | and wait for it to turn from yellow back to blue. 75 | 76 | * Hopefully the configuration will have been successful. The Processing 77 | console (or possibly system log) will contain a message if it was not 78 | successful. 79 | 80 | 81 | -------------------------------------------------------------------------------- /examples/XBeeSerialEcho/XBeeSerialEcho.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | XBeeSerialEcho -- Simple sketch for demonstrating two-way XBee communication 4 | 5 | Requires: 6 | 7 | (These items are found in the SparkFun XBee Wireless Kit Retail product 8 | or can be obtained individually.) 9 | 10 | * 1 x SparkFun XBee Explorer USB 11 | 12 | * 1 x SparkFun XBee Wireless Shield 13 | 14 | * 2 x "Series 1" Digi XBee communication modules 15 | 16 | 17 | Instructions: 18 | 19 | * Upload this sketch as normal to your Arduino without the XBee Wireless 20 | Shield connected. 21 | 22 | * Disconnect the Arduino from your computer. 23 | 24 | * Both XBee modules should be configured to use their default 25 | configuration and communicate at 9600 baud. 26 | 27 | * One XBee module should be connected to the XBee Explorer board. 28 | Ensure the orientation of the XBee module is correct with the 29 | beveled end of the module pointing away from the USB connector 30 | so the module outline matches the diagonal white lines 31 | silkscreened on the board. 32 | 33 | * The other XBee module should be connected to the XBee Wireless 34 | Shield for the Arduino. Again, ensure the orientation of the 35 | XBee module is correct with the beveled end pointing over the 36 | edge of the shield away from the USB connector on the Arduino 37 | board. The outline of the module should match the the diagonal 38 | white lines silkscreened on the shield. 39 | 40 | * The small switch located near the TX/RX pins on the shield 41 | should be set to the "UART" position so the XBee module is 42 | connected to the hardware serial port on the Arduino. 43 | 44 | * Connect the XBee Wireless Shield to your Arduino. 45 | 46 | * Connect the XBee Explorer USB to your computer with a mini-USB cable. 47 | 48 | * Select the correct serial port for your XBee Explorer USB from the 49 | Tools > Serial Port menu in the Arduino IDE. 50 | 51 | * Connect your Arduino with the XBee Wireless Shield on it to a 52 | power source--either a battery, a "wall wart" power adapter or 53 | another USB port. 54 | 55 | * Open the Serial Monitor window of the Arduino IDE and make sure 56 | the correct communication speed of "9600 baud" is selected from 57 | the pop-up menu in the lower right corner of the Serial Monitor 58 | window. 59 | 60 | * Start typing and whenever you press the button labeled "Send" or 61 | press the "Enter" or "Return" key what you type should be echoed 62 | back to you. (If only "garbage" is returned you probably have 63 | the XBee modules configured for the wrong speed. Reconfigure 64 | them to operate at 9600 baud and try again.) 65 | 66 | * The text you type is sent from your computer, over the USB cable 67 | to the XBee Explorer USB board. From there it is directed to the 68 | XBee module on the board which sends it wirelessly to the second 69 | XBee module on the shield. The second XBee module then directs 70 | the text to the hardware serial port of the Arduino. Your 71 | Arduino reads each character of the text from the serial port 72 | and then sends it back (that is, "echos" it) through the serial 73 | port to the second XBee module. The second XBee module then 74 | sends the echoed text wirelessly to the first XBee module which 75 | directs it to the Explorer USB board which sends it back up the 76 | USB cable to the Arduino IDE serial monitor window. *Phew*. 77 | 78 | 79 | Enhancements: 80 | 81 | * You can change the configuration of the XBee wireless modules to 82 | communicate at a faster speed (try 19200 baud and then 57600 83 | baud) if you also change the communication speed of the 84 | "Serial.begin()" line below and in the Serial Monitor window of 85 | the Arduino IDE to match. 86 | 87 | 88 | For more details and help read the XBee Shield and Explorer USB 89 | Quickstart Guide: 90 | 91 | 92 | 93 | */ 94 | 95 | void setup() { 96 | Serial.begin(9600); // See "Enhancements" above to learn when to change this. 97 | } 98 | 99 | void loop() { 100 | if (Serial.available()) { 101 | Serial.print((char) Serial.read()); 102 | delay(10); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /examples/XBeeCableReplacement/XBeeCableReplacement.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | XBeeCableReplacement.pde 4 | 5 | Control the color of an RGB LED wirelessly via XBee. 6 | 7 | 8 | Required (in addition to your Arduino): 9 | 10 | (These items are found in the SparkFun XBee Wireless Kit Retail product 11 | or can be obtained individually.) 12 | 13 | * 1 x SparkFun XBee Explorer USB 14 | 15 | * 1 x SparkFun XBee Wireless Shield 16 | 17 | * 2 x "Series 1" Digi XBee communication modules 18 | 19 | 20 | Instructions: 21 | 22 | * Ensure both XBee communication modules are configured to use 23 | their default configuration and communicate at 9600 baud. 24 | 25 | * Put the XBee Wireless Shield onto your Arduino but do not insert 26 | the XBee communication module. 27 | 28 | * Wire an RGB LED to your Arduino as shown in CIRC-12 of the 29 | SparkFun Inventor's Guide. 30 | 31 | * Connect your Arduino to your computer using a USB cable. 32 | 33 | * Upload this sketch as normal to your Arduino. 34 | 35 | * Test the functionality of the sketch works when connected via 36 | the USB cable. Open the Serial Monitor window and ensure it is 37 | set to communicate at 9600 baud. Type a sequence of one or more 38 | of the characters 'r', 'g' and 'b' and then press the "Send" 39 | button. The RGB LED should change color in response. A space 40 | character in the sequence will cause the LED to turn off. 41 | 42 | * Disconnect your Arduino from your computer. 43 | 44 | * Insert one XBee module into the XBee Explorer board. Ensure the 45 | orientation of the XBee module is correct with the beveled end 46 | of the module pointing away from the USB connector so the module 47 | outline matches the diagonal white lines silkscreened on the 48 | board. 49 | 50 | * Insert the other XBee module into the XBee Wireless Shield. 51 | Again, ensure the orientation of the XBee module is correct with 52 | the beveled end pointing over the edge of the shield away from 53 | the USB connector on the Arduino board. The outline of the 54 | module should match the the diagonal white lines silkscreened on 55 | the shield. 56 | 57 | * The small switch located near the TX/RX pins on the shield 58 | should be set to the "UART" position so the XBee module is 59 | connected to the hardware serial port on the Arduino. 60 | 61 | * Connect the XBee Explorer USB to your computer with a mini-USB 62 | cable. 63 | 64 | * Select the correct serial port for your XBee Explorer USB from 65 | the Tools > Serial Port menu in the Arduino IDE. 66 | 67 | * Connect your Arduino with the XBee Wireless Shield on it to a 68 | power source--either a battery, a "wall wart" power adapter or 69 | another USB port. 70 | 71 | * Open the Serial Monitor window of the Arduino IDE and make sure 72 | the correct communication speed of "9600 baud" is selected from 73 | the pop-up menu in the lower right corner of the Serial Monitor 74 | window. 75 | 76 | * You may need to press the reset button on the shield to 77 | redisplay the instructions. 78 | 79 | * Control your LED as before--except you've now replaced the cable 80 | with air! 81 | 82 | 83 | For more details and help read the XBee Shield and Explorer USB 84 | Quickstart Guide: 85 | 86 | 87 | 88 | */ 89 | 90 | // LED leads connected to PWM pins 91 | const int RED_LED_PIN = 9; 92 | const int GREEN_LED_PIN = 10; 93 | const int BLUE_LED_PIN = 11; 94 | 95 | // Change this value if you want fast color changes 96 | const int WAIT_TIME_MS = 500; 97 | 98 | 99 | void setLedColour(int redIntensity, int greenIntensity, int blueIntensity) { 100 | /* 101 | 102 | This routine sets the PWM value for each color of the RGB LED. 103 | 104 | */ 105 | analogWrite(RED_LED_PIN, redIntensity); 106 | analogWrite(GREEN_LED_PIN, greenIntensity); 107 | analogWrite(BLUE_LED_PIN, blueIntensity); 108 | } 109 | 110 | 111 | void setup() { 112 | // Configure the serial port and display instructions. 113 | Serial.begin(9600); 114 | Serial.println("Send the characters 'r', 'g' or 'b' to change LED colour:"); 115 | } 116 | 117 | 118 | void loop() { 119 | 120 | // When specific characters are sent we change the current color of the LED. 121 | if (Serial.available()) { 122 | int characterRead = Serial.read(); 123 | 124 | // If the character matches change the state of the LED, 125 | // otherwise ignore the character. 126 | switch(characterRead) { 127 | case 'r': 128 | setLedColour(255, 0, 0); 129 | break; 130 | 131 | case 'g': 132 | setLedColour(0, 255, 0); 133 | break; 134 | 135 | case 'b': 136 | setLedColour(0, 0, 255); 137 | break; 138 | 139 | case ' ': 140 | setLedColour(0, 0, 0); 141 | break; 142 | 143 | default: 144 | // Ignore all other characters and leave the LED 145 | // in its previous state. 146 | break; 147 | } 148 | 149 | delay(WAIT_TIME_MS); 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /xbeeconfigure/xbeeconfigure.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | xbeeconfigure -- a tool to configure XBee modules 4 | 5 | See the README file for more details. 6 | 7 | (C) Copyright 2010 SparkFun Electronics 8 | 9 | Licensed under the GNU GPL version 3.0 10 | 11 | */ 12 | 13 | import processing.serial.*; 14 | 15 | import guicomponents.*; 16 | 17 | 18 | GLabel lblSerialPort; 19 | GCombo cboSerialPort; 20 | 21 | GButton btnProgramAsTx; 22 | GButton btnProgramAsRx; 23 | 24 | GButton btnProgramDefault; 25 | 26 | GCombo cboBaudRate; 27 | GButton btnProgramBaudRate; 28 | 29 | 30 | void setup(){ 31 | size(435, 300); 32 | 33 | String[] availablePorts = Serial.list(); 34 | 35 | 36 | btnProgramAsTx = new GButton(this, "Configure as Transmitter", 10, 50, 200, 20); 37 | 38 | btnProgramAsRx = new GButton(this, "Configure as Receiver", 220, 50, 200, 20); 39 | 40 | 41 | btnProgramDefault = new GButton(this, "Reset to Defaults", 105, 90, 200, 20); 42 | 43 | 44 | // The button is placed above the baud rate pop-up because otherwise the overlap causes problems with 45 | // selecting items from the menu. 46 | btnProgramBaudRate = new GButton(this, "Set baud rate", 105, 132, 200, 20); 47 | 48 | cboBaudRate = new GCombo(this, new String [] {"1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200",}, 8, 155, 162, 100); 49 | 50 | cboBaudRate.setSelected("9600"); 51 | 52 | 53 | // This is added last so that it overlays the other UI elements when it pops up. 54 | cboSerialPort = new GCombo(this, availablePorts, availablePorts.length, 80, 10, 200); 55 | 56 | lblSerialPort = new GLabel(this, "Serial port:", 10, 8, 200, 20 ); 57 | 58 | } 59 | 60 | 61 | public void handleComboEvents(GCombo combo){ 62 | if (combo == cboSerialPort) { 63 | 64 | } 65 | } 66 | 67 | void handleButtonEvents(GButton button) { 68 | 69 | if (button.eventType == GButton.CLICKED) { 70 | if (button == btnProgramAsTx) { 71 | configureDevice(cboSerialPort.selectedText(), MODE_TRANSMITTER); 72 | } else if (button == btnProgramAsRx) { 73 | configureDevice(cboSerialPort.selectedText(), MODE_RECEIVER); 74 | } else if (button == btnProgramDefault) { 75 | configureDevice(cboSerialPort.selectedText(), MODE_DEFAULTS); 76 | } if (button == btnProgramBaudRate) { 77 | configureDevice(cboSerialPort.selectedText(), MODE_BAUD_RATE); 78 | } 79 | } 80 | } 81 | 82 | void handleOptionEvents(GOption option1, GOption option2) { 83 | /* To stop messages about this appearing in the console */ 84 | } 85 | 86 | void handleSliderEvents(GSlider slider) { 87 | /* To stop messages about this appearing in the console */ 88 | } 89 | 90 | void draw(){ 91 | background(200); 92 | 93 | stroke(150); 94 | 95 | line(5, 40, 430, 40); 96 | 97 | line(5, 80, 430, 80); 98 | 99 | line(5, 120, 430, 120); 100 | 101 | line(5, 190, 430, 190); 102 | } 103 | 104 | 105 | final int MATCHED = 1; 106 | final int NO_MATCH = 0; 107 | final int TIME_OUT = -1; 108 | 109 | int matchResponse(Serial theSerialPort, String matchString) { 110 | /* 111 | */ 112 | 113 | int TIME_OUT_MS = 2000; 114 | 115 | int startTime = millis(); 116 | 117 | while (theSerialPort.available() < matchString.length()) { 118 | /* Wait */ // TODO: Make event driven? 119 | if (millis() - startTime > TIME_OUT_MS) { 120 | return TIME_OUT; 121 | } 122 | delay(100); 123 | } 124 | 125 | if (theSerialPort.readString().equals(matchString)) { 126 | return MATCHED; 127 | } 128 | 129 | return NO_MATCH; 130 | } 131 | 132 | final int MODE_BAUD_RATE = -2; 133 | final int MODE_DEFAULTS = -1; 134 | final int MODE_BOTH = 0; 135 | final int MODE_TRANSMITTER = 1; 136 | final int MODE_RECEIVER = 2; 137 | 138 | 139 | String[] getConfiguration(int modeRequired) { 140 | /* 141 | */ 142 | 143 | if (modeRequired == MODE_DEFAULTS) { 144 | // This assumes we reset to the defaults before uploading. 145 | return new String[0]; 146 | } else if (modeRequired == MODE_BAUD_RATE) { 147 | // This assumes we don't reset to the defaults before uploading. 148 | return new String[] {"BD " + cboBaudRate.selectedIndex()}; 149 | } 150 | 151 | String[] configuration = loadStrings("configure.txt"); 152 | 153 | int currentMode = MODE_BOTH; 154 | 155 | for (int idx = 0; idx < configuration.length; idx++) { 156 | String line = configuration[idx]; 157 | 158 | // Skip blank lines 159 | if (line.length() == 0) { 160 | continue; 161 | } 162 | 163 | switch(line.charAt(0)) { 164 | case '#': 165 | // Skip comments 166 | configuration[idx] = ""; 167 | break; 168 | 169 | case '[': 170 | if (line.equals("[Common]")) { 171 | currentMode = MODE_BOTH; 172 | } else if (line.equals("[Transmitter]")) { 173 | currentMode = MODE_TRANSMITTER; 174 | } else if (line.equals("[Receiver]")) { 175 | currentMode = MODE_RECEIVER; 176 | } else { 177 | // Ignore everything else 178 | } 179 | configuration[idx] = ""; 180 | break; 181 | 182 | default: 183 | if (!(currentMode == MODE_BOTH || currentMode == modeRequired)) { 184 | configuration[idx] = ""; 185 | } 186 | break; 187 | } 188 | } 189 | 190 | // TODO: Return array with (now) blank lines removed? 191 | return configuration; 192 | } 193 | 194 | 195 | boolean sendCommand(Serial theSerialPort, String theCommand) { 196 | /* 197 | 198 | theCommand -- this is the command without the "AT" prefix. 199 | 200 | */ 201 | String commandToSend = "AT" + theCommand + "\r"; 202 | 203 | theSerialPort.write(commandToSend); 204 | println(commandToSend); 205 | 206 | return (matchResponse(theSerialPort, "OK\r") == MATCHED); 207 | } 208 | 209 | 210 | boolean uploadConfiguration(Serial theSerialPort, String[] theConfiguration) { 211 | /* 212 | */ 213 | 214 | for (int idx = 0; idx < theConfiguration.length; idx++) { 215 | String line = theConfiguration[idx]; 216 | 217 | // Skip blank lines 218 | if (line.length() == 0) { 219 | continue; 220 | } 221 | 222 | if (!sendCommand(theSerialPort, line)) { 223 | return false; 224 | } 225 | } 226 | 227 | return true; 228 | } 229 | 230 | 231 | void exitCommandMode(Serial theSerialPort) { 232 | /* 233 | */ 234 | 235 | // We ignore the response 236 | // TODO: Reboot instead if baud rate change doesn't stick? 237 | sendCommand(theSerialPort, "CN"); // Exit command mode. 238 | } 239 | 240 | 241 | boolean enterCommandMode(Serial theSerialPort) { 242 | /* 243 | */ 244 | 245 | theSerialPort.write("+++"); 246 | 247 | return (matchResponse(theSerialPort, "OK\r") == MATCHED); 248 | } 249 | 250 | 251 | Serial openWithBaudRateDetect(String theSerialPortName) { 252 | /* 253 | */ 254 | 255 | int[] baudRatesToDetect = {9600, 19200, 57600, 38400, 115200, 4800, 2400, 1200}; 256 | 257 | for (int idx = 0; idx < baudRatesToDetect.length; idx++) { 258 | int baudRate = baudRatesToDetect[idx]; 259 | 260 | Serial serialPort = new Serial(this, theSerialPortName, baudRate); 261 | 262 | if (enterCommandMode(serialPort)) { 263 | exitCommandMode(serialPort); 264 | delay(2000); // Guard delay 265 | return serialPort; 266 | } else { 267 | serialPort.stop(); 268 | } 269 | } 270 | 271 | return null; 272 | } 273 | 274 | 275 | void configureDevice(String serialPortName, int functionalityMode) { 276 | Serial serialPort; 277 | 278 | println(serialPortName); 279 | 280 | String[] configuration = getConfiguration(functionalityMode); 281 | 282 | 283 | serialPort = openWithBaudRateDetect(serialPortName); 284 | 285 | if (serialPort == null) { 286 | println("Could not enter command mode. (Incorrect response or no response.)"); 287 | return; 288 | } 289 | 290 | // TODO: Detect when serial port doesn't exist. 291 | 292 | if (enterCommandMode(serialPort)) { 293 | 294 | // TODO: Don't special case baud rate/reset defaults. 295 | if ((functionalityMode == MODE_BAUD_RATE) || sendCommand(serialPort, "RE")) { // Reset to defaults except if setting only baud rate 296 | 297 | if (uploadConfiguration(serialPort, configuration)) { 298 | 299 | if (!sendCommand(serialPort, "WR")) { // Write changes to storage 300 | println("Saving configuration failed. (Incorrect response or no response.)"); 301 | } 302 | 303 | } else { 304 | println("Configuration failed. (Incorrect response or no response.)"); 305 | // TODO: Do something else here? 306 | } 307 | 308 | } else { 309 | println("Reset to defaults failed. (Incorrect response or no response.)"); 310 | } 311 | 312 | } else { 313 | println("Could not enter command mode. (Incorrect response or no response.)"); 314 | } 315 | 316 | // TODO: Make sure we always exit command mode? 317 | exitCommandMode(serialPort); 318 | 319 | serialPort.stop(); 320 | 321 | println("Done."); 322 | } 323 | 324 | --------------------------------------------------------------------------------