Bowlquake

Assignment: DC Motor: Actuation Assignment 1

Collaborators:

Although we rarely feel them, earthquakes occur all around the world, many dozen times per day.  My Bowlquake provides a physical representation of this mysterious occurrence.

The Bowlquake system downloads real-time data from the United States Geological Survey regarding earthquakes that have occurred in the past 24 hours around the world.  The system then initiates "earthquakes" in the bowl to correspond with these actual earthquakes.  The length and intensity of the bowl's quakes bear direct relation to the magnitude of the actual quake; each second of the bowlquake's duration corresponds to an earthquake magnitude of one.

Like an actual earthquake, the bowlquake is initiated underneath the surface, but its effects are most visible to humans on the surface.  And like the vast majority of earthquakes, bowlquakes are benign.

Bowlquake

Bowlquake

Python Code

#!/usr/bin/env python
# encoding: utf-8
"""
bowlquake.py

Created by Daniel N. Byler on 2009-10-15.
Copyright (c) 2009 __Daniel N Byler__. All rights reserved.
"""

import sys
import os
import serial
import urllib2
import time

def serialPrint(output):
	"""Prints output to serial port. Currently requires Arduino app"""
	ser = serial.Serial('/dev/tty.usbserial-A7006RZQ', 9600, timeout=10)
	ser.write(output)
	ser.close()

def urlRead(url):
	"""Reads the given URL"""
	a = urllib2.urlopen(url)
	return a

def populatequakeslist(urlobj):
	"""Populates a list of earthquake magnitudes from given URL object"""
	quakes = []
	for line in urlobj.readlines():
		result = line.split(',')[8]
		try:
			result = int(round(float(result)))
			quakes.append(result)
		except:
			pass
	return quakes

def bowlquake(quakelist):
	"""Sends commands to control the fan."""
	for i in quakelist:
		if i == 1:				#At the 1 level, the motor doesn't
			serialPrint('2')	#...have enough torque to engage, so this
			time.sleep(0.1)		#...gives it a quick jolt
		
		serialPrint(str(i))		#Engage motor via serial command
		print i
		time.sleep(i)			#Length of burst corresponds to magnitude
		serialPrint('0')
		time.sleep(2)			#Pause between quakes

if __name__ == '__main__':
	while True:					#Repeats indefinitely, updating data
		url = "http://earthquake.usgs.gov/eqcenter/catalogs/eqs1day-M1.txt"
		rawdata = urlRead(url)
		quakes = populatequakeslist(rawdata)
		bowlquake(quakes)

Arduino Code

/*
 * Arduino input for earthquake simulator
 * By Dan Byler
 * 
 * Accepts integers 0-8 (although 9 will not throw an error)
 */

int motorPin = 9; // Motor pin
int val = 0;      // Variable for motor output
int theInput = 0; // Variable for serial input

void setup() {
  Serial.begin(9600);
  analogWrite(motorPin, 0);  // Motor starts off
}

void loop() {
  if (Serial.available() > 0) {
	theInput = Serial.read();
	val = (theInput - 48) * 32;   // Adjusts input to 256 scale
	val = constrain(val, 0, 255); // Limits to 255
	analogWrite(motorPin, val);   // Activate motor
  }
}

Layout

Layout