Lab 6 - DC Motors a.k.a. A Twista, a twista!

Posted by emily

emily's picture

 

Description

Explore motion as an output.

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
[157472,2009,3,8,'03/08/09',(12, 48),'12:48:00 PM','IN',0], #0 ""
[157571,2009,3,8,'03/08/09',(13, 37),'01:37:00 PM','IN',3], #3 ""
[161809,2009,3,8,'03/08/09',(13, 45),'01:45:00 PM','IN',0], #0 ""
[157208,2009,3,8,'03/08/09',(15, 22),'03:22:00 PM','IN',1], #1 ""
[151324,2009,3,8,'03/08/09',(16, 15),'04:15:00 PM','IN',1], #1 ""
[165954,2009,5,14,'05/14/09',(2, 25),'02:25:00 AM','IN',2], #2 ""
[171917,2009,6,11,'06/11/09',(16, 8),'04:08:00 PM','IN',0], #0 ""
[195736,2009,8,4,'08/04/09',(10, 10),'10:10:00 AM','IN',1], #1 ""
[193855,2009,8,19,'08/19/09',(18, 32),'06:32:00 PM','IN',2], #2 ""
[195824,2009,9,20,'09/20/09',(15, 58),'03:58:00 PM','IN',1], #1 ""
]
 
 
 
def calc_DOY():
    """This function converts a date (month and day) into a 
    numbered day of the year between 1 and 366."""
    month_index = [0,31,60,91,121,152,182,213,244,274,305,335]
    i = 0
    while i < len(tornado_data):
        month = tornado_data[i][2]
        day = tornado_data[i][3]
        try:
            day_of_year = (month_index[month - 1]) + day
            tornado_data[i].append(day_of_year)
            i += 1
        except:
            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.
small tornado mobile
0
Your rating: None
Tags: