Show Posts
Pages: [1] 2 3 ... 6
1  Using Arduino / Programming Questions / Re: Validating incoming GPS data on: December 20, 2011, 02:50:03 pm
There's a simple explaination for that... I'm a bl00dy idiot!

Thanks for that I've just made the change and processed 5000 records without a glitch - it's amazing what a 2nd pair of eyes will do!

P.S. I think you've just broken your (already very good) record for posting a solution.

Cheers
2  Using Arduino / Programming Questions / Validating incoming GPS data on: December 20, 2011, 02:32:57 pm
I'm having trouble with what should be a simple bit of code to validate GPS sentences on a MEGA.

First some background.... GPS units generate a NMEA 'sentence' containing navigation data (position, speed, altitiude etc), the last two bytes (after the asterix) are checksum validation codes that can be used to confirm that no data has been corrupted.

This code has a very simple function, it reads the GPS sentences from port 1, calculates the checksum validation codes and compares them with the transmitted validation code and then sends the sentence to the screen. The problem is that about 10% of the records don't get validated correctly. I've worked out that the issue seems to be because the case statement that processes each GPS character as it's recieved is occasionally missing the "$" character that indicates the start of a new record.

Heres' the code (much of it cribbed from TinyGPS in case it looks familiar)....

Code:

char _nmea_checksum[2+1];          // NMEA sentence checksum (last two characters after the asterix)
char _nmea_rec[100+1];             // NMEA record (aka sentence)
byte _parity;
unsigned long _good_recs;          // Number of records that pass checksum validation
unsigned long _bad_recs;           // Number of records that fail checksum validation
bool _sentence_comp;               // Set to true once the end of a a NMEA sentence is detected
byte _term_offset;                 // pointer indicating how far along a NMEA sentence the process is.                 


void setup()
{
  Serial.begin(115200);            // Baud rate for screen
 
  Serial.println("##################################################################");
  Serial.println("####################     START     ###############################");
  Serial.println("##################################################################");
 
  Serial1.begin(57600);          // Baud rate for GPS unit
}

void loop() {
 
  if (Serial1.available())
  {
    Serial.print(Serial1.read(), BYTE);
  }
 
  //Check that there's data waiting to be read
  while (Serial1.available())
  {
    //process current byte from the logger
    if (processGpsChar(Serial1.read()))
    {
      //return true;
    }
  }
}


bool processGpsChar(char c)
{
  // Firstly, check for possible corruption.
  // NMEA data should (I think) be limited to 0-9, A-Z and the following punctiation .,$* (and of course a space, carriage return and line feed)
  if ( (c>=48 && c<=57) || (c>=65 && c<=90) || (c>=42 && c<=46) || c==36 || c==32 || c==10 || c==13  )
  {
    // The character recieved from the GPS is VALID, display it
    Serial.print(c);
  }
  else
  {
    // Invalid character
    Serial.println("ERROR - Received unexpected ascii code <%d> from GPS");
    Serial.print("ERROR - Received unexpected ascii code <");Serial.print(c);Serial.println("> from GPS");
  }

  // Read in NMEA sentences one character at a time.
  switch(c)
  {
  case '\r': 
    //Linefeed - ignore this
    break;
  case '\n': 
    //Carriage return - marks the end of a record
    //Check that the record is valid, if it is then
    //process it.
    // Check that the buffer hasn't overflowed
    if ( strlen(_nmea_rec) > 100 )
    {
      Serial.print("ERROR - NMEA record too long");
    }
   
    byte checksum2;
   
    // Convert the transmitted checksum from a two digit string to a decimal.
    checksum2 = 16 * from_hex(_nmea_checksum[0]) + from_hex(_nmea_checksum[1]);

    Serial.print("nmea_checksum=<");Serial.print(_nmea_checksum);
    Serial.print(">, checksum2=<");Serial.print(checksum2,DEC);
    Serial.print(">, parity=<");Serial.print(_parity,DEC);Serial.println(">");

    //Check the calculated checksum (_parity) matches the transmitted checksum (checksum2).
    if (checksum2 == _parity)
    {
      _good_recs++;       // increment the good record counter
      Serial.print("-Y-");
    }
    else
    {
      _bad_recs++;       // increment the bad record counter
      Serial.print("-N-");
    }
   
    // display the calculated checksum plus the good and bad record count
    Serial.print(_nmea_checksum);Serial.print("-");Serial.print(_good_recs);Serial.print("-");Serial.println(_bad_recs);
    break;   
  case '*':
    // This marks the end of the NMEA sentence, and the begining of the
    // validation characters.
    if (_term_offset < sizeof(_nmea_rec))
    {
      _nmea_rec[_term_offset] = 0;  //put a null terminator at the end of the string
    }
    _sentence_comp = true;          // Flag the fact that the NMEA sentence is now complete
    _term_offset = 0;               // reset the pointer, it can now be used to populate the checksum
    break;
  case '$': // Start of record
    Serial.println("nmea_start");
    // Flush the stuff that needs flushing
    nmea_start();
    break;
  default :
    //any other character.
    if (_sentence_comp == false)
    {
      //If the sentence is incomplete, add the character to the end of the current sentence
      if (_term_offset < sizeof(_nmea_rec) - 1)
      {
        _nmea_rec[_term_offset] = c;
        _nmea_rec[_term_offset+1] = 0;
        _term_offset++;
      }
      // The parity check is a bitwise XOR of all characters received so far.
      _parity = _parity ^ c;   //bitwise exclusive OR
    }
    else
    {
      // The sentence IS complete, so these characters must be part of the checksum
      if (_term_offset < 2)
      {
        // this character must be part of the checksum
        _nmea_checksum[_term_offset++] = c;
      }
    }
    break;
 }

 //return false - indicates a character returned, but the sentence is still incomplete
 return false;
}

