Search This Blog

Wednesday, September 29, 2010

RFID reader

Found some info on RFID readers that i'm making note of

http://www.instructables.com/id/Weather-proof-Bluetooth-capable-RFID-reader/

makes use of
http://www.sparkfun.com/commerce/product_info.php?products_id=8419
http://www.sparkfun.com/datasheets/Sensors/ID-12-Datasheet.pdf

Also found this on Ebay.   A little too much to spend at $59, but it has some info on how they work.
Still thinking about building a fun project to detect who is in my office by reading their badges.

Datasheet at
http://www.rfidshop.com.hk/datasheet/T5567/HI-R-W26-W2%20Datasheet.pdf







HI-R-W26-W2

125Khz HID compatible RFID Reader
with wiegand 26 bit output Interface






Features  (Datasheet download here)





  • Frequency : 125Khz




  • support protocol : HID compatible protocol  




  • power : +9V to +12V DC




  • read card serial No only




  • wall mount version




  • embedded antenna




  • effective distance up to 3-5 cm




  • Less than 100ms decoding time




  • Low power dissipation with single power supply




  • Built-in LED and buzzer




  • output interface : wiegand 26 bit




  • (42x80x15) mm

Interface Description  

Wire color
Wiegand
Red
+9V To 12V DC
Black
Ground
Green
Data 0
White
Data 1
Drain
Shield Ground
Brown
Red LED (active low)
Orange
Green LED (active low)
Yellow
Buzzer (active low)
Blue
Hold
Violet
Card Present







Monday, September 27, 2010

Got the IR TV sleep timer setter code working!

Rewrote my code using the libraries from this blog:
http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html

After a little stumble with a == instead of a =, i got the first version running.  Now the IR
receiver doesn't block the code execution and I can run a timer marking when the last IR event
happened.  Also this code seems to see just about any IR activity, not just the Sony.

Feel bad that i haven't taken the time to understand what he did, just borrowed it.

This guy has also a bunch of stuff on IR remotes and interrupts too, didn't use it but wanted to note it.
http://minkbot.blogspot.com/2009/08/arduino-ir-receiver-with-interrupts.html

I wrote the code as a simple state machine (my background as a RTL designer is showing).  There are three states.  TV_OFF, TV_ON, DROWSY.    It stays in TV_OFF unless the IR activity sends it to TV_ON.  It starts a timer and kicks back to TV_ON every time the IR remote is detected.  If the timer times out without any IR activity, it moves to DROWSY.  DROWSY sends the sleep command to the TV and starts a timer.  If the timer expires, it assumes the TV sleep timer turned off the TV and goes to TV_OFF.  Any IR activity moves you back to TV_ON.  DROWSY state isn't absolutely necessary, but it prevents sending sleep again too soon and extending the sleep timer time.

Now to clean up the hardware in a more permanent form and write it up for the next post!

Sunday, September 26, 2010

Back working on the Arduino IR TV sleep timer setter

Now that the GPS is working, i'm back working on a project that stalled.

This project has an IR receiver that looks for any traffic, from multiple remotes.  Point is not to decode them, just to detect them.   A timer runs and if no traffic has been seen for a set time (say 1/2 hour) it sends via an IR diode a sleep timer set code for the TV.  The device is placed in front of the TV where it will see the IR remote and be able to send a code to the TV out the back.   The point is that when someone is watching, they skip commercials, change volume, channel, etc.  When they fall asleep they stop using the remote.  If we mess up and accidentally set the sleep timer on an awake user, so what.  They will notice.

