Showing posts with label Geekiness. Show all posts
Showing posts with label Geekiness. Show all posts

Wednesday, January 25, 2012

Trimble Copernicus GPS Receiver & Arduino

I recently got my Arduino and Copernicus GPS receiver to communicate nicely.  Here’s how I got it working:
User Joezawaki at Sparkfun Electronics posted this very helpful diagram about a month ago:
copernicus_connection
I followed that almost to the letter to get the unit powered up properly. 
I had a bit of trouble because the above graphic shows the underside of the module, so I made this to make things a bit clearer:
Arduino GPS 003
I used an Arduino Duemilanove which runs at 5 volts, so I also used a Sparkfun Logic-Level Converter in between the serial port on the GPS module and the Arduino.  I tried for a while to build a voltage divider to knock the serial communication down but I never could get it right (I know, my n00b is showing).  The Sparkfun convertor is a great piece to have in your parts arsenal.  They’re cheap, breadboard friendly and make life much easier.
Now to the matter of code.  As would be expected, the code you use is really driven by a matter of what you want to do with the Copernicus.  The TinyGPS library is a great NMEA parser and the example code will get you up and running if you want to pull data from the GPS into text.  If you want raw NEMA sentences in order to use your Copernicus with software such as ArcGIS or Google Earth you will need to use a sketch designed to output unparsed NMEA data such as the one provided in the Aduino Playground. 
There’s a few things I learned in my futzing with the Copernicus that I think are useful.
1.  Realize that you are working with a serious GPS unit.  The Copernicus is capable of a lot of great things and as such it is a bit more complicated than working with other units.  With great power comes a lot of headscratching.
2.  There are two serial ports, one (RXB and TXB) default to outputting NMEA sentences at 4800 baud.  The other (RXA and TXA) default to outputting Trimble Standard Interface Protocol (TSIP) data, which is Trimble’s proprietary data stream.  TSIP is incredibly powerful and cool.  I have no idea how to use it. 
3.  RTFM.  Just do it, the manual is 238 pages long and it’s written in really good english.  It’s not something to be trifled with.
Feel free to comment or email with any questions or corrections, I’m always up for input!


UPDATE:
Here is a very basic GPS sketch that I was using when I was working with this unit more frequently.  I'm pretty sure it works - it at least outlines the basics of what you need to do to receive data from the unit.  I don't have a decent workbench set up right now so I'm not able to test it out.

It's pretty straightforward.  Bear in mind that this code is four years old now, there have likely been updates to the libraries that it uses - I would highly recommend looking through the documentation for those before diving into this.  (But who am I kidding - you're just going to copy/paste it and see if it works before you do any of that.)
#include
#include

//GPS Shield switch set to UART
#define RXPIN 0
#define TXPIN 1

//Set this value equal to the baud rate of your GPS
#define GPSBAUD 4800

// Create an instance of the TinyGPS object
TinyGPS gps;

// Initialize the NewSoftSerial library to the pins you defined above
NewSoftSerial nss(RXPIN, TXPIN);

// This is where you create prototypes for the functions that will be used.
void getgps(TinyGPS &gps);

//General variables
float latitude, longitude;
float velocity, azimuth;

void setup()
{
  //Serial for debugging purposes
  Serial.begin(4800);
  Serial.println("Serial Started");

  //Sets baud rate of your GPS
  nss.begin(GPSBAUD);

}

void loop()
  //Serial.println("Out of loop");
  
  while(nss.available())     // While there is data on the RX pin...
  {
      int c = nss.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        // Do Stuff
        gps.f_get_position(&latitude, &longitude);
        //lcd.noBlink();
        //lcd.clear();
        //lcd.setCursor(0,0);
        //lcd.print(latitude,4); lcd.print(longitude,4);
        //lcd.setCursor(0,1);
        
        // Get speed and azimuth
        velocity = gps.f_speed_mph();
        azimuth = gps.f_course();
       
        //Debugging serial stuff
        Serial.println(latitude);
        Serial.println(longitude);
        Serial.println(velocity);
        Serial.println(azimuth);
      }
  }  
  delay(3000);
}

Friday, February 12, 2010

First Arduino Project!

I bought an Arduino a while back and haven't really done anything with it until today...

From Arduino Mug Heater Temp Gauge


Frustrated with working on my thesis I decided to implement and idea I had about an arduino project. I have a mug-heater that sits on my desk to keep my coffee warm when I forget about (nothing is worse than grabbing for a shot of coffee and coming back with an icy-cold bleh).

Well, actually, I one of those candle-warmer things that you use to make candles smell nice without burning them that I use as a coffee-warmer because Bed-Bath and Beyond did not have any mug-warmers when I went looking for one and the clerk said that he thought a candle-warmer would be fine. Generally it is, except that it takes a long time to heat up and it gets a little too hot for my liking...

So I decided that I would use a 10k thermistor, a tri-color LED and my Arduino to make a gauge that would tell me how hot the warmer plate is. Naturally I could have just left the arduino plugged in with the serial monitor up and paid attention to it to find out the temps from the thermistor - but if I can't remember that I have coffee, what do you think the chances are that I will remember to check an extra window?

Since the Arduino is open source and the Arduino community consists of generally awesome people who know MUCH more about all of this than I do I was able to find a great function that converts the resistance values from the thermistor into Fahrenheit temperatures. (Really, it's amazing, no look-up table, very lightweight and effective.) I then run the temp value through an 'if' statement and determine which of the three leads on the LED to light up. Blue is for temperatures below 90; green is for temperatures between 90 and 110; and red is for temps above 110.

Here are some photos:

Arduino Mug Heater Temp Gauge

Here is the code for the whole project:
The 'Thermistor' function was taken from: http://www.arduino.cc/playground/ComponentLib/Thermistor2
The rest I wrote myself - my apologies for the lack of comments.
#include

int RED = 2;
int GREEN = 3;
int BLUE = 4;

int THERM = 1;

double Thermistor(int RawADC) {
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celcius
Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
return Temp;
}

void setup() {
Serial.begin(300);
pinMode(RED,OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
}

void loop() {
Serial.println(Thermistor(analogRead(THERM))); // display Fahrenheit
delay(1000);
if (Thermistor(analogRead(THERM)) <>
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(BLUE, HIGH);
}
else if (Thermistor(analogRead(THERM)) > 90 && Thermistor(analogRead(THERM)) <>
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(GREEN, HIGH);
}
else {
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
digitalWrite(RED, HIGH);
}
}