Go Down

Topic: need help understanding a while loop problem (Read 623 times) previous topic - next topic

fbriggs4

I am using a breadboard 328P with the breadboard boot loader. I use an internal 8mhz clock and IDE 1.0. I have a GPS connected using software serial with the GPS TX connected to pin5. I am attempting to collect GPS data from the soft serial line and send the data over the main UART for testing. I created a super simple while loop that will run forever just to test things. My problem is that all I get is junk data. However, if I run a while loop inside of a while loop I can get the proper NMEA data from the GPS and it works perfectly. So all of my code works perfectly but I don't understand why I get junk if I run everything in a single loop. is this a weird quirk or do I not understand something about the while loop? Any insights are appreciated.

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial mySerial(5, 6); // RX, TX

int test = 1; //dummy variable to keep the while loop going

void setup() 
{
  // Open serial communications
  Serial.begin(9600);

  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);

  //turns on the transistor for power to the GPS
  pinMode(A2, OUTPUT);
  digitalWrite(A2, LOW);

  //toggles the on/off pin of the GPS to turn in it on
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  delay(20);
  digitalWrite(9, LOW);

  Serial.println("GPS power is on");
 
  delay(1000); //gives time for the GPS to power up 

}

void loop()
{
  //this works perfectly and gives proper NMEA data
  while(test == 1){
    while (mySerial.available()){
      Serial.write(mySerial.read());
  }
  }
   
 
//this gives only junk output, why?
//  while (test == 1){
//    Serial.write(mySerial.read());
//  }
}
 

SurferTim

Code: [Select]
//this gives only junk output, why?
//  while (test == 1){
//    Serial.write(mySerial.read());
//  }
}

You are not waiting for characters to arrive, so normally the read() function will return integer -1. That is the "funny ÿ". Is that the junk you are getting? Like this?
ÿÿÿÿÿÿÿÿÿÿÿ

fbriggs4

SurferTim- yes, exactly like that. Is creating a while loop inside of a while loop an appropriate way to deal with this? If not what is a better way to handle it?

SurferTim

You don't need the "while(test == 1)" loop. The loop() function does that for you. Like this should be fine:
Code: [Select]
void loop()
{
  //this works perfectly and gives proper NMEA data
    while (mySerial.available()){
      Serial.write(mySerial.read());
    }
}

That way it only reads when characters are available.

fbriggs4

thanks for the help, that is exactly what I needed!

MarkT

read() is non-blocking, so you must test available() for each character you read without fail.  Cleanest way to achieve reliable code is to write a blocking version and use it:
Code: [Select]

char my_blocking_read ()
{
 while (!mySerial.available ())
 {}
 return mySerial.read() ;
}

...

 while (t == 1)
 {
   Serial.write (my_blocking_read ()) ;
 }
...

or something like that.  You can still test available() to decide whether to read of course.
[ I won't respond to messages, use the forum please ]

Go Up