GPS Direction

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

GPS Direction

Post by bobulisk »

I purchased one of your GPS breakout boards (https://www.adafruit.com/products/746) and was wondering whether there was a way to tell one's direction in degrees. I am working on a rover that navigates to GPS waypoints and was going to sense direction by driving in one direction to tell whether one is moving further away or closer. Is there an easier way to find one's direction? Is it accurate and is a fix necessary?

If I use GPS.angle, is this accurate? Could it guide me to a waypoint?

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: GPS Direction

Post by adafruit_support_bill »

I believe what you want is track angle - your direction of movement relative to true north: http://forums.adafruit.com/viewtopic.ph ... 9&p=152481

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I can't see that topic (sorry), and I have one question that's a bit unrelated.

I am trying to read numbers from the serial port (later lat/lon). All the numbers display a "-38" after every piece of data. When I try to input a two digit number, they come up separately. Is there any way to have a two digit number stored by the arduino?

Code: Select all

void setup(){
  Serial.begin(9600);  
}

void loop(){

}


void serialEvent(){
  int coordData = Serial.read() - '0'; 
  Serial.println(coordData); 
}

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: GPS Direction

Post by adafruit_support_bill »

My mistake. Link fixed.

The -38 is the Line-Feed character (ASCII decimal 10) after you subtract the value of '0' (ASCII decimal 48).

To read multi-digit numbers: Start with a value of 0. Then for each new valid digit (you will need to screen out anything that is not between '0' and '9'), multiply your existing value by 10, then add the new digit. When you get to a non-digit characgter (such as the Line Feed), you are done.

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I can't seem to get it right. I've been trying to get this to work and I get really negative numbers - very strange.

Code: Select all

void serialEvent(){
  int counter = 1; 
  float incomingData[15]; 
  while(Serial.read() > 0){
    incomingData[counter] = Serial.read() - '0';
    incomingTotal += incomingData[counter] * pow(10, counter); 
    counter ++; 
  }
  Serial.println(incomingTotal); 
}

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I think I was over complicating it. New code:

Code: Select all

void serialEvent(){
  while (Serial.available()) {
    delay(10);
    if (Serial.available() >0) {
      char c = Serial.read();
      incomingData += c; 
    }
  }

  if (incomingData.length() >0) {
    Serial.println(incomingData); 
    incomingData="";
  }
}

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: GPS Direction

Post by adafruit_support_bill »

That's good. It is simpler to just echo the data if you don't need the values for computation,

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS Direction

Post by adafruit_support_rick »

Well, you've got several problems there.

First of all, your loop test, while (Serial.read() > 0), is going to read a character and throw it away. That means that the next line, incomingData[counter] = Serial.read() - '0'; will only see every other character.

I don't know what the data stream you're trying to parse looks like, so you may want a different loop test than I'm going to give you. My loop test assumes that you are just receiving a single number.

Next, as adafruit_support said, you have to test the characters you read to see if they are digits. You ONLY want to subtract '0' from characters that are between '0' and '9'. There will be other characters in the data stream, such as new lines, that are NOT part of the number you are trying to parse, and so you do NOT want to add them to incomingTotal.

You are not initializing incomingTotal, so you could be starting out with some random value in it.

You also don't need an array for incoming data, since you just add each digit to incomingTotal as it arrives, and never look at it again.

You don't need to use the pow function, either, since you can simply multiply incomingTotal by 10 every time you add a digit.

Code: Select all

void serialEvent(){
  char digit;
  int incomingTotal = 0;
  while(Serial.available() > 0)  //while there is something in the input buffer. 
  {                             //You will probably want something different, depending on your input data format.
    digit = Serial.read();       //read a character
    if ((digit >= '0') and (digit <= '9'))    //if the character is a numeric digit
    {
        incomingTotal = (incomingTotal * 10) + (digit - '0');   //shift current total, convert digit to integer and add
    }
  }
  Serial.println(incomingTotal); 
}

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

Thanks so much for your help. I have worked extensively in processing and there is a string.split(string name, anything to split around) function that makes it easy to convert comma separated data into an array. I can't seem to find the same function in arduino - does it exist?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS Direction

Post by adafruit_support_rick »

You've got the standard C libraries available to you on arduino. However, you are working with I/O, not strings. You could read chars into a string and process the the string later. Or, you could change the SerialEvent function to recognize commas:

Code: Select all

void readNumber()
{
  char digit;
  int incomingTotal = 0;
  bool complete = false;
  while(Serial.available()) && (!complete))  //while there is something to read, and we don't have a complete number yet
  {
    digit = Serial.read();       //read a character
    if ((digit >= '0') and (digit <= '9'))    //if the character is a numeric digit
    {
        incomingTotal = (incomingTotal * 10) + (digit - '0');   //shift current total, convert digit to integer and add
    }
    else   //the number is complete when we see a comma or a newline
    {
        complete = ((digit == ',') || (digit == '\n'));
    }
  }
  Serial.println(incomingTotal); 
}

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I'm still having troubles - sorry for the beginner problems. When I enter in numbers (new lines or comma separated), the Serial monitor puts each digit on a separate line - not combining them. How can I get them to be in one number?

Code: Select all

