12.31.2010

Shift Register with LEDs

So I bought a cool LED bar graph from Sparkfun and wanted a good way to light it up.....in steps the Shift Register (datasheet).

Shift Register
A shift register is a good to way to multiply the digital outputs on a microcontroller. By using 3 digital I/O pins you can get at a minimum 8 digital I/O pins. And on top of that by adding a second Shift Register you can turn 3 pins into 16 pins.

See the diagram for reference of the operation of a Shift Register. The Shift Register is aptly named because you bit by bit 'shift' the 1's and 0's into its registers. Internally the device has two registers, the Shift Register and Storage Register. You can think of the shift register as a waiting area and the storage register as the active area. You shift in your desired 1's and 0's into the shift register initially, and then once you are ready, you flip a switch and those 1's and 0's get transferred to the storage register. Whatever is in the storage register is what you can see on the external pins. Shift in a zero at a spot and the pin that is mapped to that spot will look like a ground or LOW. Shift in a one and that spot will look like a HIGH on that pin.


My Test Circuit
So back to my little LED bar graph. See picture of my test circuit below. In words, the Shift Register is connected to the Arduino by pins 5, 6 and 7. Pin 5 is connected to the Serial Data pin of the Shift Register, pin 6 the Latch pin and pin 7 the Clock pin. The 8 outputs of the Shift Register are connected through resistors to the anodes of LEDs.

So, not a terribly difficult circuit but a good way to learn the use of a Shift Register.

See my test code below......


/***************************************************************
Single Shift Register Test Sketch
Shift_Reg_Test.pde

Kyle Kuepker
31 December 2010

A test sketch to exercise a single Shift Register to light 8 LEDs.

Intended Hardware implementation:
Arduino pins 5,6,7 are connected to Shift Register data,
latch and clock pins respectively. Each output of the Shift
Register is connected through a resistor to the anode of an
LED. Shift register outputs are active HIGH for the LEDs
(a HIGH output on a Shift Register pin will turn ON an LED).
***************************************************************/
// Data pin number for Arduino
#define data_Pin 5
// Latch pin number for Arduino
#define latch_Pin 6
// Clock pin number for Arduino
#define clock_Pin 7

//Define a delay for testing purposes
#define delay_ms 100

void setup() {
//Setup serial test for debugging
Serial.begin(9600);
Serial.println("Connected");

//Set shift register control pins to outputs on Arduino
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}

void loop() {
// Turn on first LED
sendByte(0b00000001);
delay(delay_ms);
// Turn on second LED
sendByte(0b00000010);
delay(delay_ms);
// Turn on third LED
sendByte(0b00000100);
delay(delay_ms);
// Turn on fourth LED
sendByte(0b00001000);
delay(delay_ms);
// Turn on fifth LED
sendByte(0b00010000);
delay(delay_ms);
// Turn on sixth LED
sendByte(0b00100000);
delay(delay_ms);
// Turn on seventh LED
sendByte(0b01000000);
delay(delay_ms);
// Turn on eighth LED
sendByte(0b10000000);
delay(delay_ms);
// Turn on seventh LED
sendByte(0b01000000);
delay(delay_ms);
// Turn on sixth LED
sendByte(0b00100000);
delay(delay_ms);
// Turn on fifth LE
sendByte(0b00010000);
delay(delay_ms);
// Turn on fourth LED
sendByte(0b00001000);
delay(delay_ms);
// Turn on third LED
sendByte(0b00000100);
delay(delay_ms);
// Turn on second LED
sendByte(0b00000010);
delay(delay_ms);
}

void sendByte(byte data){
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(latchPin, HIGH);
}

8.27.2010

EEPROM anomaly

I got some time tonight to run a more extended test on my EEPROM setup to really see if it will write correctly to all three 24FC512 EEPROMs.

My setup:


The code is below.

So the program is setup to write data across the 3 EEPROMs until it fills all available space. The program creates 300 records at a time and loops for 66 times. This will create 19800 records which is 141 records more than the maximum allowable amount of 19659. The total number of records available is a function of the total memory size of the 3 EEPROMs and the size of my data structure. The test will be to see if it writes correctly to the 3 EEPROMS and what it will do when it runs out of addressable space.

I uploaded the code and let it start cranking. Building the random data takes some time so I was prepared to wait.

So far so good......but wait my data looks corrupted.

But it still is exhibiting a discernable pattern. But wait.....the pattern changed again.

Hmmm....I wonder why it doesnt write the data correctly. It is writing to valid addresses on the EEPROM, but the data has gotten jumbled and isn't printing out correctly. This will need some investigation. My initial guess is it is running into problems when it meets the address boundaries between the separate EEPROMs.

