I'm trying to design an RC controller using an Arduino and an XBee Series 2 Pro. I have the hardware serial running for debug information and I want the XBee to be connected to a soft serial on pins 8 and 9.
My arduino keeps restarting, or at least the setup function keeps looping, every time I try to send data through the XBee. If I modify the code so the XBee runs on the hard serial, the program works, but I would rather not have that setup because then to load new code onto the arduino I have to open the controller and disconnect the XBee.
I tried changing the pins that the soft serial runs on and that makes no difference, nor does unplugging the power to the XBee but leaving the serial connections in. I also tried to write another pin high to make sure there's enough current, and that didn't cause a restart.
My arduino is connected to the XBee, 4 potentiometers, and 1 switch.
#include <XBee.h>
#include <SoftwareSerial.h>
#define NOTE_A3 220
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define THR_JOYSTICK A0
#define YAW_JOYSTICK A1
#define RL_JOYSTICK A2
#define FB_JOYSTICK A3
#define POT A4
#define TOGGLE 4
#define SPEAKER_PIN 3
//#define WAKE_PIN 10
#define YAW_MIN 0
#define YAW_OFFSET 386
#define YAW_MAX 815
#define RL_MIN 0
#define RL_OFFSET 359
#define RL_MAX 800
#define FB_MIN 0
#define FB_OFFSET 355
#define FB_MAX 795
#define THR_MIN 0
#define THR_OFFSET 0
#define THR_MAX 754
const int ESC_MIN = 764;
const int ESC_OFFSET = 1500;
const int ESC_MAX = 2000;
XBee xbee = XBee();
SoftwareSerial nss(13,12);
uint8_t payload[10];
// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x40c67584);
ZBTxRequest packet = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();
void setup() {
//start serials
Serial.begin(9600);
nss.begin(9600);
xbee.setSerial(nss);
//pin modes
pinMode(THR_JOYSTICK,INPUT);
pinMode(YAW_JOYSTICK,INPUT);
pinMode(RL_JOYSTICK,INPUT);
pinMode(FB_JOYSTICK,INPUT);
pinMode(POT,INPUT);
pinMode(TOGGLE,INPUT);
pinMode(SPEAKER_PIN,OUTPUT);
//delay to allow inputs to settle
delay(1000);
//the speaker will need a total resistance of at least 125 Ohm
//so if it's an 8 Ohm speaker, an additional 117 is needed etc...
//calibrate THR
int first = millis();
tone(SPEAKER_PIN,NOTE_A3);
int reading = analogRead(THR_JOYSTICK);
while(reading > THR_OFFSET + 5 || reading < THR_OFFSET - 5) {
delay(20);
reading = analogRead(THR_JOYSTICK);
}
int dif = 200 - millis() + first;
if(dif <= 200 && dif >= 0) {
delay(dif);
}
//calibrate YAW
first = millis();
tone(SPEAKER_PIN,NOTE_B3);
reading = analogRead(YAW_JOYSTICK);
while(reading > YAW_OFFSET + 5 || reading < YAW_OFFSET - 5) {
delay(20);
reading = analogRead(YAW_JOYSTICK);
}
dif = 200 - millis() + first;
if(dif <= 200 && dif >= 0) {
delay(dif);
}
//calibrate FB
first = millis();
tone(SPEAKER_PIN,NOTE_C4);
reading = analogRead(FB_JOYSTICK);
while(reading > FB_OFFSET + 5 || reading < FB_OFFSET - 5) {
delay(20);
reading = analogRead(FB_JOYSTICK);
}
dif = 200 - millis() + first;
if(dif <= 200 && dif >= 0) {
delay(dif);
}
//calibrate RL
first = millis();
tone(SPEAKER_PIN,NOTE_D4);
reading = analogRead(RL_JOYSTICK);
while(reading > RL_OFFSET + 5 || reading < RL_OFFSET - 5) {
delay(20);
reading = analogRead(RL_JOYSTICK);
}
dif = 200 - millis() + first;
if(dif <= 200 && dif >= 0) {
delay(dif);
}
//done
tone(SPEAKER_PIN,NOTE_E4);
delay(200);
noTone(SPEAKER_PIN);
delay(15);
tone(SPEAKER_PIN,NOTE_E4);
delay(200);
noTone(SPEAKER_PIN);
delay(15);
tone(SPEAKER_PIN,NOTE_E4);
delay(350);
noTone(SPEAKER_PIN);
}
void loop() {
int POTReading = analogRead(POT);
int toggle = digitalRead(TOGGLE);
int throttleValue = mapLimit(analogRead(THR_JOYSTICK) - THR_OFFSET,THR_MIN,THR_MAX - THR_OFFSET,0,ESC_OFFSET);
int yawValue = mapLimit(analogRead(YAW_JOYSTICK),YAW_MIN,YAW_MAX,ESC_OFFSET-ESC_MAX,ESC_MAX - ESC_OFFSET);
int rightLeftValue = mapLimit(analogRead(RL_JOYSTICK) - RL_OFFSET,RL_MIN,RL_MAX - RL_OFFSET,0,ESC_MAX - ESC_OFFSET);
int frontBackValue = mapLimit(analogRead(FB_JOYSTICK) - FB_OFFSET,FB_MIN,FB_MAX - FB_OFFSET,0,ESC_MAX - ESC_OFFSET);
int potValue = analogRead(POT);
int toggleValue = digitalRead(toggle);
//throttle
payload[0] = throttleValue >> 8 & 0xff;
payload[1] = throttleValue & 0xff;
//yaw
payload[2] = yawValue >> 8 & 0xff;
payload[3] = yawValue & 0xff;
//RL
payload[4] = rightLeftValue >> 8 & 0xff;
payload[5] = rightLeftValue & 0xff;
//FB
payload[6] = frontBackValue >> 8 & 0xff;
payload[7] = frontBackValue & 0xff;
//Pot
payload[8] = potValue >> 8 & 0xff;
payload[9] = potValue & 0xff;
//toggle
payload[10] = (byte) toggleValue;
//wake XBee
//digitalWrite(WAKE_PIN,LOW);
xbee.send(packet);
if(xbee.readPacket(500)) {
if(xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
xbee.getResponse().getZBTxStatusResponse(txStatus);
if(txStatus.getDeliveryStatus() != SUCCESS) {
//the remote XBee didn't ACK
tone(SPEAKER_PIN,NOTE_C4,100);
}
}
} else {
//error or something
tone(SPEAKER_PIN,NOTE_E4);
noTone(SPEAKER_PIN);
tone(SPEAKER_PIN,NOTE_E4,50);
}
//sleep XBee
//digitalWrite(WAKE_PIN,HIGH);
delay(100);
}
int mapLimit(int val, int fromLow, int fromHigh, int toLow, int toHigh) {
int result = map(val,fromLow,fromHigh,toLow,toHigh);
if(result > toHigh) {
result = toHigh;
} else if(result < -toHigh) {
result = -toHigh;
}
return result;
}