void nmea_start(void)
{
  // flushes and resets stuff when a new record starts
  _parity = 0;               // reset the parity checker
  _nmea_checksum[0] = 0;     // Reset the checksum
  _nmea_checksum[1] = 0;
  _nmea_checksum[2] = 0;
  _sentence_comp = false;    // reset the flag for detecting the end of the sentence
  _term_offset = 0;          // reset the pointer
}


int from_hex(char a)
{
  // Returns 0-9 for an input of '0'-'9' and 10-15 for an input of 'A'-'F'
  if (a >= 'A' && a <= 'F')
    return a - 'A' + 10;
  else if (a >= 'a' && a <= 'f')
    return a - 'a' + 10;
  else
    return a - '0';
}
 


And here are some examples of correctly processed records as they appear on the screen…
Quote
$nmea_start
GPGLL,,,,,184219.340,V,N*7A
nmea_checksum=<7A>, checksum2=<122>, parity=<122>
-Y-7A-1-1
$nmea_start
GPGSA,A,1,,,,,,,,,,,,,,,*1E
nmea_checksum=<1E>, checksum2=<30>, parity=<30>
-Y-1E-2-1
$nmea_start
GPGSV,1,1,00*79
nmea_checksum=<79>, checksum2=<121>, parity=<121>
-Y-79-3-1
Each NMEA record starts with the “$”, then the record itself gets displayed along with some variables.

Here’s and example of a record that has failed the checksum validation….
Quote
$GPGGA,184221.940,,,,,0,0,,,M,,M,,*49
nmea_checksum=<49>, checksum2=<73>, parity=<50>
-N-49-61-13

The big difference  (apart from it not working!) is the absence of “nmea_start” between the “$” and the rest of the sentence. This seems to indicate an issue with the case statement in my code, if the start of the sentence isn’t recognized, then the various variables don’t get reset properly and the sentence fails validation .

My first guess was that there was interfacing issue between the GPS module and the Mega, but since the GPS data is being correctly displayed on the screen, then it must be getting read successfully, therefore the problem must be with my code.

Any suggestions? 

The GPS unit is a Locosys LS20031 http://www.sparkfun.com/products/8975 connected to a Mega2560.
3  Using Arduino / Storage / Re: SD card breakout board on: November 08, 2011, 04:29:10 pm
I've just found this on one of Ladyada's pages....

Quote
There is a small power supply on the board for generating 3.3V @ 250mA. We don't use the 'built in' 3.3v regulator on the Arduino because its only guaranteed up to 50mA and some SD card need a lot of power when writing. This supply is nice and steady, we can use it as an analog reference too! We have two sets of bypass caps to try and keep both 5V and 3.3V supply nice and clean - the 100uF ones are for the low frequency noise and 0.1 for higher frequency
I guess that explains the reason for not using the 3.3v supply from the motherboard.
4  Using Arduino / Storage / Re: SD card breakout board on: November 08, 2011, 09:06:39 am
Thanks Paul,