I had been using code from the Arduino playground and successfully detected Sony remote codes at just bout 100% accuracy.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434
I had some trouble sending the same codes to the TV.  There were two problems.  First the bit order was opposite what i thought, and I think the code on the website was not symmetrical.  After printing the codes out I figured that out.  More vexing however was that the TV ignored the codes I sent.  I tried several Sony TVs.  Luckily the TV I want to use is a Sony, which has easier codes.   I discovered after playing a long while, and looking at the time measurements of the real IR remote versus what I was sending (this took two Arduinos with the same hardware) that my pulses were longer than the real remote.  The real remote times were much less than the spec times of 600us and 1200us .  I think the clock in the Arduinos are off.  By changing the bit transmit times in the code to what i measured, I got the TV to respond.  That took a while to sort out.  However this varies Arduino to Arduino, so you have to tweak the times to the specific Arduino.  Disappointing but I'll live.

The problem that finally stalled me, was that the Arduino IR remote code is using a pulse measurement command and a while loop. 



while(pulseIn(ir_pin, LOW) < 2200) { //Wait for a start bit

} data[0] = pulseIn(ir_pin, LOW);


Problem is that I want a timer to increment, and this command uses up the whole of the Arduino's attention.  Additionally it is reliable with only Sony remotes, but remember i want to notice codes from a variety of remotes.   The 2000us pulse width doesn't apply to the other protocols and doesn't work reliably.

Whoa! ... a google search just turned up this blog, which is much more professional than mine, and has a lot of useful information.   Early posts point to the code i had been using.

http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
http://www.arduino.cc/playground/Code/InfraredReceivers

Alright.  Off to lick this problem with some new code!!

Friday, September 24, 2010

Repairing the L + R buttons on Nintendo DS

The most common failure I've seen is that either the R or L button stop working on Nintendo DS and DSlite.  I've not opened a DSi yet.

Basically I've found that you just have to disassemble the DS, blow it out and splash the button with some rubbing alcohol.  That has worked every time.  The odd thing is I can't really figure out what has gone wrong.  If I use an ohm meter on the switch, they always seem to work.  Maybe dirt has gotten in that falls out when the DS lite is disassembled.

Anyway, you need a Tri Wing screwdriver, available on ebay for less than $5.  You can get by with a small jewelers flat head if you force it into the screw.  It is do-able but a bit difficult if the screws are stuck in tight.   The tri wing is worth the investment.

You have to take out the battery and all the screws under it.  You have to pry off the two rubber feet and there are screws under them.  There is a small screw near the game slot too.  Take them all out.

Gently pry open the case.  The L R buttons have a small spring, be careful you don't lose it.  It likes to fall out as you are taking the DS apart.  Watch the power and volume buttons.  The little plastic slider will get out of position and you should make sure they are still working before you put all the screws back in.  You might have to futz with them to get them back into position.

Of course, if your DS is relatively new, like less than a year, I have sent them back to Nintendo and they have replaced them, very few questions asked.  Just go on the nintendo website customer support and fill out an RMA.  I've found that if you avoid talking to anyone and get to the step where you just send it back, they will fix it even if it is borderline your fault.   If you phone or even email in too much depth, they will tell you that the repair isn't covered and charge you.

Thursday, September 23, 2010

Trick to get a 20x4 Optrex display working

Bought this display from Digikey for the Arduino.  It was the biggest and cheapest display I can find, and it is pretty cool.  20x4 display.


73-1249-NDLCD MOD CHAR 20X4 WHT TRANSFLECT017.72000



Previously I only used NewHaven Displays, and they all worked out of the box with the Arduino examples.

Optrex LCD worked very sporadically.  Every once in a while i'd see the correct text, but usually i got garbage on the display.  I ohmed out the board, and all was wired right.   I found a post that indicated that in 4 bit
mode the display waits between sending bytes, and the default code does not read the busy bits.  I thought maybe i needed to add some time between the nibbles in the library.

However it was much easier than that.  I wasn't sure how to recompile the library, etc, so i experimented with adding some delays in the sketch.   Turns out this big module just takes longer to boot up.

I added a delay like this:

lcd.begin(20,4);
delay(500);
lcd.print("hello, world!");

Ba Da Bing!  The display works now, every time.

Wednesday, September 22, 2010

Arduino GPS Tracker completed

Wrapped up the Arduino based GPS tracker project!

