Go Down

Topic: serial.read() and pulseIn() not compatible? (Read 2048 times) previous topic - next topic

GuYSmileZ

Jan 19, 2011, 07:06 am Last Edit: Jan 20, 2011, 06:21 am by guysmilez Reason: 1
hey all my first post and it just so happens to be a problem im having. i have a arduino mega and a sparkfun 9DOF and a spektrum RC reciever.

im am reading  the serial from the sparkfun board just fine but then i add the pulseIn()'s for reading my spectrum RX and then it seems to not let me read the serial from the Sparkfun board. is there something im doing wrong ive google the forums and can find anyone else with this problem.

im thinking the problem is when reading the pulse's its taking too much time and not synching with the serial read from the sparkfun board.

anyone have any ideas or work around?

heres my code

Code: [Select]

#define TIMEOUT 100

// { roll, pitch, yaw }
float angles[3] = {0.0, 0.0, 0.0};

#include <Servo.h>
Servo motor1;
int pos = 0;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int pin8 = 8;
int pin9 = 9;
int pin10 = 10;
int pin11 = 11;

void setup() {
 Serial.begin(57600);
 Serial1.begin(57600);
 motor1.attach(8);
 pinMode(pin3, INPUT);
 pinMode(pin4, INPUT);
 pinMode(pin5, INPUT);
 pinMode(pin6, INPUT);
 pinMode(pin7, INPUT);
}

void loop() {
 int uGear, uYaw, uPitch, uRoll, uThrtl;

 uGear = pulseIn(pin3, HIGH);
 uYaw = pulseIn(pin4, HIGH);
 uPitch = pulseIn(pin5, HIGH);
 uRoll = pulseIn(pin6, HIGH);
 uThrtl = pulseIn(pin7, HIGH);
 
 read_9dofahrs();
   
 
//  Serial.print("Gear: ");
//  Serial.print(uGear);
//  Serial.print("Yaw: ");
//  Serial.print(uYaw);
//  Serial.print("Pitch: ");
//  Serial.print(uPitch);
//  Serial.print("Roll: ");
//  Serial.print(uRoll);
//  Serial.print("Throttle: ");
//  Serial.print(uThrtl); //throttle
//  Serial.println("");

 Serial.print(angles[0]);
 Serial.print(" | ");
 Serial.print(angles[1]);
 Serial.print(" | ");
 Serial.print(angles[2]);
 Serial.println("");
 
 pos = abs(angles[0]);
 //Serial.println(pos);
 

 motor1.write(pos);
}

char read_char() {
 unsigned long starttime = millis();
 do {
   if(Serial1.available() > 0)
     return((char)Serial1.read());
 } while((millis() - starttime) < TIMEOUT);
 return NULL;
}

void get_angles() {
 for(int n=0; n<3; n++) {
   char buffer[9];
   int received = 0;
   char ch;
   do {
     if((ch = read_char()) == NULL) return;
   } while(ch != ',' && ch != '\r' && (buffer[received++] = ch));  
   buffer[received] = '\0';
   angles[n] = atof(buffer);
 }
}

void read_9dofahrs() {
 char beginstr[6] = {'!','A','N','G','\:','\0'};
 for(int i=0; i<5; i++)
   if(read_char() != beginstr[i]) return;
 get_angles();
}

robtillaart

Welcome!
Please use the # button in the editor to encapsulate your code with the [ code] and [/code] tags.

PulseIn is a blocking call, it can wait quite a long time, and if there are more characters received that fit into the buffer they might get lost. Try to run your sketch with a lower serial speed e.g. 9600 Baud. If that works it is probably a bufferoverflow .

Rob
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

GuYSmileZ

actually after getting completely frustrated i started from square one.

i just used this basic code

Code: [Select]
#define TIMEOUT 100

// { roll, pitch, yaw }
float angles[3] = {0.0, 0.0, 0.0};



void setup() {
 Serial.begin(57600);
 Serial1.begin(57600);
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
 Serial.println("STARTING UP!!!");
}

void loop() {
 read_9dofahrs();

 Serial.print(angles[0]);
 Serial.print(" | ");
 Serial.print(angles[1]);
 Serial.print(" | ");
 Serial.print(angles[2]);
 Serial.println("");
 delay(100);
}


char read_char() {
 unsigned long starttime = millis();
 do {
   if(Serial1.available() > 0)
     return((char)Serial1.read());
 } while((millis() - starttime) < TIMEOUT);
 return NULL;
}

void get_angles() {
 for(int n=0; n<3; n++) {
   char buffer[9];
   int received = 0;
   char ch;
   do {
     if((ch = read_char()) == NULL) return;
   } while(ch != ',' && ch != '\r' && (buffer[received++] = ch));  
   buffer[received] = '\0';
   angles[n] = atof(buffer);
 }
}

void read_9dofahrs() {
 char beginstr[6] = {'!','A','N','G','\:','\0'};
 for(int i=0; i<5; i++)
   if(read_char() != beginstr[i]) return;
 get_angles();
}


now i put the delay in the code to imitate some pulse reads. with the delay the board resets without the code it works fine.

GuYSmileZ

with the delay code in and ur suggestion the baud rate doesnt seem to change also i cant change the baud rate from the sparkfun board otherwise it breaks

James C4S

If it is because the serial buffer is overflowing, why not just read the serial buffer more often?  Couldn't you just call your read function after each pulse-in?  The data doesn't really matter and only the last one is the one you do anything with anyway.

Alternatively, call Serial.flush() after each pulseIn.  (Or at least try to see if it resolves the problem.)

Another thing you my try.  Serial.println the value of millis() before your pulseIns and again after.  So you can measure how long that section of code is taking to run.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

GuYSmileZ

your right it is the buffer. the Serial.flush() is the route im going in it works great thanx all!

Go Up