I have managed to send potentiometer data wirless from one arduino to another using xbee series 1s. I used a method where I store the incoming ascii values in an array and then use atoi to convert the value back to an integer (i think there was a thread about it on here somewhere).
However I am now trying to implement this with my main code (controlling 4 motors to move a camera, using PWM/PPM) and I am having problems achieveing communication again, I believe it is due to me overflowing the buffer of only 128bytes, as I can only process the incoming data from the sender only every 10ms or so (as while im creating the pulse train the program can do nothing).
My code for the arduino sending potentiometer value (working):
int sensorPin = 0; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
// declare the ledPin as an OUTPUT:
Serial.begin(9600); // set up Serial library at 9600 bps
}
void loop() {
// read the value from the sensor:
sensorValue = analogRead(sensorPin);
// send value
Serial.print("<");
Serial.print(sensorValue);
Serial.print(">");
delay(5);
}
My code for receiver (working), just basic communication to prove im getting data:
#define LEDPIN 13
char inData[10];
int index;
int inInt;
boolean started = false;
boolean ended = false;
void setup() {
// Serial port enable
Serial.begin(9600);
}
void loop()
{
while(Serial.available() > 0)
{
char aChar = Serial.read();
if(aChar == '<')
{
started = true;
index = 0;
inData[index] = '\0';
}
else if(aChar == '>')
{
ended = true;
}
else if(started)
{
inData[index] = aChar;
index++;
inData[index] = '\0';
}
}
if(started && ended)
{
// Convert the string to an integer
int inInt = atoi(inData);
Serial.println(inInt);
if ( inInt > 500) {
digitalWrite(LEDPIN, HIGH);
} else if ( inInt < 500) {
digitalWrite(LEDPIN, LOW);
}
// Get ready for the next time
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
Implemented in main code (just trying to change throttle now):
#define LEDPIN 13
char inData[10];
int index;
int inInt;
boolean started = false;
boolean ended = false;
int Throttlepot; // Ana In raw var - 0->1023
int Throttleoffset; // Ana In var - 0->1023 compensated
int Throttledelay = 750; // Ana In Ch.2 uS var - Throttle
int Fixed_Delay = 300; // PPM frame fixed LOW phase
int pulseMin = 750; // pulse minimum width minus start in uS
int pulseMax = 1700; // pulse maximum width in uS
float DualrateMultThr = 0.9; // Dual rate mult
int DualrateAdjThr = 0; // Dual rate mid adjustment
int outPPM = 10; // digital pin 10
ISR(TIMER1_COMPA_vect) {
ppmoutput(); // Jump to ppmoutput subroutine
}
void setup() {
Serial.begin(9600) ; // Test
pinMode(outPPM, OUTPUT); // sets the digital pin as output
// Setup timer for 22ms
TCCR1A = B00110001; // Compare register B used in mode '3'
TCCR1B = B00010010; // WGM13 and CS11 set to 1
TCCR1C = B00000000; // All set to 0
TIMSK1 = B00000010; // Interrupt on compare B
TIFR1 = B00000010; // Interrupt on compare B
OCR1A = 22000; // 22ms
OCR1B = 1000;
}
void ppmoutput() { // sub for ppm/pwm output for motors
// 1st channel
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(1225); // Hold for x microseconds
// Channel 2
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(1225); // Hold for x microseconds
// Channel 3 - Throttle
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(Throttledelay); // Hold for Throttledelay microseconds
// Channel 4
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(1225); // Hold for x microseconds
// Channel 5
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(1700); // Hold for x microseconds
// Channel 6
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH);
delayMicroseconds(750); // Hold for x microseconds
// Synchrochronisation pulse width
digitalWrite(outPPM, LOW);
delayMicroseconds(Fixed_Delay); // Hold
digitalWrite(outPPM, HIGH); // Start Synchro pulse, interuppted by timer
}
void loop() { // Main loop to recieve wireless data from pots
while(Serial.available() > 0)
{
char aChar = Serial.read();
if(aChar == '<')
{
started = true;
index = 0;
inData[index] = '\0';
}
else if(aChar == '>')
{
ended = true;
}
else if(started)
{
inData[index] = aChar;
index++;
inData[index] = '\0';
}
}
if(started && ended)
{
// Convert the string to an integer
int Throttlepot = atoi(inData);
// offset if needed
Throttleoffset = map(Throttlepot, 0, 1023, 0, 1023) + 0; // Throttle
// Map analogue inputs to PPM rates for each of the channels
Throttledelay = (Throttleoffset * DualrateMultThr) + pulseMin + DualrateAdjThr;
// Check limits
if (Throttledelay <= 750) Throttledelay = 750; // Min
if (Throttledelay >= 1700) Throttledelay = 1700; // Max
Serial.println(Throttlepot);
DualrateMultThr = 0.9;
DualrateAdjThr = 0;
// Get ready for the next time
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
When I implement it in the main code nothing happens, the communciation just drops. If you notice on the sender code I have put a delay of 5ms after sending each value. At first this was at 500ms just so I could see values easier and make it easy for me to see whether communication is working. Now I realise that this is needed as if I remove it, communication fails (presumabely something to do with the serial buffer?)
Does anyone have any ideas on how to deal with this, should I be looking at using higher or lower baud rates, trial and error with delay time, or changing code structure all together?
Thanks for any help