This project used a SIRF GPS module I bought off Ebay, integrated with a data logging shield that can write to an SD card.  The Arduino microcontroller board makes it all work together.  The code supports and LCD readout of the GPS coordinates, heading, speed, etc.   In the photos below the LCD is removed because it didn't fit in the case nicely.  I'm making another version that has a readout when the parts come.

Basically this is a teen tracker.  As long as it is powered, it logs GPS coordinates of the trip every few seconds.  It records speed as well (not perfectly accurate).   Using gpsvisualizer web site, you can pull out the SD card, put it in your computer, point to the file that is saved and draw a map of the trip.  I even tested this in the trunk of the car, and it worked perfectly. 

Here is a photo of the completed unit, in it's box.   Also shown is the cell phone USB battery that I got at Target, foam taped to the side of the unit.  This might seem odd, but the unit would normally draw power from a USB adapter from a car, not from this battery.



Here is a shot with the case open, showing the adafruit data logger shield with the GPS module hanging off to the side, installed in the prototype area of the shield.  The Arduino itself is beneath the shield that you can see.
It all snaps inside this project box from Sparkfun.



I polished up the code so the waypoints are taken more often, unless the speed is low in which case some delays are added to keep the file down.  I added some LCD display improvements including displaying the compass direction next to the heading (i.e. N, E, S, W, NE, etc).  Took it bike riding at it worked perfectly too.

Earlier posts have links to the build, but a couple notes on the circuit, since i havent drawn it.

The box is $11.95 from Sparkfun http://www.sparkfun.com/commerce/product_info.php?products_id=10088

The adafruit sd logger card is the base prototype board.  I built it up according to it's directions, it is a nice prototype card.  I attached the GPS in the empty prototype area.  $19.50 and worth every penny.
http://www.adafruit.com/index.php?main_page=product_info&cPath=17_21&products_id=243
It supports the SDFat library, which writes to and SD card in a format that is directly readable by your PC in a .csv file.

You can get several LCD modules from Digikey if you want one.  I used this one for $9.25
http://search.digikey.com/scripts/DkSearch/dksus.dll?WT.z_header=search_go&lang=en&site=us&keywords=NHD-0208AZ-FL-YBW-ND&x=21&y=15

The GPS module came for $30 from ebay http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=250686123796&ssPageName=STRK:MEWAX:IT#ht_500wt_898

The GPS has a two wire serial interface, described in it's documentation and the photo below.  Instead of pins 2,3 I moved the interface to pins 8,9 to avoid conflicts with the LCD and SD card.   Pins 10 and above are used by the SD card interface built into the proto board.   I did not use a serial LCD like in this example, i used a parallel one.   The LCD is hooked up like the Arduino library examples, except the pins are moved to 7,6,5,4,3,2.
(photo borrowed from i182will)

Here is a dump of the code.  Atrocious coding as it is.  I works though!  I am a brute force programmer.

Tuesday, September 21, 2010

Awesome - The GPS tracker makes a map

Hooray, the GPS worked perfectly, the logger logged and the gpsvisualizer sucked in the data and made a map.

By now someone could figure out where i live by these posts, but i'm pretty sure nobody will ever read any of this.

The log file can be uploaded directly to this website, and badabing, a map like this one:
http://www.gpsvisualizer.com/map_input?form=google

Arduino GPS Unit, photos and links to parts




Here are pictures of the completed working unit.  A quick compilation of what it is made of:

Arduino board from hacktronics via Amazon $28
http://www.amazon.com/gp/product/B004A7L3NC/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=workingsilico-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B004A7L3NC

Adafruit datalogger board
http://www.adafruit.com/index.php?main_page=product_info&products_id=243

GPS module from Ebay $30 This is a SIRF3 module
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=250686123796&ssPageName=STRK:MEWAX:IT#ht_500wt_1154