The code:


/*
EDB_24XX512.pde
Extended Database Library + 24XX512 EEPROM Demo Sketch

The Extended Database library project page is here:
http://www.arduino.cc/playground/Code/ExtendedDatabaseLibrary

The E24C1024 library project page is here:
http://www.arduino.cc/playground/Code/I2CEEPROM24C1024

*/
#include "WProgram.h"
#include

// Use the 24XX512 EEPROM as storage
#include
#include // Should be compatible with 24XX512 series in this instance

// From the 24XX512 datasheet:
//
// The Chip Select bits A2, A1 and A0 can be used to expand the
// contiguous address space for up to 4 Mbit by adding up to eight
// 24XX512 devices on the same bus.
//
// So, each device must be have their address pins wired as listed below to
// create a single, contiguous address space across one or more devices.
//
// Example - 1 device:
// Device connections: A0->GND, A1->GND, A2->GND
// Uncomment only the #define TABLE_SIZE 65536 line below.

// Example - 3 devices:
// Device 1 connections: A0->GND, A1->GND, A2->GND
// Device 2 connections: A0->+5V, A1->GND, A2->GND
// Device 3 connections: A0->GND, A1->+5V, A2->GND
// Uncomment only the #define TABLE_SIZE 196608 line below.
//
// Uncomment the ONE line appropriate for your platform.
//#define TABLE_SIZE 65536 // 1 device: A0->GND, A1->GND, A2->GND
//#define TABLE_SIZE 131072 // 2 devices: A0->+5V, A1->GND, A2->GND
#define TABLE_SIZE 196608 // 3 devices: A0->GND, A1->+5V, A2->GND
//#define TABLE_SIZE 262144 // 4 devices: A0->+5V, A1->+5V, A2->GND
//#define TABLE_SIZE 327680 // 5 devices: A0->GND, A1->GND, A2->+5V
//#define TABLE_SIZE 393216 // 6 devices: A0->+5V, A1->GND, A2->+5V
//#define TABLE_SIZE 458752 // 7 devices: A0->GND, A1->+5V, A2->+5V
//#define TABLE_SIZE 524288 // 8 devices: A0->+5V, A1->+5V, A2->+5V

// default to the smallest - 1 device
#ifndef TABLE_SIZE
#define TABLE_SIZE 65536
#endif

// The number of demo records that should be created. This should be less
// than (TABLE_SIZE - sizeof(EDB_Header)) / sizeof(LogEvent). If it is higher,
// operations will return EDB_OUT_OF_RANGE for all records outside the usable range.
#define RECORDS_TO_CREATE 300

// Arbitrary record definition for this table.
// This should be modified to reflect your record needs.
struct LogEvent {
int Lat1;
int Lat2;
int Lon1;
int Lon2;
unsigned int UTC_Time;
}
logEvent;

// Create an EDB object with the appropriate write and read handlers
EDB db(&E24C1024::write, &E24C1024::read);

// Run the demo
void setup()
{
Serial.begin(9600);
Serial.println("Extended Database Library + 24XX512 EEPROM Demo");

randomSeed(analogRead(0));

// create a table with starting address 0
Serial.print("Creating table...");
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
Serial.println("DONE");

recordLimit();
countRecords();

for(int j = 0; j < 66; j++)
{
createRecords(RECORDS_TO_CREATE);
countRecords();
}

selectAll();
countRecords();
deleteAll();
countRecords();
// createRecords(RECORDS_TO_CREATE);
// countRecords();
// selectAll();
// countRecords();
// deleteAll();
// countRecords();
}

void loop()
{
}

void recordLimit()
{
Serial.print("Record Limit: ");
Serial.println(db.limit());
}

void deleteAll()
{
Serial.print("Truncating table...");
db.clear();
Serial.println("DONE");
}

void countRecords()
{
Serial.print("Record Count: ");
Serial.println(db.count());
}

void createRecords(int num_recs)
{
Serial.print("Creating Records...");
for (int recno = 1; recno <= num_recs; recno++)
{
logEvent.Lat1 = random(1001, 1100);
logEvent.Lat2 = random(1101, 1200);
logEvent.Lon1 = random(1201, 1300);
logEvent.Lon2 = random(1301, 1400);
logEvent.UTC_Time = random(0, 240000);
EDB_Status result = db.appendRec(EDB_REC logEvent);
if (result != EDB_OK) printError(result);
}
Serial.println("DONE");
}

