Pages: [1]   Go Down
Author Topic: serial.read() and pulseIn() not compatible?  (Read 1600 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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();
}
« Last Edit: January 20, 2011, 12:21:45 am by guysmilez » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12465
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Tillaart

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

actually after getting completely frustrated i started from square one.

i just used this basic code

Code:
#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.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 64
Posts: 6055
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: