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: 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: 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: 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: #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: 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
|
|
|
|
|
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: 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: 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: 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? 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; }
|
|
|
|
|
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. 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; }
|
|
|
|
|
59
|
Using Arduino / Project Guidance / Re: Schematic review before sending PCB to be made
|
on: January 17, 2013, 06:08:10 am
|
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! 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.
|
|
|
|
|