void selectAll()
{
for (int recno = 1; recno <= db.count(); recno++)
{
EDB_Status result = db.readRec(recno, EDB_REC logEvent);
if (result == EDB_OK)
{
Serial.print("Recno: "); Serial.print(recno);
Serial.print(" LAT: ");
Serial.print(logEvent.Lat1); Serial.print("."); Serial.print(logEvent.Lat2);
Serial.print(" LON: ");
Serial.print(logEvent.Lon1); Serial.print("."); Serial.print(logEvent.Lon2);
Serial.print(" TIME: "); Serial.println(logEvent.UTC_Time);
}
else printError(result);
}
}

void printError(EDB_Status err)
{
Serial.print("ERROR: ");
switch (err)
{
case EDB_OUT_OF_RANGE:
Serial.println("Recno out of range");
break;
case EDB_TABLE_FULL:
Serial.println("Table full");
break;
case EDB_OK:
Serial.println("OK");
break;
default:
Serial.println("Unknown Error");
break;
}
}

8.25.2010

Serial EEPROM Memory cont.

So a couple more notes on my last post...

The code posted is actually my second working sketch for this Serial EEPROM test. For that particular sketch I was using 3 24FC512s all hooked up on the I2C bus at the same time. The original code can be found at this link. The only differences are defining the TABLE_SIZE to include the memory space of 3 devices and I also modified the logEvent structure to suit my anticipated needs for a GPS logger. But most of the code is left untouched. Like I said earlier, all the heavy lifting was done by other smarter people. Maybe if I get the time, and more importantly, the motivation I will go back and rewrite my own library so I can better understand what is really going on behind the scenes. But for now, its working, and thats good enough for me.

Thanks Arduino Community! You make my life so much easier.

Serial EEPROM Memory

So on my journey to ultimately one day making a killer quadcopter or other autonomous aerial vehicle, I have identified a few key technologies that I need to get a good grasp on that will ultimately be used in any project. Dove-tailing off my previous tinkering with my GPS and with an impending family trip coming up I was hoping to have a working GPS logger ready to capture the path we take on our daily adventures. (Not sure how the wife is gonna feel about me tinkering at night on vacation?!)

So besides getting a full SD card logger ready I thought I might try to use some serial EEPROMs from Microchip. I have had an account with Microchip all the way back to my undergrad days and it is very easy and very quick to get free samples from them, and totally free is my favorite price.

