Pages: 1 [2]   Go Down
Author Topic: Bathymetry Measuring Apparatus  (Read 1995 times)
0 Members and 1 Guest are viewing this topic.
Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

It's a cool project you have here, i'm looking forward to hear how it goes.
I'm a noob myself, still tinkering with blinking LED's and motors.

I just have a thought regarding the issue logging the data simultaneously.
The question might more be to the guys following the thread with some more experience.

Would it be possible to take a time stamp from the GPS NMEA sentence and stamp the transducer data with it? then you would have a latency from the equipment.
Many GPS systems can output more than one sentence at once (GGA, GGL, ZDA(time and data as i recall), ect.)
I'm sure it will involve some advanced programming if its possible.

Just putting it out there smiley
Logged

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

This guy has done something very similar to my project:

http://letsmakerobots.com/node/21098

He gives his sketches but they are way different than what I have been putting together. I asked him about the logging data simultaneously problem and he kinda shrugged it off like it wasn't really as big of a deal as I made it out to be.
Logged

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can argue that it really depends on what the collected data is used for, if its just for fun or you actually have to use the data for serious purposes.
I have been working with Multibeam echosounders for a couple of years, here the latency of all instruments is of high importance, but here you also have gyro and motion sensor, so if one sensor is off by a second the result bad.

What rate does the transducer send data with compared to the GPS?

It might be worth to think about the accuracy of your GPS, compared to your speed, and the transducer "latency" during logging.
If the GPS has an accuracy of a few meters or more, how much do you gain in data quality from a correct logging time?
I must note, i dont know what systems you are using, so you might have far better accuracy if you are using an argumentation system.
see http://www.gps.gov/systems/gps/performance/accuracy/

 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

strange coincidence - I am working on exactly the same problem.

I am using a GPS module that transmits NMEA 0183 and is mounted on a data logger shield

http://www.ladyada.net/make/gpsshield/

I can get this to work no problem with the code "supplied" with the unit - https://github.com/adafruit/SD-Basic-GPS-logger/blob/master/SD_GPSLogger.pde. I am using an UNO so am using softwareserial for communication.

I also have a depth sounder that transmits NMEA 0183 data - a Garmin Intelliducer. I can connect it to the arduino and with a very slight modification of the gps program (get it to look for the appropriate NMEA string for depth instead of gps) I can log the data from the depth sounder. I did have to run the output of the depth transducer through an inverter but that was no big deal.

So, I then thought to define two softwareserial ports, one for gps and one for depth and alternately poll them. I have tried many iterations and versions of this but basically cannot get two softwareserial ports to alternate reliably.

Any clever folks out there with a solution? Will share all code once we get it working nicely

Thanks,

Peter
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 51
Posts: 3438
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

From the documentation for SoftwareSerial.listen:
Quote
Only one software serial port can listen at a time; data that arrives for other ports will be discarded. Any data already received is discarded during the call to listen() (unless the given instance is already listening).

Could this be your problem? If not, it's time to post your code.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

i have messed around with the port.listen() to no avail.

Code

I started with a working program that read on a single port and logged the data to a SD card. I did the following.

Anticipating I would need a few functions to get the gps and depth data, I

1) declared a void function getgps() and moved all the code from the original program that read and logged the gps data to that function
2) called the function getups() from the main program

I run this and and it works just fine - logs the gps data

Wanting to make sure I could read the depth sounder ok I
3) connected the depth sounder to the pin the gps had been connected to
4) modified getgps to look for a NMEA depth string instead of a gps string
5) run this and it works just fine - logs the depth data

So, thinking if I declare two software serial ports, I will be good to go, I create a void function getdepth() which is identical to get gps except it looks for a depth NMEA string and it looks on a different serial port. I also modify getgps() so it is looking for GPS data again.

To create the second serial port i do the following
Code:
#if ARDUINO >= 100
 SoftwareSerial gpsSerial =  SoftwareSerial(2, 3);
 SoftwareSerial depthSerial =  SoftwareSerial(7, 8); // add a port for the depth sounder
#else
 NewSoftSerial gpsSerial =  NewSoftSerial(2, 3);
 NewSoftSerial depthSerial =  NewSoftSerial(7, 8);  // add a port for the depth sounder
#endif

// Set the GPSRATE to the baud rate of the GPS module. Most are 4800
// but some are 38400 or other. Check the datasheet!

#define GPSRATE 4800
#define DEPTHRATE 4800  // added this for the depth sounder

a little farther along we "start" the serial ports

Code:
gpsSerial.begin(GPSRATE);
 depthSerial.begin(DEPTHRATE);

and then in the main loop we call the void functions
Code:
getgps();
getdepth();
When I run this program I only get depth data

If I switch the order of the begin statements to
Code:
depthSerial.begin(DEPTHRATE);
 gpsSerial.begin(GPSRATE);
I only get gps data.

I tried adding listen commands as follows
Code:
gpsSerial.listen();
getgps();
depthSerial.listen();
getdepth();
I get mostly nothing but occasionally I get an error message from wither getgps or getdepth that is related to a checksum failure or a buffersize problem.

If I tell it to wait after I start listening like this
Code:
gpsSerial.listen();
delay(10000);
getgps();
depthSerial.listen();
delay(10000);
getdepth();
i get nothing at all

pretty much stumped. appreciate any help!

Full code attached. Please note that for testing purposes, I am using two gps modules as my depth sounder is attached to the boat which is a little tricky to get in to the lab.

Peter


