GPS Synchronised Data Logging

30 Sep 2009

Hi,

I've been looking at a GPS synchronised data logger for a while using a Basic Stamp BS2PE, but got to the stage where  was running out of RAM and program space.  Also as a Linux user it is difficult get BS2 programming to work reliably.

I've spent quite a few hours transferring the Stamp program to the MBED and have been really pleased with how easy it is to use the MBED compiler from multiple computer platforms.

A bare-bones version of this program can be found here:

http://mbed.org/users/prf/published/f5c2b003ae38423640de0fc5e0727190/GPS_Logger_01.zip

Presently, it reads the time and date every second and if it the time is zero seconds it takes a sensor reading and prints it out.  It doesn't use the MBED GPS library because I needed the $GPRMC to supply time and date.  All the other data strings except $GPRMC are disabled.  Eventually, I would like to send the sensor data to a server via the LAN interface (but haven't worked out to telnet to a particular port using the MBED LAN interface!)

One really useful Stamp feature I find difficult to simulate with the MBED is the PBASIC SERIN command, I'd be really interested in hearing if anyone has any ideas in how to replicate this in C++.

30 Sep 2009 . Edited: 30 Sep 2009

Hi Peter,

Peter Foden wrote:
I've spent quite a few hours transferring the Stamp program to the MBED and have been really pleased with how easy it is to use the MBED compiler from multiple computer platforms

Glad you've been enjoying it. Always good to hear!

Peter Foden wrote:
One really useful Stamp feature I find difficult to simulate with the MBED is the PBASIC SERIN command, I'd be really interested in hearing if anyone has any ideas in how to replicate this in C++.

From what I remember, the SERIN and SEROUT commands in PBASIC are bit-bang/software emulated serial ports? If that is the case, the natural alternatives would be to use a real serial port (Serial), or I guess implement a bit-bang serial port (which is probably not too hard, but would require good testing to know it is solid); it is really just a Timer and a DigitalIn/DigitalOut assuming you don't want to go for really high speeds.

Could you potentially use a std serial port for your application? Or is there some function or flexibility the SERIN/OUT gives you that may be useful to recreate?

Simon

30 Sep 2009

Hi Simon,

Thanks for your reply.  I wasn't very clear about what functions in SERIN I wanted replicate.  I'm trying to talk to a Lantronix Xport, which can be made to behave much like a modem so responds to AT commands.  Speed is 9600 baud.

Firstly, what I'd like to simulate from the SERIN command is a variable time-out option that can be set to 'n' seconds, so that the serial read function does not hang waiting around for characters that don't arrive.  Secondly, the ability to look out for and react to command responses, such as 'CONNECT' or 'NO CARRIER' that come back from the modem.

My results so far have been unreliable trying to use the string compare routines. Sorry if this sounds pretty basic but its my first experience of using C++.

Pete

01 Oct 2009

While there is no built-in timeout functionality in the Serial class, you can use readable() method to check whether read() will block. So you could do something like this:

class MySerial: public Serial
{
public:
  MySerial(PinName tx, PinName rx, const char *name = NULL) : Serial(tx, rx, name) {};
  // reads a character, waiting for up to timeout ms
  // returns -1 in case of timeout
  // timeout: timeout in ms, -1 for infinite
  int getc( int timeout = -1 );
};

int MySerial::getc( int timeout )
{
  // if infinite timeout or we have a character, call base getc()
  if ( timeout == -1 || readable() )
    return Serial::getc();
    
  // no character yet  
  bool has_data = false;
  // count elapsed time
  Timer timer;
  timer.start();
  // loop until we have data or timeout elapses
  while ( !has_data && timer.read_ms() < timeout )
  {
    // wait a short time
    wait_ms(1);
    // check again
    has_data = readable();
  }
  // do we have anything?
  if ( has_data )
    // yes, read it
    return Serial::getc();
  else
    // no, timed out
    return -1;
};

MySerial pc(USBTX, USBRX);
...
// get a character using 1000ms timeour

int ch = pc.getc(1000);


For reading a string, you could use the scanf() function. However, it doesn't have a timeout version either, so you might need to write up something.

01 Oct 2009

Hi Igor,

Thanks - much appreciated!   That's a great help.

Peter