This week we look at an easy GPS tracking unit using an Arduino and GPS shield.

Downloads

HD Apple HD Apple SD Audio MP3

Components:

Arduino Uno

GPS Shield from ITEAD Studios – http://imall.iteadstudio.com/im120417017.html

Datasheet:  ftp://imall.iteadstudio.com/IM120417017_Arduino_GPS_shield/DS_IM120417017_ArduinoGPSshield.pdf

TinyGPS Library – http://arduiniana.org/libraries/tinygps/

GPSVisualizer: http://www.gpsvisualizer.com/map_input?form=googleearth

For debugging, load a blank sketch on the Arduino, change the jumpers to 1 and 2, then use this software on Windows.

https://www.u-blox.com/en/evaluation-tools-a-software/u-center/u-center.html

Blank Sketch:
void setup(){}
void loop(){}

Code:


/**************************************************************
  Name      GPS_Shield_SDCard                                
  Author    Bob Powell 
            texanfromiowa@gmail.com
            Copyright (C) 2012-2014, Parallelus Automation, Inc.
          
  Date      Febuary 24, 2014    
  Modified  Febuary 24, 2014                               
  Version   1.0.0      
  Arduino   1.0.5
  
  Notes     This demo shows use of logging GPS data to an SD Card for later review.
  
            GPS Unit used: ITEAD GPS shield Model IM120417017
            
            Datasheet & : http://imall.iteadstudio.com/im120417017.html
 
            The jumper pins set for Arduino pin 3 for RX and pin 4 for TX, and 
            toggle switch set for 5V.  A 2gig SD card was used 
            
            The beginning of the program was taken from the TinyGPS "simple_test"
            example.
            
            
Legal Stuff:
============

            This program is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            at your option, any later version.
     
            This program is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            GNU General Public License for more details.
     
            You should have received a copy of the GNU General Public License
            along with this program.  If not, see <http://www.gnu.org/licenses/>.
   
     
Personal note:
==============

            If you do something interesting with this code, expand it, or just
            have a question, please email me at the address above.  

            I hope you find this example helpful.  Enjoy.

            Bob

****************************************************************/
#include <SoftwareSerial.h>
#include <SD.h>
#include <TinyGPS.h>


TinyGPS gps;
// The jumpers on the shield set to work with
// these pins, and can be changed if needed.
SoftwareSerial ss(2, 3);

// File for logging data
File rawdata;

/**************************************************************
Function: setup
Purpose:  set up Arduino
Args:     none
Returns:  nothing
Notes:    This function is required by the Arduino
***************************************************************/
void setup()
{
  
  // Serial monitor
  Serial.begin(9600);
  // baud rate for GPS - 38400 is prefered, but 4800 can also be used
  ss.begin(38400);
  
  // Comments from TinyGPS simple_test example
  Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  
  // Initialize card
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(10)) {
    Serial.println("...initialization failed!");
  }
  else
    Serial.println("...initialization done.");

}

/**************************************************************
Function: loop
Purpose:  loop funtion for Arduino
Args:     none
Returns:  nothing
Notes:    This function is required by the Arduino, and the 
          Arduino will loop through this function indefinately.
          
***************************************************************/
void loop(){
  
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // Open data file
  File rawdata = SD.open("rawdata.txt", FILE_WRITE);
  
  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
       // Send raw data to the terminal window
       Serial.write(c); 
       
       // Send raw data to the SD card
       if(rawdata)
         rawdata.write(c);
         
      if (gps.encode(c)) 
        newData = true;
    }
  }

  // Send manipulate data to the terminal window.
  /* 
  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }*/
  
  // Send a carriage return and close the file
  Serial.println("");
  rawdata.write("\r");
  rawdata.close();
  

}

16 x 16 Panel Source Code

#include <Adafruit_NeoPixel.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(256, PIN, NEO_GRB + NEO_KHZ800);                        
                          
uint32_t image_x2[257] = { 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
                          1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
                          0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,
                          0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
                          0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
                          0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,
                          0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
                          0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
                          0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
                          0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,
                          0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,
                          0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,
                          0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,
                          0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,
                          1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,
                          1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1 };
                          
prog_uint32_t PROGMEM image_check[257] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
                             0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
                             0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
                             0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,
                             0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,
                             0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,
                             0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
                             1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,
                             1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
                             1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,
                             0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,
                             0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
                             0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0 };
