8.15.2010

GPS redo!

So, after sleeping on it and waking up to a new day I realized that I wasnt converting my GPS lat/long data to the correct format when I was inputting it into Google Earth. I was just moving the decimal point over two places so it would look similar to what Google Earth was showing me (IDIOT!). So when I sat down today to tinker I put in some Google searching to find a quick and easy way to convert my ddmm.mmmm format to the little more familiar decimal format (dd.dddddd). A handy website I found was called Earth Point - Tools for Google Earth. It is able to take numerous lat/long data formats and output to the Google Earth preferred decimal format. So I hooked up the SUP500F again to my Arduino and waited to get a lock. I walked away assuming it would take awhile and it already had a lock by the time I walked back (not sure how long I walked away but I'm just glad it got a lock).

My Arduino setup:


Its working!


So the GPS position I picked out of the data stream was 3447.0834 N, 8644.3538 W. The website converted it to 34.7847233°, -086.7392300°.
A formula from this website gave me the formula of ddmm.mmmm = dd + (mm.mmmm / 60); which works very well and wouldnt be too hard to put into code for a GPS parser.

So this is me....(im sad Google hasnt updated their images in a really long time, i have lived in my house over two years and Google still thinks I live in a dirt patch)


I think my impressions of the SUP500F are quickly changing. I guess I should make sure I'm not making a simple mistake before going off and thinking that something is a piece of junk. Now I need to get around to setting up a more robust way of powering and connecting the SUP500F to the arduino (i.e. level translator, optoisolators). Then I can start sending commands to the module and playing with some of the settings.

So for today, SUP500F = AWESOME!

8.14.2010

GPS!

So I finally took the plunge and purchased a GPS module. After reading through Sparkfun's GPS buying guide I decided to go with their favorite, the SUP500F.



I was hoping it would be easy enough to get up and running pretty quickly but robust enough that I could grow into its many features.

After tinkering off and on for about a day and a half (and reading many, many, many blog posts) I finally started getting NMEA sentences output to my Arduino.

So I am a little disappointed in the SUP500F's ability to get a fix and even more disappointed that once it does get a fix the GPS data for longitude and latitude is not even close to pinpointing my correct location (like not even the correct town?!).

So I am hoping that some of this can be remedied by either changing some settings on the SUP500F and/or using a Level Translator to make sure the serial connection between the unit and the Arduino is more electrically correct.

If all else fails I have seen where Sparkfun has run into some troubles with these units (SUP500F blog post.....scroll near bottom) and in some cases have either replaced or refunded the SUP500F for a customer.

So the verdict on the SUP500F module is not decided but it's not looking very good.

Most of the sketches I saw used the NewSoftSerial Library for the serial connection to the GPS so I downloaded it to my Arduino library folder and included it in my sketch.

Here is the simple sketch I used to start talking to my Arduino:


/**************************************************
GPS_Test
Kyle Kuepker
14 August 2010

A simple sketch to test my SUP500F. I use the
NewSoftSerial library for the serial connection.
***************************************************/

#include 'newsoftserial.h'

#define GPXRS 3
#define GPSTX 2
#define GPSBAUD 9600

NewSoftSerial nss(GPXRS, GPSTX);

void setup()
{
StartTime = millis();
nss.begin(GPSBAUD);
Serial.begin(9600);
Serial.println("Connected to Arduino");
}

void loop()
{
while (nss.available())
{
Serial.print(nss.read(), BYTE);
}
}


Next step is to insert some timer functionality and get some data on how long it takes to get a GPS fix with the unit. That way if I do want to go back to Sparkfun and try to return or replace my unit I will have some valid data to back up my claims.

7.26.2010

Processing Sketch - Mouse Comet

Here is the first sketch i created. I call it Mouse Comet. Hit a mouse button to create a comet that follows your mouse cursor. Again, this was a quick test for me to get back into coding and thinking like a programmer.





/*******************************************
* Test Program
* Kyle Kuepker
* 19 July 2010
*
* Simple Test Program To Draw Lines with
* Mouse
********************************************/

int array_max = 60;
int index_last = 0;
float shrink_index = 1.01;
int mx[] = new int[array_max];
int my[] = new int[array_max];
int mw[] = new int[array_max];
PImage reticle;
PFont fontA;

void setup()
{
size(400, 400);
reticle = createImage(11, 11, ARGB);
formReticleBullseye();
noCursor();
smooth();
noStroke();
fill(255, 150);

}

void draw()
{
background(50);
image(reticle, mouseX-5, mouseY-5);

if(mousePressed)
{
mx[index_last] = mouseX;
my[index_last] = mouseY;
mw[index_last] = 35;
index_last++;
}

for (int i = 0; i < array_max; i++)
{
mw[i] /= shrink_index;
if(int(mw[i]) < 1)
{
stroke(0);
fill(0);
}
else
{
noStroke();
fill(255, 150);
}
ellipse(mx[i], my[i], mw[i], mw[i]);
}

if(index_last == array_max)
{
index_last = 0;
}
}

/*************************
Form a reticle instead of a cursor
*************************/
void formReticleSquare()
{
for(int i=0; i < reticle.pixels.length; i++)
{
reticle.pixels[0] = color(255);
reticle.pixels[1] = color(255);
reticle.pixels[2] = color(255);
reticle.pixels[3] = color(255);
reticle.pixels[4] = color(255);
reticle.pixels[5] = color(255);
reticle.pixels[6] = color(255);
reticle.pixels[7] = color(255);
reticle.pixels[8] = color(255);
reticle.pixels[9] = color(255);
reticle.pixels[10] = color(255);
reticle.pixels[11] = color(255);
reticle.pixels[21] = color(255);
reticle.pixels[22] = color(255);
reticle.pixels[32] = color(255);
reticle.pixels[33] = color(255);
reticle.pixels[43] = color(255);
reticle.pixels[44] = color(255);
reticle.pixels[54] = color(255);
reticle.pixels[55] = color(255);
reticle.pixels[65] = color(255);
reticle.pixels[66] = color(255);
reticle.pixels[76] = color(255);
reticle.pixels[77] = color(255);
reticle.pixels[87] = color(255);
reticle.pixels[88] = color(255);
reticle.pixels[98] = color(255);
reticle.pixels[99] = color(255);
reticle.pixels[109] = color(255);
reticle.pixels[110] = color(255);
reticle.pixels[111] = color(255);
reticle.pixels[112] = color(255);
reticle.pixels[113] = color(255);
reticle.pixels[114] = color(255);
reticle.pixels[115] = color(255);
reticle.pixels[116] = color(255);
reticle.pixels[117] = color(255);
reticle.pixels[118] = color(255);
reticle.pixels[119] = color(255);
reticle.pixels[120] = color(255);
}
}

void formReticleBullseye()
{
for(int i=0; i < reticle.pixels.length; i++)
{
// Vertical Line
reticle.pixels[5] = color(255);
reticle.pixels[16] = color(255);
reticle.pixels[27] = color(255);
reticle.pixels[38] = color(255);
reticle.pixels[49] = color(255);
reticle.pixels[60] = color(255);
reticle.pixels[71] = color(255);
reticle.pixels[82] = color(255);
reticle.pixels[93] = color(255);
reticle.pixels[104] = color(255);
reticle.pixels[115] = color(255);
// Horizontal Line
reticle.pixels[55] = color(255);
reticle.pixels[56] = color(255);
reticle.pixels[57] = color(255);
reticle.pixels[58] = color(255);
reticle.pixels[59] = color(255);
reticle.pixels[60] = color(255);
reticle.pixels[61] = color(255);
reticle.pixels[62] = color(255);
reticle.pixels[63] = color(255);
reticle.pixels[64] = color(255);
reticle.pixels[65] = color(255);
// Circle
reticle.pixels[35] = color(255);
reticle.pixels[46] = color(255);
reticle.pixels[68] = color(255);
reticle.pixels[79] = color(255);
reticle.pixels[41] = color(255);
reticle.pixels[52] = color(255);
reticle.pixels[74] = color(255);
reticle.pixels[85] = color(255);
reticle.pixels[25] = color(255);
reticle.pixels[26] = color(255);
reticle.pixels[28] = color(255);
reticle.pixels[29] = color(255);
reticle.pixels[91] = color(255);
reticle.pixels[92] = color(255);
reticle.pixels[94] = color(255);
reticle.pixels[95] = color(255);
}
}

7.25.2010

Processing Sketches - Spew

So hit this link first........http://processing.org/learning/........and work through every tutorial if you want to get up to speed quickly with the Processing programming language. Each one is very concisely written and each has well developed example code to help through each lesson.

So here is my example code for the sketch I have called Spew. It is basically a mouse input sketch that creates 'fireworks' from your cursor. It was my test for understanding mouse cursor following as well as simple class writing (you tend to forget those things when you dont use them on a daily basis).





/**************************************************
Spewing Cursor Test v. 3
Kyle Kuepker
July 21, 2010

The idea is to have the mouse move a cursor and have
it spew pixels in different directions like a fountain

**************************************************/
int array_max = 60;
int firework_count = 0;
int spew_length_max = 200;
int spew_length_min = 50;
int fade_speed = 7;
float angle;
int MouseX;
int MouseY;
int spew_length;
PImage reticle;
Firework f_array[] = new Firework[array_max];

void setup()
{
size(400, 400);
background(25);
reticle = createImage(15, 15, ALPHA);
formReticleSquare();
noCursor();
smooth();
stroke(255, 150);
strokeWeight(3);
strokeCap(ROUND);
fill(255, 150);
for(int i = 0; i < array_max; i++)
{
f_array[i] = new Firework(0,0,0,0);
}

}

void draw()
{
background(25);
image(reticle, mouseX-8, mouseY-8);

if(mousePressed)
{
spew_length = int(random(spew_length_min, spew_length_max));
angle = random(0, 2*PI);
f_array[firework_count] = new Firework(mouseX, mouseY, spew_length, angle);
f_array[firework_count].f_draw();
firework_count++;
println(firework_count);
if(firework_count > 59)
{
firework_count = 0;
println("RESET");
}
}

for(int i = 0; i < f_array.length; i++)
{
f_array[i].update();
}
}

/*****************************
A simple Firework class
******************************/

class Firework
{
int startX, startY, f_length, endX, endY;
float f_angle;

Firework(int X1, int Y1, int LENGTH, float ANGLE)
{
startX = X1;
startY = Y1;
f_length = LENGTH;
f_angle = ANGLE;
endX = X1 + int(LENGTH * cos(ANGLE));
endY = Y1 + int(LENGTH * sin(ANGLE));
}

void f_draw()
{
line(startX, startY, endX, endY);
}

void update()
{
f_length = f_length - fade_speed;

if(f_length < 1)
noStroke();
else
stroke(255, 150);

startX = endX - int((f_length) * cos(f_angle));
startY = endY - int((f_length) * sin(f_angle));
line(startX, startY, endX, endY);
}
}

/*****************************
A simple reticle to replace the mouse cursor
This creates a square cursor....boring....i know
******************************/

void formReticleSquare()
{
for(int i=0; i < reticle.pixels.length; i++)
{
reticle.pixels[i] = color(255, 200);
}
}

Processing



So I have started messing with the programming language Processing. It has a very similar feel to the Arduino environment and is a very easy language to pick up for those familiar with programming. Hit up their website (www.processing.org) to learn more about their mission and what the langauge can do, as well some great tutorials for newbies or even very experienced programmers. I was very impressed with the progression of their tutorials and they way they introduced and taught Object Oriented Programming principles. I wish I had read these tutorials while I was in college.

So, go check them out. I am hoping to make some great visual interactions for my Arduino tinkering by hooking my Arduino up to my laptop and interfacing it with a Processing sketch.

I will post some of my sketches.......

Do work.......

7.12.2010

So the Taylor indoor/outddoor thermometer was pretty easy to take apart.



A couple of small screws and the front screen pops right out. A couple more screws and the circuit boards come right off as well.



In the picture above, the bottom PCB holds two momentary switches for inputs. One button switches degC to degF and back while the other button toggles min and max temperatures recorded.

The top PCB in the picture above, holds the brains of the device as well as one thermistor for the indoor temperature reading directly on the PCB and I'm assuming another thermistor is encapsulated inside the remote probe at the end of a length of wire attached to the same PCB.

7.11.2010


So my wife loves Target.....and when i say love i mean we almost named our first child Target. But anyways, she always walks at the end of the aisles looking for deals on the end-caps. Well yesterday she brought home this indoor/outdoor thermometer for your house. I was like 'Hey...that would be really cool to tear apart. Do they have anymore?' She said, 'Yes, we can go get another.' I replied happily, 'Lets do it!' So the next day on my errand run I stopped by Target and luckily I got the last one.

At $2.00 this little thing is at least worth its parts. I'm thinking it has at least some salvageable thermistors or whatever it uses for temp sensing. And hopefully a hackable LCD screen.

So, next post I will hopefully have some pictures of the innards of this little bugger.

So do like my wife does and search the end-caps of Target (or just get your wife to do it like I do). You never know what little hackable tech goodies you can find.