NewHaven LCD DisplayNHD-0216K1Z-FS(RGB)-FBW-REV1-ND  from digikey $8
http://search.digikey.com/scripts/DkSearch/dksus.dll?WT.z_header=search_go&lang=en&site=us&keywords=NHD-0216K1Z-FS(RGB)-FBW-REV1-ND&x=0&y=0


Duracell Instant USB Charger with Lithium ion battery / includes universal cable with USB and mini USB $26 (paid too much!)


http://www.amazon.com/gp/product/B002FU6KF2/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&tag=workingsilico-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B002FU6KF2



I will post the circuit and code in a later post, as soon as i clean up some LCD display formatting issues

GPS to do list

Tracked some car trips today, worked awesome.  It showed my position to within a few feet.

Some things on my to do list for the GPS:
-More frequent GPS updates.  At highway speed the waypoints are too far apart and it looks like I'm going off the road.  I have a lot of delays, like 5sec, to make the LCD readable.  I only have a 2x8 LCD on the unit, and i have to switch from lat/lon, speed/course, time/altitude.  That loop takes 5 seconds and meanwhile the GPS is waiting. I think i will add code to log more often

-I think i need a push switch to scroll between the three possible readouts.  The constantly switching display is kinda hard to monitor anyway.

-Put the speed column ahead of altitiude in the log file.  gpsvisualizer wants to color my route for altitude, not for speed.

GPS battery and Monoprice.com for cable

I used this rechargeable battery to power the Arduino GPS.

Duracell Instant USB Charger with Lithium ion battery / includes universal cable with USB and mini USB

It worked well, i haven't seen how long it lasts, but it has a USB plug that can connect to the Arduino and it charges from a PC USB or wall charger.  It was a bit expensive but it seemed like such a nice solution for portable power, rather than burning through 9V batteries.


Monoprice.com is a crazy cheap place to buy cables.  I needed a short USB cable to connect the Arduino to the rechargeable battery with a USB plug.  The USB cables at best buy were $25.00 and up!  At Target they were $15.  At monoprice the cables were  $0.84 plus $2.24 to ship.  I got a cord to charge my cell phone while I was at it.  All for $4.24.

Monday, September 20, 2010

Arduino GPS - data logger added

Woot!

I got the data logger shield from adafruit.  A nice kit
http://www.adafruit.com/index.php?main_page=product_info&cPath=17_21&products_id=243
It was 19.50, which if you count the parts and proto board, i think it is a good deal.  It would have cost me more to buy separately and it looks professional and fits right on top of the Arduino.

The sdfat library i mentioned in an earlier post worked first try after i soldered up the board.  I was able to run their data logging example first try on an SD card.  Pop it in the computer and the file is there.  Totally awesome.

I pasted my gps code from the ebay SIRF3 tinygps library (in an earlier post) together with the sdfat data logger code.   I made it only record data when it had a GPS fix that was >0ms and <2000ms to filter out no signal cases that were filling the file with zeros.   A little messing with the header that gps visualizer wants on top the file.  http://www.gpsvisualizer.com  and i was good to go.  Sitting at the kitchen table it logged data just fine.

Tossed on a small LCD 8x2 display i got off EBAY so i could tell what it was doing.  Between the SD card, GPS and LCD the pins are maxed out on the Arduino.

I used a USB cigarette lighter plug and a USB cable and took it in the car with me.  I drove on some errands.  The GPS showed all zeros, no signal.  boo!!!!!   Held it up through the sunroof.  Still NADA.  Frustration mounted.    Tried again the next day driving to work.  Nothing.  AAAAARRRGH.  Is the GPS signal that weak?

Brought it back inside, plugged the USB into my computer.  Bingo! signal!  Working great again.  Walked out to the car.. still working fine.  Sat in the car with the Arduino and GPS powered from the laptop USB on battery power.  Works great.  Here is a picture of my walk to the car, from gps visualizer.

So the problem was the power, either the current or the voltage supplied by the cheapo USB cigarette plug is too low for the GPS to get signal.  OK tomorrow we run with the 9V adapter and my inverter!  Banzai!

Got the Gamecube working