void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  //colorWipe(strip.Color(0, 0, 0), 1);
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 20); // Red
  colorWipe(strip.Color(0, 255, 0), 20); // Green
  colorWipe(strip.Color(0, 0, 255), 20); // Blue
  rainbow(20);
  rainbowCycle(20);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 2, 20, 200);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 3, 20, 200);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 4, 20, 200);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 5, 20, 200);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 255), 6, 20, 200);
  colorwalk2(strip.Color(255, 0, 0), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk2(strip.Color(100, 100, 0), strip.Color(0, 100, 100), 4, 20, 200);
  colorwalk2(strip.Color(10, 20, 0), strip.Color(20, 10, 0), 4, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), 2, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), 3, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), 4, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(0, 255, 255), 5, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(0, 255, 255), 6, 20, 200);
  colorwalk3(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(0, 255, 0), 4, 20, 200);
  colorwalk3(strip.Color(100, 100, 0), strip.Color(0, 100, 100), strip.Color(100, 0, 100), 4, 20, 200);
  colorwalk3(strip.Color(30, 50, 0), strip.Color(50, 30, 0), strip.Color(10, 50, 30),4, 20, 200);
  
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), strip.Color(0, 0, 0), 2, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), strip.Color(0, 0, 0), 3, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(0, 255, 255), strip.Color(0, 0, 0), 5, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(0, 255, 255), strip.Color(0, 0, 0), 6, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(0, 255, 0), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk4(strip.Color(100, 100, 0), strip.Color(0, 100, 100), strip.Color(100, 0, 100), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk4(strip.Color(30, 50, 0), strip.Color(50, 30, 0), strip.Color(10, 50, 30), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(255, 255, 255), strip.Color(0, 0, 0), 4, 20, 200);
  colorwalk4(strip.Color(255, 0, 0), strip.Color(0, 0, 255), strip.Color(255, 255, 255), strip.Color(0, 255, 0), 4, 20, 200);
  
  //drawmonoimage(strip.Color(255, 0, 0), strip.Color(0, 0, 0), image_x2);
  monoimageblink(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(255, 0, 0), strip.Color(0, 0, 0), 10, 500, image_x2);

  monoimageblink(strip.Color(0, 255, 0), strip.Color(0, 0, 0), strip.Color(0, 255, 0), strip.Color(0, 5, 0), 10, 500, (uint32_t*)pgm_read_word(&(image_check[0])));
  monoimageblink(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(255, 0, 0), strip.Color(20, 5, 0), 10, 500, image_x2);
  monoimageblink(strip.Color(255, 0, 0), strip.Color(0, 0, 0), strip.Color(255, 0, 0), strip.Color(255, 0, 0), 10, 500, image_x2);
  monoimageblink(strip.Color(255, 0, 0), strip.Color(255, 255, 255), strip.Color(255, 255, 255), strip.Color(255, 0, 0), 10, 500, image_x2);
  colorWipe(strip.Color(0, 0, 0), 1);  // off
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}


void colorwalk2(uint32_t color1, uint32_t color2, int width, int repeat, uint8_t wait) {
  uint32_t ccolor = color1;
  int l1, l2, l3, crow;
  
  for (l1=0; l1<repeat; ++l1) {
    crow=0;
    while (crow < 16) {
      for (l2=0; l2<width; ++l2) {
        for (l3=0; l3<16; ++l3) {
          strip.setPixelColor((crow*16)+(l2*16)+l3, ccolor);
        }
      }
      
      crow += width;
      if (crow < 16) {
        if (ccolor == color1)
          ccolor = color2;
        else
          ccolor = color1;
      }
    }
    strip.show();
    delay(wait);
  }
}

void colorwalk3(uint32_t color1, uint32_t color2, uint32_t color3, int width, int repeat, uint8_t wait) {
  uint32_t ccolor = color1;
  uint32_t scolor = color1;
  int l1, l2, l3, crow;
  
  for (l1=0; l1<repeat; ++l1) {
    crow=0;
    ccolor = scolor;
    while (crow < 16) {
      for (l2=0; l2<width; ++l2) {
        for (l3=0; l3<16; ++l3) {
          strip.setPixelColor((crow*16)+(l2*16)+l3, ccolor);
        }
      }
      
      crow += width;
      //if (crow < 16) {
        if (ccolor == color1)
          ccolor = color2;
        else if (ccolor == color2)
          ccolor = color3;
        else 
          ccolor = color1;
      //}
    }
    strip.show();
    if (scolor == color1)
      scolor = color2;
    else if (scolor == color2)
      scolor = color3;
    else 
      scolor = color1;
    
      
    delay(wait);
  }
}

void colorwalk4(uint32_t color1, uint32_t color2, uint32_t color3, uint32_t color4, int width, int repeat, uint8_t wait) {
  uint32_t ccolor = color1;
  uint32_t scolor = color1;
  int l1, l2, l3, crow;
  
  for (l1=0; l1<repeat; ++l1) {
    crow=0;
    ccolor = scolor;
    while (crow < 16) {
      for (l2=0; l2<width; ++l2) {
        for (l3=0; l3<16; ++l3) {
          strip.setPixelColor((crow*16)+(l2*16)+l3, ccolor);
        }
      }
      
      crow += width;
      //if (crow < 16) {
        if (ccolor == color1)
          ccolor = color2;
        else if (ccolor == color2)
          ccolor = color3;
        else if (ccolor == color3)
          ccolor = color4;
        else 
          ccolor = color1;
      //}
    }
    strip.show();
    if (scolor == color1)
      scolor = color2;
    else if (scolor == color2)
      scolor = color3;
    else if (scolor == color3) 
      scolor = color4;
    else
      scolor = color1;
    
      
    delay(wait);
  }
}

void monoimageblink(uint32_t color1, uint32_t color2, uint32_t color3, uint32_t color4, int repeat, int dly, uint32_t dimg[]) {

  for (int l = 0; l<repeat; ++l) {
    drawmonoimage(color1, color2, dimg);
    delay(dly);
    drawmonoimage(color3, color4, dimg);
    delay(dly);
  }
}

void drawmonoimage(uint32_t color1, uint32_t color2, uint32_t image[]) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
      if (image[j] == 1) {
        strip.setPixelColor(j, color1);
      } else {
        strip.setPixelColor(j, color2);
      }
    }
  strip.show();
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}