Hello!
My RC Plane project hit another obstacle. I have a setup like this,
XBee ZigBee S2 RF(wired antenna, they have promissed 120m outdoor range) modules connected to arduino via funduino XBee shields. They are setup as Point-to-point communication.
My Transmitter is a Mega2560 and Receiver is an Uno.
This is the code for Transmitter:
/* TX
* using elevons?
* have 2 servos for 2 elevons, ignore aileron.
*/
#define aileron 2
#define elevon 3
#define esc 4
#define elevontrim 0
#define ailerontrim 1
#define esctrim 5
#define signalLED 13
int ailerontrimVal,elevontrimVal,aileronVal,elevonVal,esctrimVal,escVal;
void setup()
{
Serial.begin(9600);//1152200 only 9600 works, check XBEE forum
pinMode(signalLED,OUTPUT);
}
void loop()
{
aileronVal = analogRead(aileron);
aileronVal = map(aileronVal, 0, 1023, 0, 179);
ailerontrimVal = analogRead(ailerontrim);
ailerontrimVal = map(ailerontrimVal, 0, 1023, -25, 25);
aileronVal = aileronVal+ ailerontrimVal;
constrain(aileronVal, 0, 179);
elevonVal = analogRead(elevon);
elevonVal = map(elevonVal, 0, 1023, 0, 179);
elevontrimVal = analogRead(elevontrim);
elevontrimVal = map(elevontrimVal, 0, 1023, -25, 25);
elevonVal = elevonVal+ elevontrimVal;
constrain(elevonVal, 0, 179);
escVal = analogRead(esc);
escVal = map(escVal, 0, 1023, 0, 179);
esctrimVal = analogRead(esctrim);
esctrimVal = map(esctrimVal, 0, 1023, -25, 25);
escVal = escVal+ esctrimVal;
constrain(escVal, 0, 179);
Serial.print("L");
Serial.print(aileronVal);
Serial.print("R");
Serial.print(elevonVal);
Serial.print("S");
Serial.print(escVal);
delay(10);
/*if(Serial.available())
{
if(Serial.read() == 1)
digitalWrite(signalLED,HIGH);
else
digitalWrite(signalLED,LOW);
}*/
}
This is the code for Receiver:
/* RX
* State machine
* 2 servos, esc. extend if a rudder is needed, currently using a servo for esc as well
*/
#include <Servo.h>
#define laileron 11
#define raileron 10
#define throttle 9
typedef enum{NONE,GOT_L,GOT_R,GOT_S} states;
Servo left,right,esc;
states state = NONE;
unsigned int currentValue;
unsigned long successfulMillis;
void setup()
{
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
Serial.begin(9600); //1152200 only 9600 works, check whats wrong
state=NONE;
left.attach(laileron);
right.attach(raileron);
esc.attach(throttle);
}
void processLeft(const unsigned int value)
{
left.write(value);
//Serial.print(1);
//delay(10);
}
void processRight(const unsigned int value)
{
right.write(value);
//Serial.print(1);
//delay(10);
}
void processEsc(const unsigned int value)
{
esc.write(value);
//Serial.print(1);
//delay(10);
}
void hanldlePreviousState()
{
switch(state)
{
case GOT_L:
processLeft(currentValue);
break;
case GOT_R:
processRight(currentValue);
break;
case GOT_S:
processEsc(currentValue);
break;
}
currentValue=0;
}
void processIncomingByte(const byte c)
{
if(isdigit(c))
{
currentValue *= 10;
currentValue += c-'0';
}
else
{
hanldlePreviousState();
switch(c)
{
case 'L': state=GOT_L;
break;
case 'R': state=GOT_R;
break;
case 'S': state=GOT_S;
break;
default: state=NONE;
}
}
}
void defaults()
{
left.write(90);
right.write(90);
esc.write(0);
digitalWrite(13,HIGH);
while(true);
}
/*void signalLossProtocol(int attempts)
{
if(Serial.available()<=0)
{
attempts++;
delay(500);
if(attempts<11)
signalLossProtocol(attempts);
else
{
defaults();
while(1>0);//exit(0); forum advices not to do so. check if works
}
}
}*/
void signalLossProtocol()
{
/*while(millis()-successfulMillis<5000)
{
if(Serial.available()>0)
return;
}*/
defaults();
}
void loop()
{
if(Serial.available()>0) //>0 not needed?
{
digitalWrite(13,LOW);
processIncomingByte(Serial.read());
successfulMillis = millis();
}
//else
if(millis()-successfulMillis>5000)
{
defaults();
while(true);
}
}
Please ignore my comments!
I have connected all the servos to the 5v pin and respective PwM pins at the receiver end (outdoor test done with only one servo).
I have POTs at the transmitter end wich sends the analog signal to the receiver.
I tested my setup like this. My friend took the receiver end while i was turning the POTs at the transmitter end. They work great at a close range but when my friend took the receiver longer than 15m the Servos start to turn at their will. even after he came close the servos does not respond. I had to kill the power to the transmitter and restart it again to get that to work even at the close range.
I thinks this could still be a programming issue (since they work at close range).
Am I using my delays correctly?
And i found out that if I don’t have enough power to the XBees they could loose the range too. how would i check the power coming to XBEE?