Sunny Doll + Weather Art Dashboard

For this assignment, I have connected to a weather API that would return the temperature of the city I’m searching for. I’ve made a list of cities in a list and a for loop that would request temperature for the cities every few seconds. The motor is attached to the sunny doll, however, my motor is currently broken so I can’t show the video here. I’ve attached the picture of sunny doll though. The concept is that if a city is hot the motor will spin the doll faster and spin it slower if it’s colder. Sunny doll is a popular item in Japan that people hang on the brink of their roof as a prayer of good weather.

I’ve also connected arduino with processing that would make sine waves of warm/cool color based on the temperature. I’ve attached the video link as below.

Weather Art Dashboard Youtube Video

Sunny Doll Made with Napkin…Will have face by tomorrow
img_0970

Python Code


import pyowm
import time
import serial
# Code to add widgets will go here...

#setting up serial communication
ser = serial.Serial('/dev/cu.usbmodem1411', 9600)
#creating pyowm object
owm = pyowm.OWM(API_key='37ec6df9d804fe26229ccf5d4bfb9a28')
#get address
while True:
    cityID = [(4570707, 'Berkeley'), (3602359, 'Sandy Bay'), (285570, 'Kuwait'), (2205218,'Fiji'), (1259110,'Qadian'), (6362039,'Montesa'),
    (2514896,'Lopera'), (1668341, 'Taipei'), (4930956,'Boston'), (2643743, 'London'),
    (1850147, 'Tokyo'), (734198,'Sokhos'), (5128638, 'New York'), (192950, 'Kenya'),
    (5861900, 'Fairbanks'), (1822029, 'Stoeng Treng'), (2656877, 'Astley'), (3345279, 'Price Town'),
    (256606, 'Nea Kios')]

    cityName = ['Berkeley', 'Sandy Bay', 'Kuwait', 'Fiji', 'Qadian', 'Montesa',
    'Lopera', 'Taipei', 'Boston', 'London',
    'Tokyo', 'Sokhos', 'New York', 'Kenya', 'Fairbanks', 'Stoeng Treng',
    'Astley', 'Price Town', 'Nea Kios']

    for city in cityID:
        observation = owm.weather_at_id(city[0])
        print("city: " + str(city[1]))
        w = observation.get_weather()
        temp = w.get_temperature('celsius')
        temp = temp['temp']
        print temp
        if int(temp) >= 20:
            print 'HOT'
            ser.write(b'' + str(255) + str(city[1]))
        elif int(temp) < 20 & int(temp) >= 10:
            print 'Meh'
            ser.write(b'' + str(120)+ str(city[1]))
        elif int(temp) < 10:
            print 'COLD'
            ser.write(b'' + str(80)+ str(city[1]))
        time.sleep(1)

Arduino Code


/*
 * one pot fades one motor
 * modified version of AnalogInput
 * by DojoDave <http://www.0j0.org>
 * http://www.arduino.cc/en/Tutorial/AnalogInput 
 * Modified again by dave
 */
float data;
int potPin = 0;   // select the input pin for the potentiometer
int motorPin = 9; // select the pin for the Motor
int val = 0;      // variable to store the value coming from the sensor
String str = "";

void setup() {
  Serial.begin(9600);
}
void loop() {
//  val = analogRead(potPin);    // read the value from the sensor, between 0 - 1024
//  Serial.println(val);
//  analogWrite(motorPin, val); // analogWrite can be between 0-255
  if(Serial.available() > 0) {
    data = Serial.parseFloat();
    Serial.println(data);
    analogWrite(motorPin, data); // analogWrite can be between 0-255
  }
}

Processing Code


import processing.serial.*;
Serial port;
String portname = "/dev/cu.usbmodem1411";
int SerialVal = 0;
String myString = null;
int xspacing = 16;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave
int r = 255;
int warmIncrement = 0;
int coldIncrement = 0;
int g = 255;
int b = 255;
String buf="";
int cr = 13;  // ASCII return   == 13
int lf = 10;  // ASCII linefeed == 10
float theta = 0.0;  // Start angle at 0
float amplitude = 500.0;  // Height of wave
float period = 500.0;  // How many pixels before the wave repeats
float dx;  // Value for incrementing X, a function of period and xspacing
float[] yvalues;  // Using an array to store height values for the wave
String[] cityName = {"Berkeley", "Sandy Bay", "Kuwait", "Fiji", "Qadian", "Montesa", 
  "Lopera", "Taipei", "Boston", "London", "Tokyo", "Sokhos", "New York", "Kenya",
  "Fairbanks", "Stoeng Treng", "Astley", "Price Town", "Nea Kios"};
int cityIndex = 0;

void setup() {
  size(1300, 800);
  w = width+16;
  dx = (TWO_PI / period) * xspacing;
  yvalues = new float[w/xspacing];
  
 port = new Serial(this, portname, 9600);
 port.bufferUntil('\n');
}

void draw() {
 while (port.available() > 0) {
   myString = port.readStringUntil(lf);
   if (myString != null) {
     print(myString);  // Prints String
     SerialVal = int(myString);  // Converts and prints float
     if (SerialVal == 255) {
       //textSize(100);
       //fill(190, 190, 190);
       //text(cityName[cityIndex], 500, 400);
       //cityIndex += 1; 
       r = 255;
       g = 50 + warmIncrement;
       b = 0 + warmIncrement;
       warmIncrement += 50;
       if (warmIncrement > 255){
         warmIncrement = 0;
       }
     } else if (SerialVal == 120) {
       //textSize(100);
       //fill(190, 190, 190);
       //text(cityName[cityIndex], 500, 400);
       //cityIndex += 1; 
       r = 190;
       g = 190;
       b = 190;
     } else {
       //textSize(100);
       //fill(190, 190, 190);
       //text(cityName[cityIndex], 500, 400);
       //cityIndex += 1; 
       r = 0 + coldIncrement;
       g = 180 + coldIncrement;
       b = 255;
       coldIncrement += 50;
       if (coldIncrement > 255){
         coldIncrement = 0;
       }
     }
     println("val="+SerialVal);
   }
 }
 calcWave();
 renderWave();
}

void calcWave() {
  // Increment theta (try different values for 'angular velocity' here
  theta += 0.02;
  // For every x value, calculate a y value with sine function
  float x = theta;
  for (int i = 0; i < yvalues.length; i++) {
    yvalues[i] = sin(x)*amplitude;
    x+=dx;
  }
}

void renderWave() {
  noStroke();
  fill(r, g, b);
  // A simple way to draw the wave with an ellipse at each location
  for (int x = 0; x < yvalues.length; x++) {
    ellipse(x*xspacing, height/2+yvalues[x], 16, 16);
  }
}

Leave a Reply