So finally the slotted screwdriver from Amazon came and i cracked open the gamecube.

I simultaneously experimented with another gamecube we had lying around that the laser wore out on, and it would frequently freeze or fail to see disks.

The gamecube i was attempting to fix you could see the laser light up red, move in and out, but the platter never spun.  I thought initially it was the motor.  I tried the other gamecube, and it would begin spinning the platter right after the laser lit up and moved around.

I found some surprises inside the gamecube.  The black platter floats on some rubber grommets.  You can pop it off by pushing in some clips next to each grommet.  THen you can see the platter motor and laser underneath, but they are tethered by wires.   The laser flex cable pops out of the connector if you slide back the clamp.  The motor is hard wired soldered to the board.  The laser motor is also soldered to the board by two wires.

So it is impossible to just swap out the motor.  

If you take out about 16 screws on the shiny metal cover under the black platter, you can pop off the whole platter assembly and circuit board, they simply plug into one connector.

I decided to take the laser from one game cube, and the platter/circuit board from another and put them together. As i said, the laser can be disconnected and removed by a couple screws.  I put it all back together and there was another surprise!  The combined assembly of parts i thought would all work, didn't.  The laser lit up and moved in and out, but the platter never started spinning!!.  This is the same motor that worked a few minutes ago.  So i realized that the laser was really bad.  So bad it didn't even see the disk, worse than the guinea pig broken gamecube that at least saw the disk.

So I realized I had two gamecubes with broken lasers, and no spare parts.  Doh!

I went to ebay, searched for gamecube replacement laser.  I found many in the 10 to $15 range, from US sellers.  Watch out for stuff shipped from China, the quality can be spotty and you are unlikely to get much customer support.  I think it is worth the couple bucks extra to buy domestic.

Got the laser, popped it in, and Voila!  The platter spins now.  The motor was never bad.  So if you are repairing a gamecube, ebay is your best friend.  Buy the screwdriver, buy the laser, pop off the platter and don't remove all the screws, no point.

Monday, September 13, 2010

PCB

ExpressPCB was recommended by a friend.  They have free software and make the boards fast.  No DRC/LVS for the software.

Sunday, September 12, 2010

Fixing a GameCube

My daughter's friend's Gamecube wont spin the disk anymore.

Went to crack it open, and it has the oddest security screws you will ever see.

Bought this, but none of the tools fit.  Doh!  15 bucks gone.
http://www.amazon.com/gp/product/B0018D88ZW/ref=oss_product

Silverhill "Best Of" Tool Kit, with Tools for Nintendo Products and Microsoft Xbox Products



Then bought this for 3.95
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=310242191765&ssPageName=STRK:MEWNX:IT#ht_1641wt_1025

4.5 mm NINTENDO SNES NES N 64 SECURITY GAME BIT TOOL



I'll let you know how the repairs go when it comes.

Arduino Ethernet Clock Code


// Code to run an internet enabled digital clock
// gets data off the web and parses it
// Tom Wilson 9/2010
// Hardware is an Arduino D, Ethernet shield, and a big 20x4 LCD

#include <Ethernet.h>
// Borrowed code from a couple blogs....
// DHCP support
// Author: Jordan Terrell - blog.jordanterrell.com
//http://blog.jordanterrell.com/post/Arduino-DHCP-Library-Version-04.aspx
#include "Dhcp.h"

//Code to parse and scrape out the data you want
//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231812230

#include <LiquidCrystal.h>

// Include description files for other libraries used (if any)
#include <string.h>

// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN  21

// Setup vars
char tagStr[MAX_STRING_LEN] = "";
char dataStr[MAX_STRING_LEN] = "";
char tmpStr[MAX_STRING_LEN] = "";
char endTag[3] = {'<', '/', '\0'};
int len;
int line_num = 0;
int j = 0;

// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;
boolean dataFlag = false;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6 , 5, 4, 3, 2);