So I went to their website and started searching through their memory product line. I was initially interested in checking out their Flash based product line but that link sent me to another website, SST - Silicon Storage Technology Inc., that wasnt managed through Microchip Sample website. To get samples of their flash products you have to fill out a request form.....that wasnt going to happen. So back to the Microchip website and looking at some Serial EEPROM devices. Since Arduino has I2C and SPI interfaces I started looking for products that interface through those protocols. I eventually settled on the 24XXYYY family of devices that communicate through I2C. Their sizes range from 128 bit all the way up to 8 MBit and up to 8 separate devices can be placed on the same I2C bus to expand your storage capabilities even further. Unfortunately the largest EEPROM, the 24FC1025, had a long lead time of something like 46 weeks (RIDICULOUS!) so I wound up placing an order for the 24FC512 (which will more than accomplish what I am doing.

So after some google and forum searching for Arduino and Serial EEPROM help and reading through the 24FC512's datasheet I figured I had found enough to try and get it working. A few of the more helpful sites are:
Arduino Tutorial
Arduino Forum with links to the Extended Database Library and a 24ACas well as a sample Arduino program for working with the 24FC512

Basically most of my work was done for me. I just needed to ensure I hooked up everything correctly, like the Arduino to EEPROM I2C interface, and not surprisingly it worked exactly like I had hoped.

To use my sketch you must download and place in your Arduino library these two files:
Extended Database Library
AT24C1024 Library

Once you have those you can upload the sketch below, and assuming everything is connected properly you should be good to go.

The Arduino sketch looks like this:


#include "WProgram.h"
#include

// Use the 24XX512 EEPROM as storage
#include //Handles the I2C interface
#include // Should be compatible with 24XX512 series in this instance

// From the 24XX512 datasheet:
//
// The Chip Select bits A2, A1 and A0 can be used to expand the
// contiguous address space for up to 4 Mbit by adding up to eight
// 24XX512 devices on the same bus.
//
// So, each device must be have their address pins wired as listed below to
// create a single, contiguous address space across one or more devices.
//
// Example - 1 device:
// Device connections: A0->GND, A1->GND, A2->GND
// Uncomment only the #define TABLE_SIZE 65536 line below.

// Example - 3 devices:
// Device 1 connections: A0->GND, A1->GND, A2->GND
// Device 2 connections: A0->+5V, A1->GND, A2->GND
// Device 3 connections: A0->GND, A1->+5V, A2->GND
// Uncomment only the #define TABLE_SIZE 196608 line below.
//
// Uncomment the ONE line appropriate for your platform.
//#define TABLE_SIZE 65536 // 1 device: A0->GND, A1->GND, A2->GND
//#define TABLE_SIZE 131072 // 2 devices: A0->+5V, A1->GND, A2->GND
#define TABLE_SIZE 196608 // 3 devices: A0->GND, A1->+5V, A2->GND
//#define TABLE_SIZE 262144 // 4 devices: A0->+5V, A1->+5V, A2->GND
//#define TABLE_SIZE 327680 // 5 devices: A0->GND, A1->GND, A2->+5V
//#define TABLE_SIZE 393216 // 6 devices: A0->+5V, A1->GND, A2->+5V
//#define TABLE_SIZE 458752 // 7 devices: A0->GND, A1->+5V, A2->+5V
//#define TABLE_SIZE 524288 // 8 devices: A0->+5V, A1->+5V, A2->+5V

// default to the smallest - 1 device
#ifndef TABLE_SIZE
#define TABLE_SIZE 65536
#endif

// The number of demo records that should be created. This should be less
// than (TABLE_SIZE - sizeof(EDB_Header)) / sizeof(LogEvent). If it is higher,
// operations will return EDB_OUT_OF_RANGE for all records outside the usable range.
#define RECORDS_TO_CREATE 327

// Arbitrary record definition for this table.
// This should be modified to reflect your record needs.
struct LogEvent {
int Lat;
int Lon;
int UTC_Time;
}
logEvent;

// Create an EDB object with the appropriate write and read handlers
EDB db(&E24C1024::write, &E24C1024::read);

// Run the demo
void setup()
{
Serial.begin(9600);
Serial.println("Extended Database Library + 24XX512 EEPROM Demo");

randomSeed(analogRead(0));

// create a table with starting address 0
Serial.print("Creating table...");
db.create(0, TABLE_SIZE, (unsigned int)sizeof(logEvent));
Serial.println("DONE");

recordLimit();
countRecords();
createRecords(RECORDS_TO_CREATE);
countRecords();
selectAll();
countRecords();
deleteAll();
countRecords();
// createRecords(RECORDS_TO_CREATE);
// countRecords();
// selectAll();
// countRecords();
// deleteAll();
// countRecords();
}

void loop()
{
}

void recordLimit()
{
Serial.print("Record Limit: ");
Serial.println(db.limit());
}

void deleteAll()
{
Serial.print("Truncating table...");
db.clear();
Serial.println("DONE");
}

void countRecords()
{
Serial.print("Record Count: ");
Serial.println(db.count());
}

void createRecords(int num_recs)
{
Serial.print("Creating Records...");
for (int recno = 1; recno <= num_recs; recno++)
{
logEvent.Lat = recno;
logEvent.Lon = random(1, 125);
logEvent.UTC_Time = random(126, 250);
EDB_Status result = db.appendRec(EDB_REC logEvent);
if (result != EDB_OK) printError(result);
}
Serial.println("DONE");
}

void selectAll()
{
for (int recno = 1; recno <= db.count(); recno++)
{
EDB_Status result = db.readRec(recno, EDB_REC logEvent);
if (result == EDB_OK)
{
Serial.print("Recno: "); Serial.print(recno);
Serial.print(" LAT: "); Serial.print(logEvent.Lat);
Serial.print(" LON: "); Serial.print(logEvent.Lon);
Serial.print(" TIME: "); Serial.println(logEvent.UTC_Time);
}
else printError(result);
}
}

void printError(EDB_Status err)
{
Serial.print("ERROR: ");
switch (err)
{
case EDB_OUT_OF_RANGE:
Serial.println("Recno out of range");
break;
case EDB_TABLE_FULL:
Serial.println("Table full");
break;
case EDB_OK:
Serial.println("OK");
break;
default:
Serial.println("Unknown Error");
break;
}
}


Hopefully this helps those looking to use Serial EEPROMs in their projects. I leaned very heavily on the work of others but thats usually the best way to get up to speed. Once you have a working knowledge its much easier to dive back in and truly understand the internal workings of the code.

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.

Welcome to Blogging!

This should be interesting....

I hope to use this blog as a way to motivate and chronicle my adventures in tinkering with electronics. As an intro, heres a quick background on me.

I am an EE by day and father and husband by night. I enjoy all kinds of sports; lacrosse, basketball, soccer, cycling and play most of them for fun. While I am blessed to have a great job working for Boeing I miss the creativity of designing and building electronic creations for fun.

So hopefully this blog will be filled with creations, frustrations, tear-downs and general good natured exploration of the world as experienced through electronics.