problem with receiver and gyro

Hello! I am a bit of a newbie here, and fairly new to programming anything at all, so I’ll try not screw this up. I decided to try build a quadcopter using an arduino micro and an arduIMU gyro. I probably should have just bought an off the shelf thing, but where is the fun in that? I wrote two short programs. The first one was to read the incoming channel values from my RC receiver. The program worked, but they were a bit choppy sometimes, so I decided to do a rolling average of five values. This also worked fine.
I wrote a second program to get the pitch and roll values from my IMU. I’m using the arduIMU v3. Like I said, I’m a newbie to all this stuff, and I initially thought I could just plug that into my arduino and use it like I would a sensor. Instead, I wound up using the serial from the IMU to send the pitch and roll to the arduino using parseFloat. This program also worked pretty much fine. The problems started happening when I tried to combine these two sketches together into one.
When I try run the receiver and IMU together in one sketch the pitch and roll values go nuts. Not quite random, but they tend to jump around from high to low even if the IMU is sitting flat on the desk. I eventually discovered that if I comment out the RC channel inputs in the loop (ch1 = pulseIn(A2, HIGH, 25000); and so forth) the IMU values go back to normal. If those four lines are removed, the IMU works fine.
My first guess is that there is something about pulseIn that is screwing with the parseFloat values. Beats me…
My second guess is that it has something to do with multiplying and dividing things by big numbers like 20000.
I did this because, from what I understand, the map function only works as integers. I was trying to save all those decimal places and divide them up later. I’ll post the code below. Anybody got any comments or ideas? Other than making me sit in the dunce chair :slight_smile:

#include <Servo.h>

const int numReadings = 5; //average input values setup//
int readings1[numReadings];   
int readings2[numReadings];
int readings3[numReadings];
int readings4[numReadings];

int index1 = 0;
int index2 = 0;
int index3 = 0;
int index4 = 0;

int total1 = 0;
int total2 = 0;
int total3 = 0;
int total4 = 0;

float average1 = 0; 
float average2 = 0; 
float average3 = 0; 
float average4 = 0;  //average input values setup//

int ch1; // channel rc values//
int ch2;
int ch3;
int ch4;  // channel rc values//

Servo motor1;
Servo motor2;
Servo motor3;
Servo motor4;

float fwdrev;  // I named these weird thing because//
float yawlr;   // pitch and roll were used already // 
float sideroll;

///////////////////////////////////////////////////////
                    ///imu setup//
const int NUMBER_OF_FIELDS = 2; // how many comma-separated fields we expect
int fieldIndex = 0;             // the current field being received

float pitch;  //pitch and roll//
float roll;

float p1;  //pos and neg mapped pitch//
float p2;  //pos and neg mapped pitch//

float r1;  //pos and neg mapped roll//
float r2;  //pos and neg mapped roll//
////////////////////////////////////////////////////////////
        ////end imu setup/////

void setup(){
 
Serial.begin(115200); // Initialize serial port //
Serial1.begin(115200); //read incoming//

motor1.attach(9);
motor2.attach(6);
motor3.attach(5);
motor4.attach(3);

pinMode(A1, INPUT); // set rc channels as input//
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT); // set rc channels as input//
}

void loop()
{

ch1 = pulseIn(A2, HIGH, 25000); //attach rc channels//
ch2 = pulseIn(A1, HIGH, 25000); 
ch3 = pulseIn(A3, HIGH, 25000);
ch4 = pulseIn(A4, HIGH, 25000);  //attach rc channels//

//channel 1//
total1= total1 - readings1[index1]; // subtract the last reading//
readings1[index1] = ch1;  // read next value//
total1= total1 + readings1[index1]; //add value//
index1 = index1 + 1;  // advance to the next position//

if (index1 >= numReadings) 
index1 = 0; //wrap around//
average1 = total1 / numReadings; //average//

average1= map(average1,970,2020,800,1200);
fwdrev=average1/1000;  //pitch variable//
//channel 1//

//channel 2//
total2= total2 - readings2[index2]; // subtract the last reading//
readings2[index2] = ch2;  // read next value//
total2= total2 + readings2[index2]; //add value//
index2 = index2 + 1;  // advance to the next position//

if (index2 >= numReadings) 
index2 = 0; //wrap around//
average2 = total2 / numReadings; //average//
average2= map(average2,970,2020,800,1200);
yawlr=average2/1000;  //yaw variable//
//channel 2//

//channel 3//
total3= total3 - readings3[index3]; // subtract the last reading//
readings3[index3] = ch3;  // read next value//
total3= total3 + readings3[index3]; //add value//
index3 = index3 + 1;  // advance to the next position//

if (index3 >= numReadings) 
index3 = 0; //wrap around//
average3 = total3 / numReadings; //average//
//channel 3//

//channel 4//
total4= total4 - readings4[index4]; // subtract the last reading//
readings4[index4] = ch4;  // read next value//
total4= total4 + readings4[index4]; //add value//
index4 = index4 + 1;  // advance to the next position//

if (index4 >= numReadings) 
index4 = 0; //wrap around//
average4 = total4 / numReadings; //average//
average4= map(average4,970,2020,800,1200);
sideroll=average4/1000;
//channel 4//

////////////////////////////////////////////////////////
                 ////imu loop////
                 
if( Serial1.available()) {
    for(fieldIndex = 0; fieldIndex  <= 2; fieldIndex ++)
    {
     roll = Serial1.parseFloat(); // get a numeric value
     pitch = Serial1.parseFloat();
     
if (pitch > 30000) pitch=30000;
if (pitch < -30000) pitch=-30000;   

if (roll > 30000) roll=30000;
if (roll < -30000) roll=-30000; 
 
}}

p1 = map(pitch, -30000, 30000, 24000 ,16000);
p1=(p1/20000);  
p2=1-(p1-1);

r1 = map(roll, -30000, 30000, 24000 ,16000);
r1=(r1/20000);  
r2=1-(r1-1);
 
////////////////////////////////////////////////
///////end imu loop//////////




Serial.print(fwdrev);
Serial.print("   ");
Serial.print(yawlr);
Serial.print("   ");
Serial.print(average3);
Serial.print("   ");
Serial.print(sideroll);
Serial.print("  /////  ");

Serial.print(pitch );
Serial.print("  ");
Serial.println(roll);

My first guess is that there is something about pulseIn that is screwing with the parseFloat values.

No. Taking time to measure the RC pulses does not affect serial data coming in. What it DOES do is cause the data coming in to overflow the serial buffer, result in random characters being dropped.

You need to measure one channel, collect any serial data, measure another channel, collect any serial data, etc. Notice I said collect, NOT use parseFloat().

When you have data that is a complete packet (whatever that means in terms of delimiters), THEN you parse it.