boolean ipAcquired = false;
byte mac[] = { 0xDE, 0xAD, 0xDE, 0xED, 0xBE, 0xEF };
//byte ip[] = { 192, 168, 1, 113 }; for non dhcp
//byte server[] = { 72, 14, 204, 99 }; // Google
//byte server[] = { 76, 13, 115, 78 }; // yahooapis
byte server[] = { 199, 211, 133, 239 }; // tycho.usno.navy.mil

Client client(server, 80);

void setup()
{
  Serial.begin(9600);

  lcd.begin(20, 4);
  //backlight on pin 8
  pinMode(8, OUTPUT);
  digitalWrite(8, LOW);

  // some router may require a delay before it will route network packets
  // add a delay if needed:
  Serial.println("delaying...");
  delay(5000);
  Serial.println("getting ip...");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("getting ip address...");
  int result = Dhcp.beginWithDHCP(mac);

  if(result == 1)
  {
    ipAcquired = true;
    digitalWrite(8, HIGH);
    
    byte buffer[6];
    Serial.println("ip acquired...");
    lcd.clear();

    Dhcp.getMacAddress(buffer);
    Serial.print("mac address: ");
    printArray(&Serial, ":", buffer, 6, 16);
  
    Dhcp.getLocalIp(buffer);
    Serial.print("ip address: ");
    printArray(&Serial, ".", buffer, 4, 10);

    //print the ip address to screen
    lcd.setCursor(0,0);
    lcd.print("IP Address obtained");
    lcd.setCursor(0,1);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,1);
    lcd.print(".");
    lcd.setCursor(4,1);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,1);
    lcd.print(".");
    lcd.setCursor(8,1);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,1);
    lcd.print(".");
    lcd.setCursor(12,1);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getSubnetMask(buffer);
    Serial.print("subnet mask: ");
    printArray(&Serial, ".", buffer, 4, 10);

    //print the ip address to screen
    lcd.setCursor(0,2);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,2);
    lcd.print(".");
    lcd.setCursor(4,2);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,2);
    lcd.print(".");
    lcd.setCursor(8,2);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,2);
    lcd.print(".");
    lcd.setCursor(12,2);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getGatewayIp(buffer);
    Serial.print("gateway ip: ");
    printArray(&Serial, ".", buffer, 4, 10);


    Dhcp.getDhcpServerIp(buffer);
    Serial.print("dhcp server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
  
    //print the ip address to screen
    lcd.setCursor(0,3);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,3);
    lcd.print(".");
    lcd.setCursor(4,3);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,3);
    lcd.print(".");
    lcd.setCursor(8,3);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,3);
    lcd.print(".");
    lcd.setCursor(12,3);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getDnsServerIp(buffer);
    Serial.print("dns server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
  
    delay(5000);
    /*
    Serial.println("connecting...");

    if (client.connect()) {
      Serial.println("connected");
      client.println("GET /search?q=arduino HTTP/1.0");
      client.println();
    } else {
      Serial.println("connection failed");
    }
    */
  
  }
  else {
    Serial.println("unable to acquire ip address...");
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("unable to acquire ip address");
  }

  delay(1000);


  Serial.println("connecting...");
  lcd.setCursor(0,0);
  lcd.print("Connecting...     ");


  if (client.connect()) {
    Serial.println("connected");
    digitalWrite(8, HIGH);
    lcd.clear();

    delay(2000);
    client.println("GET  /cgi-bin/timer.pl HTTP/1.0");  //get military time
    client.println();
  
  } else {
    Serial.println("connection failed");
    digitalWrite(8, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Connection Failed    ");
  }

}

void loop()
{

  line_num = 0;
  delay(1000);

  Serial.println("connecting...");
  
  while (client.available()) {
    serialEvent();
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    Serial.print("client.status = ");
    Serial.println(client.status(),DEC);

   client.stop();

  Serial.println("connecting...");

  delay(2000);
  if (client.connect()) {
    digitalWrite(8, HIGH);
    Serial.println("connected");
    client.println("GET  /cgi-bin/timer.pl HTTP/1.0");  //get military time
    client.println();
  
  } else {
    digitalWrite(8, LOW);
    Serial.println("connection failed");
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Connection Failed    ");
  }
  }
}

