PHYSCI 70: Introduction to Digital Fabrication

Marie Konopacki

Final Project Proposal

About Me

Week 10

This week, we had to demonstrate a communication between a microcontroller and another device. I decided I wanted to use the government’s weather API, and I was thinking of ways to use the output devices we have in stock. I then decided to use my LED strip after realizing I really liked working with it a few weeks ago! I decided to depict a week’s forecast with 7 of the pixels on the LED strip.

At first I thought about translating sunny/cloudy/rainy/snowy into pixels, but I wanted to interact with a range of colors instead, so I used the temperature in Fahrenheit. So for temperatures between 70 and 80, for instance, it would show an orangish color, whereas a temperature in between 30 and 40 would be a purplish blue. I used a LAN connection to allow my computer to interact with the microcontroller. I created 5 different city options, and, when clicked on my IP address site, the LED strip would display the city color code and 7 days worth of temperatures.

I think it turned out well! There were some huge obstacles to overcome, and I found myself constantly debugging. But it all worked out in the end, and I’m happy with the result. I've attached the code below.

Code

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_NeoPixel.h>


// Set up LED strip
#define PIN       14 
#define NUMPIXELS 9 

Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


const char* ssid = "MYWIFINAME";
const char* password =  "MYWIFIPASS";

const String endpoint = "https://api.weather.gov/gridpoints/";

WiFiServer server(80);

void setup() {

  Serial.begin(115200);

  // Set up LED
  strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(10); // Set BRIGHTNESS low to reduce draw (max = 255)

  // Set up wifi

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");
  Serial.println(WiFi.localIP());

  server.begin();

}

int value = 0;

void loop(){
 WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/NYC\">here</a> to show the weather forecast for New York City.<br>");
            client.print("Click <a href=\"/LA\">here</a> to show the weather forecast for Los Angeles.<br>");
            client.print("Click <a href=\"/CAM\">here</a> to show the weather forecast for Cambridge.<br>");
            client.print("Click <a href=\"/MIA\">here</a> to show the weather forecast for Miami.<br>");
            client.print("Click <a href=\"/CHI\">here</a> to show the weather forecast for Chicago.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        if (currentLine.endsWith("GET /NYC")) {
          strip.clear();
          strip.setPixelColor(1, strip.Color(0, 0, 255));
          const String location = "OKX/33,36/forecast";
          getWeather(location);
        }
        if (currentLine.endsWith("GET /LA")) {
          strip.clear();
          strip.setPixelColor(1, strip.Color(252, 254, 2));
          const String location = "LOX/152,44/forecast";
          getWeather(location);
        }
        if (currentLine.endsWith("GET /CAM")) {
          strip.clear();
          strip.setPixelColor(1, strip.Color(164, 22, 2));
          const String location = "BOX/68,76/forecast";
          getWeather(location);
        }
        if (currentLine.endsWith("GET /MIA")) {
          strip.clear();
          strip.setPixelColor(1, strip.Color(255,165,0));
          const String location = "MFL/108,50/forecast";
          getWeather(location);
        }
        if (currentLine.endsWith("GET /CHI")) {
          strip.clear();
          strip.setPixelColor(1, strip.Color(0,128,0));
          const String location = "LOT/75,72/forecast";
          getWeather(location);
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");

  }
}


void getWeather(const String location) {
  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status

    HTTPClient http;

    const String url = endpoint + location;

    http.begin(url); //Specify the URL
    int httpResponseCode = http.GET();  // Make the GET request

    if (httpResponseCode > 0) {   // Execute if we get a good response

      String payload = http.getString();
      Serial.println(httpResponseCode);
      // Serial.println(payload); // Uncomment to view the entire payload

      DynamicJsonDocument doc(15000); // Create a buffer of 10000 bytes

      // Deserialize the JSON document
      DeserializationError error = deserializeJson(doc, payload);

      // Test if parsing succeeds.
      if (error) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        return;
      }

      // Navigate through JSON document, extracting some values
      const int day1 = doc["properties"]["periods"][0]["temperature"];
      const int day2 = doc["properties"]["periods"][2]["temperature"];
      const int day3 = doc["properties"]["periods"][4]["temperature"];
      const int day4 = doc["properties"]["periods"][6]["temperature"];
      const int day5 = doc["properties"]["periods"][8]["temperature"];
      const int day6 = doc["properties"]["periods"][10]["temperature"];
      const int day7 = doc["properties"]["periods"][12]["temperature"];

      findColor(day1, 2);
      findColor(day2, 3);
      findColor(day3, 4);
      findColor(day4, 5);
      findColor(day5, 6);
      findColor(day6, 7);
      findColor(day7, 8);
      strip.show();
      http.end();   // Close the connection
    }
  }
}


void findColor(int daytemp, int pixel) {
  if (daytemp << 10) {
    strip.setPixelColor(pixel, strip.Color(0, 0, 255));
    strip.show();
  };
  if (daytemp >= 10 && daytemp < 20) {
     strip.setPixelColor(pixel, strip.Color(3, 140, 184));
     strip.show();
  };
  if (daytemp >= 20 && daytemp < 30) {
    strip.setPixelColor(pixel, strip.Color(3, 110, 253));
    strip.show();
  };
  if (daytemp >= 30 && daytemp < 40) {
    strip.setPixelColor(pixel, strip.Color(3, 9, 253));
    strip.show();
  };
  if (daytemp >= 40 && daytemp < 50) {
    strip.setPixelColor(pixel, strip.Color(103, 9, 236));
    strip.show();
  };
  if (daytemp >= 50 && daytemp < 60) {
    strip.setPixelColor(pixel, strip.Color(138, 2, 224));
    strip.show();
  };
  if (daytemp >= 60 && daytemp < 70) {
    strip.setPixelColor(pixel, strip.Color(208, 75, 202));
    strip.show();
  };
  if (daytemp >= 70 && daytemp < 80) {
    strip.setPixelColor(pixel, strip.Color(208, 75, 111));
    strip.show();
  };
  if (daytemp >= 80 && daytemp < 90) {
    strip.setPixelColor(pixel, strip.Color(230, 75, 69));
    strip.show();
  };
  if (daytemp >= 90 && daytemp < 100) {
    strip.setPixelColor(pixel, strip.Color(230, 37, 19));
    strip.show();
  };
  if (daytemp >= 100) {
    strip.setPixelColor(pixel, strip.Color(225, 0, 0));
    strip.show();
  };
}