Either I've misunderstood what's happening, or I haven't explained my issue clearly. The SD breakout boards' Vcc pin takes power from the arduino 5v pin and feeds this to a 3.3v regulator on the breakout board, which then goes straight to pad 4 on the SD card (Vcc 3.3v).

The data/control pins (MISO,SCK,SS and MOSI) go straight from the arduino to the SD card via various resistors to drop the voltage. (I'm not suggesting I can do without these).

What I am saying is do I really need the 3.3 v regulator, capacitors, diodes and resistors from the breakout board when all they do is provide 3.3 volts to pad 4 on the card? Can't I just use the 3.3 volt source on the arduino?

Hope this clarifies the question.
5  Community / Website and Forum / New 'PCB fabrication' forum? on: November 08, 2011, 07:18:41 am
Is there scope for a new arduino forum here to discuss PCB fabrication and related issues? I'm thinking of the following sort of stuff....
  • CAD pcb design software (eagle / gerber etc)
  • PCB fabrication methods - Photographic techniques and toner transfer.
  • Etching
  • Soldering
I know we've got the general electronics section, but to my thinking thats more of R & D forum rather than manufacturing.

Probably not the right place to make this suggestion.

Ducking my head below the parapet........
6  Using Arduino / Storage / SD card breakout board on: November 08, 2011, 07:00:28 am
Hi,

I've been using the SD card breakout board supplied by cutedigi....
http://www.cutedigi.com/product_info.php?products_id=4435
It's worked fine on a breadboard, but I'm now trying to make a mega shield with a SD card onboard. The breakout board comes with an SD card holder plus half a dozen extra components, from what I can make out these extra components are only there to provide 3.3 volts to the card. Does anyone know if this is correct? I think I only need to include the card holder on my shield, and there's no need for these extra components, I think can just use the 3.3v supply from the board, again does anyone know if this is correct?

If I am correct on all counts, then why does the breakout board use these extra components, is it designed for for prototyping non-arduino systems, or does it date from a time before arduinos had a 3.3v supply?

Regards
7  Using Arduino / General Electronics / Re: PCB fabrication forum on: November 07, 2011, 03:10:51 pm
Quote
What questions do you have?   I make my own boards at home all the time
Ok, here's the issue, I'm using the toner transfer process, after ironing most of the toner seems to transfer ok, so I dunk the board in hot water and start removing the paper. Most of the paper comes off ok, but it seem that the paper fibres actually attached to the toner prefer to stick to the toner rather than wash off. I'm using a toothbrush to remove the paper, but anything more than a gentle scrubbing and the toner comes off the board, if I don't scrub then a few tiny paper fibres remain sticking to the toner and the tracks end up blurred. First question, why is the toner not sticking very well to the board - is the iron not hot enough, am I not pressing hard enough, or not pressing for long enough? Second question, is there any paper where the fibres don't end up sticking to the toner? I seem to have gone through most of the staples product line, but to no avail. I've also tried a couple of glossy 'photo quality' papers but when I use these the paper seems to melt and stick to the pcb along with the toner! (if I turn the temperature down the toner doesn't transfer). I've also tried one of the press 'n' peel systems http://www.maplin.co.uk/press-n-peel-pcb-transfersystem-13464?c=froogle&u=13464&t=module but these seem to be only slightly better and at £20 for 5 sheets it ain't cheap!
Before starting I clean the boards with an abasive block, then accetone, then dry them. I'm having so little luck with the toner transfer process, I'm thinking of biting the bullet and buying/making a UV light box instead.

Cheers
8  Using Arduino / General Electronics / TTL and RS232 voltage levels. on: November 07, 2011, 02:17:19 pm
I know that this question pops up now and again, but can someone please refresh my memory on what an arduino can and can’t talk to directly on the serial and serial 2,3 & 4 ports?

I’m looking at a couple of GPS modules  LS20031 &  LS20032 (http://www.sparkfun.com/datasheets/GPS/Modules/LS20030~3_datasheet_v1.0.pdf). The LS20031 uses TTL voltage levels, I think this mean it can be plugged directly to an arduino port, is this correct? The LS20032 uses RS232 and therefore needs to go through a MAX232 level converter (or something similar). Is this correct?

Thanks
9  Using Arduino / General Electronics / Re: PCB fabrication forum on: November 06, 2011, 03:09:03 pm
Thanks for the suggestions guys, I've since discovered that there's a yahoo group forum called 'Homebrew_PCBs' which seems pretty active.
10  Using Arduino / General Electronics / PCB fabrication forum on: November 05, 2011, 07:00:52 am
Hi,

This might be a little-off topic, but does anyone know where to go to discuss PCB fabrication? I've reached the stage in my project where I want to move from a breadboard to my own PCB. I've made my own pcbs in the past using the photoresist/UV light/etching process and I've just started again using the laserjet toner-transfer method.

I've got some questions and issues to discuss, but the few forums I can find seem to be very infrequently visited.

I guess a lot of arduino users also build their own boards? Where do you go to discuss pcb fabrication issues.

Cheers
11  Using Arduino / Audio / Re: Noise level detector on: October 31, 2011, 03:34:44 pm
Thanks - I understand the need to keep the voltage within the 0-5volt range, but where could a negative voltage come from on the pre-amp circuit?

Good point about sound being logarithmic I forgot that. Cheers
12  Using Arduino / Audio / Noise level detector on: October 31, 2011, 01:02:02 pm
Hi, I’m about to start on what I hope will be a pretty simple project. I want to build an arduino based noise level sensor. I’m not interested in analyzing what the noise is, just whether it’s loud or quiet. (basically, I’m just trying to detect if a particularly loud item of machinery is functioning or not).

I’m trying to find out if I need an ‘envelope follower’ (and if I do, what is it?). There are several posts on this subject, but I’m still unclear on what it’s for. It sounds like it’s basically just a ‘sound averager’ that will give an output proportional to the ambient noise level, is this correct?

Can’t I just get a cheap electret microphone, connect it to a pre-amp (for example, this one…http://www.sparkfun.com/products/8872) and then wire the output of that pre-amp to one of the analogue input pins on an arduino and then use the analogueRead() function to decide how noisy it is?

Won’t this do what I need? Or is it more complicated than that?

Thanks
13  Using Arduino / Programming Questions / Re: Unique processor identifier? on: October 30, 2011, 03:26:45 am
Thanks guys - looks like the one wire solution will best meet my needs in the long term. In the short term, since my devices include an SD card I think I'll add a file to each card that contains a unique ID - although that still relies on me slotting the correct card into the correct arduino!

World Series? isn't that named after the bloke who established it, rather than being a reference to who it's open to?

Cheers
14  Using Arduino / Programming Questions / Unique processor identifier? on: October 29, 2011, 10:52:33 am
Hi,

Is there any form of unique Identifier on an arduino mega processor (something that can be accessed programatically) ? I want to build a dozen identical arduino units, each running the same software, but each with a different ID. At the moment I change a single line in my code each time I upload, but this relies on me remembering to make the change, and loading the right ID into the correct arduino. I guess what I'm looking for is something like this....
if serial_number = 1234 then
    ID = A
if serial_number = 5678 then
    ID = B
etc etc.....

Any suggestions?

Regards
15  Using Arduino / Project Guidance / Re: anti-tamper circuit for Arduino Mega on: March 05, 2011, 05:19:01 am
Thanks guys, lots of good ideas.

The device in question is a gps data logger designed for long-distance cycling. The requirements are the organisers, not mine. I think it's overkill, but the idea is that the data integrity needs to be guaranteed whilst the device is on and logging, and the device integrity needs to be guaranteed even when the device is powered down. The main power for the device is external, I could add an extra internal button cell just for the anti-tamper circuit, but then I'd have to add circuitry to charge it.

The data being written to the SD card is encoded, the idea is that every time the device is powered up it will check if it's been tampered with, and write the results of that check (in an encrypted format) to the SD card. So long as no-one works out how to write encoded data to the card themselves then the data should be secure.

The use of low power sleep mode looks good - I wasn't aware the arduino had this option, I'll do some research on this. Thanks
Pages: [1] 2 3 ... 6