Blowin' in the wind
Description
A cardboard fan changes speed based on the speed of the wind outside. Wind data gathered by a python program calling a Weatherbug station via a JSON API and passed to the Arduino over serial. Use a potentiometer to scale the speed of the fan, so you don't have to keep recalibrating the code.
Materials
Pathetic cardboard fan blade
Pathetic plastic cup base
DC Motor
Diode
Potentiometer
Battery pack
Video
manual demo: http://www.youtube.com/watch?v=rvQoHUaME68
updating with the wind (speeded up 5x): http://www.youtube.com/watch?v=clSxfE0CnfM
Python Code
import simplejson, urllib, serial, time url = 'http://i.wxbug.net/REST/Direct/GetObs.ashx?zip=94720&ic=1&api_key=ITSASECRET' ser = serial.Serial('/dev/ttyACM1',9600) windSpeed = 0 while 1: oldSpeed = windSpeed result = simplejson.load(urllib.urlopen(url)) windSpeed = str(result['windSpeed']) if windSpeed != oldSpeed: ser.write(windSpeed) ser.write('E') print windSpeed time.sleep(15)
Arduino Code
float motorPin = 9; float potPin = A0; float windSpeed = 0; void setup() { Serial.begin(9600); } void loop() { float value = 0; // this part from MrCode at ArduinoForums, took me and apparently many others a long time to figure out how to do the simple task of reading in multi-character integers from serial. //http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1270424569/5 while(1) { /*Read a byte as it comes into the serial buffer*/ char byteBuffer = Serial.read(); if(byteBuffer > -1) //Is the data a valid character? { if(byteBuffer >= '0' && byteBuffer <= '9') //Is the character a digit? /*Yes, shift left 1 place (in decimal), and add floateger value of character (ASCII value - 48)*/ value = (value * 10) + (byteBuffer - '0'); else /*No, stop*/ break; } } float windSpeed = map(value,1,15,31,150); if(windSpeed > 255) { windSpeed = 255; } if(value == 0) { windSpeed = 0; } float potVal = analogRead(potPin); float potMulti = potVal/1023; float motorSpeed = windSpeed*potMulti; // there is a problem with the motors not having enough power to spin up, but enough to keep spinning. so ramp up the power quickly, get it started, then bring it down to a lower level if(motorSpeed < 100) { for(int z=75;z>motorSpeed;z--) { analogWrite(motorPin,z); Serial.println(z); delay(5); } } analogWrite(motorPin,motorSpeed); Serial.println(motorSpeed); }