// Process each char from web
void serialEvent() {

   // Read a char
char inChar = client.read();
   //Serial.print(".");

   if (inChar == '<') {
      addChar(inChar, tmpStr);
      tagFlag = true;
      dataFlag = false;

   } else if (inChar == '>') {
      addChar(inChar, tmpStr);

      if (tagFlag) {    
         strncpy(tagStr, tmpStr, strlen(tmpStr)+1);
      }

      // Clear tmp
      clearStr(tmpStr);

      tagFlag = false;
      dataFlag = true;    
    
   } else if (inChar != 10) {
      if (tagFlag) {
         // Add tag char to string
         addChar(inChar, tmpStr);

         // Check for </XML> end tag, ignore it
         if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) {
            clearStr(tmpStr);
            tagFlag = false;
            dataFlag = false;
         }
      }
    
      if (dataFlag) {
         // Add data char to string
         addChar(inChar, dataStr);
      }
   }

   // If a LF, process the line
   if (inChar == 10 ) {

/*
      Serial.print("tagStr: ");
      Serial.println(tagStr);
      Serial.print("dataStr: ");
      Serial.println(dataStr);
*/

      // Find specific tags and print data
      if (matchTag("<BR>")) {
         Serial.print(line_num);
         Serial.print(dataStr);
         Serial.println("");
         //lcd.setCursor(0,line_num);  
         //lcd.print(dataStr);
         if ((line_num > 0) & (line_num < 5)) {
             lcd.setCursor(0,line_num-1);  
             lcd.print(dataStr);
         } else {
             //line_num = 0;
         }
         line_num = line_num + 1;
         //if (line_num >4) line_num = 0;
      }

      
      // Clear all strings
      clearStr(tmpStr);
      clearStr(tagStr);
      clearStr(dataStr);

      // Clear Flags
      tagFlag = false;
      dataFlag = false;
   }
}

/////////////////////
// Other Functions //
/////////////////////

// Function to clear a string
void clearStr (char* str) {
   int len = strlen(str);
   for (int c = 0; c < len; c++) {
      str[c] = 0;
   }
}

//Function to add a char to a string and check its length
void addChar (char ch, char* str) {
   char *tagMsg  = "<TRUNCATED_TAG>";
   char *dataMsg = "-TRUNCATED_DATA-";

   // Check the max size of the string to make sure it doesn't grow too
   // big.  If string is beyond MAX_STRING_LEN assume it is unimportant
   // and replace it with a warning message.
   if (strlen(str) > MAX_STRING_LEN - 2) {
      if (tagFlag) {
         clearStr(tagStr);
         strcpy(tagStr,tagMsg);
      }
      if (dataFlag) {
      //   clearStr(dataStr);
      //   strcpy(dataStr,dataMsg);  just stop instead of killing the string
      }

      // Clear the temp buffer and flags to stop current processing
      clearStr(tmpStr);
      tagFlag = false;
      dataFlag = false;

   } else {
      // Add char to string
      if ((ch != '.') & (ch != ',')) str[strlen(str)] = ch;
   }
}

// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
   if ( strcmp(tagStr, searchTag) == 0 ) {
      return true;
   } else {
      return false;
   }
}

void printArray(Print *output, char* delimeter, byte* data, int len, int base)
{
  char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

  for(int i = 0; i < len; i++)
  {
    if(i != 0)
      output->print(delimeter);
    
    output->print(itoa(data[i], buf, base));
  }

  output->println();
}

Places to buy Arduino stuff

Hacktronics
http://www.hacktronics.com/
Stuff comes really fast.  I bought originally through Amazon.  Got all my arduinos through them so far.

Sparkfun
http://www.sparkfun.com/commerce/categories.php
Haven't bought anything from them yet, but they have a lot of stuff.

