Monday, September 27, 2010
Moving to http://rickology.tumblr.com
http://rickology.tumblr.com
Tuesday, August 24, 2010
AVR GCC Makefile build project
Anyway, the code is on Github, and I will be updating it with whatever positive improvements I find.
http://github.com/ricklon/avrgcc-macosx-makefile
Friday, July 02, 2010
Makerbot Heated Platform 2.0
img_5591.jpg
Originally uploaded by flirianders.
Just some quick notes on the experience. Overall not difficult, and straightforward. However:
1. Remember to get Kapton tape.
2. Remember to obtain solder paste.
3. Think about the color of led you would like. It comes with red, but you can always substitute your favorite color.
4. Wasted time on soldering 3 wires onto an adapter. Could have just used a servo cable instead.
5. The thermistor solders to the PCB in an annoying way.
So you have to solder one wire then put Kapton tape over it and the solder the other wire. More room could be made for this in the design.
I'm planning to work with Matt from Fubar Labs to re work the aluminum so that it screws together flush. I'm worried the extruder head will crash into the exposed bolts.
That's all for now.
Monday, April 12, 2010
Thoughts on the Adafruit protoshield
So why would you stack a proto shield? Well, in my case I have a nice Serial Display and an awesome Serial shield from Mark Sproul. So that has to go on top, doesn't make sense to stack things on top of your output display anyway. I've got a nice GPS shield from Adafruit. Oops, that not got stackale headers either. Anyway a decent accelerometer from Adafruit on a break out board. I'd like to combine all that info together, and equipment together. The theory goes, stack on an Arduino the GPS shield, add the accelerometer on a proto shield, and finally the serial shield with a 2x16 read out of the serial data.
I'll get this done, once I've got my stackable headers.
Tuesday, April 06, 2010
Adafruit Wave Shield Kit 1.1
Originally uploaded by flirianders.
Yea! Another kit assembled, and just shy of being ready to try out. It's bed time, and I'll have to check it out in detail tomorrow.
Monday, April 05, 2010
Completed GPS Logger
Completed GPS Logger
Originally uploaded by flirianders.
Yea. it's done and works. Now I'm looking forward to playing with it and and see about incorporating it into some new projects.
In general the "make it" section of the Adafruit site was great. Easy to follow and solder. It was a lot tougher following the steps in the "use it section." Being on netbook and going through section was somewhat confusing. There steps where the wires need be configured one way to test the GPS unit, and another for testing the SD card, and then plugging it all back together. For some reason it wasn't as clear.
So I soldered in an extra row of header pins and just jumped the wires over to reconfigure easily. Made it easy to try the different configurations.
I found that it was critical that the SD Cards be formatted in fat16. Reading through the forums, that seemed to really trip people up. GParted on Ubuntu made formatting for fat16 very easy.
The last issue was that there was multiple versions of the code to upload to test with and it wasn't clear which worked with the 328 chip. Also, it wasn't clear if the memory hack for serial by bring the buffer down to 32 was necessary for the 328 chip. I don't think it was but I'm not sure, I'll have to check that out.
I was thinking with the one kind of hack I'd like to do is have timestamp of when the position were recorded and then sync to a photo set for gathering geolocation data.
Thursday, April 01, 2010
Not March Madness: Adafruit GPS Log Shield
Adafruit GPS Shield
Originally uploaded by flirianders.
Yea, I get to do something nice and physical tonight. I soldered up the Adafruit GPS log shield and didn't have to write a program to see if it worked. So satisfying. I'm going to got o bed around 11pm.
No longer do I have to program from 10pm to midnight, and then debug until satisfied. I can do it tomorrow. Yea! Another thought about March madness is some projects had physical components, then the Arduino sketch, and then some program that listened to the serial port. That program would have to talk to some web server, and ... so on. Tough to get all that done in one day.
Here's a Flickr set of the fun I had:
http://www.flickr.com/photos/rickanderson/sets/72157623626704103/
Next time I promise no iPhone documentation.I'll get my real camera.
Wednesday, March 31, 2010
March Madness Challenge - Day 31
I'd like to do a manual calibration for brightness and compare it to the automatic version. Since the analogRead function yields a 10 bit value at 4.9mV per unit it's possible to calculate what resistor needs to be place on each color in order to calibrate them with physical resistors and then not need the Arduino to calculate the relative values.
http://www.youtube.com/watch?v=QmNnJd9drYs
int redPin = 9; // LED connected to digital pin 9 int greenPin = 11; int bluePin = 10; int pins[] = { redPin, greenPin, bluePin }; int photoPin = 0; int redPot = 1; int greenPot = 2; int bluePot = 3; int photoVal = -1; int rr, gg, bb = -1; int minmax, rmax, gmax, bmax = 0; void setup() { Serial.begin(9600); Serial.println("Start"); pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); digitalWrite(redPin, HIGH); digitalWrite(greenPin, HIGH); digitalWrite(bluePin, HIGH); digitalWrite(redPin, LOW); delay(500); rmax = analogRead(photoPin); digitalWrite(redPin, HIGH); digitalWrite(greenPin, LOW); delay(500); gmax = analogRead(photoPin); digitalWrite(greenPin, HIGH); digitalWrite(bluePin, LOW); delay(500); bmax = analogRead(photoPin); digitalWrite(bluePin, HIGH); sendMax(); minmax = min(rmax, min(gmax, bmax)); setRGB(255, 255, 255); } void setRGB(int red, int green, int blue) { //These values are the 10 bit values, they need to be mapped to minmax //For some reason some values were mapping negative red = map(red, 0, 1023, 0, minmax); green = map(green, 0, 1023, 0, minmax); blue = map(blue, 0, 1023, 0, minmax); sendRGB(red, green, blue); red = map(red, 0, minmax, 255, 0); green = map(green, 0, minmax, 255, 0); blue = map(blue, 0, minmax, 255, 0); analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue); sendRGB(red, green, blue); } void sendRGB(int red, int green, int blue) { Serial.print(" { \"red\" : "); Serial.print(red); Serial.print(", \"green\" : "); Serial.print(green); Serial.print(", \"blue\" : "); Serial.print(blue); Serial.print("}"); } void sendMax() { Serial.print(" { \"rmax\" : "); Serial.print(rmax); Serial.print(", \"gmax\" : "); Serial.print(gmax); Serial.print(", \"bmax\" : "); Serial.print(bmax); Serial.println("}"); } void loop() { rr = analogRead(redPot); gg = analogRead(greenPot); bb = analogRead(bluePot); setRGB(rr, gg, bb); sendRGB(rr, gg, bb); Serial.print(" { \"minmax\" : "); Serial.print(minmax); Serial.println("}"); }
Tuesday, March 30, 2010
March Madness Challenge - Day 30
Here's the important part:
str = $("form").serialize().split("&").sort().join("&");
hex_str = hex_sha1(str);
console.log(str + "&sig=" + hex_str);
Full code:
Monday, March 29, 2010
March Madness Challenge - Day 29
This code could be crossed with the httpserver mechanism and it could be controlled from outside of Second Life.
http://www.youtube.com/watch?v=eZWtsDzr0Qw
// touch to trigger binary actions involving llSetPrimitiveParams integer trigger=FALSE; default { touch_start(integer nn) { if (trigger==FALSE) { llSetPrimitiveParams([PRIM_POINT_LIGHT, TRUE, <1, 1, 1>, 1.0, 10.0, 0.75] ); llSetPrimitiveParams([PRIM_SIZE, <0.5, 0.5, 0.5>]); llSetPrimitiveParams( [PRIM_ROTATION, ZERO_ROTATION] ); rotation yrot = llEuler2Rot( < 0, 15 * DEG_TO_RAD, 0 > ); integer ii; for (ii = 0; ii < 59; ii++) { llSetPrimitiveParams( [PRIM_ROTATION, llGetRot() * yrot] ); } llSetPrimitiveParams([PRIM_POSITION, llGetPos() + <0,0,1>]); trigger=TRUE; } else { llSetPrimitiveParams([PRIM_POINT_LIGHT, FALSE, <1, 1, 1>, 1.0, 10.0, 0.75] ); llSetPrimitiveParams([PRIM_SIZE, <2, 2, 2>]); integer ii; integer increase; for (ii = 0; ii < 50; ii++) { llSetPrimitiveParams([PRIM_POSITION, llGetPos() + <0,0,1>]); } for (ii = 0; ii < 50; ii++) { llSetPrimitiveParams([PRIM_POSITION, llGetPos() + <0,0,-1>]); } trigger=FALSE; } } }
Sunday, March 28, 2010
March Madness Challenge - Day 28
httpserver.lsl
key requestURL; string gURI; integer CHANNEL = 43; integer LINK_TARGET = -1; integer gPosterPrim = 1; default { state_entry() { requestURL = llRequestURL(); // Request that an URL be assigned to me. llOwnerSay((string) llGetLinkNumber()); llOwnerSay((string) llGetNumberOfPrims()); llMessageLinked(gPosterPrim,0,gURI,gURI); } on_rez(integer param) { // Triggered when the object is rezzed, like after the object has been sold from a vendor llResetScript();//By resetting the script on rez forces the listen to re-register. } touch_start(integer number) { llOwnerSay("My URI: " + gURI); llSay(0,"linknum: " + (string)llGetLinkNumber()); llSay(0, gURI); llMessageLinked(gPosterPrim,0,gURI,gURI); } link_message(integer sender_num, integer num, string msg, key id) { llOwnerSay(msg); llMessageLinked(gPosterPrim,0,gURI,gURI); } changed (integer change) { if (change && CHANGED_REGION ) { requestURL = llRequestURL(); // Request that an URL be assigned to me. } else { llOwnerSay("No need to update URL."); } } http_request(key id, string method, string body) { if ((method == URL_REQUEST_GRANTED) && (id == requestURL) ){ // An URL has been assigned to me. llOwnerSay("LSL server obj: " + (string)llGetKey()); llOwnerSay("URI: " + body); llSay(CHANNEL, body); gURI = body; requestURL = NULL_KEY; } else if ((method == URL_REQUEST_DENIED) && (id == requestURL)) { // I could not obtain a URL llOwnerSay("There was a problem, and an URL was not assigned: " + body); requestURL = NULL_KEY; } else if (method == "POST") { list headers = [ "x-script-url", "x-path-info", "x-query-string", "x-remote-ip", "user-agent", "x-secondlife-shard", "x-secondlife-object-name", "x-secondlife-object-key", "x-secondlife-region", "x-secondlife-local-position", "x-secondlife-local-rotation", "x-secondlife-local-velocity", "x-secondlife-owner-name", "x-secondlife-owner-key" ]; integer pos = ~llGetListLength(headers); while( ++pos ) { string header = llList2String(headers, pos); llOwnerSay(header + ": " + llGetHTTPHeader(id, header)); } // Anincoming message was received. string time = llGetTimestamp(); llOwnerSay("lslhttpserver (" + time + ") Received information from the outside: " + body); llHTTPResponse(id,200,"Thank you for calling. All of our operators are busy."); } else { // An incoming message has come in using a method that has not been anticipated. llHTTPResponse(id,405,"Unsupported Method"); } } }
post.lsl
key requestid; // just to check if we're getting the result we've asked for; all scripts in the same object get the same replies string uri; integer listen_handle; string gURI; key gServerPrimKey; integer gPrimServer = 2; default { state_entry() { llMessageLinked(gPrimServer,0,"Send gPrimURI","Send gPrimURI"); } on_rez(integer param) { // Triggered when the object is rezzed, like after the object has been sold from a vendor llResetScript();//By resetting the script on rez forces the listen to re-register. } link_message(integer sender_num, integer num, string msg, key id) { llOwnerSay(msg); gURI = msg; } touch_start(integer number) { llOwnerSay("My URI: " + gURI); llSay(0,"linknum: " + (string)llGetLinkNumber()); llSay(0, gURI); llMessageLinked(gPrimServer,0,"Send gPrimURI","Send gPrimURI"); requestid = llHTTPRequest(gURI, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"], "time=" + llGetTimestamp() +"¶meter2=world"); } http_response(key request_id, integer status, list metadata, string body) { string time = llGetTimestamp(); if (request_id == requestid) llOwnerSay( "http resp(" + time + ") key: " + (string)request_id); llOwnerSay( "http resp(" + time + ") status: " + (string)status); llOwnerSay( "http resp(" + time + ") metadata: " + (string)metadata); llOwnerSay( "http resp(" + time + ") body: " + body); llWhisper(10, " Whisper to test box"); } }
Saturday, March 27, 2010
March Madness Challenge - Day 27
I wrote a quick serial console for the Seriality API using jQuery, also, I have the RGB slider control project written. However, the serial.write() function seems to not do anything today. I went back to my original on/off code from Day 23 and it failed to work too, even though it had worked fine originally. So I'm going to post the code for the Serial Console and call it a night, and use some fresh eyes tomorrow to figure out why the one way communication is happening.
Friday, March 26, 2010
March Madness Challenge - Day 26
It only set's the values if it understands and leaves the values with the previous value. This should be a nice feature if used with sliders because there would be no off and on flickering it just stays on at the last combination it had.
This program also just echoes back the setting sent to it. Nice thing to look for for debugging. This is also a tool to be used for testing since, I know what went in should match what come out.
Finally, I added a map function that reverses HIGH, LOW and makes to analog numbers feel more natural. Also, I need to find a way to test that using the map function the way I'm using it really results in balance colors.
/*
* Day 26 RGB calibrated fading code with serial controls
*/
char str[11];
int redPin = 9; // LED connected to digital pin 9
int greenPin = 11;
int bluePin = 10;
int pins[] =
{
redPin, greenPin, bluePin
};
int photoPin = 0;
int photoVal = -1;
int rr, gg, bb = -1;
int minmax, rmax, gmax, bmax = 0;
void setup() {
Serial.begin(9600);
Serial.println("Start");
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(redPin, LOW);
delay(500);
rmax = analogRead(photoPin);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(500);
gmax = analogRead(photoPin);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(500);
bmax = analogRead(photoPin);
digitalWrite(bluePin, HIGH);
sendMax();
minmax = min(rmax, min(gmax, bmax));
setRGB(255, 255, 255);
}
void setRGB(int red, int green, int blue)
{
red = map(red, 0, minmax, 255, 0);
green = map(green, 0, minmax, 255, 0);
blue = map(blue, 0, minmax, 255, 0);
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void sendRGB(int red, int green, int blue)
{
Serial.print(" { \"red\" : ");
Serial.print(red);
Serial.print(", \"green\" : ");
Serial.print(green);
Serial.print(", \"blue\" : ");
Serial.print(blue);
Serial.println("}");
}
void sendMax()
{
Serial.print(" { \"rmax\" : ");
Serial.print(rmax);
Serial.print(", \"gmax\" : ");
Serial.print(gmax);
Serial.print(", \"bmax\" : ");
Serial.print(bmax);
Serial.println("}");
}
void loop()
{
int ii = 0;
int nn = 0;
char num[2];
int rgb = 0;
boolean keepgoing = true;
while (keepgoing)
{
while (Serial.available() )
{
{
str[ii] = Serial.read();
num[nn] = str[ii];
//Echo the character as you type
//Serial.write(str[ii]);
if (str[ii] == 44)
{
if (rgb == 0)
{
rr = atoi(num);
nn = -1;
rgb++;
}
else if (rgb == 1)
{
gg = atoi(num);
nn = -1;
rgb++;
}
}
if (str[ii] == 0x0d )
{
keepgoing = false;
if (rgb == 2)
{
bb = atoi(num);
nn = -1;
rgb = 0;
}
sendRGB(rr,gg, bb);
setRGB(rr, gg, bb);
}
ii++;
nn++;
}
}
}
str[ii] = 0;
Serial.println();
Serial.println(str);
setRGB(rr, gg, bb);
}
Thursday, March 25, 2010
March Madness Challenge - Day 24
/*
* Echo Serial on the Arduino
* with advice from Mark Sproul
*/
char str[10];
void setup() {
Serial.begin(9600);
Serial.println("Start");
}
void loop()
{
int ii = 0;
boolean keepgoing = true;
while (keepgoing)
{
while (Serial.available() )
{
{
str[ii] = Serial.read();
//Echo the character as you type
//Serial.write(str[ii]);
if (str[ii] == 0x0d )
{
keepgoing = false;
}
ii++;
}
}
}
str[ii] = 0;
Serial.println();
Serial.println(str);
delay(200);
}
Wednesday, March 24, 2010
March Madness Challenge - Day 24
Also, I need to figure out how to use the BitBucket embed. Would be much nicer.
Screen is awesome
Look for your serial port:
ls /dev/tty.*
screen /dev/tty.usbserial-ADxxx
and you are goog to go!
Tuesday, March 23, 2010
March Madness Challenge - Day 23
I was thinking how neat it would be to be able to reach out to a serial device through the browser. Did some quick searching and found the Seriality API browser plugin. Tested it out and it works well on Mac OS X, and in Firefox. So for tonight I will take my JSON RGB Calibration project and hook it to a web page hosted locally in a web browser.
Started to move my code over to Bit Bucket. The project code can be found here: March Madness
I've got a nifty on off switch. It's a pause on color and other weird things, thing.
//*
* The RGB Calibrator
*
* Find, and monitor max brightness of red, green, and blue in an RGB led
*/
int redPin = 9; // LED connected to digital pin 9
int greenPin = 11;
int bluePin = 10;
int pins[] =
{
redPin, greenPin, bluePin
};
int i =0;
int photoPin = 0;
int potPin = 1;
int photoVal = -1;
int r,g,b = -1;
int rmax, gmax, bmax = 0;
int rmin, gmin, bmin = 1024;
char on = '-';
long interval = 500;
long previousMillis = 0;
void setup()
{
Serial.begin(9600);
// Serial.println("Setup done");
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(redPin, LOW);
delay(1000);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(1000);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(1000);
digitalWrite(bluePin, HIGH);
}
void loop()
{
if (i > 2) //The number of LEDS being measured
{
i = 0;
}
if (Serial.available()) {
on = Serial.read();
}
if (on == '!' ) {
digitalWrite(pins[i], LOW);
photoVal = analogRead(photoPin);
switch (i)
{
case 0: //red led
r = photoVal;
rmin = min(rmin, r);
rmax = max(rmax, r);
break;
case 1: //green led
g = photoVal;
gmin = min(gmin, g);
gmax = max(gmax, g);
break;
case 2: //blue led
b = photoVal;
bmin = min(bmin, b);
bmax = max(bmax, b);
break;
default: //should not happen
break;
}
Serial.print ("{ \"entry\" :");
Serial.print(" { \"photoVal\" : ");
Serial.print(photoVal);
Serial.print(", \"rmax\" : ");
Serial.print(rmax);
Serial.print(", \"gmax\" : ");
Serial.print(gmax);
Serial.print(", \"bmax\" : ");
Serial.print(bmax);
Serial.print(", \"rmin\" : ");
Serial.print(rmin);
Serial.print(", \"gmin\" : ");
Serial.print(gmin);
Serial.print(", \"bmin\" : ");
Serial.print(bmin);
Serial.print(", \"r\" : ");
Serial.print(r);
Serial.print(", \"g\" : ");
Serial.print(g);
Serial.print(", \"b\" : ");
Serial.print(b);
Serial.println("}}");
if (millis() - previousMillis > interval) {
previousMillis = millis();
digitalWrite(pins[i], HIGH);
i++;
}
}
else
{
digitalWrite(pins[i], HIGH);
}
}
Monday, March 22, 2010
March Madness Challenge - Day 22
Python
import serial
import simplejson as json
ser = serial.Serial('/dev/tty.usbserial-A7004qpc',19200)
while 1:
try:
entry = json.loads(ser.readline())
print entry
print entry[u'entry'].keys()
except KeyboardInterrupt:
raise
except:
print "value not json"
Arduino RGB Calibration JSON code
/*
* The RGB Calibrator
*
* Find, and monitor max brightness of red, green, and blue in an RGB led
*/
int redPin = 9; // LED connected to digital pin 9
int greenPin = 11;
int bluePin = 10;
int pins[] =
{
redPin, greenPin, bluePin
};
int i =0;
int photoPin = 0;
int potPin = 1;
int photoVal = -1;
int r,g,b = -1;
int rmax, gmax, bmax = 0;
int rmin, gmin, bmin = 1024;
long interval = 500;
long previousMillis = 0;
void setup()
{
Serial.begin(19200);
// Serial.println("Setup done");
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(redPin, LOW);
delay(1000);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(1000);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(1000);
digitalWrite(bluePin, HIGH);
}
void loop()
{
if (i > 2) //The number of LEDS being measured
{
i = 0;
}
digitalWrite(pins[i], LOW);
photoVal = analogRead(photoPin);
switch (i)
{
case 0: //red led
r = photoVal;
rmin = min(rmin, r);
rmax = max(rmax, r);
break;
case 1: //green led
g = photoVal;
gmin = min(gmin, g);
gmax = max(gmax, g);
break;
case 2: //blue led
b = photoVal;
bmin = min(bmin, b);
bmax = max(bmax, b);
break;
default: //should not happen
break;
}
Serial.print ("{ \"entry\" :");
Serial.print(" { \"photoVal\" : ");
Serial.print(photoVal);
Serial.print(", \"rmax\" : ");
Serial.print(rmax);
Serial.print(", \"gmax\" : ");
Serial.print(gmax);
Serial.print(", \"bmax\" : ");
Serial.print(bmax);
Serial.print(", \"rmin\" : ");
Serial.print(rmin);
Serial.print(", \"gmin\" : ");
Serial.print(gmin);
Serial.print(", \"bmin\" : ");
Serial.print(bmin);
Serial.print(", \"r\" : ");
Serial.print(r);
Serial.print(", \"g\" : ");
Serial.print(g);
Serial.print(", \"b\" : ");
Serial.print(b);
Serial.println("}}");
if (millis() - previousMillis > interval) {
previousMillis = millis();
digitalWrite(pins[i], HIGH);
i++;
}
}
Sunday, March 21, 2010
March Madness Challenge - Day 21
Hmmm.... interesting maybe this could be made automatic and not need a manual override. If it appears one is brighter than another after calibration a manual setting should be possible.
Well. After a bit of work I got the basics of this running. I ran to a very interesting set of issues. The RGB led I used is common anode vs common cathode. So after a while of confusion it was resolved that LOW is on, and HIGH is off for that configuration for the Arduino. That brought up the question of why does the AnnoyLatron work at all then. Turns, out I was writing analog values to RGB led. What that did was show values from dark to bright, as opposed to on and off values. So the larger the number the dimmer it got. Smaller the number the brighter it got. It worked in inverse. So for this kind of project it didn't matter too much. I'll go look at the code a little later and see if there were any other "interesting" things in there.
Anyway, once that was resolved the rest was pretty simple, but testing it out and making sure the basics were right took a lot of time. I also ended up with a few questions like how do the analog pins sample and return the values detected. I want to confirm that it's strictly a voltage reading. Then I started worrying about noise, and calibrating the calibrator. I had a potentiometer hooked to the pin 1 next the photoresistor pin 0. I pulled that off the bread board, and the values changed to be more consistent. Also, there was light in the room. I was treating that as a constant.
Things did stabilize. So I was getting decent readings, and I got some decent data on max brightness. However, there was a real problem with the detecting minimum brightness. I figured out a few obvious issues, but some where the min is being assigned a 0, and I can't tell if that is a real reading or not. Also, once maxs and mins are found I didn't provide a way to have maxs and mins readjust overtime and experimentation. THe program needs a reset to adjust as things change. So if I do add some potentiometers to calibrate the brightness, I would need to be able to find those new values without restarting.
Not perfect but way fun.
/*
* The RGB Calibrator
*
* Find, and monitor max brightness of red, green, and blue in an RGB led
*/
int redPin = 9; // LED connected to digital pin 9
int greenPin = 11;
int bluePin = 10;
int pins[] =
{
redPin, greenPin, bluePin
};
int i =0;
int photoPin = 0;
int potPin = 1;
int photoVal = -1;
int r,g,b = -1;
int rmax, gmax, bmax = 0;
int rmin, gmin, bmin = 1024;
long interval = 500;
long previousMillis = 0;
void setup()
{
Serial.begin(19200);
Serial.println("Setup done");
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(redPin, LOW);
delay(1000);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(1000);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
delay(1000);
digitalWrite(bluePin, HIGH);
}
void loop()
{
if (i > 2) //The number of LEDS being measured
{
i = 0;
}
digitalWrite(pins[i], LOW);
photoVal = analogRead(photoPin);
switch (i)
{
case 0: //red led
r = photoVal;
rmin = min(rmin, r);
rmax = max(rmax, r);
break;
case 1: //green led
g = photoVal;
gmin = min(gmin, g);
gmax = max(gmax, g);
break;
case 2: //blue led
b = photoVal;
bmin = min(bmin, b);
bmax = max(bmax, b);
break;
default: //should not happen
break;
}
Serial.print(" photoVal: ");
Serial.print(photoVal);
Serial.print(" rmax: ");
Serial.print(rmax);
Serial.print(" gmax: ");
Serial.print(gmax);
Serial.print(" bmax: ");
Serial.print(bmax);
Serial.print(" rmin: ");
Serial.print(rmin);
Serial.print(" gmin: ");
Serial.print(gmin);
Serial.print(" bmin: ");
Serial.print(bmin);
Serial.print(" r: ");
Serial.print(r);
Serial.print(" g: ");
Serial.print(g);
Serial.print(" b: ");
Serial.println(b);
if (millis() - previousMillis > interval) {
previousMillis = millis();
digitalWrite(pins[i], HIGH);
i++;
}
}
Saturday, March 20, 2010
March Madness Challenge - Day 20
http://www.youtube.com/watch?v=qobngrJLDNw
/*
* The AnnoyAlatron 2000
*
* Accelorometer controled red, green, blue leds, and piezo buzzer
* ADXL335
*/
#define NOTE_C6 1047
#define NOTE_E6 1319
#define NOTE_G6 1568
int notes[] = {
NOTE_C6, NOTE_E6,NOTE_G6 };
int piezoPin = 8;
int greenPin = 9; // LED connected to digital pin 9
int redPin = 10;
int bluePin = 11;
int Z = 0;
int Y = 1;
int X = 2;
int r,g,b = 0;
int xmax, ymax, zmax = 0;
int xmin, ymin, zmin = 1024;
float xg, yg, zg;
void rgb (int r, int g, int b)
{
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
}
//From the Adafruit forums
float to_g(const int axis_value)
{
const float arduino_power_supply = 5;
const float sensor_power_supply = 3.3;
const float zero_g_bias = sensor_power_supply / 2;
float voltage = axis_value * arduino_power_supply / 1024;
return (voltage - zero_g_bias) * 1000 / 330;
}
void setup()
{
Serial.begin(19200);
Serial.println("Setup done");
tone(piezoPin, notes[0], 200);
tone(piezoPin, notes[1], 200);
tone(piezoPin, notes[2], 200);
}
void loop()
{
r = analogRead(Z);
g = analogRead(Y);
b = analogRead(X);
xg = to_g(b);
yg = to_g(g);
zg = to_g(r);
Serial.print(" X: ");
Serial.print(b);
Serial.print(" xg: ");
Serial.print(xg);
Serial.print(" Y: ");
Serial.print(g);
Serial.print(" yg: ");
Serial.print(yg);
Serial.print(" Z: ");
Serial.print(r);
Serial.print(" zg: ");
Serial.println(zg);
xmin = min(xmin, b);
ymin = min(ymin, g);
zmin = min(zmin, r);
xmax = max(xmax, b);
ymax = max(ymax, g);
zmax = max(zmax, r);
tone(piezoPin, (r + notes[0]), 10);
tone(piezoPin, (g + notes[1]), 10);
tone(piezoPin, (b + notes[2]), 10);
r = map(r, zmin, zmax, 0, 255);
g = map(g, ymin, ymax, 0, 255);
b = map(b, xmin, xmax, 0, 255);
rgb(r, g, b);
}
Friday, March 19, 2010
March Madness Challenge - Day 19
Non working code, sorry.
function getAllContacts() {
var contacts = ContactsApp.getAllContacts();
for (var i = 0; i < contacts.lengh; i++)
{
var contact = [];
contact.push(contacts[i].getFullName());
contact.push(contacts[i].getPrimaryEmail());
contact.push(contacts[i].getEmailAddresses());
contact.push(contacts[i].getHomeAddress());
contact.push(contacts[i].getWorkAddress());
contact.push(contacts[i].getPager());
contact.push(contacts[i].getHomeFax());
contact.push(contacts[i].getWorkFax());
contact.push(contacts[i].getHomePhone());
contact.push(contacts[i].getWorkPhone());
contact.push(contacts[i].getMobilePhone());
contact.push(contacts[i].getNotes());
contact.push(contacts[i].getUserDefinedField());
contact.push(contacts[i].getUserDefinedFields());
range = SpreadsheetApp.getActiveSheet().getRange((3+i),1,1,contact.length);
range.setValues([contact]);
}
}
Thursday, March 18, 2010
March Madness Challenge - Day 18
//Apply force and torque to large sphere in Second LIfe
default
{
touch(integer i)
{
llSetStatus(STATUS_PHYSICS, TRUE);
llSetForceAndTorque(<0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF>, <10,0x7FFFFFFF,10>,0);
}
}
Wednesday, March 17, 2010
March Madness Day 17
testdata.json
{"foo":"bar", "baz":1, "a":2}
jsonstdio.py
import sys
import json
def getjson(jd):
jsondata = json.loads(jd)
print "JSON Data: "
print repr(jsondata)
def main():
stdin = sys.stdin.read()
getjson(stdin)
if __name__=="__main__":
main()
How to run:
python jsonstdio.py < testdata.json
Tuesday, March 16, 2010
March Madness Challenge - Day 16
/*
* Accelerometer controlled red, green, blue leds
* ADXL35
*/
int redPin = 9; // LED connected to digital pin 9
int greenPin = 10;
int bluePin = 11;
int Z = 0;
int Y = 1;
int X = 2;
int r,g,b = 0;
int xmax, ymax, zmax = 0;
int xmin, ymin, zmin = 1024;
void rgb (int r, int g, int b)
{
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
}
void setup() {
Serial.begin(9600);
Serial.println("Setup done");
}
void loop() {
r = analogRead(Z);
g = analogRead(Y);
b = analogRead(X);
xmin = min(xmin, b);
ymin = min(ymin, g);
zmin = min(zmin, r);
xmax = max(xmax, b);
ymax = max(ymax, g);
zmax = max(zmax, r);
/*
Serial.print("xmin: ");
Serial.print(xmin);
Serial.print(", xmax: ");
Serial.print(xmax);
Serial.print(" ymin: ");
Serial.print(ymin);
Serial.print(", zmax: ");
Serial.println(zmax);
*/
r = map(r, zmin, zmax, 0, 255);
g = map(g, ymin, ymax, 0, 255);
b = map(b, xmin, xmax, 0, 255);
rgb(r, g, b);
/*
Serial.print(r);
Serial.print(", ");
Serial.print(g);
Serial.print(", ");
Serial.println(b);
*/
}
Monday, March 15, 2010
March Madness Challenge - Day 15
I did find this useful set of examples when I was flailing around Maintaing a Google Calendar from a Spreadsheet, Reprise.
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "MakeEvent", functionName: "getEventFromSpreadSheet"} ];
sheet.addMenu("Events", menuEntries);
}
function getEventFromSpreadSheet () {
var range = SpreadsheetApp.getActiveRange();
var vals = range.getValues();
var Title = vals[0];
var Description = vals[1];
var Summary = vals[2];
var StartTime = vals[3];
var EndTime = vals[4];
var Location = vals[5];
var Guests = vals[6];
var GuestsStatus = vals[7];
var Invites = vals[8];
var Options = {description: Description,
guests: Guests,
location: Location,
sendInvites: Invites
};
makeEvent(Title, StartTime, EndTime, Options);
}
function makeEvent(Title, StartTime, EndTime, Options) {
var cal = CalendarApp.getDefaultCalendar();
cal.createEvent(Title, new Date(StartTime), new Date(EndTime), {location:'blah loc'}, {description: 'blah desc'});
}
W00t the fixes just clicked. Given my comments below here is the fixed code:
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "MakeEvent", functionName: "getEventFromSpreadSheet"} ];
sheet.addMenu("Events", menuEntries);
}
function getEventFromSpreadSheet () {
var range = SpreadsheetApp.getActiveRange();
var vals = range.getValues();
var Title = vals[0][0];
var Description = vals[0][1];
var Summary = vals[0][2];
var StartTime = vals[0][3];
var EndTime = vals[0][4];
var Location = vals[0][5];
var Guests = vals[0][6];
var GuestsStatus = vals[0][7];
var Invites = vals[0][8];
var Options = {description: Description,
guests: Guests,
location: Location,
sendInvites: Invites
};
makeEvent(Title, StartTime, EndTime, Options);
}
function makeEvent(Title, StartTime, EndTime, Options) {
var cal = CalendarApp.getDefaultCalendar();
cal.createEvent(Title, new Date(StartTime), new Date(EndTime), Options);
}
And here is the CSV of the spreadsheet I tested with:
Title,Description,Summary,StartTime,EndTime,Location,Guests,GuestsStatus
MyTest,MyTest Description,MyTest Summary,9/22/2010 10:00:00,9/22/2010 11:00:00,Home Test,0000@noemail.gmail.com,yes
MyTest1,MyTest Description,MyTest Summary,10/22/2010 0:00:00,10/22/2010 0:00:00,Home Test,0000@noemail.gmail.com,yes
Sunday, March 14, 2010
March Madness Challenge - Day 14
I really liked the Logger object, but it started causing errors so I removed that code. I put it back and everything seemed good so I moved on.
Hint to get oriented for selecting range values:
var range = SpreadsheetApp.getActiveSheet().getRange(1,1,1,8);
Browser.msgBox("row: " + range.getRowIndex() + " rows: " + range.getNumRows() + " col: " + range.getColumnIndex() + " cols: " + range.getNumColumns() + " Vals: " + range.getValues());
The code for tonight. Make a Google Apps Script and paste the code in. However, I use the JSON.stringify library for the full dump of the event Object. It has to be pasted in at the bottom of the file. You can get that code here:
This code dumps the entire object including the functions. So if you need analyze what Google is doing this approach get's every piece of data and method for the object. Some times it's nice to get all the detail. As a short cut I use JSON.stringify to dump the data held in some of the fields. If you can read the JSON this is nice because it directly translates into the object, and you can keep drilling down.
function dumpEventObject() {
// The code below will retrieve all the events for the user's default calendar and
// display the description of the first event
var cal = CalendarApp.getDefaultCalendar();
var events = cal.getEvents(new Date("July 21, 2009 EST"), new Date());
var text = "";
var range;
event = [];
Logger.log(JSON.stringify(events[0]));
//set the headers
var key;
for (key in events[0]){
event.push(key);
}
range = SpreadsheetApp.getActiveSheet().getRange(2,1,1,event.length);
range.setValues([event]);
//add the dat into appropriate rows/columns
var i;
for (i = 0; i < events.length; i++)
{
event = [];
for (ev in events[i] )
{
if (typeof events[i][ev] != 'function') {
event.push(JSON.stringify(events[i][ev]));
} else {
event.push(events[i][ev]);
}
}
range = SpreadsheetApp.getActiveSheet().getRange((3+i),1,1,event.length);
range.setValues([event]);
}
}
Dumps only the data. This is useful to get information you need and work with. I can see cleaning this up more and really make a nice library. This doesn't use JSON.stringify. It iterates through any arrays and separates them on a new line. So all the email address for guests of an event are clearly listed.
function dumpEventData () {
// The code below will retrieve all the events for the user's default calendar and
// display the description of the first event
var cal = CalendarApp.getDefaultCalendar();
var events = cal.getEvents(new Date("July 21, 2009 EST"), new Date());
var event = [];
//set the headers
for (var key in events[0]){
if ((typeof events[0][key] != 'function' ) && ( typeof events[0][key] != 'undefined' ) ){
event.push(key);
}
}
var range = SpreadsheetApp.getActiveSheet().getRange(2,1,1,event.length);
range.setValues([event]);
for (var i = 0; i < events.length; i++)
{
event = [];
for (key in events[i] )
{
if ((typeof events[i][key] != 'function' ) && ( typeof events[i][key] != 'undefined' ) ){
if ((typeof events[i][key] == 'object') && (events[i][key].length))
{
var txt = "";
for (var k in events[i][key])
{
txt = txt + events[i][key][k] + "\n";
}
event.push(txt);
}
else
{
event.push(events[i][key]);
}
}
}
range = SpreadsheetApp.getActiveSheet().getRange((3+i),1,1,event.length);
range.setValues([event]);
}
}
I'm pretty excited about this new capability. If anyone has feedback I'd appreciate it. This is my first rough crack at Google Apps Scripting. I think there is some amazing potential here.
Saturday, March 13, 2010
March Madness Challenge - Day 13
from itertools import izip
c1 = ["ft","fu","fs","fv"]
c2 = ["gt","gu","gs","gv"]
c3 = ["ht","hu","hs","hv"]
c4 = ["it","iu","is","iv"]
c = [c1,c2,c3,c4]
ind = ["r1","r2","r3","r4"]
def showit(c):
for i in c:
for k in i:
print k
def izipit(c):
for (i,k) in izip(ind, c):
print i
print k
def zipit(ind, c):
d = dict(zip(ind, c))
return d
print "showit(c)"
showit(c)
print "izipit(c)"
izipit(c)
print "zipit(c)"
print zipit(ind, c)
Friday, March 12, 2010
March Madness Challenge - Day 12
In the meantime I wrote this script which sends messages from the sender prim to the receiver prim and tells it to fade away the more it is clicked.
The Red Message Sending Box/Prim:
integer chan = -12878;
default
{
state_entry()
{
llOwnerSay( "Sending prim ready");
}
touch_start(integer total_number)
{
llSay(chan, "Hello, this is from RK");
}
}
The Blue Spinny Thing that receives messages from Red Message Box.
float spin_rate = 0.1;
integer chan = -12878;
float alpha = 1.0;
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
llListen(chan, "", "", "");
llTargetOmega(<1.0,0.0,0.0>,spin_rate,0.2);
}
listen(integer channel, string name, key id, string message)
{
llSay(0,"I heard:"+message);
alpha = alpha - 0.1;
llSetAlpha(alpha,ALL_SIDES);
if (alpha < 0.0)
{
alpha = 1.0;
}
}
}
Thursday, March 11, 2010
March Madness Challenge - Day 11
#test the default args
def test2args(arg1="default1", arg2="default2"):
print "arg1: " + arg1
print "arg2: " + arg2
def test2argskwargs(arg1="default1", arg2="default2", **kwargs):
print "arg1: " + arg1
print "arg2: " + arg2
for k, v in kwargs:
print "%s=%s" % (k, v)
test2args()
test2args("1","2")
args = ("3","4")
test2args(*args)
#test2args(a="5", b="6")
test2argskwargs("3","4", a="5", b="6")
Wednesday, March 10, 2010
March Madness Challenge - Day 10
Live Page
<!DOCTYPE html>
<html>
<head>
<title>QUnit Cookie test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAyOcYQmrUZiRTkZD33sBhThSYG2nKbTfLUqOyuY0R-KaU9CNsSxQHWg8je-XfTEMamlZKbXxG4Z752A">
</script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">
</script>
<script type="text/javascript" charset="utf-8">
google.load("jquery", "1.4.2");
</script>
<link rel="stylesheet" href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js"></script>
<script type="text/javascript" src="jquery.cookies.2.2.0.min.js">
</script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
test("a basic test example", function() {
ok( true, "this test is fine" );
var value = "hello";
equals( "hello", value, "We expect value to be hello" );
});
test("Are cookies available?", function() {
ok(true, $.cookies.test());
});
//Are there existing cookies
test("Is there an existing cookie?", function() {
equals(true, $.cookies.get('newcookie')[0].test, "Cookie exists from last time.");
});
//Load cookie values nd check
//Create a new cookie test
test("Created new cookie.", function () {
var markers = [];
var marker = {test: true, date: new Date() } ;
markers.push(marker);
$.cookies.set('newcookie', markers);
var cookiedata = $.cookies.get('newcookie');
equals(true, cookiedata[0].test, "Cookie data is true");
});
//if not created create cookie data
//find and display existing markers
});
</script>
<style type="text/css">
div.c1 {width:100%; height:100%}
</style>
</head>
<body>
<h1 id="qunit-header">QUnit Cookie Tests</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
</body>
</html>
Tuesday, March 09, 2010
March Madness Challenge - Day 9
Preview URL
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Where in the world is my dog pooin!</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAyOcYQmrUZiRTkZD33sBhThSYG2nKbTfLUqOyuY0R-KaU9CNsSxQHWg8je-XfTEMamlZKbXxG4Z752A"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" charset="utf-8">
google.load("jquery", "1.4.2");
</script>
<script type="text/javascript" src="jquery.cookies.2.2.0.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var markers = [];
function setPosition(position) {
console.log("setPosition: lat: " + position.coords.latitude + " lng: " + position.coords.longitude );
var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
console.log("Map: " + map);
map.setCenter(location, 13);
addMarker(location, "Quality: " + $("input[name='quality']:checked").val() + "Date: " + new Date());
}
function addMarker(location, msg) {
var marker = new google.maps.Marker({
position: location,
map: map,
title: msg
});
markers.push(marker);
$.cookies.set('dogdata', markers);
}
function detectBrowser() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map_canvas");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '600px';
mapdiv.style.height = '800px';
}
}
if( !$.cookies.test() )
{
alert("Please enable cookies for this program to track very important information");
}
//if not created create cookie data
//find and display existing markers
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$("#setcenter").bind("click", function(e){
console.log("bind click");
navigator.geolocation.getCurrentPosition(setPosition);
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setPosition);
} else {
alert("navigator.geolocation not available.");
}
// detectBrowser();
navigator.geolocation.getCurrentPosition(setPosition);
});
</script>
</head>
<body >
<h1>Warning the SQLite poo storage db is not installed yet.</h1>
<h2>This means you have to never reload the page to record all the necessary poo data.</h2>
<div>Where in the world does my dog poo?</div>
<div>Use the geolocation information to mark the spots your dog marks, with optional quality indicator.</div>
<form name="controls">
<div>Quality: </div>
<input type="radio" name="quality" value="1">1</input>
<input type="radio" name="quality" value="2">2</input>
<input type="radio" name="quality" value="3" checked="checked">3</input>
<input type="radio" name="quality" value="4">4</input>
<input type="radio" name="quality" value="5">5</input>
<button name="setcenter" id="setcenter">Mark!</button>
</form>
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
Monday, March 08, 2010
March Madness Challenge - Day 8
Compatibiltiy note: Marking poo locations works in Firefox 3.5 and higher, iPhone, and maybe Droid. When SQLite is added it will end up being only iPhone or Droid.
One thing that took way too much time to debug was how get the code recognized as HTML5. One way is to strip out all the things indicating that it's not HTML 5 and include only an html tag by itself. This let's the browser choose.
And here's the code:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Where in the world is my dog pooin!</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAyOcYQmrUZiRTkZD33sBhThSYG2nKbTfLUqOyuY0R-KaU9CNsSxQHWg8je-XfTEMamlZKbXxG4Z752A"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" charset="utf-8">
google.load("jquery", "1.4.2");
</script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
function setPosition(position) {
console.log("setPosition: lat: " + position.coords.latitude + " lng: " + position.coords.longitude );
var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
console.log("Map: " + map);
map.setCenter(location, 13);
addMarker(location, "msg");
}
function addMarker(location, msg) {
var marker = new google.maps.Marker({
position: location,
map: map,
title: msg
});
}
function detectBrowser() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map_canvas");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '600px';
mapdiv.style.height = '800px';
}
}
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$("#setcenter").bind("click", function(e){
console.log("bind click");
navigator.geolocation.getCurrentPosition(setPosition);
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setPosition);
} else {
alert("navigator.geolocation not available.");
}
// detectBrowser();
navigator.geolocation.getCurrentPosition(setPosition);
});
</script>
</head>
<body >
<h1>Warning the SQLite poo storage db is not installed yet.</h1>
<h2>This means you have to never reload the page to record all the necessary poo data.</h2>
<div>Where in the world does my dog poo?</div>
<div>Use the geolocation information to mark the spots your dog marks, with optional quality indicator.</div>
<form name="controls">
<div>Quality: </div>
<input type="radio" name="quality" value="1">1</input>
<input type="radio" name="quality" value="2">2</input>
<input type="radio" name="quality" value="3">3</input>
<input type="radio" name="quality" value="4">4</input>
<input type="radio" name="quality" value="5">5</input>
<button name="setcenter" id="setcenter">Mark!</button>
</form>
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
Sunday, March 07, 2010
March Madness Challenge - Day 7
Yesterdays entry was way unsatisfying. I wanted to enumerate all the possible RGB combinations, but was impatient, and made errors. Today's project took on the issue of determining what exact PWM values were set on this RGB led, and getting a starting point to calibrate the brightness between leds so get a decent color mix. Well, I didn't get to the issue of calibration, but I did get connect 2 thumb joysticks to the led and adjust the brightness values by reading the joystick data. Hook up 3 potentiometers and you can dial the exact combination RGB values you want.
/*
* 3 Potentiometers or Joystick controled rgb led
*/
int redPin = 9; // LED connected to digital pin 9
int greenPin = 10;
int bluePin = 11;
int potR = 0;
int potG = 1;
int potB = 2;
int r,g,b = 0;
void rgb (int r, int g, int b)
{
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
}
void setup() {
Serial.begin(9600);
Serial.println("Setup done");
}
void loop() {
r = analogRead(potR);
g = analogRead(potG);
b = analogRead(potB);
r = map(r, 0, 1023, 0, 255);
g = map(g, 0, 1023, 0, 255);
b = map(b, 0, 1023, 0, 255);
rgb(r, g, b);
Serial.print(r);
Serial.print(", ");
Serial.print(g);
Serial.print(", ");
Serial.println(b);
}
Saturday, March 06, 2010
March Madness Challenge - Day 6
int redPin = 9; // LED connected to digital pin 9
int greenPin = 10;
int bluePin = 11;
void fadeIn(int pin, int fadeInc, int delayValue)
{
for (int fadeValue = 0; fadeValue<= 255; fadeValue += fadeInc)
{
analogWrite(pin, fadeValue);
delay(delayValue);
}
}
// fade out from max to min in increments
void fadeOut(int pin, int fadeInc, int delayValue)
{
for (int fadeValue = 255; fadeValue >= 0; fadeValue -= fadeInc)
{
analogWrite(pin, fadeValue);
delay(delayValue);
}
}
void rgb (int r, int g, int b)
{
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
delay(30);
}
void setup() {
Serial.begin(9600);
// diagnostic lights on
fadeIn(redPin, 5, 60);
fadeOut(redPin, 5, 60);
analogWrite(redPin, 0);
delay(30);
fadeIn(greenPin, 5, 60);
fadeOut(greenPin, 5, 60);
analogWrite(greenPin, 0);
delay(30);
fadeIn(bluePin, 5, 60);
fadeOut(bluePin, 5, 60);
analogWrite(bluePin, 0);
delay(30);
Serial.print(redPin);
Serial.print(", ");
Serial.print(greenPin);
Serial.print(", ");
Serial.println(bluePin);
}
void loop() {
for (int r = 0; r <= 255; r++)
{
for (int g = 0; g <= 255; g++)
{
for (int b = 0; b <= 255; b++)
{
rgb(r, g, b);
Serial.print(r);
Serial.print(", ");
Serial.print(g);
Serial.print(", ");
Serial.println(b);
}
}
}
}
Friday, March 05, 2010
March Madness Challenge - Day 5
A bit of preparation is required. I'm using the python library huBarcode. You will need to run some flavor of "git clone git://github.com/hudora/huBarcode.git" followed by python setup.py install. Last option: sudo easy_install huBarcode
This code would have worked brilliantly if not for this error:
IOError: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/huBarcode-0.56p5-py2.4.egg/qrcode/qrcode_data/qrv1_0.dat'
And here is the code:
#
# Turn a username/password into a QRCode
#
#
import getopt
import sys
import getpass
import qrcode
#Describe usage
def usage():
print "-h, --help\n -v, --verbose\n -u, --username\n -p, --password\n -f, --filename\n"
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "h:u:pvf:", ["help", "username=", "password", "filename"])
except getopt.GetoptError, err:
#print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
username = None
password = None
verbose = False
filename = "default.png"
for o, a in opts:
if o == "-v":
verbose = True
elif o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-u", "--username"):
username = a
if verbose:
print "username: " + username
elif o in ("-p", "--password"):
password = getpass.getpass("Enter password: ")
if verbose:
print "password: " + password
elif o in ("-f", "--filename"):
filename = a;
if verbose:
print "filename: " + filename
else:
assert False, "unhandled option"
if username is None:
print "-u, --username was not given"
usage()
sys.exit(2)
if password is None:
print "-p, --password was not given"
usage()
sys.exit(2)
encoder = qrcode.QRCodeEncoder( username + "\n" + password)
print encoder.get_ascii()
encoder.save(filename, 3)
if __name__ == "__main__":
main()
Thursday, March 04, 2010
March Madness Challenge - Day 4
setTimeout("runShow(" + (i + 1) + ")", holdTime);
setTimeout(function () {runShow(i + 1);}, holdTime);
If I was executing more code or had more values in my function then anonymous function route is much easier to type, and less error prone. Other thing, I love jQuery, but none of my Javascript entries have used it. Sort of just checking out the plain old DOM and seeing what can be done.
Without further ado here is the html, css, and js.
test.html
====
====
rgb.css
====
====
rgb.js
====
====
Wednesday, March 03, 2010
March Madness Challenge - Day 3
Well not really. I wrote the delay function, but it's not the recommended technique. Why block all actions on a page waiting for one thing to happen. The above code is closer. But doesn't solve the key issues. The setTimeout needs to have values assigned for red, green, and blue for the showColor function. Additionally, this code requires a web page. I needed to upload that. I needed to assign an event listener, and lastly had to resolve an issue about setTimeout being inside a loop. The issue being the loop sets all the "setTimeout"s as quickly as possible, so all time outs occur almost in parallel. I could be wrong about that, but I did have some kind of issue. I needed to examine Javascript fader examples more closely, and I would have figured it out, but ran out of time.
Ok. I wrote a super quick brute force demonstration of the problem. This requires Firebug in order to run. Paste the following code into the Firebug console. Warning whatever web page you are viewing in firebug will go through some awful color contortions.
function showColor(red, green, blue)
{ document.body.style.backgroundColor="rgb(" + red + "," + green + "," + blue + ")";
console.log("Color set");
}
console.log("Start");
console.log('setTimeout("showColor(0,0,0)",10000);');
setTimeout("showColor(0,0,0)",10000);
console.log('setTimeout("showColor(10,10,10)",9000);');
setTimeout("showColor(10,10,10)",9000);
console.log('setTimeout("showColor(100,100,100)",8000);');
setTimeout("showColor(100,100,100)",8000);
console.log('setTimeout("showColor(200,200,200)",7000);');
setTimeout("showColor(200,200,200)",7000);
console.log('setTimeout("showColor(200,0,0)",6000);');
setTimeout("showColor(200,0,0)",6000);
console.log('setTimeout("showColor(100,0,0)",5000);');
setTimeout("showColor(100,0,0)",5000);
console.log('setTimeout("showColor(0,100,0)",4000);');
setTimeout("showColor(0,100,0)",4000);
console.log('setTimeout("showColor(0,100,100)",3000);');
setTimeout("showColor(0,100,100)",3000);
console.log("Done")
So nesting the setTimeout inside SetTimeout should be interesting. Onto the next challenge.
Tuesday, March 02, 2010
March Madness Challenge - Day 2
#
# Hello World Get Opt for Python
#
#
import getopt
import sys
import getpass
#Describe usage
def usage():
print "-h, --help\n -v, --verbose\n -u, --username\n -p, --password\n"
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "h:u:pv", ["help", "username=", "password"])
except getopt.GetoptError, err:
#print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
username = None
password = None
verbose = False
for o, a in opts:
if o == "-v":
verbose = True
elif o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-u", "--username"):
username = a
print "username: " + username
elif o in ("-p", "--password"):
password = getpass.getpass("Enter password: ")
print "password: " + password
else:
assert False, "unhandled option"
if __name__ == "__main__":
main()
Monday, March 01, 2010
March Madness Challenge - Day 1
* Get list of emails address from the guests invited to a Google event
*/
(function () {
var guests, emails;
//Handily there is class associated to each guest
guests = document.getElementsByClassName("guest");
emails = "";
//iterate the guests
for (var i in guests)
{
if (guests.hasOwnProperty(i))
{
//each guest name/email is the first child textContent of guest element
emails = emails + guests[i].childNodes[0].textContent + ",\n";
}
}
alert(emails);
})();
---
In order to run this you need to can run it in the Firebug console. Testing this, you need to create a Google Calendar Event add a few people to it. Find an old event with people in the guest list.Another way to run this would be as a Greasemonkey script. Hey, that might be a good project for tomorrow.
I did discover the source code for Google Hosted applications is not quite the same as it's standard gmail offerings. To run this in a hosted environment you would need to use the following to select the guests:
(function () {//Final Note: Not Happy with editor at Blogger.com
var guests, emails, guest, tmp;
guests = document.getElementsByClassName("ep-gl-guest");
emails = "";
guest = "";
tmp = "";
for ( var i in guests)
{
if (guests.hasOwnProperty(i))
{
guest = guests[i].id;
tmp = guest.split(":i");
emails = emails + tmp[1] + ",\n";
}
}
alert(emails);
})();