void serialEvent()
{
  char digit;
  int incomingTotal = 0;
  boolean complete = false;
  while(Serial.available() && (!complete))  {
    digit = Serial.read(); 
    if ((digit >= '0') and (digit <= '9')) {
      incomingTotal = (incomingTotal * 10) + (digit - '0');   //shift current total, convert digit to integer and add
    }
    else  if(digit == ',' || complete == '\n'){ //the number is complete when we see a comma or a newline{
      complete = true;
    }
  }
  Serial.println(incomingTotal);
}
Also, how can I input a decimal?

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I've gone through this code so many times and it won't work. I just can't get the arduino to read large numbers separated by commas.

Code: Select all

float inputData; 
int num1, num2; 
String incomingData; 

void setup(){
 Serial.begin(9600);  
}

void loop(){ 
}

void serialEvent(){
  inputData = 0; 
  boolean complete = false; 
  while (Serial.available()) {
    char c = Serial.read();
    if (!complete) {
      incomingData += c; 
    }
    if(c == '\n' || ','){
      char dataArray[incomingData.length() + 1]; 
      incomingData.toCharArray(dataArray, sizeof(dataArray)); 
      float n = atoi(dataArray);
      incomingData = "";  
      if(inputData == 0) {
        num1 = n;
      } 
      else if(inputData == 1){
        num2 = n; 
      }
      inputData ++; 

      Serial.print(num1);
      Serial.print(","); 
      Serial.println(num2);   
    }   
  }
}

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: GPS Direction

Post by adafruit_support_rick »

try this:

Code: Select all

if((c == '\n') || (c == ',')){
Also, you only want to print out num1 and num2 AFTER you have num2:

Code: Select all

      else if(inputData == 1){
        num2 = n; 
        Serial.print(num1);
        Serial.print(","); 
        Serial.println(num2);   
      }
      inputData ++; 

bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

It took a few hours to get here - and I think I'm close - but there is still a problem. It runs through serialEvent and returns a nonsense, incorrect reading the first time. Why does it not read the entire input in the function while(Serial.available >= 0) ?

Here is the entire code I'm using:

Code: Select all

float inputData; 
float num1, num2; 
String incomingData; 
String data1, data2; 
boolean set = false; 

void setup(){
  Serial.begin(9600);  
}

void loop(){ 
  if(set){
    data1.trim(); 
    data2.trim(); 
    char dataArray1[data1.length() + 1]; 
    char dataArray2[data2.length() + 1]; 
    data1.toCharArray(dataArray1, sizeof(dataArray1));
    data2.toCharArray(dataArray2, sizeof(dataArray2));
    num1 = atoi(dataArray1);
    num2 = atoi(dataArray2);
    Serial.println(num1); 
    Serial.println(num2); 
    delay(1000); 
  }
}

void serialEvent(){
  data1 = ""; 
  data2 = ""; 
  inputData = 0; 
  while (Serial.available() > 0) {
    char c = Serial.read();
    incomingData += c; 
  }
  char dataArray[incomingData.length()+1]; 
  incomingData.toCharArray(dataArray, sizeof(dataArray)); 
  for(int ii = 0; ii < incomingData.length()+1; ii++){
    if((dataArray[ii] == '\n') || (dataArray[ii] == ',')){
      inputData ++; 
    } 
    else {
      if(inputData == 0) {
        data1 += dataArray[ii];
      }
      else if(inputData == 1) {   
        data2 += dataArray[ii];    
      }
    }
  }
  set = true; 
}





bobulisk
 
Posts: 84
Joined: Tue Nov 02, 2010 7:29 am

Re: GPS Direction

Post by bobulisk »

I can now get it to accept 6 digit numbers (very important for my project - I'm using latitude and longitude). There is still a fairly large problem - when I divide the 6 digit number by a factor of ten, the Serial monitor prints only 0's to the right of the decimal place - 123456 becomes 12345.00. How can I get this to work?

Code: Select all

#include <stdlib.h> 
int inputData; 
unsigned long num1, num2; 
String incomingData; 
String data1, data2; 
boolean set = false; 

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if(set){
    char dataArray1[data1.length() + 1]; 
    char dataArray2[data2.length() + 1]; 
    data1.toCharArray(dataArray1, sizeof(dataArray1));
    data2.toCharArray(dataArray2, sizeof(dataArray2));
    num1 = atol(dataArray1);
    num2 = atol(dataArray2);

    Serial.print(num1/10000, 6);
    Serial.print(","); 
    Serial.println(num2/10000, 6); 
    delay(1000); 
  }
}

void serialEvent(){
  set = false; 
  data1 = ""; 
  data2 = ""; 
  inputData = 0; 
  while (Serial.available() > 0) {
    char c = Serial.read();
    incomingData += c; 
  }
  char dataArray[incomingData.length()+1]; 
  incomingData.toCharArray(dataArray, sizeof(dataArray)); 
  for(int ii = 0; ii < incomingData.length()+1; ii++){
    if((dataArray[ii] == '\n') || (dataArray[ii] == ',')){
      inputData ++; 
    } 
    else {
      if(inputData == 0) {
        data1 += dataArray[ii];
      }
      else if(inputData == 1) {   
        data2 += dataArray[ii];    
      }
    }
  }
  set = true; 
}


Is this a problem with the Serial monitor? Is the arduino thinking it is a decimal number but only printing 0s after the decimal?

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”