Adafruit
http://www.adafruit.com/
Super chip proto shields.  Bought a couple, waiting to see how fast them come.

Digikey
http://www.digikey.com/
Defacto parts site.  Stuff comes fast.  Gotta pay a shipping charge, so best to combine into larger orders.  You have to know what you want, our creep through a catalog.  They have so much stuff that you can't find whachamacalits.  Gotta know the name.
Bought all my LCD displays, protoboards, connectors, etc from here

BatchPCB
Haven't tried them yet, but this is how to make your own boards.
http://batchpcb.com/index.php/Products

And of course Amazon.com shouldn't be forgotten.  Stuff comes fast, and you have some guarantee to back it up.

Ebay is worth looking at.  Watch out for all the Chinese Arduinos and ethernet boards, etc.  See my other post.  Never got those to work.  Plus i feel a little better sending my money to Italy to the Arduino developers by buying an authentic Arduino.    You will never see you money again if the Chinese ones don't work.  However you can get parts here from other hobbists.  Dont be afraid, Ebay is reliable.

Arduino GPS working too!

Ordered a GPS module off Ebay for $30 plus shipping
http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=250686123796&ssPageName=STRK:MEWAX:IT#ht_500wt_896

It came with a tutorial wiring diagram.

http://www.fileden.com/files/2010/8/21/2948335/GPS_Arduino_Tutorial.zip

I hooked it up to the Arduino, and strapped on an LCD.  Loaded the tutorial.   After about 15 secs of 0.000 0.000 data started pouring out.  Wow!
That was easy.  Less than an hour.

SInce then i've gone through the software and have the LCD outputing time , data, speed, course, as well as the GPS data.
Now what??  I think I will make a GPS logger.  Something like a teen tracker, that writes the data to an SD card.  The onboard EEPROM is 512 bytes, too small to do anything with.

I decided to order a data logging shield from adafruit for 19.50.
A protoboard and connectors would cost me that much, and it comes with an SD card slot.

The SD card writer i made earlier is a bit of a kluge, and the one on adafruit seems like a good deal.  I got my sd card writer to work though the SPI interface, but only the arduino can read it.  I want to be able to take the files to a PC.

The sdfat libraries look like they will do the trick to log the data.

I found a cool website that will plot the gps data to a map, showing the whole route.




Got the arduino ethernet shield working

Ordered an ethernet shield from ebay, and it was shipped from Hong Kong.  It cost 9.95 plus another 9.95 to ship.  I got it in about a week.  I was kinda shocked it came so fast.  Plugged it in and the lights flashed.  Tried the ethernet client and server apps, neither would work.  Fooled with my router, trying to see what IP address was assigned to it.  It never showed up on the DHCP table in the router.  I decided it was busted.

Eventually I gave up and ordered for $39
http://www.hacktronics.com/Arduino/Arduino-Ethernet-Shield/flypage.tpl.html
I bought it through Amazon, but now i see it is out of stock.  It had an SD card slot and was much nicer than the chinese one i bought.  My router saw it immediately, and after changing the IP address to the one my router showed in the DHCP table, and changing the server to google for me.  This is done by
using cmd in the run box and opening a terminal window. type ping www.google.com and you will get back the local IP address for google.    Uploaded to the arduino and ba da bing, data started pouring back.

I found that someone had developed a DHCP version of the ethernet library, that worked perfectly
http://blog.jordanterrell.com/post/Arduino-DHCP-Library-Version-04.aspx
This was awesome.   You download and replace the Arduino libraries.  I had trouble at first getting it to find an IP address, until i notice the line that said some routers need a delay to work, and a delay statement commented out.   I uncommented it, and bingo.  The IP address was obtained at home , and also at work where we have a typical big company network monstrosity.

I used this and the tycho navy time site, and the yahoo stock download pages to write an app to pull some data down and made a little desk clock with an LCD display.  Within the weekend of getting the ethernet shield, my little toy was done!