├── 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 |
--------------------------------------------------------------------------------