* SD_GPSlogger_modified.ino (5.24 KB - downloaded 3 times.)
« Last Edit: March 29, 2013, 06:49:43 am by jenkin507 » Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 51
Posts: 3438
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Without the two key routines it's hard to say what's wrong. Do they share any buffer to accumulate NMEA sentences?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Below is the one routine

the other is identical except it calls depthserial in stead of gps serial and it looks for the appropriate NMEA string.

buffer is global and used by both...

p

Code:
void getgps() {
 
  char c;
  uint8_t sum;

Serial.println("getgps");

  // read one 'line'
  if (gpsSerial.available()) {
    c = gpsSerial.read();
#if ARDUINO >= 100
    //Serial.write(c);
#else
    //Serial.print(c, BYTE);
#endif
    if (bufferidx == 0) {
      while (c != '$')
        c = gpsSerial.read(); // wait till we get a $
    }
    buffer[bufferidx] = c;

#if ARDUINO >= 100
    //Serial.write(c);
#else
    //Serial.print(c, BYTE);
#endif
    if (c == '\n') {
      //putstring_nl("EOL");
      //Serial.print(buffer);
      buffer[bufferidx+1] = 0; // terminate it

      if (buffer[bufferidx-4] != '*') {
        // no checksum?
        Serial.print("g*");
        bufferidx = 0;
        return;
      }
      // get checksum
      sum = parseHex(buffer[bufferidx-3]) * 16;
      sum += parseHex(buffer[bufferidx-2]);

      // check checksum
      for (i=1; i < (bufferidx-4); i++) {
        sum ^= buffer[i];
      }
      if (sum != 0) {
        //putstring_nl("Cxsum mismatch");
        Serial.print("g~");
        bufferidx = 0;
        return;
      }
      // got good data!

      gotGPRMC = strstr(buffer, "GPRMC");
      if (gotGPRMC) {
        // find out if we got a fix
        char *p = buffer;
        p = strchr(p, ',')+1;
        p = strchr(p, ',')+1;       // skip to 3rd item
       
        if (p[0] == 'V') {
          digitalWrite(led1Pin, LOW);
          fix = false;
        } else {
          digitalWrite(led1Pin, HIGH);
          fix = true;
        }
      }
      if (LOG_RMC_FIXONLY) {
        if (!fix) {
          Serial.print('_');
          bufferidx = 0;
          return;
        }
      }
      // rad. lets log it!
     
      Serial.print(buffer);    //first, write it to the serial monitor
      Serial.print('#');
     
      if (gotGPRMC)      //If we have a GPRMC string
      {
        // Bill Greiman - need to write bufferidx + 1 bytes to getCR/LF
        bufferidx++;

        digitalWrite(led2Pin, HIGH);      // Turn on LED 2 (indicates write to SD)

        logfile.write((uint8_t *) buffer, bufferidx);    //write the string to the SD file
        logfile.flush();
        /*
        if( != bufferidx) {
           putstring_nl("can't write!");
           error(4);
        }
        */

        digitalWrite(led2Pin, LOW);    //turn off LED2 (write to SD is finished)

        bufferidx = 0;    //reset buffer pointer

        if (fix) {  //(don't sleep if there's no fix)
         
          if ((TURNOFFGPS) && (SLEEPDELAY)) {      // turn off GPS module?
         
            digitalWrite(powerPin, HIGH);  //turn off GPS

            delay(100);  //wait for serial monitor write to finish
            sleep_sec(SLEEPDELAY);  //turn off CPU
 
            digitalWrite(powerPin, LOW);  //turn on GPS
          } //if (TURNOFFGPS)
         
        } //if (fix)
       
        return;
      }//if (gotGPRMC)
     
    }
    bufferidx++;
    if (bufferidx == BUFFSIZE-1) {
       Serial.print("g!");
       bufferidx = 0;
    }
  } else {

  }
 
 
 
 
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

declared separate buffers for the two routines- no change

p
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 51
Posts: 3438
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That getgps routine is designed to be called multiple times in the course of reading a gps sentence. It builds up the string in the buffer until it sees a end of line and then parses it. The problem is that as you are switching between soft serial ports, there is opportunity to miss data. You need to restructure this so that you listen on one serial port until you have a complete sentence ($ to '\n') and then you can parse it. Then switch to the other serial port and repeat.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

WildBill,

I think you have hit the nail on the head. I tried this on a mega with separate buffers for each and it works perfectly.

I am thinking that to make this work on the uno, i could instead declare getups() as an int and have it return 1 when it gets a full sentence and then call it

while(getgps() != 1);

make sense?

This will half my data acquisition rate - on the mega using hardware serial  I get pairs of fixes separated by the approx 1 second xmit rate of the NMEA units

Really really appreciate your input!

Geoguy - the NMEA depth sounder is not too expensive - about $170 - so you may wish to consider using it. Once I get some nice code working (either uno or mega) I will share.

Best wishes for this fine long weekend!

Peter
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 51
Posts: 3438
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think in your position, since you have a Mega, I'd just use it and be done. Do you need to get the Uno version working?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bill,

Got both working.

The advantage/attraction of the UNO is I have the GPS data-logging shield all ready to go - it has the SD card and the GPS module integrated in to the shield. And, I also have the data-logging program for the SD card.

I do have a shield kit for the mega and another SD card so maybe will go with that. However, it will only gain me a factor of 2 in my data rate.

Once again, much appreciation for your insights and suggestions!

Peter
Logged

Pages: 1 [2]   Go Up
Jump to: