It's almost spring, which means that it's also almost tornado season in Indiana, my home state. For this lab, I was inspired by the Live Wire project by Natalie Jeremijenko at Xerox PARC and tried to build a tornado mobile that spun in relationship to Indiana's 2009 tornado data.
I got the 2009 tornado data from http://www.spc.noaa.gov/wcm/data/2009_torn.csv and selected only tornados in Indiana (along with some other data scrubbing and formatting). Next, I used Python to set-up a serial connection with the Arduino so that I could feed it each tornado's Enhanced Fujita score (EF score). The EF scale rates tornados' strength by various attributes, including windspeed (http://en.wikipedia.org/wiki/Enhanced_Fujita_Scale). The Arduino translated each tornado's EF score to its respective windspeed (conveniently between 65 and 200+ mph, acceptable values for the DC motor) and fed that value to the DC motor. When the Python script is run, it loops through each day of the year from 1 - 366, prints the day of the year, and when it finds a day that had a tornado, prints the date, time, and the tornado's EF score to the console. Components, code, photos, and comments are below.
Components Used
Arduino x 1
Breadboard x 1
wires x several
external battery x 1
1K resistor x 1
DC motor x 1
Diode x 1
Transistor x 1
blue construction paper
red plastic coffee stirer
Scotch tape
hot glue gun & hot glue
Python Code
#!/usr/bin/env python
# encoding: utf-8
"""
tornados.py
Created by Emily Wagner on 2011-03-07.
"""
import serial
import time
tornado_data = [
[157005,2009,2,11,'02/11/09',(14, 30),'02:30:00 PM','IN',1], #1 EF value
print 'Error. Why didn\'t the tornado data have valid values?...'
continue
def find_tornados():
"""This function iterates through the calendar looking for
tornadoes in Indiana in 2009."""
import time
ser = serial.Serial('/dev/tty.usbmodem411', 9600)
i = 0
while i < 367:
ser.write('')
print i
j = 0
while j < len(tornado_data):
if i == tornado_data[j][-1]:
date = tornado_data[j][4]
time_of_day = tornado_data[j][6]
ef_score = tornado_data[j][8]
ser.write(str(ef_score))
print (date, time_of_day, ef_score)
time.sleep(1) #pause between tornados
j += 1
time.sleep(0.5) #pause between calendar days
i += 1
if __name__ == '__main__':
calc_DOY()
find_tornados()
Arduino Code
/*
* tornado data controls the speed of one dc motor
* modified version of AnalogInput
* by DojoDave <http://www.0j0.org>
* http://www.arduino.cc/en/Tutorial/AnalogInput
* Modified again by dave
* Modified again by Emily Wagner
*/
int motorPin = 9; // select the pin for the Motor
int val = 0; // variable to store the motor output
int input = 0; // variable for the serial input
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
input = Serial.read();
if (input == 48) {
val = 65;
}
else if (input == 49) {
val = 95;
}
else if (input == 50) {
val = 150;
}
else if (input == 51) {
val = 200;
}
else if (input == 52) {
val = 225;
}
else if (input == 53) {
val = 255;
}
else {
val = 0;
}
Serial.println(val);
analogWrite(motorPin, val); //needed several write statements to get the
analogWrite(motorPin, val); //mobile to spin
analogWrite(motorPin, val);
analogWrite(motorPin, val);
analogWrite(motorPin, val);
}
}
Video
Creator Comments
As you can see from the video, I didn't manage to achieve a totally seamless realization of my idea. I couldn't figure out how to make the DC motor spin at a given speed for only a finite amount of time before moving on to the next tornado, so after it receives the first tornado's data, it continues to spin. Additionally, the centrifugal force from the spinning disturbed the paper mobile's shape, and adding weight or a large mobile weighed down the motor.