Loading...
  Show Posts
Pages: 1 2 3 [4] 5 6 ... 16
46  Using Arduino / Programming Questions / Re: GPS logger works fine...as long as the serial data coming in isn't valid on: January 20, 2013, 09:25:05 pm
I took your advice and started pairing back the instructions and found that it works fine if I just take out the last mytok call in this section of code:

Code:
if(strcmp(messageID, "GPGGA") == 0)
  {
    ptr = mytok(time, ptr);
    ptr = mytok(latit1, ptr, '.'); //get the first half of latitude
    ptr = mytok(latit2, ptr); //get the second half of latitude
    ptr = mytok(NS, ptr);
    ptr = mytok(longit1, ptr, '.');
    ptr = mytok(longit2, ptr);
    ptr = mytok(EW, ptr);
    ptr = mytok(fixindicator, ptr);
    ptr = mytok(satsUsed, ptr);
    ptr = mytok(HDOP, ptr);
    ptr = mytok(MSLalt, ptr);
    ptr = mytok(Geoid, ptr);
    ptr = mytok(GeoUnits, ptr); //works fine if I take this out

I also am handling the NULL pointer in the mytok function by just doing this:

Code:
ptr = mytok(time, ptr); if(ptr == NULL) {Serial.println("Out1"); return;}
    ptr = mytok(latit1, ptr, '.'); if(ptr == NULL) {Serial.println("Out2"); return;}//get the first half of latitude
    ptr = mytok(latit2, ptr); if(ptr == NULL) {Serial.println("Out3"); return;}//get the second half of latitude
    ptr = mytok(NS, ptr); if(ptr == NULL) {Serial.println("Out4"); return;}
    ptr = mytok(longit1, ptr, '.'); if(ptr == NULL) {Serial.println("Out5"); return;}
    ptr = mytok(longit2, ptr); if(ptr == NULL) {Serial.println("Out6"); return;}
    ptr = mytok(EW, ptr); if(ptr == NULL) {Serial.println("Out7"); return;}
    ptr = mytok(fixindicator, ptr); if(ptr == NULL) {Serial.println("Out8"); return;}
    ptr = mytok(satsUsed, ptr); if(ptr == NULL) {Serial.println("Out9"); return;}
    ptr = mytok(HDOP, ptr); if(ptr == NULL) {Serial.println("Out10"); return;}
    ptr = mytok(MSLalt, ptr); if(ptr == NULL) {Serial.println("Out11"); return;}
    ptr = mytok(Geoid, ptr); if(ptr == NULL) {Serial.println("Out12"); return;}
    //ptr = mytok(GeoUnits, ptr); if(ptr == NULL) {Serial.println("Out13"); return;}

Thanks for your help!  Now if I can just figure out why the GPS is telling me that I am about 200 yards from my actual position and walking out in the middle of the water(at least according to google maps).

These are the coordinates from a short walk I took....uploaded them into google maps and apparently I can walk on water:

Code:
40.689712,-74.115570
40.689708,-74.115562
40.689701,-74.115539
40.689689,-74.115524
40.689689,-74.115516
40.689685,-74.115501
40.689682,-74.115486
40.689666,-74.115463
40.689659,-74.115447
40.689659,-74.115432
40.689655,-74.115417
40.689643,-74.115402
40.689640,-74.115379
40.689640,-74.115364
40.689640,-74.115348
40.689632,-74.115333
40.689628,-74.115310
40.689620,-74.115295
40.689609,-74.115272
40.689598,-74.115249
40.689586,-74.115226
40.689579,-74.115211
40.689571,-74.115196
40.689563,-74.115180
40.689559,-74.115165
40.689563,-74.115173
40.689579,-74.115196
40.689586,-74.115219
40.689594,-74.115242
40.689598,-74.115257
40.689605,-74.115264
40.689609,-74.115287
40.689613,-74.115303
40.689620,-74.115318
40.689628,-74.115333
40.689632,-74.115356
40.689636,-74.115379
40.689640,-74.115402
40.689647,-74.115432
40.689655,-74.115455
40.689659,-74.115478
40.689666,-74.115501
40.689682,-74.115509
40.689689,-74.115531
40.689697,-74.115554
40.689701,-74.115570
40.689704,-74.115600
40.689716,-74.115608
40.689723,-74.115623
40.689735,-74.115646
40.689743,-74.115661
40.689750,-74.115676
40.689762,-74.115684
40.689769,-74.115707
40.689777,-74.115722
40.689788,-74.115737
40.689796,-74.115760
40.689807,-74.115768
40.689815,-74.115791
40.689830,-74.115798
40.689838,-74.115806
40.689842,-74.115806
40.689842,-74.115791
40.689849,-74.115783
40.689853,-74.115776
40.689857,-74.115768
40.689865,-74.115760
47  Using Arduino / Programming Questions / GPS logger works fine...as long as the serial data coming in isn't valid on: January 20, 2013, 07:49:07 pm
Feeling so close yet so far.  As the data comes in I am parsing it, pulling the latitude and longitude data out and converting it to a decimal format before printing it out to the serial port.  Eventually it will be written to an sd card (as 1000's have done before me I'm sure).  The problem is, as long as the data coming in is invalid, the program behaves as expected.  As soon as the GPS spits out some valid data, the program processes it and then stops reading any additional data from the GPS.  I know that the GPS is still transmitting because if I reset the micro controller I get one valid line of data before it freezes up again.  I threw in a line of code at the top of my looping function just to see if the controller was freezing up completely and it doesn't, i.e. it still prints out the string at the top of the loop even though it isn't processing any more of the incoming data from the GPS.  Can someone spot my problem because I am at a loss?  My program is below:

Code:
#include <SoftwareSerial.h>

SoftwareSerial softSerial(4,5); //receive on pin 4 and transmit on pin 5

byte START_CMD[] = {
                    0xA0,
                    0xA2,
                    0x00,
                    0x18};
byte NMEA_SET[] = {
                  0x81,
                  0x02,
                  0x01, //GGA
                  0x01, //check sum
                  0x00, //GLL 
                  0x00, //check sum
                  0x00, //GSA
                  0x00, //check sum
                  0x00, //GSV
                  0x00, //check sum
                  0x01, //RMC
                  0x01, //check sum
                  0x00, //VTG
                  0x00, //check sum
                  0x00, //MSS
                  0x00, //check sum
                  0x00, //EPE
                  0x00, //check sum
                  0x00, //ZDA
                  0x00, //check sum
                  0x00, //unused
                  0x00, //unused
                  0x12, //baud in hex high byte
                  0xC0}; //baud in hex low byte

volatile int state = 0;
boolean sentenceBegins = false;
char buffer[90];
int index = 0;
const byte wakePin = 3;
const byte Control = 2;
const byte On_Off = 7;
char messageID[6];
char time[11];
char latit1[5];
char latit2[5];
char NS[2];
char longit1[6];
char longit2[5];
char EW[2];
char fixindicator[2];
char satsUsed[3];
char HDOP[4];
char MSLalt[10];
char Units[2];
char Geoid[6];
char GeoUnits[2];
char GPSstatus[2];
char GPSspeed[8];
char GPScourse[7];
char Date[7];
char Dummy[12];
boolean sdfileOK = false;





void setup()
{
  Serial.begin(115200);
  softSerial.begin(4800);
 
  pinMode(wakePin,INPUT);  //GPS Wakeup Pin
  pinMode(Control,INPUT);  //Control Button
  pinMode(On_Off,OUTPUT); //GPS ON/OFF Pin
  digitalWrite(On_Off,LOW);
  digitalWrite(Control,HIGH);
 
  ADCSRA = 0; //disable ADC as we don't need it
 
  //configure GPS to transmit GGA and RMC data only

  Serial.println("Waking GPS");
  //wake up GPS unless it is already awake
  while(!GPSisAwake())
  {   
    digitalWrite(On_Off, HIGH);
    delay(200);
    digitalWrite(On_Off, LOW);
  }
 
    Serial.println("GPS is awake!");
    Serial.println("Switching to Binary");
    //set to binary mode
    softSerial.println("$PSRF100,0,4800,8,1,0*0F");
    delay(100);
   
    //set back to NMEA mode with GGA and RMC messages active
    Serial.println("Switching to NMEA");
    for(int x=0; x<4; x++)
    {
      softSerial.write(START_CMD[x]);
    }
   
    for(int x = 0; x<24; x++)
    {
      softSerial.write(NMEA_SET[x]);
    }
   
    softSerial.write(highByte(calc_check()));
    softSerial.write(lowByte(calc_check())); 
    softSerial.write(0xB0);
    softSerial.write(0xB3);
     
}

void loop()
{
  if(checkforSentence())
  {
    //Serial.println("Sentence Found");
    //Serial.println(buffer);
    Process_message();

  }
}


boolean GPSisAwake()
{
 
  //check to see if GPS is already awake by purging serial data and then
  //checking to see if Serial data is still coming in
  while(softSerial.available()) softSerial.read();
  delay(1200);
  if(softSerial.available()) return true;
  return false;
}

boolean checkforSentence()
{
  char c;
  while(softSerial.available())
  {
    c = softSerial.read();
   
    if(sentenceBegins && c == '\r') //we have a full sentence
    {
      sentenceBegins = false;
      return true;
    }
   
    if(sentenceBegins) //store characters to buffer
    {
      buffer[index] = c;
      index++;
      buffer[index] = '\0';
    }
   
    if(c == '$') //beginning of sentence...start saving to buffer
    {
      sentenceBegins = true;
      index = 0;
    }
   
  }
  return false;
}

int calc_check()
{
  byte msglen = sizeof(NMEA_SET);
  byte index = 0;
  int checksum = 0;
  while(index<msglen)
  {
    checksum+=NMEA_SET[index++];
    checksum&=(0x7FFF);
  }
  return checksum;
}

const char* mytok(char* pDst, const char* pSrc, char sep = ',')
{
    while ( *pSrc )
    {
        if ( sep == *pSrc )
        {
            *pDst = '\0';

            return ++pSrc;
        }

        *pDst++ = *pSrc++;
    }

    *pDst = '\0';

    return NULL;
}


void Process_message()
{
  const char*     ptr;
 
  //check message ID to see what kind of message we got
  ptr = mytok(messageID, buffer);
 
  //if it is GGA, read in the data and write to SDCard if
  //the data is valid and an SD file has been created
  if(strcmp(messageID, "GPGGA") == 0)
  {
    ptr = mytok(time, ptr);
    ptr = mytok(latit1, ptr, '.'); //get the first half of latitude
    ptr = mytok(latit2, ptr); //get the second half of latitude
    ptr = mytok(NS, ptr);
    ptr = mytok(longit1, ptr, '.');
    ptr = mytok(longit2, ptr);
    ptr = mytok(EW, ptr);
    ptr = mytok(fixindicator, ptr);
    ptr = mytok(satsUsed, ptr);
    ptr = mytok(HDOP, ptr);
    ptr = mytok(MSLalt, ptr);
    ptr = mytok(Geoid, ptr);
    ptr = mytok(GeoUnits, ptr);
   
    float f, GPSdegrees, fminutes, fseconds, latdecCoords, longdecCoords;
   
    //convert latitude to GPS Decimal format
    f = atof(latit1);
    f /= 100.00;
    GPSdegrees = (int)f; //isolate degrees
    fminutes = (f - (int)f) * 100;
    //float fminutes = (int)(temp); //isolate minutes
    fseconds = atof(latit2)/100.00; //isolate seconds
    latdecCoords = GPSdegrees + (((fminutes * (60.0)) + fseconds)/3600.0);
    if(NS[0] == 'S') latdecCoords *= -1.0;
   
    //cconvert longitude to GPS decimal format
    f = atof(longit1);
    f /= 100.00;
    GPSdegrees = (int)f; //isolate degrees
    fminutes = (f - (int)f) * 100;
    fseconds = atof(longit2)/100.00; //isolate seconds
    longdecCoords = GPSdegrees + (((fminutes * (60.0)) + fseconds)/3600.0);
    if(EW[0] == 'W') longdecCoords *= -1.0;
   
   
   
    Serial.print(latdecCoords, 6);
    Serial.print(",");
    Serial.println(longdecCoords,6);
  }

}

and this is what the output looks like:

Code:
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
...lots more lines of 0.00000 here deleted for space
0.000000,0.000000
0.000000,0.000000
0.000000,0.000000
40.689670,-74.115737
Waking GPS             //This is where I tried a few resets with no luck
GPS is awake!
Switching to Binary
Switching to NMEA
40.689731,-74.115287
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689811,-74.115303
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689834,-74.115661
Waking GPS
GPS is awake!
Switching to Binary
Switching to NMEA
40.689792,-74.115745
48  Using Arduino / Programming Questions / Re: Floating point math issues....last significant digit not what I expected on: January 20, 2013, 11:28:23 am
Thanks everyone for the great explanations.  Quick and easy fix in my code was to separate the digits before and after the decimal using the decimal as the delimiter and then working the math on each section individually.  Works perfect now!
49  Using Arduino / Programming Questions / Floating point math issues....last significant digit not what I expected on: January 20, 2013, 09:54:26 am
Hello!  Given the following code:

Code:
char latit[10] = {"4041.2358"};  //Degrees = 40, Minutes = 41, Seconds = 23.58
Serial.print("latit = ");
Serial.println(latit);

float flatit = atof(latit);
Serial.print("flatit = ");
Serial.println(flatit, 6);

flatit /= 100.00;
Serial.print("flatit = ");
Serial.println(flatit, 6);

float flatitdegrees = (int)flatit; //isolate degrees
float temp = (flatit - (int)flatit) * 100;
float fminutes = (int)(temp); //isolate minutes
float fseconds = (temp - fminutes) * 100; //isolate seconds

Serial.print("Degrees = ");
Serial.println(flatitdegrees);
Serial.print("Minutes = ");
Serial.println(fminutes,2);
Serial.print("Seconds = ");
Serial.println(fseconds, 2);

I get an output that looks like this:

Code:
latit = 4041.2358
flatit = 4041.235839
flatit = 40.412357
Degrees = 40.00
Minutes = 41.00
Seconds = 23.57

Can someone help me to understand what is going on with those last significant digits?
50  Using Arduino / Programming Questions / Re: Trouble manipulating comma delimited strings on: January 20, 2013, 07:49:51 am
Oh my....lloyddean!!!......that just works FANTASTIC!!!  And as a bonus, for once I can actually understand what you did there.  That is exactly what I was trying to do.  Thank you so much!!! And thank you everyone else for all of the great suggestions, all of which were incorporated in one way or another into my sketch.
51  Using Arduino / Programming Questions / Re: Trouble manipulating comma delimited strings on: January 20, 2013, 07:46:12 am

I was originally going to use strtok but I read on one of the other forum threads that a known issue with strtok is that if you have empty fields it can screw it up so "data,data,data,,,data,data,,,,data" could have problems.  I also had a hard time figuring out how to store the various tokens for future use.  I'm not very good with pointers.....often to my detriment.
52  Using Arduino / Programming Questions / Re: Trouble manipulating comma delimited strings on: January 20, 2013, 12:01:35 am
what does it say when you try to compile ?

If it fails to compile,  it means you have a syntax error rather than a logical error with what you
are trying to do. 

It is usually a good idea to have the definition or declaration of the function,  before you try to use it.
But this does not seem to be always necessary.

This is the error messages that I get:
Code:
sketch_jan18a.cpp: In function 'void loop()':
sketch_jan18a:25: error: 'mytok' was not declared in this scope
sketch_jan18a.cpp: In function 'int mytok(const char*, int, char, char*)':
sketch_jan18a:36: error: default argument missing for parameter 4 of 'int mytok(const char*, int, char, char*)'
sketch_jan18a:39: error: lvalue required as left operand of assignment
53  Using Arduino / Programming Questions / Trouble manipulating comma delimited strings on: January 19, 2013, 11:43:49 pm
I am trying to make my own string tokenizer and I am failing miserably.  Its a GPS parsing problem.  I have my sample code below but I can't get it to compile.  I am horrible with pointers and I have a feeling that is where the problem is.  Can someone help me to work my way through this please?

Code:
char buffer[] = "GPGGA,205952.987,4041.2358,N,07406.5601,W,1,05,1.9,12.1,M,-34.2,M,,0000*5C";
char messageID[6];
char time[11];
char latit[10];
char NS[2];
char longit[11];
char EW[2];
char fixindicator[2];
char satsUsed[3];
char HDOP[4];
char MSLalt[10];
char Units[2];
char Geoid[6];
char GeoUnits[2];



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

void loop()
{
int idx = 0;
idx = mytok(buffer, idx, ',', &messageID);
idx = mytok(buffer, idx, ',', &time);
idx = mytok(buffer, idx, ',', &latit);
idx = mytok(buffer, idx, ',', &NS);
idx = mytok(buffer, idx, ',', &longit);
idx = mytok(buffer, idx, ',', &EW);
idx = mytok(buffer, idx, ',', &fixindicator);
idx = mytok(buffer, idx, ',', &satsUsed);
  
}

int mytok(const char *str, int idx = 0, char sep = ',', char *target)
{
    
      while(str[idx] != sep) target++ = str[idx++];

      return idx+1;
}
54  Using Arduino / Programming Questions / Re: Checking if a device is transmitting serial data before taking an action? on: January 19, 2013, 10:43:16 am
Now see.....this is why I love this forum!  Thanks both of you for the solution to this!
55  Using Arduino / Programming Questions / Checking if a device is transmitting serial data before taking an action? on: January 19, 2013, 07:44:31 am
I have a GPS module that you can cycle between "active" and "hibernate" mode by giving a 200ms pulse on its "ON/OFF" pin.  It transmits data once per second when it is "active" and doesn't transmit any data when it is in "hibernate" mode.  The only way for me to know which state it is in is to see if it is transmitting data so for instance, when I am ready to start receiving location data i will need to toggle the "ON/OFF" pin but first I want to check and make sure that it isn't already active or else my pulse is just going to turn it off instead of on.  Likewise when I go to put it into "hibernate" mode I want to be sure that it isn't already in "hibernate" mode or else my pulse is going to inadvertently turn it on.  I wrote some code to try to check this because in my mind I need to first empty out the Serial buffer, wait a bit more than a second, and then check to see if any Serial data has come in.  I would like some guidance on the most reasonable way to do this.  My attempt at it is below.

Code:
boolean GPSisAwake()
{
  //check to see if GPS is already awake by purging serial data and then
  //checking to see if Serial data is still coming in
  while(softSerial.available()) softSerial.read();
  delay(1200);
  if(softSerial.available()) return true;
}
56  Using Arduino / General Electronics / Re: Serial.end and SoftwareSerial.end - does it clear the character buffer? on: January 19, 2013, 07:34:39 am
Code:
while(Serial.available()>0) Serial.read();

Thanks!  I have a follow up question but it is long so I will put it in its own thread under the Programming forum. 
57  Using Arduino / General Electronics / Serial.end and SoftwareSerial.end - does it clear the character buffer? on: January 18, 2013, 09:21:52 pm
I have a need to start off with an empty character buffer so that subsequent calls to Serial.read only returns new information.  If I call Serial.end and then Serial.begin(4800) again, does that give me an empty character buffer?
58  Using Arduino / Project Guidance / Re: Charging 3.7v 165mAh LiPo battery on: January 17, 2013, 10:18:46 pm
You can put together a simple circuit using something like this:

http://ww1.microchip.com/downloads/en/DeviceDoc/21984e.pdf
59  Using Arduino / Project Guidance / Re: Schematic review before sending PCB to be made on: January 17, 2013, 06:08:10 am
Quote
Basically I just need someone to take a look at the voltage regulator and LiPo charger circuits on the right hand side of the schematic and tell me if anything looks off about it.  Thanks in advance for your assistance!
I reviewed this part, compared it to data sheets and it looks OK.
Do you want to put optional pads for 2 resistors on FB & Vout (63001)

Thanks Larry for providing a second set of eyes for me!

Quote
Do you want to put optional pads for 2 resistors on FB & Vout (63001)

For this application I am just using a fixed voltage of 3.3V, however I was going to make a few extra standalone voltage regulators using the TPS63000 which is the adjustable voltage version. 
60  Using Arduino / Project Guidance / Re: Schematic review before sending PCB to be made on: January 16, 2013, 10:26:26 pm
I can't really breadboard it because the parts are tiny little SON-10 packages for the 3.3V regulator and SOT-23 package for the charger circuit.  I have designed the PCB to look as close as possible to the sample layouts in the data sheet.
Pages: 1 2 3 [4] 5 6 ... 16