Tuesday, July 14, 2009

Ok, so I've toyed with the absolute minimal Arduino I could figure, see: http://itp.nyu.edu/physcomp/Tutorials/ArduinoBreadboard



I've drawn the electrical schematic (also with the corresponding Arduino pins from Arduino.cc):




Now for the best part - I priced the components (including a DIP socket for the ATMega8) from Jameco.com it comes out to $5.73! (8 pennies less if you don't care to have the power LED)

From what I can gather, it has no serial I/O, so complex sensors are out, but for simple read a sensor, take an action it doesn't get any better than this!

I'm hoping that it'll be as simple as swapping out the ATMega chips on an existing Arduino to burn the bootloader, then download your program. Then simply put in the ATMega chip and power up. Not 100% sure, I'll have to check the bootloader stuff on Arduino.cc


The best thing here is you won't have to waste your $30 Arduino for simple stuff!

Friday, July 10, 2009

Python - Recursively Zip Directories (extended)

This looks pretty useful, especially for work since we rip through hundreds of files for zipping and unzipping.

The idea and snippet are from Corey Goldberg's post sharing the work he did to improve a bit of recursive zipping code. I extended what he made to include command line options and some usage help, complete with lazy loading in case somebody wants to use it as a library later. Just wanted to share and record for my own purposes.


#!/usr/bin/env python

import os, zipfile

def zipper(dir, zip_file):
zip = zipfile.ZipFile(zip_file, 'w', compression=zipfile.ZIP_DEFLATED)
root_len = len(os.path.abspath(dir))
for root, dirs, files in os.walk(dir):
archive_root = os.path.abspath(root)[root_len:]
for f in files:
fullpath = os.path.join(root, f)
archive_name = os.path.join(archive_root, f)
print f
zip.write(fullpath, archive_name, zipfile.ZIP_DEFLATED)
zip.close()
return zip_file

if '__main__' == __name__:
# Late import, in case this project becomes a library, never to be run as main again
import optparse

# Populate our options, -h/--help is already there for you
usage = "usage: %prog [options]"
version="%prog 1.0"
parser = optparse.OptionParser(usage=usage, version=version)
parser.add_option("-d", "--dir", dest="inputDir", default="~/test", action="store", help="sets the input directory to something other than the default (~/test)")
parser.add_option("-f", "--file", dest="outputFile", default="~/temp/test.zip", action="store", help="sets the output zip file to something other than the default (~/temp/test.zip)")
parser.set_defaults()

# Parse the arguments (defaults to parsing sys.argv)
(options, args) = parser.parse_args()

# Here would be a good place to check what came in on the command line and
# call parser.error("Useful message") to exit if all is not well
if len(args) > 0 and (1 != options.inputDir or 1 != options.outputFile):
parser.error("Additional arguments are not supported\nYou can only change the inputDir or outputFile using the -d and -f options.\nType zippy.py -h for help.\n")


# Do the actual work
zipper(options.inputDir, options.outputFile)

Thursday, July 9, 2009

Weekend

My Arduino has arrived and I'm stoked =P Now I need to make some time to mess around with it. There are some oscilloscope projects I'm interested in fiddling with. Link Link Link

This morning I found a nifty little snippet for adding an ascii spinner to your output. So if you have a long process, which we face often here at work, you can have this displaying to let you know it's doing stuff.

And of course this Saturday is when Mom, Lowell, and my Grandparents are arriving for a week long visit =D To say we're excited is an understatement. So much to do in just a week.

Ben is looking into some local positioning systems. I don't know much about these yet so some investigation is needed. Surely there's a way to use bluetooth or rfid in a manner similar to how gps works.

Wednesday, July 8, 2009

Arduino GPS guidance

I've done a little bit of digging on GPS guidance for the Arduino, my main concern being accuracy of the unit. I've got several projects backed up in my head that involve GPS to some extent, the main project being the Lawnmowbot. But it seems that these projects are in jeopardy as I've found out that the accuracy of the GPS unit ( http://www.robotshop.us/adafruit-gps-logger-shield-kit-arduino-1.html ) is 5 to 10 meters - that's almost 33 feet! I can't mow a lawn leaving a 10 meter buffer ring around obstacles, infact for my yard that may only be one stripe down the center. So unless we can figure out some fancy workaround, the Lawnmowbot is going to have to be shelved. One idea I had is to mount two or three GPS units onto the mowbot. They'll be fixed (and known) relative to eachother, so perhaps we can come up with a method to trim down the error based on their readings and their known distances from eachother. I dunno, I'll probably have to buy one and tinker with it for a while. Worst case, I move on to the next GPS project - I'm thinking a UAV based on a R/C helicopter; 10 meters error shouldn't be detrimental for something like that :)

Monday, July 6, 2009

Arduino + Fridge + Beer = Happiness

Now this is a project worth working on =P link

this is the code from the project. there is likely some cleanup that can be done, or expansion.


/*
Purpose: Temperature Regulator for a Kegerator with LCD display.
Using a LM35 and Arduino to check temperature and display current temp to an LCD.
Also the Arduino will turn a Solid State Relay on/off within a defined temp range
-LM35 connected to 5V, Grd, Analog Pin 0
-Serial LCD connected to 5V, Grd, Digital Pin 1 (tx pin)
-SS Relay connected to Grd, Digital Pin 12
-Back Light Button connected to Digital Pin 3, Grd, 5V via 10K resistor (pin pulled HIGH in open state).

Many thanks to Brutus@ brutusweb.com and Mikal @ the Arduino forums for all the help and inspiration!
*/

#define ledPin 13 // LED connected to digital pin 13
#define lm35 0 // LM35 on Analog 0
#define blightPin 3 // Momentary switch for back light to digital pin 3
#define relayPin 7 // Relay connected to digital pin 7

unsigned long last_temperature_check_time = 0;
unsigned long last_lcd_turn_on_time = 0;

void sendlcd(byte command) //Quick function to send LCD commands.
{
Serial.print(command, BYTE);
}

void setup() // run once, when the sketch starts
{
analogReference(INTERNAL); //using internal voltage reference ~1.1v
pinMode(ledPin, OUTPUT); // sets the digital pin as output
pinMode(lm35, INPUT); // sets the analog pin as input
pinMode(blightPin, INPUT); // sets the digital pin as input
pinMode(relayPin, OUTPUT); // sets the digital pin as output
digitalWrite(ledPin, HIGH);

delay(1000);

Serial.begin(9600);
delay(1000); //Let Ports Stabilize

sendlcd(27); //Reset Command For LCD
sendlcd(122);

delay(500); //Full Reset takes a bit

sendlcd(254); //Clear and Go Home on LCD
sendlcd(1);
digitalWrite(ledPin, LOW); //turn off LED
delay(250);
}

//new loop with millis... sweet

void loop() // run till the end of days or the beer runs out...
{
unsigned long time = millis();
if (time - last_temperature_check_time > 20000) //has it been 20 seconds?
{ last_temperature_check_time = time;
digitalWrite(ledPin,HIGH); //turn on LED for running routine status

//Check Temperature routine
long temp;
long temp1;
long temp2;
long temp_x;
int lm35_val=0;

//delay(500); //Delay to allow stabilized analog read.. not needed?
lm35_val=analogRead(lm35); //read value of center leg of LM35
temp = lm35_val; //output voltage of LM35, 10mV = 1 Degree Celcius
temp1=temp/10; //creates true Celcius reading
temp2=temp%10; //modulus operation to calculate remainder for higher resolution reading

if (temp2 >= 5){
temp_x++;
}

//Send temperature to LCD routine
sendlcd(254); //Clear LCD Screen
sendlcd(1);
Serial.println("Current Temp"); //Print "Current Temp" message
Serial.print(temp1); //Print CelsuisTemperature
Serial.print("."); //Print decimal place
Serial.print(temp2); //Print "Tenths" place
sendlcd(223); //Print degree charater
Serial.print("C"); //Print "C" for Celsuis

digitalWrite(ledPin,LOW); //Turn off LED

//Turn Relay on/off routine
if ((temp1) > 7 ) //check temp is above x degrees
{
digitalWrite (relayPin, HIGH); //if temp is above x degrees turn pin "ON"
}
else if ((temp1) < last_lcd_turn_on_time =" time;"> 10000) // has it been 10 seconds?
{
sendlcd(27); //Turn back light off
sendlcd(42);
sendlcd(0);
}

}

Tuesday, June 30, 2009

On Productivity

One of my biggest problems is distraction and forgetfulness. There are so many projects and related things I want to get to that finding time to do them, heck even remembering to do them, is becoming a real challenge. Thats why when I come across good ideas for addressing this, I try to remember them.

Here is a nice collection from lifehacker for productivity

Try some of those out and let me know what you think.

Oh, and Firefox 3.5 was released =) We finally have multi-threaded Firefox =P

Now my system shouldn't hang so bad when I have 100 tabs open. Woot

More learning on the Arduino...

So I was able to control a servomotor with a potentiometer this past weekend. That was pretty cool, it was pretty much 1:1, half turn on the pot was about a half turn on the servo. I was using Analog out to control the motor, most of the tutorials I've found use PWM on a digital pin. Seems my way is easier (but I'm sure there's a reason for the PWM on digital that I have yet to discover).
Then I got the wild hair to hack an old mouse. Didn't work too well, but nothing detrimental. I cut off the PS/2 plug and stripped the wires: red, green, blue and white - notice anything missing? That's right, the black. But that's not the worst of it, the red wasn't even the power in; the blue was. green happened to be ground, red and white were send and receive. It took 5V @ 20 mA - just about the upper safe threshold for the Arduino. I wrote a program that read the red and white and sent back to the computer what it was reading to print on screen. I know something was going on because I initialized the variables to 0 but all I got on screen was:
mouseVar1 = 1
mouseVar2 = 1
mouseVar1 = 1
mouseVar2 = 1...
so it was reading something, but nothing discernible. I read online that the receive line was supposed to be a clock signal, so I'm guessing the mouse was having a hissy fit because it wasn't getting a clock in. I probably should have read a little more on the PS/2 mouse - somehow you're supposed to get an X, a Y, and 3 mouse clicks from just one line.
Next on the list, I'm going to have to buy a few MOSFETs and start learning about controlling high loads. Though here is a gripe I'm having with all of these tutorials, it's a trap I'm sure I'd fall into if I were writing them as well. It seems to me that the people writing these tutorials know the subject so well they're taking for granted that their audience knows certain things. For example, yesterday I searched between 10 and 15 tutorials for controlling DC motors with the Arduino, no two were alike when it came to the additional circuitry required to control the higher loads. That's fine, it shows the flexibility and different options. But what's not fine is not a single one explained why they chose what they did. Some used MOSFETs, others used H-bridges, some used 2 H-bridges, others used commercial motor control chips, and there were more that used off the shelf motor shields. Another example is the resistors, all the tutorials say "use xx Ohm resistor" and I'm left thinking, "Ok, no problem but... why that value?"
I'm mechanical. If I can't see it, I have a hard time figuring out how it works. A little explanation would go a long way to improving some of these tutorials.

[EDIT] Ok, so I'm learning now :P

It seems that the MOSFET is used for simple one direction high load on/off switching.
The H-bridge is for bi-direction, varying loading, and multiple high loads, and seems to be basically an array of MOSFETs.

here's a good academic link:
http://itp.nyu.edu/physcomp/Labs/DCMotorControl