Lab 5: Security

 

Objective

  • Design a security architecture for your garage door system  
  • Extend the event hub architecture to accommodate another device  
  • Establish more complex conditions an additional sensor.

Requirements

For this lab, you will study Don Borthwick’s story in Case Study 5. While the specific requirements set forth in the narrative should be met, your objective in this lab is to shift from focusing on developing the individual devices, to designing the system as a whole. You should think through the security ramifications of this system and present a system security architecture, with appropriate diagrams and descriptions.

Materials

The items used to complete this lab were:

  • 3x Arduino D1 Mini
  • 3x Micro USB Cable for power and data transfer
  • 5v Relay Switch
  • Raspberry Pi
  • Ultrasonic sensor
  • Red LED
  • Yellow LED
  • Green LED
  • Blue LED
  • 4x 330 Ohm resistors
  • Assorted male-male jumper wires for breadboard
  • 3x Breadboard

 

References

The following references were used in the completion of this lab. Please note that large chunks of code were used as the basis / foundation upon which I could build my particular use case, and can therefore be attributed to their developers:

 

Procedure

These instructions assume you have already soldered the pins to your D1 Mini. If not, complete that task first.

 

First D1 Mini: Stoplight

 

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.    
  2. Take a jumper cable and connect it from a ground (G) output of the Mini to one of the negative rails running along the sides of the breadboard. This will send the ground along the entire row of that breadboard.
  3. Connect three jumper cables to three GPIO pin outputs of your choice. In this example, we will be using D5, D6, and D7.
  4. Connect the other ends of those jumper cables on rows 23, 25, and 27 of your breadboard, as close to the side as possible. These are the positive leads for your LEDs.
  5. Insert the long end of each LED into a hole which is on the same row as a jumper cable from the previous step. You’ll note that there is conveniently an extra hole between each jumper cable from step 4; this is for the ground.
  6. Insert one end of each resistor into the negative rail you established in step 2. Insert the other end along a row where you placed the negative leg of an LED. Once this is done, you should have a positive and negative connection for each LED. See the picture for confirmation.
  7. Plug the micro USB cable into the D1 Mini and insert it into the USB port on your machine. Your system should begin a basic driver installation. Take special note when the OS reports it is done installing; it should inform you of the COM Port the Mini is on.
  8. Obtain the Arduino IDE from https://www.arduino.cc/en/Main/Software, making sure to select your operating system and the latest software version. Install the IDE.
  9. Begin the process of adding the necessary modules for the board by navigating to File > Preferences in the IDE.
  10. Under “Additional Board URLs”, paste in http://arduino.esp8266.com/stable/package_esp8266com_index.json and press OK.
  11. Navigate to Tools > Board > Board Manager and locate “esp8266” from the list. Press install.
  12. Under Tools > Board, select “D1 & D1 Mini”.
  13. Under Tools > Port, select the COM port as reported by the OS in step 7.
  14. You should now be ready to load code. Copy and paste the code as found in the appendix of this document into the IDE. Modify the network SSID and password fields found near the beginning of the code accordingly.
  15. Verify that the code compiles by pressing the “checkmark” button in the upper-left.
  16. Once it has compiled, press the “upload” button (located next to the checkmark) to begin the upload process.
  17. Whenever the D1 mini has power and the specified network is available, it awaits signals from the ultrasonic sensor and responds accordingly.

 

Second D1 Mini: Ultrasonic Sensor

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  2. Mount the ultrasonic sensor across four rows (not columns) of pins.
  3. Connect the ground pin of the D1 to the ground pin of the sensor.
  4. Connect the VCC pin of the sensor to the 5V pin of the D1.
  5. Choose two GPIO pins for use with the pulse and echo pins of the sensor and connect them. Here, D4 and D3 were chosen.
  1. Follow steps 7-16 of the previous D1 mini to upload the corresponding code to it.
  2. Whenever the D1 mini has power and the specified network is available, it will send signals to the stoplight.

Third D1 Mini: Reed Switch

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  2. Connect an LED across two rows of the breadboard.
  3. Connect a jumper from the positive lead of the LED to a GPIO pin. We use D7 here.
  4. Connect a resistor from the negative lead of the LED to the negative side rail of the breadboard.
  5. Connect a jumper from the ground pin of the D1 mini to the ground rail.
  6. Connect one end of the reed switch to a GPIO pin. We use D5 here.
  7. Connect the other end to the ground rail of the breadboard.
  8. Follow steps 7-16 of the first D1 mini to upload the corresponding code to it.
  9. Whenever the reed switch is open, it will send a message via MQTT to the other devices indicating the garage door is “open” and turn off the LED. When it is closed, it will send a “closed” message and turn on the LED.

 

Fourth Device: Relay Switch

  1. Taking the stoplight board from earlier, mount the relay switch onto it. You may need to relocate some LEDs and wiring to make room.
  2. Connect a line from the 8266’s ground to the relay ground.
  3. Connect 5V from the 8266 to the relay.
  4. Connect a GPIO pin from the 8266 to pin D1 of the relay.

Raspberry Pi: Initial Mosquitto Configuration

  1. Start up the Pi and connect it to the same wireless network the D1 minis will be on.
  2. Install the MQTT client with these commands:
    1. sudo apt-get install mosquitto -y
    2. sudo apt-get install mosquitto-clients -y
  3. Open the file /etc/mosquitto/mosquitto.conf for editing.
  4. Add the following line to the bottom of the file and save:
    1. listener 1883
  5. Restart the service with the following command:
    1. sudo service mosquitto restart
  6. Subscribe the Pi to the topic with the following command:
    1. mosquitto_sub -d -t GARAGE
  7. The Pi is now set to listen.

 

Raspberry Pi: Certificate Generation and MQTT SSL

  1. On the Pi, download a certificate generation script with
    1. wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh
  2. Allow it to be executed with
    1. Chmod +x generate-CA.sh
  3. Run the script. It will generate six files, three starting with “CA” and three starting with (likely) raspberrypi, or whatever your Pi’s hostname is.
  4. Run the following commands to copy the certificates to your Mosquitto directory:
    1. sudo cp CA.csr /etc/mosquitto/certs
    2. sudo cp rasberrypi.* /etc/mosquitto/certs
  5. Generate a mosquitto password file with the following command:
    1. cd /etc/mosquitto
    2. mosquitto_passwd -c <desired name of output file> <desired username>
      1. It will then prompt you for a password and finish.
  6. Open /etc/mosquitto/mosquitto.conf for editing and do the following:
    1. Comment out the “listener 1883” line.
    2. Add “listener 8883” to the bottom.
    3. Add “allow_anonymous false” below that.
    4. Add “password_file /etc/mosquitto/<what you named the file in 5b>”
    5. Add “cafile /etc/mosquitto/certs/ca.crt”
    6. Add “certfile /etc/mosquitto/certs/raspberrypi.crt”
    7. Add “keyfile /etc/mosquitto/certs/raspberrypi.key”
  7. Restart mosquitto with
    1. sudo service mosquitto restart
  8. Set up the Pi as its own network hotspot by running
    1. wget -q https://git.io/voEUQ -O /tmp/raspap && bash /tmp/raspap
  9. Restart the pi.
  10. Once it’s back, open a web browser and point it to localhost.
    1. The default username is “admin” and password is “secret”.
    2. Go to “configure hotspot”
    3. Change the SSID if desired.
    4. Go to the “security” tab in the same section and change the password. This will need to match what is in the code on each node.
    5. Save the settings, then press “Stop hotspot” and “Start hotspot”.
    6. The Pi should now be independent and broadcasting an SSID. No Internet connections are necessary, and the nodes can all connect.

Diagram and Reasoning

General Devices

The MQTT broker sits and waits for all incoming messages. While the reed switch is closed, no signals are sent aside from the signal that the switch is closed, and the LED is turned on. When the switch is closed, a new message is sent indicating the switch is closed, which is then broadcast to the other two devices. The Ultrasonic sensor reads this message and then begins pinging for distance. It sends the appropriate message back to the MQTT topic depending on this distance. The stoplight then reads in this message alongside the open/closed information to light the correct LEDs. If it receives a “Closed” message, all LEDs turn off. The relay is activated via the web page, and received the “Open/Closed” messages sent so that it can display the status of the garage on the web page.

The system was designed in this way because it seemed like the most efficient method for directing traffic. No receiving needs to be done by the reed switch, as it is the “catalyst” for the rest of the system. The ultrasonic sensor needs to know when to operate, but also needs to instruct the stoplight, so two-way communication is necessary. The stoplight only needs to be told what to do, so no transmissions are necessary.

 

Security

The Raspberry Pi was configured to run its own, isolated WiFi network, to which the nodes could all connect. It was also configured as a certificate authority, issuing certificates which are then used by Mosquitto to secure communications. Of course, a WPA2 pass code was set on the wireless network itself, and credentials were also added to the MQTT credentials for further security, especially considering the communications are now encrypted with TLS. For further security against most vectors, SSH should be disabled on the Pi, and the root password should be changed to something very obscure.

Thought Questions

  • How did you secure devices that are not inherently secure devices? How does layering security approaches help?
    • I had to utilize the RPi’s ability to act as a CA and host certificates, then create secure connections between it (as an MQTT broker) and the other devices. The 8266s can then connect using WiFiClientSecure. I also added password protection for further security, especially since it is now encrypted. Lastly, I created an entirely isolated network which could be accessed separately from the home network to reduce risks.
  • What was the biggest challenge you overcame in this lab?
    • Figuring out how to make PubSubClient and a Server play along together on one ESP8266. Turns out there was a much better library, ESP8266WebServer, which can handle requests much more quickly and won’t interfere with MQTT’s loop() function.
  • Please estimate the total time you spent on this lab and report.
    • About 7-8 hours. I made the mistake of not eating enough one night before working on this, and my brain pretty much shuts down when I do that.

Appendix

Figure 1: Picture of garage page

Figure 2: Useful Pinout Diagram

 

Lab5Stoplight.ino

#include <ESP8266WebServer.h>

#include <ESP8266WebServerSecure.h>

#include <ESP8266WebServerSecureAxTLS.h>

#include <ESP8266WebServerSecureBearSSL.h>

 

#include <PubSubClient.h>

#include <WiFiClientSecure.h>

//#include <ESP8266WiFi.h>

//#include <ESP8266mDNS.h>

//#include <WiFiUdp.h>

//#include <TimedAction.h>

 

const char* ssid = “”;           

const char* password = “”;              

const char* mqtt_server = “”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “Stoplight”;

const char* fingerprint = “3B 39 AD D0 7A F1 7F 83 4C 0F 68 D4 C7 08 B5 3F 35 BD 4D 36”;

 

int redPin = D5;

int yellowPin = D6;

int greenPin = D7;          

int relayPin = D3;

 

int freaky = LOW;

 

int garOpen = LOW;

 

int timediff = 0;

 

unsigned long lastiter = 0;

int redstate = 0;

 

String garry = “CLOSED”;

 

ESP8266WebServer server(80);

WiFiClientSecure client;

 

PubSubClient pubcli(mqtt_server, 8883, client); // 1883 is the listener port for the Broker

 

void setup() {

 Serial.begin(115200);

 delay(10);

 //set pins

 pinMode(greenPin, OUTPUT);

 pinMode(yellowPin, OUTPUT);

 pinMode(redPin, OUTPUT);

 pinMode(relayPin, OUTPUT);

 digitalWrite(greenPin, LOW);

 digitalWrite(yellowPin, LOW);

 digitalWrite(redPin, LOW);

 digitalWrite(relayPin, LOW);

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 

server.on(“/GARAGE=OPEN”,opened);

 server.on(“/GARAGE=CLOSE”,closed);

 server.on(“/”,render);  

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

if (client.verify(fingerprint,”hostname”)) {

   Serial.println(“certificate matches”);

 } else {

   Serial.println(“certificate doesn’t match”);

 }

 

 //set the message callback function, connect to MQTT broker, subscribe

 pubcli.setCallback(ReceivedMessage);

 if (pubcli.connect(clientID,”user”,”password”)) {

   Serial.println(“Connected to MQTT Broker!”);

 }

 else {

   while(!pubcli.connect(clientID,”user”,”password”)){

   Serial.println(“Connection to MQTT Broker failed…”);

   }

 }

 pubcli.subscribe(mqtt_topic);

 

 

}

 

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 

 char commd = (char)payload[0];

 

 //set the garage open variable

 if (commd == ‘O’) {

   garOpen = HIGH;

   garry = “OPEN”;

 }

 else if (commd == ‘C’) {

   garry = “CLOSED”;

   garOpen = LOW;

 }

 

 //if the garage is open, operate lights. If not, blackout

 if(garOpen == HIGH) {

 

   switch(commd){

     case ‘R’:

       digitalWrite(redPin,HIGH);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,LOW);

       break;

     case ‘Y’:

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,HIGH);

       digitalWrite(greenPin,LOW);

       break;

     case ‘G’:

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,HIGH);

       break;

     case ‘F’:

       freakout();

       break;

   }

 

 

 }

 else {

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,LOW);    

 }

 

}

 

void opened(){

digitalWrite(relayPin,HIGH);

String page = “<h1>GARAGE:”+garry+”</h1><a href=\”/GARAGE=OPEN\”><button>OPEN GARAGE</button></a><br><a href=\”/GARAGE=CLOSE\”><button>CLOSE GARAGE</button></a>”;

server.send(200,”text/html”,page);

}

 

void closed(){

digitalWrite(relayPin, LOW);

String page = “<h1>GARAGE:”+garry+”</h1><a href=\”/GARAGE=OPEN\”><button>OPEN GARAGE</button></a><br><a href=\”/GARAGE=CLOSE\”><button>CLOSE GARAGE</button></a>”;

server.send(200,”text/html”,page);

}

 

void render(){

String page = “<h1>GARAGE:”+garry+”</h1><a href=\”/GARAGE=OPEN\”><button>OPEN GARAGE</button></a><br><a href=\”/GARAGE=CLOSE\”><button>CLOSE GARAGE</button></a>”;

server.send(200,”text/html”,page);

}

 

void loop() {    

   pubcli.loop();

   server.handleClient();

}

 

void freakout(){

 if (millis() > lastiter) {

   digitalWrite(redPin, (redstate) ? HIGH : LOW);

   digitalWrite(yellowPin, (redstate) ? HIGH : LOW);

   digitalWrite(greenPin, (redstate) ? HIGH : LOW);

   redstate = !redstate;

   lastiter = millis()+500UL;

 }

}

 

Lab5Reed.ino

 

#include <PubSubClient.h>

#include <ESP8266WiFi.h>

#include <WiFiClientSecure.h>

//#include <ESP8266mDNS.h>

//#include <WiFiUdp.h>

 

const char* ssid = “”;           

const char* password = “”;

const char* mqtt_server = “”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “GarSense”;

const char* fingerprint = “3B 39 AD D0 7A F1 7F 83 4C 0F 68 D4 C7 08 B5 3F 35 BD 4D 36”;

 

//WiFiServer server(80);

WiFiClientSecure client;

 

PubSubClient pubcli(mqtt_server, 8883, client); // 1883 is the listener port for the Broker

 

int sensorPin = D5;

int cute = D7;

 

int gar = LOW;

 

void setup() {

 pinMode(sensorPin,INPUT_PULLUP);

 pinMode(cute,OUTPUT);

 Serial.begin(115200);

 

WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

//  server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

if (client.verify(fingerprint,”hostname”)) {

   Serial.println(“certificate matches”);

 } else {

   Serial.println(“certificate doesn’t match”);

 }

 

//set callback function, connect to broker

 pubcli.setCallback(ReceivedMessage);

   if (pubcli.connect(clientID,”user”,”password”)) {

   Serial.println(“Connected to MQTT Broker!”);

 }

 else {

   while(!pubcli.connect(clientID,”user”,”password”)){

   Serial.println(“Connection to MQTT Broker failed…”);

   }

 }

 

}

 

//the receivedmessage function here is for later, in case. Not needed by reed switch

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 

 // Handle the message we received

 // Here, we are only looking at the first character of the received message (payload[0])

 // If it is 0, turn the led off.

 // If it is 1, turn the led on.

 if ((char)payload[0] == ‘0’) {

   digitalWrite(cute, HIGH); // Notice for the HUZZAH Pin 0, HIGH is OFF and LOW is ON. Normally it is the other way around.

 }

 if ((char)payload[0] == ‘1’) {

   digitalWrite(cute, LOW);

 }

}

 

void loop() {

 //if the reed is closed but the garage variable is open, set to closed. Do opposite for open.

if(digitalRead(sensorPin)== LOW && gar == HIGH){

 if(pubcli.publish(mqtt_topic,”C”)) Serial.println(“Sent C”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”C”);

 }

 digitalWrite(cute, HIGH);

 gar = LOW;

}

else if(digitalRead(sensorPin) == HIGH && gar == LOW) {

 if(pubcli.publish(mqtt_topic,”O”)) Serial.println(“Sent O”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”O”);

 }

 digitalWrite(cute, LOW);

 gar = HIGH;

}

pubcli.loop();

}

 

Lab5Sonic.ino

 

#include <PubSubClient.h>

#include <NewPing.h>

#include <WiFiClientSecure.h>

#include <ESP8266WiFi.h>

//#include <ESP8266mDNS.h>

//#include <WiFiUdp.h>

 

const char* ssid = “”;           

const char* password = “”;

const char* host = “192.168.43.5”;  

const int httpPort = 80;

const char* mqtt_server = “”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “Sonic”;

const char* fingerprint = “3B 39 AD D0 7A F1 7F 83 4C 0F 68 D4 C7 08 B5 3F 35 BD 4D 36”;

 

int trigPin = D4;    // Trigger

int echoPin = D3;    // Echo

long duration, cm, inches;

 

int garOpen = LOW;

 

int red = 0;

int yellow = 0;

int green = 0;

int freak = 0;

 

int iters = 1;

int realinches = 0;

NewPing sonar(trigPin, echoPin, 360);

//WiFiServer server(80);

WiFiClientSecure client;

 

PubSubClient pubcli(mqtt_server, 8883, client); // 1883 is the listener port for the Broker

 

void setup() {

 //Serial Port begin

 Serial.begin (115200);

 //Define inputs and outputs

 pinMode(trigPin, OUTPUT);

 pinMode(echoPin, INPUT);

 

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 //server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

if (client.verify(fingerprint,”hostname”)) {

   Serial.println(“certificate matches”);

 } else {

   Serial.println(“certificate doesn’t match”);

 }

 

 //set mqtt callback, connect to broker and subscribe

   pubcli.setCallback(ReceivedMessage);

 if (pubcli.connect(clientID,”user”,”password”)) {

   Serial.println(“Connected to MQTT Broker!”);

   

 }

 else {

   while(!pubcli.connect(clientID,”user”,”password”)){

   Serial.println(“Connection to MQTT Broker failed…”);

   delay(1000);

   //pubcli.connect(clientID);

 }

 }

 pubcli.subscribe(mqtt_topic);

}

 

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 Serial.println(“received!”);

 

 //set garage open or closed variable

 if ((char)payload[0] == ‘O’) {

   garOpen = HIGH;

 }

 if ((char)payload[0] == ‘C’) {

   garOpen = LOW;

 }

}

 

void loop() {

 pubcli.loop();

 //if garage is open, operate distance measurement

 if (garOpen == HIGH){

 inches = sonar.convert_in(sonar.ping_median(10));

 

 Serial.print(inches);

 Serial.print(“in, “);

 Serial.print(cm);

 Serial.print(“cm”);

 Serial.println();

 

String url = “”;

 

if(inches > 24){

 if(pubcli.publish(mqtt_topic,”G”)) Serial.println(“Sent G”);

 else{

   pubcli.connect(clientID,”user”,”password”);

   delay(10);

   pubcli.publish(mqtt_topic,”G”);

 }

 green = 1;

}

else if (inches > 12){

 if(pubcli.publish(mqtt_topic,”Y”)) Serial.println(“Sent Y”);

 else{

   pubcli.connect(clientID,”user”,”password”);

   delay(10);

   pubcli.publish(mqtt_topic,”Y”);

 }

 yellow = 1;

}

else if (inches > 6) {

 if(pubcli.publish(mqtt_topic,”R”)) Serial.println(“Sent R”);

 else{

   pubcli.connect(clientID,”user”,”password”);

   delay(10);

   pubcli.publish(mqtt_topic,”G”);

 }

 red = 1;

}

else {

 if(pubcli.publish(mqtt_topic,”F”)) Serial.println(“Sent F”);

 else{

   pubcli.connect(clientID,”user”,”password”);

   delay(10);

   pubcli.publish(mqtt_topic,”F”);

 }

 freak = 1;

}

 

 }

 

}

Lab 4: Event Bus

Objective

  • Implement an Event Hub for publish/subscribe notifications between devices  
  • Develop a communications protocol for devices across the event bus  
  • Establish more complex conditions for the actuator involving multiple sensors

Requirements

For this lab, you will study Don Borthwick’s story in Case Study 4. While the specific requirements set forth in the narrative should be met, your objective in this lab is to shift from a system of two intercommunicating devices to a framework that could grow exponentially. This lab will require you to create a new device, and to make modifications to your devices from Labs 2 and 3.

Materials

The items used to complete this lab were:

  • 3x Arduino D1 Mini
  • 3x Micro USB Cable for power and data transfer
  • Raspberry Pi
  • Ultrasonic sensor
  • Red LED
  • Yellow LED
  • Green LED
  • Blue LED
  • 4x 330 Ohm resistors
  • Assorted male-male jumper wires for breadboard
  • 3x Breadboard

References

The following references were used in the completion of this lab. Please note that large chunks of code were used as the basis / foundation upon which I could build my particular use case, and can therefore be attributed to their developers:

 

Procedure

These instructions assume you have already soldered the pins to your D1 Mini. If not, complete that task first.

 

First D1 Mini: Stoplight

 

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.    
  2. Take a jumper cable and connect it from a ground (G) output of the Mini to one of the negative rails running along the sides of the breadboard. This will send the ground along the entire row of that breadboard.
  3. Connect three jumper cables to three GPIO pin outputs of your choice. In this example, we will be using D5, D6, and D7.
  4. Connect the other ends of those jumper cables on rows 23, 25, and 27 of your breadboard, as close to the side as possible. These are the positive leads for your LEDs.
  5. Insert the long end of each LED into a hole which is on the same row as a jumper cable from the previous step. You’ll note that there is conveniently an extra hole between each jumper cable from step 4; this is for the ground.
  6. Insert one end of each resistor into the negative rail you established in step 2. Insert the other end along a row where you placed the negative leg of an LED. Once this is done, you should have a positive and negative connection for each LED. 
  7. Plug the micro USB cable into the D1 Mini and insert it into the USB port on your machine. Your system should begin a basic driver installation. Take special note when the OS reports it is done installing; it should inform you of the COM Port the Mini is on.
  8. Obtain the Arduino IDE from https://www.arduino.cc/en/Main/Software, making sure to select your operating system and the latest software version. Install the IDE.
  9. Begin the process of adding the necessary modules for the board by navigating to File > Preferences in the IDE.
  10. Under “Additional Board URLs”, paste in http://arduino.esp8266.com/stable/package_esp8266com_index.json and press OK.
  11. Navigate to Tools > Board > Board Manager and locate “esp8266” from the list. Press install.
  12. Under Tools > Board, select “D1 & D1 Mini”.
  13. Under Tools > Port, select the COM port as reported by the OS in step 7.
  14. You should now be ready to load code. Copy and paste the code as found in the appendix of this document into the IDE. Modify the network SSID and password fields found near the beginning of the code accordingly.
  15. Verify that the code compiles by pressing the “checkmark” button in the upper-left.
  16. Once it has compiled, press the “upload” button (located next to the checkmark) to begin the upload process.
  17. Whenever the D1 mini has power and the specified network is available, it awaits signals from the ultrasonic sensor and responds accordingly.

 

Second D1 Mini: Ultrasonic Sensor

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  2. Mount the ultrasonic sensor across four rows (not columns) of pins.
  3. Connect the ground pin of the D1 to the ground pin of the sensor.
  4. Connect the VCC pin of the sensor to the 5V pin of the D1.
  5. Choose two GPIO pins for use with the pulse and echo pins of the sensor and connect them. Here, D4 and D3 were chosen.
  6. Follow steps 7-16 of the previous D1 mini to upload the corresponding code to it.
  7. Whenever the D1 mini has power and the specified network is available, it will send signals to the stoplight.

Third D1 Mini: Reed Switch

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  2. Connect an LED across two rows of the breadboard.
  3. Connect a jumper from the positive lead of the LED to a GPIO pin. We use D7 here.
  4. Connect a resistor from the negative lead of the LED to the negative side rail of the breadboard.
  5. Connect a jumper from the ground pin of the D1 mini to the ground rail.
  6. Connect one end of the reed switch to a GPIO pin. We use D5 here.
  7. Connect the other end to the ground rail of the breadboard.
  8. Follow steps 7-16 of the first D1 mini to upload the corresponding code to it.
  9. Whenever the reed switch is open, it will send a message via MQTT to the other devices indicating the garage door is “open” and turn off the LED. When it is closed, it will send a “closed” message and turn on the LED.

 

Raspberry Pi

  1. Start up the Pi and connect it to the same wireless network the D1 minis will be on.
  2. Install the MQTT client with these commands:
    1. sudo apt-get install mosquitto -y
    2. sudo apt-get install mosquitto-clients -y
  3. Open the file /etc/mosquitto/mosquitto.conf for editing.
  4. Add the following line to the bottom of the file and save:
    1. listener 1883
  5. Restart the service with the following command:
    1. sudo service mosquitto restart
  6. Subscribe the Pi to the topic with the following command:
    1. mosquitto_sub -d -t GARAGE
  7. The Pi is now set to listen.

 

Overall Picture

The MQTT broker sits and waits for all incoming messages. While the reed switch is closed, no signals are sent aside from the signal that the switch is closed, and the LED is turned on. When the switch is closed, a new message is sent indicating the switch is closed, which is then broadcast to the other two devices. The Ultrasonic sensor reads this message and then begins pinging for distance. It sends the appropriate message back to the MQTT topic depending on this distance. The stoplight then reads in this message alongside the open/closed information to light the correct LEDs. If it receives a “Closed” message, all LEDs turn off.

The system was designed in this way because it seemed like the most efficient method for directing traffic. No receiving needs to be done by the reed switch, as it is the “catalyst” for the rest of the system. The ultrasonic sensor needs to know when to operate, but also needs to instruct the stoplight, so two-way communication is necessary. The stoplight only needs to be told what to do, so no transmissions are necessary.

 

Thought Questions

  • How does the communication between devices change with the shift to using an event hub? How does this facilitate greater scalability?
    • It changes greatly; this type of communication is so much more simple. There is no need for HTTP calls or servers; each device simply acts as a wifi client and subscribes to a channel. Adding devices is as simple as subscribing to this MQTT channel, which makes it infinitely scalable without any major adjustment to backend code.
  • What are strengths and weaknesses of the direct communication between the sensor and actuator? What are strengths and weaknesses of the event hub? Which do you feel is better for this application?
    • Direct communication does not have to rely on any sort of network or wireless protocol; it runs indefinitely so long as there is power. However, this limits the distance signals can be traveled by the length of cable or wire run between the two. The event hub has the downside of relying on a network and its uptime, but carries a huge advantage of being able to separate sensors and actuators by great distances so long as there is a network connection. In this particular garage situation, either would work since it’s a small room, but the most convenient solution is without question the event hub.
  • What was the biggest challenge you overcame in this lab?
    • Remembering that a device needs to subscribe to a topic and not just to the broker for it to, you know, actually work.
  • Please estimate the total time you spent on this lab and report.
    • Around three hours.

 

Appendix

Figure 1: Useful Pinout Diagram

 

Lab4Stoplight.ino

 

#include <PubSubClient.h>

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

//#include <TimedAction.h>

 

const char* ssid = “x”;           

const char* password = “x”;              

const char* mqtt_server = “192.168.43.3”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “Stoplight”;

 

int redPin = D5;

int yellowPin = D6;

int greenPin = D7;          

 

int freaky = LOW;

 

int garOpen = LOW;

 

int timediff = 0;

 

unsigned long lastiter = 0;

int redstate = 0;

 

WiFiServer server(80);

WiFiClient client;

 

PubSubClient pubcli(mqtt_server, 1883, client); // 1883 is the listener port for the Broker

 

void setup() {

 Serial.begin(115200);

 delay(10);

 //set pins

 pinMode(greenPin, OUTPUT);

 pinMode(yellowPin, OUTPUT);

 pinMode(redPin, OUTPUT);

 digitalWrite(greenPin, LOW);

 digitalWrite(yellowPin, LOW);

 digitalWrite(redPin, LOW);

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

 //set the message callback function, connect to MQTT broker, subscribe

 pubcli.setCallback(ReceivedMessage);

 if (pubcli.connect(clientID)) {

   Serial.println(“Connected to MQTT Broker!”);

 }

 else {

   while(!pubcli.connect(clientID)){

   Serial.println(“Connection to MQTT Broker failed…”);

   }

 }

 pubcli.subscribe(mqtt_topic);

}

 

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 

 char commd = (char)payload[0];

 

 //set the garage open variable

 if (commd == ‘O’) {

   garOpen = HIGH;

 }

 else if (commd == ‘C’) {

   garOpen = LOW;

 }

 

 //if the garage is open, operate lights. If not, blackout

 if(garOpen == HIGH) {

 

   switch(commd){

     case ‘R’:

       digitalWrite(redPin,HIGH);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,LOW);

       break;

     case ‘Y’:

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,HIGH);

       digitalWrite(greenPin,LOW);

       break;

     case ‘G’:

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,HIGH);

       break;

     case ‘F’:

       freakout();

       break;

   }

 

 

 }

 else {

       digitalWrite(redPin,LOW);

       digitalWrite(yellowPin,LOW);

       digitalWrite(greenPin,LOW);    

 }

 

}

void loop() {  

   pubcli.loop();

}

 

void freakout(){

 if (millis() > lastiter) {

   digitalWrite(redPin, (redstate) ? HIGH : LOW);

   digitalWrite(yellowPin, (redstate) ? HIGH : LOW);

   digitalWrite(greenPin, (redstate) ? HIGH : LOW);

   redstate = !redstate;

   lastiter = millis()+500UL;

 }

}

 

Lab4Sonic.ino

 

#include <PubSubClient.h>

#include <NewPing.h>

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

 

const char* ssid = “x”;           

const char* password = “x”;

const char* host = “192.168.43.5”;  

const int httpPort = 80;

const char* mqtt_server = “192.168.43.3”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “Sonic”;

 

int trigPin = D4;    // Trigger

int echoPin = D3;    // Echo

long duration, cm, inches;

 

int garOpen = LOW;

 

int red = 0;

int yellow = 0;

int green = 0;

int freak = 0;

 

int iters = 1;

int realinches = 0;

NewPing sonar(trigPin, echoPin, 360);

WiFiServer server(80);

WiFiClient client;

 

PubSubClient pubcli(mqtt_server, 1883, client); // 1883 is the listener port for the Broker

 

void setup() {

 //Serial Port begin

 Serial.begin (115200);

 //Define inputs and outputs

 pinMode(trigPin, OUTPUT);

 pinMode(echoPin, INPUT);

 

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

 //set mqtt callback, connect to broker and subscribe

   pubcli.setCallback(ReceivedMessage);

 if (pubcli.connect(clientID)) {

   Serial.println(“Connected to MQTT Broker!”);

   

 }

 else {

   while(!pubcli.connect(clientID)){

   Serial.println(“Connection to MQTT Broker failed…”);

   delay(1000);

   //pubcli.connect(clientID);

 }

 }

 pubcli.subscribe(mqtt_topic);

}

 

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 Serial.println(“received!”);

 

 //set garage open or closed variable

 if ((char)payload[0] == ‘O’) {

   garOpen = HIGH;

 }

 if ((char)payload[0] == ‘C’) {

   garOpen = LOW;

 }

}

 

void loop() {

 pubcli.loop();

 //if garage is open, operate distance measurement

 if (garOpen == HIGH){

 inches = sonar.convert_in(sonar.ping_median(10));

 

 Serial.print(inches);

 Serial.print(“in, “);

 Serial.print(cm);

 Serial.print(“cm”);

 Serial.println();

 

String url = “”;

 

if(inches > 24){

 if(pubcli.publish(mqtt_topic,”G”)) Serial.println(“Sent G”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”G”);

 }

 green = 1;

}

else if (inches > 12){

 if(pubcli.publish(mqtt_topic,”Y”)) Serial.println(“Sent Y”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”Y”);

 }

 yellow = 1;

}

else if (inches > 6) {

 if(pubcli.publish(mqtt_topic,”R”)) Serial.println(“Sent R”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”G”);

 }

 red = 1;

}

else {

 if(pubcli.publish(mqtt_topic,”F”)) Serial.println(“Sent F”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”F”);

 }

 freak = 1;

}

 

 }

 

}

 

Lab4Reed.ino

 

#include <PubSubClient.h>

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

 

const char* ssid = “x”;           

const char* password = “x”;

const char* mqtt_server = “192.168.43.3”;

const char* mqtt_topic = “GARAGE”;

const char* clientID = “GarSense”;

 

WiFiServer server(80);

WiFiClient client;

 

PubSubClient pubcli(mqtt_server, 1883, client); // 1883 is the listener port for the Broker

 

int sensorPin = D5;

int cute = D7;

 

int gar = LOW;

 

void setup() {

 pinMode(sensorPin,INPUT_PULLUP);

 pinMode(cute,OUTPUT);

 Serial.begin(115200);

 

WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

//set callback function, connect to broker

 pubcli.setCallback(ReceivedMessage);

 if (pubcli.connect(clientID)) {

   Serial.println(“Connected to MQTT Broker!”);

 }

 else {

   Serial.println(“Connection to MQTT Broker failed…”);

 }

 

}

 

//the receivedmessage function here is for later, in case. Not needed by reed switch

void ReceivedMessage(char* topic, byte* payload, unsigned int length) {

 // Output the first character of the message to serial (debug)

 Serial.println((char)payload[0]);

 

 // Handle the message we received

 // Here, we are only looking at the first character of the received message (payload[0])

 // If it is 0, turn the led off.

 // If it is 1, turn the led on.

 if ((char)payload[0] == ‘0’) {

   digitalWrite(cute, HIGH); // Notice for the HUZZAH Pin 0, HIGH is OFF and LOW is ON. Normally it is the other way around.

 }

 if ((char)payload[0] == ‘1’) {

   digitalWrite(cute, LOW);

 }

}

 

void loop() {

 //if the reed is closed but the garage variable is open, set to closed. Do opposite for open.

if(digitalRead(sensorPin)== LOW && gar == HIGH){

 if(pubcli.publish(mqtt_topic,”C”)) Serial.println(“Sent C”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”C”);

 }

 digitalWrite(cute, HIGH);

 gar = LOW;

}

else if(digitalRead(sensorPin) == HIGH && gar == LOW) {

 if(pubcli.publish(mqtt_topic,”O”)) Serial.println(“Sent O”);

 else{

   pubcli.connect(clientID);

   delay(10);

   pubcli.publish(mqtt_topic,”O”);

 }

 digitalWrite(cute, LOW);

 gar = HIGH;

}

pubcli.loop();

}

 

Lab 3

Lab 3: Sensor

Code

The code and online version of this report can be found at http://www.b3audioproductions.com

Objective

The purposes of this lab are to:  Build an IoT sensor using GPIO pins for inputs  Establish a machine-to-machine (M2M) communication protocol  Design an IoT interaction between a sensor and an actuator.

Requirements

For this lab, you will study Don Borthwick’s story in Case Study 3. While the specific requirements set forth in the narrative should be met, your objective in this lab is to develop a system of two devices that communicate to accomplish the objective. This lab will require you to create a new device, and to make modifications to your device from Lab 2.

Materials

The items used to complete this lab were:

  • 2x Arduino D1 Mini
  • 2x Micro USB Cable for power and data transfer
  • Ultrasonic sensor
  • Red LED
  • Yellow LED
  • Green LED
  • Three 330 Ohm resistors
  • Assorted male-male jumper wires for breadboard
  • Breadboard

References

The following references were used in the completion of this lab. Please note that large chunks of code were used as the basis / foundation upon which I could build my particular use case, and can therefore be attributed to their developers:

 

Procedure

These instructions assume you have already soldered the pins to your D1 Mini. If not, complete that task first.

First D1 Mini: Stoplight

 

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.    
  2. Take a jumper cable and connect it from a ground (G) output of the Mini to one of the negative rails running along the sides of the breadboard. This will send the ground along the entire row of that breadboard.
  3. Connect three jumper cables to three GPIO pin outputs of your choice. In this example, we will be using D5, D6, and D7.
  4. Connect the other ends of those jumper cables on rows 23, 25, and 27 of your breadboard, as close to the side as possible. These are the positive leads for your LEDs.
  5. Insert the long end of each LED into a hole which is on the same row as a jumper cable from the previous step. You’ll note that there is conveniently an extra hole between each jumper cable from step 4; this is for the ground.
  6. Insert one end of each resistor into the negative rail you established in step 2. Insert the other end along a row where you placed the negative leg of an LED. Once this is done, you should have a positive and negative connection for each LED. 
  7. Plug the micro USB cable into the D1 Mini and insert it into the USB port on your machine. Your system should begin a basic driver installation. Take special note when the OS reports it is done installing; it should inform you of the COM Port the Mini is on.
  8. Obtain the Arduino IDE from https://www.arduino.cc/en/Main/Software, making sure to select your operating system and the latest software version. Install the IDE.
  9. Begin the process of adding the necessary modules for the board by navigating to File > Preferences in the IDE.
  10. Under “Additional Board URLs”, paste in http://arduino.esp8266.com/stable/package_esp8266com_index.json and press OK.
  11. Navigate to Tools > Board > Board Manager and locate “esp8266” from the list. Press install.
  12. Under Tools > Board, select “D1 & D1 Mini”.
  13. Under Tools > Port, select the COM port as reported by the OS in step 7.
  14. You should now be ready to load code. Copy and paste the code as found in the appendix of this document into the IDE. Modify the network SSID and password fields found near the beginning of the code accordingly.
  15. Verify that the code compiles by pressing the “checkmark” button in the upper-left.
  16. Once it has compiled, press the “upload” button (located next to the checkmark) to begin the upload process.
  17. Whenever the D1 mini has power and the specified network is available, it awaits signals from the ultrasonic sensor and responds accordingly.

 

Second D1 Mini: Ultrasonic Sensor

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  2. Mount the ultrasonic sensor across four rows (not columns) of pins.
  3. Connect the ground pin of the D1 to the ground pin of the sensor.
  4. Connect the VCC pin of the sensor to the 5V pin of the D1.
  5. Choose two GPIO pins for use with the pulse and echo pins of the sensor and connect them. Here, D4 and D3 were chosen.
  6. Follow steps 7-16 of the previous D1 mini to upload the corresponding code to it.
  7. Whenever the D1 mini has power and the specified network is available, it will send signals to the stoplight.

Thought Questions

 

  • Think of the interaction between your devices. How well would this scale to multiple devices? Is it easy to add another sensor? Another actuator?

 

      • This should scale rather well on both ends, since you’d really only have to specify additional addresses to send to or set up another listening address. My concern with adding more sensors would be the potential to overload the actuator with HTTP requests. Some sort of queue may need to be implemented to keep that under control.

 

  • What are strengths and weaknesses of the tennis-ball-on-a-string system that Don had originally? What are strengths and weaknesses of the IoT system that he developed? What enhancements would you suggest?

 

      • The tennis ball system was simple to both set up and troubleshoot, did not require any sort of electricity, and was inexpensive to implement. However, it was vulnerable to failure because of outside forces like kids with bats. The IoT system has more vulnerability against vandalism, though it’s still possible it could be destroyed. It also has much more precision and flexibility in measuring distance by offering distinct warnings. On the downside, it’s expensive, requires power, and is much more complex to set up and troubleshoot.

 

  • What was the biggest challenge you overcame in this lab?

 

      • The biggest was probably getting the response time trimmed down. Initially it would take a good 5-10 seconds for the stoplight to respond to readings, but I simplified the code down to cut out any unnecessary calls so that the server could spend more time listening for light requests.

 

  • Please estimate the total time you spent on this lab and report.

 

    • I’d say about 4.5 hours, with the majority of that working on speed of response as well as the consistency of the supersonic readings.

Appendix

Figure 1: Useful Pinout Diagram

 

Lab3.ino: Sensor code

 

#include <NewPing.h>

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

 

const char* ssid = “xxxxx”;           

const char* password = “xxxxx”;

const char* host = “192.168.43.5”;  

const int httpPort = 80;

 

int trigPin = D4;    // Trigger

int echoPin = D3;    // Echo

long duration, cm, inches;

 

int red = 0;

int yellow = 0;

int green = 0;

int freak = 0;

 

int iters = 1;

int realinches = 0;

NewPing sonar(trigPin, echoPin, 360);

WiFiServer server(80);

WiFiClient client;

void setup() {

 //Serial Port begin

 Serial.begin (115200);

 //Define inputs and outputs

 pinMode(trigPin, OUTPUT);

 pinMode(echoPin, INPUT);

 

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

 

}

void loop() {

 inches = sonar.convert_in(sonar.ping_median(10));

 

 Serial.print(inches);

 Serial.print(“in, “);

 Serial.print(cm);

 Serial.print(“cm”);

 Serial.println();

 

String url = “”;

 

if(inches > 24){

 url = “/GREEN=ON”;

 green = 1;

}

else if (inches > 12){

 url = “/YELLOW=ON”;

 yellow = 1;

}

else if (inches > 6) {

 url = “/RED=ON”;

 red = 1;

}

else {

 url = “/FREAKY=ON”;

 freak = 1;

}

 

Serial.print(“Requesting URL: “);

 Serial.println(url);

 

 // This will send the request to the server

 client.connect(host, httpPort);

 client.print(String(“GET “) + url + ” HTTP/1.1\r\n” +

              “Host: ” + host + “\r\n” +

              “Connection: close\r\n\r\n”);

}

 

Lab3Stoplight.ino: Stoplight code

 

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

//#include <TimedAction.h>

 

const char* ssid = “xxxxxx”;           

const char* password = “xxxxxx”;              

 

int redPin = D5;

int yellowPin = D6;

int greenPin = D7;          

 

int freaky = LOW;

 

int timer;

 

int timediff = 0;

 

unsigned long lastiter = 0;

int redstate = 0;

 

WiFiServer server(80);

WiFiClient client;

String request;

 

void setup() {

 Serial.begin(115200);

 delay(10);

 pinMode(greenPin, OUTPUT);

 pinMode(yellowPin, OUTPUT);

 pinMode(redPin, OUTPUT);

 digitalWrite(greenPin, LOW);

 digitalWrite(yellowPin, LOW);

 digitalWrite(redPin, LOW);

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

}

 

void loop() {

 

timer = millis();   

 

// Check if a client has connected

 client = server.available();

 if (!client) {

   return;

 }

 

 // Wait until the client sends some data

 Serial.println(“new client”);

 while(!client.available()){

   delay(1);

 }

 

 // Read the first line of the request

 request = client.readStringUntil(‘\r’);

 Serial.println(request);

 client.flush();

 // Match the request

   //resetlights();

 

 if (request.indexOf(“/GREEN=ON”) != -1) {

   digitalWrite(greenPin, HIGH);

   digitalWrite(redPin, LOW);

   digitalWrite(yellowPin, LOW);

 }

 else if (request.indexOf(“/YELLOW=ON”) != -1){

   digitalWrite(yellowPin, HIGH);

   digitalWrite(redPin, LOW);

   digitalWrite(greenPin, LOW);

 }

 else if (request.indexOf(“/RED=ON”) != -1){

   digitalWrite(redPin, HIGH);

   digitalWrite(yellowPin, LOW);

   digitalWrite(greenPin, LOW);

 }

 else if (request.indexOf(“/FREAKY=ON”) != -1){

   freakout();

 }

 else {

   int silly = 0;

 }

 

 // Return the response

 client.println(“HTTP/1.1 200 OK”);

 client.println(“Content-Type: text/html”);

 client.println(“”);

 client.println(“<!DOCTYPE HTML>”);

 client.println(“<html>”);

 client.println(“</html>”);

 delay(1);

 Serial.println(“Client disconnected”);

 Serial.println(“”);

}

 

void freakout(){

 if (millis() > lastiter) {

   digitalWrite(redPin, (redstate) ? HIGH : LOW);

   digitalWrite(yellowPin, (redstate) ? HIGH : LOW);

   digitalWrite(greenPin, (redstate) ? HIGH : LOW);

   redstate = !redstate;

   lastiter = millis()+500UL;

 }

}

 

Stoplight v2

Objective

The purposes of this lab are to:  Reinforce enumerating requirements from use cases and user stories  Become familiar with the Arduino platform and its programming methodologies.  Program an Arduino-based microcontroller to use the GPIO pins to control LEDs.  Develop iteratively, beginning with a minimum viable product and add functionality until the requirements are met.

 

Requirements

For this lab, you will study Don Borthwick’s story in Case Study 2, and identify the requirements that he set forth for his prototype. You should then deliver a working project that meets those specifications. Part of your grade will be how well you enumerate the requirements, based on the limited information provided to you in the case study.

 

Materials

The items used to complete this lab were:

  • Arduino D1 Mini
  • Micro USB Cable for power and data transfer
  • Red LED
  • Yellow LED
  • Green LED
  • Three 330 Ohm resistors
  • Assorted male-male jumper wires for breadboard
  • Breadboard

 

References

The following references were used in the completion of this lab. Please note that large chunks of code were used as the basis / foundation upon which I could build my particular use case, and can therefore be attributed to their developers:

 

 

Procedure

These instructions assume you have already soldered the pins to your D1 Mini. If not, complete that task first.

 

  1. Mount the D1 Mini to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.    
  2. Take a jumper cable and connect it from a ground (G) output of the Mini to one of the negative rails running along the sides of the breadboard. This will send the ground along the entire row of that breadboard.
  3. Connect three jumper cables to three GPIO pin outputs of your choice. In this example, we will be using D5, D6, and D7.
  4. Connect the other ends of those jumper cables on rows 23, 25, and 27 of your breadboard, as close to the side as possible. These are the positive leads for your LEDs.
  5. Insert the long end of each LED into a hole which is on the same row as a jumper cable from the previous step. You’ll note that there is conveniently an extra hole between each jumper cable from step 4; this is for the ground.
  6. Insert one end of each resistor into the negative rail you established in step 2. Insert the other end along a row where you placed the negative leg of an LED. Once this is done, you should have a positive and negative connection for each LED. See the picture for confirmation.
  7. Plug the micro USB cable into the D1 Mini and insert it into the USB port on your machine. Your system should begin a basic driver installation. Take special note when the OS reports it is done installing; it should inform you of the COM Port the Mini is on.
  8. Obtain the Arduino IDE from https://www.arduino.cc/en/Main/Software, making sure to select your operating system and the latest software version. Install the IDE.
  9. Begin the process of adding the necessary modules for the board by navigating to File > Preferences in the IDE.
  10. Under “Additional Board URLs”, paste in http://arduino.esp8266.com/stable/package_esp8266com_index.json and press OK.
  11. Navigate to Tools > Board > Board Manager and locate “esp8266” from the list. Press install.
  12. Under Tools > Board, select “D1 & D1 Mini”.
  13. Under Tools > Port, select the COM port as reported by the OS in step 7.
  14. You should now be ready to load code. Copy and paste the code as found in the appendix of this document into the IDE. Modify the network SSID and password fields found near the beginning of the code accordingly.
  15. Verify that the code compiles by pressing the “checkmark” button in the upper-left.
  16. Once it has compiled, press the “upload” button (located next to the checkmark) to begin the upload process.
  17. Once that has happened, click the “View Serial Output” button, located in the upper-right of the IDE. This will open the serial output produced by the Mini and allow you to see the Mini’s IP address.
  18. Navigate to the IP address from a browser on the same network and utilize the buttons on the screen to operate the stoplight.

 

Thought Questions

 

  • What are some key differences between developing this lab on a Raspberry Pi, and developing on Arduino?

 

      • One of the most major differences is simplicity, so to speak. The Arduino simply turns off and on, has no OS, and just executes the code it has in its memory. This leads to very quick startups, as there are no frills. Along that same note, however, that simplicity can get rather frustrating. The D1 Mini is not capable of multiple threads or processes, so the developer is forced to get creative with running multiple tasks at once all inside the primary execution loop. Aside from these points, the wiring and voltages are essentially identical. From a more obvious standpoint, the Arduino allows for one coding language and nothing else: C. The RPi, however, allows a developer to use virtually any language in existence, so long as it is compatible with the Pi’s ARM architecture.

 

  • What are the strengths and trade-offs of each of these platforms?

 

      • I addressed many of these in the previous question, but the Arduino is excellent due to its low power usage, no frills, and straightforward execution. If you have a very direct process to complete, where A leads to B and no complex computations or threading needs to take place, then absolutely go for the Arduino. If you need more versatility, including onboard sound and video, threading and more, go for the Pi, but at the expense of complexity and startup times. So much more can go wrong with a Pi because of all it is capable of, whereas an Arduino has much less it needs to concern itself with.

 

  • How familiar were you with the Arduino platform prior to this lab?

 

      • I had worked with a handful of them before, so it really wasn’t anything new. Regardless, any level of familiarity with C/C++ is mostly what you need to get moving on the platform.

 

  • What was the biggest challenge you overcame in this lab?

 

      • The classic threading/multitasking issue. I spent multiple hours solely trying to figure out how to keep the stoplight function from blocking everything else, including the webserver. Executing the stoplight would prevent the server from listening to further requests, so the web page and function would end up in a permanent locked state until new code was loaded onto the board. I eventually solved this issue using millis and timers.

 

  • Please estimate the total time you spent on this lab and report.

 

    • Somewhere in the vicinity of five hours, with a little more than two of those spent solely on the blocking issue I just described.

 

Appendix

Figure 1: Useful Pinout Diagram

Code: Lab2.ino. Again, note that the foundational code here was written by its respective developers and (aside from the WiFi setup functions) was heavily modified and expanded upon for my use case.

 

#include <ESP8266WiFi.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

 

const char* ssid = “<the ssid of my phone>”;           

const char* password = “<the password of my phone’s network>”;              

 

//set up pin numbers for each lights

int redPin = D5;

int yellowPin = D6;

int greenPin = D7;          

 

//these variables track the status of each light

int greenValue = LOW;

int yellowValue = LOW;

int redValue = LOW;

int stoplValue = LOW;

 

//set variables which track where the light currently is if on stoplight mode

int yellowcycle = 0;

int greencycle = 0;

int redcycle = 0;

 

//declare time variable to track millis

int timer;

 

//declare time variable to track time elapsed for stoplight function

int timediff = 0;

 

WiFiServer server(80);

WiFiClient client;

String request;

 

void setup() {

 Serial.begin(115200);

 delay(10);

//set pin modes and voltages initially

 pinMode(greenPin, OUTPUT);

 pinMode(yellowPin, OUTPUT);

 pinMode(redPin, OUTPUT);

 digitalWrite(greenPin, LOW);

 digitalWrite(yellowPin, LOW);

 digitalWrite(redPin, LOW);

 // Connect to WiFi network

 Serial.println();

 Serial.println();

 Serial.print(“Connecting to “);

 Serial.println(ssid);

 WiFi.mode(WIFI_STA);

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

   delay(500);

   Serial.print(“.”);

 }

 Serial.println(“”);

 Serial.println(“WiFi connected”);

 // Start the server

 server.begin();

 Serial.println(“Server started”);

 // Print the IP address

 Serial.print(“Use this URL : “);

 Serial.print(“http://”);

 Serial.print(WiFi.localIP());

 Serial.println(“/”);

}

 

void loop() {

 

//get current time for tracking with use of stoplight function

timer = millis();   

 

//make sure a client is connected, check the URL to know what to do, render the HTML page   

getServerStatus();

getRequest();

renderHTML();

 

//If stoplight mode is engaged, check the stoplight to see if it needs to change colors

if(stoplValue==HIGH){

  checkStoplight();

}

 

}

 

void checkStoplight(){

 

//get the time elapsed since the last change

int gettime = timer – timediff;

 

//check if each light color has executed or not, and act accordingly

if(redcycle = 0){

digitalWrite(redPin, HIGH);

redcycle = 1;

return;

}

else if(gettime > 5000 && greencycle == 0){

 digitalWrite(redPin, LOW);

 digitalWrite(greenPin, HIGH);

 greencycle = 1;

 timediff = timer;

 return;

}

else if(gettime > 10000 && yellowcycle == 0)

{

 digitalWrite(greenPin, LOW);

 digitalWrite(yellowPin, HIGH);

 yellowcycle = 1;

 timediff = timer;

 return;

}

else if (gettime > 3000 && yellowcycle == 1)

{

  digitalWrite(yellowPin, LOW);

  digitalWrite(redPin, HIGH);

  redcycle = 1;

  greencycle = 0;

  yellowcycle = 0;

  timediff = timer;

  return;

}

 

}

 

void resetlights(){

   digitalWrite(greenPin, LOW);

   digitalWrite(yellowPin, LOW);

   digitalWrite(redPin, LOW);

   greenValue = LOW;

   yellowValue = LOW;

   redValue = LOW;

   return;

}

 

void getServerStatus(){

 

 // Check if a client has connected

 client = server.available();

 if (!client) {

   return;

 }

 

 // Wait until the client sends some data

 Serial.println(“new client”);

 while(!client.available()){

   delay(1);

 }

}

 

void getRequest(){

// Read the first line of the request

 request = client.readStringUntil(‘\r’);

 Serial.println(request);

 client.flush();

 // Look at the requested page and act on the URL accordingly, changing lights or modes

 if (request.indexOf(“/GREEN=ON”) != -1) {

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(greenPin, HIGH);

   greenValue = HIGH;

 }

 else if (request.indexOf(“/GREEN=OFF”) != -1){

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(greenPin, LOW);

   greenValue = LOW;

 }

 else if (request.indexOf(“/YELLOW=ON”) != -1){

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(yellowPin, HIGH);

   yellowValue = HIGH;

 }

 else if (request.indexOf(“/YELLOW=OFF”) != -1){

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(yellowPin, LOW);

   yellowValue = LOW;

 }

 else if (request.indexOf(“/RED=ON”) != -1){

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(redPin, HIGH);

   redValue = HIGH;

 }

 else if (request.indexOf(“/RED=OFF”) != -1){

   if(stoplValue==HIGH){

     stoplValue=LOW;

     resetlights();

   }

   digitalWrite(redPin, LOW);

   redValue = LOW;

 }

 else if (request.indexOf(“/STOPLIGHT=ON”) != -1){

   resetlights();

   stoplValue=HIGH;

 }

 else if (request.indexOf(“/STOPLIGHT=OFF”) != -1){

   resetlights();

   stoplValue=LOW;

 }

 else if (request.indexOf(“/ALL=OFF”) != -1){

   resetlights();

   stoplValue=LOW;

 }

 else {

   int silly = 0;

 }

}

 

void renderHTML(){

 // Return an HTML response and print the whole page out with buttons conditional on status, set URL

 client.println(“HTTP/1.1 200 OK”);

 client.println(“Content-Type: text/html”);

 client.println(“”);

 client.println(“<!DOCTYPE HTML>”);

 client.println(“<html>”);

 client.println(“<h1>SUPER STOPLIGHT TIME</h1>”);

 client.println(“<br><br>”);

 client.println(” <a href=\”/GREEN=”);

 if(greenValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“\”><button>TURN GREEN “);

 if(greenValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“</button></a><br>”);

 

 client.println(” <a href=\”/YELLOW=”);

 if(yellowValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“\”><button>TURN YELLOW “);

 if(yellowValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“</button></a><br>”);

 

 client.println(” <a href=\”/RED=”);

 if(redValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“\”><button>TURN RED “);

 if(redValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“</button></a><br>”);

 

 client.println(” <a href=\”/STOPLIGHT=”);

 if(stoplValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“\”><button>STOPLIGHT TIME “);

 if(stoplValue == HIGH) {

   client.print(“OFF”);  

 } else {

   client.print(“ON”);

 }

 client.println(“</button></a><br>”);

 

 client.println(” <a href=\”/ALL=OFF\”><button>ALL OFF</button></a><br>”);

 client.println(“</html>”);

 delay(1);

 Serial.println(“Client disconnected”);

 Serial.println(“”);

}

 

Web Page Screenshot

Lab 1

Objective

The purposes of this lab are to:

  • Learn to enumerate requirements from use cases and user stories
  • Learn to utilize the general purpose input/output (GPIO) pins on the Raspberry Pi to control LEDs.
  • Learn to develop a minimum viable product, and deliver new functionality through subsequent updates until the requirements are met, and all of the deliverables are acceptable.
  • Learn to use Github for progressive code commits and version tracking.

 

Materials

The items used to complete this lab were:

  • Raspberry Pi 3
  • Sparkfun Pi Wedge and ribbon cable
  • Red LED
  • Yellow LED
  • Green LED
  • Three 330 Ohm resistors
  • Assorted male-male jumper wires for breadboard
  • Breadboard

 

References

I used the following references in this lab. All of them concern smaller problems I was having with remembering specific syntax or how certain functions work.

Procedures

  • Connect the Sparkfun Pi Wedge to the Raspberry PI pins using the provided ribbon cable, and mount the T-shaped portion to the breadboard, straddling the break in the middle of the breadboard which indicates a break in the circuit of the board.
  • Take a jumper cable and connect it from a ground (GND) output of the Pi Wedge to one of the negative rails running along the sides of the breadboard. This will send the ground along the entire row of that breadboard.
  • Connect three jumper cables to three GPIO pin outputs of your choice. In this example, we will be using G17, 16, and 13.
  • Connect the other ends of those jumper cables on rows 23, 25, and 27 of your breadboard, as close to the side as possible. These are the positive leads for your LEDs.
  • Insert the long end of each LED into a hole which is on the same row as a jumper cable from the previous step. You’ll note that there is conveniently an extra hole between each jumper cable from step 4; this is for the ground.
  • Insert one end of each resistor into the negative rail you established in step 2. Insert the other end along a row where you placed the negative leg of an LED. Once this is done, you should have a positive and negative connection for each LED.
  • Power on your RPi. It is assumed you have already installed an operating system such as Raspbian.
  • Ensure that the pins are prepared for output by running the command gpio -g mode <pin number> out for each of the pins listed in step three.
  • Install the Apache web server by issuing the command sudo apt-get install apache2.
  • Enable CGI (the protocol necessary for running our light-controlling scripts from a browser) by running the command sudo a2enmod cgi
  • Create a directory for scripts by running the command sudo mkdir /var/www/html/cgi-bin
  • Navigate to the directory just created and create script files by issuing the command sudo touch <file name>, with these file names:
    • alloff.py
    • red.py
    • green.py
    • yellow.py
    • status.py
    • stoplight.py
    • stoppython.py
  • Open /var/www/html/index.html in a file editor (sudo nano <file name>) and erase its contents, replacing them with the code for index.html found in the appendix.
  • Fill each of the files mentioned in step 11 with their respective contents from the appendix.
  • Make each script from step 11 executable by navigating to the cgi-bin directory and running the command sudo chmod +x *
  • Navigate to the web page locally on the Pi by opening up a browser to localhost/
  • Press the buttons on the screen to operate the stoplight

 

Thought Questions

  • What language did you choose for implementing this project? Why?
    • For the web front-end, I used HTML and JS (jQuery). HTML is a necessary no-brainer, but I chose jQuery because it’s straightforward to get simple scripts stood up and run asynchronous commands (such as the buttons changing their status depending on the actual status of the LED as reported from the Pi). For the back end, I chose Python because of its ability to quickly and efficiently access GPIO pins as well as send JSON back to jQuery, which Is necessary for status reporting.
  • What is the purpose of the resistor in this simple circuit? What would happen if you omitted it?
    • The resistor is there to reduce the amount of electricity reaching the LED so that it doesn’t overload it and melt (or explode). Omitting this critical piece would eventually result in failure of the LED.
  • What are practical applications of this device? What enhancements or modifications would you make?
    • Honestly, this device isn’t particularly practical in its current state. Considering the premise of the lab was that Don Borthwick was simply wanting to refresh his skills, I’d say it accomplished its task. For a real stoplight, perhaps one which could be placed outside a bathroom or other office room (hey, I’m just being imaginative), some major aesthetic changes would need to be made, and it’d make more sense to allow the light to also be controlled by hardware. Additionally, measures would need to be taken so that multiple users could (or could not) control the stoplight as appropriate.
  • Please estimate the total time you spent on this lab and report.
    • I’d say somewhere in the vicinity of three to three-and-a-half hours.

 

Certification of Work

I certify that the solution presented in this lab represents my own work. In the case where I have borrowed code or ideas from another person, I have provided a link to the author’s work in the references and included a citation in the comments of my code.

 

 

Appendix

Web Page

Code

Index.html

<!DOCTYPE HTML>

 

<html>

<head>

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js”></script>

</head>

<body>

<h1>TRAFFIC LIGHT</h1>

<button id=”redbutt” type=”button” onclick=”red()”>HELLO</button>

<button id=”yellowbutt” type=”button” onclick=”yellow()”>HELLO</button>

<button id=”greenbutt” type=”button” onclick=”green()”>HELLO</button>

<button id=”offbutt” type=”button” onclick=”off()”>ALL OFF</button>

<button id=”stopbutt” type=”button” onclick=”stoplight()”>STOPLIGHT TIME</button>

<button id=”stopstopbutt” type=”button” onclick=”stopstoplight()”>STOP STOPLIGHT TIME</button>

</body>

<script>

$(document).ready(function(){

var green = “”;

var red = “”;

var yellow = “”;

$.getJSON(‘cgi-bin/status.py’,function(data){

data.Green==”Off” ? green=”On” : green=”Off”;

data.Yellow==”Off” ? yellow=”On” : yellow=”Off”;

data.Red==”Off” ? red=”On” : red=”Off”;

$(“#greenbutt”).html(“Turn Green “+green);

$(“#yellowbutt”).html(“Turn Yellow “+yellow);

$(“#redbutt”).html(“Turn Red “+red);

});

})

 

function green(){

$.getJSON(‘cgi-bin/green.py’,function(data){

localgreen = “”;

data.Status==”Off” ? localgreen=”On” : localgreen=”Off”;

$(“#greenbutt”).html(“Turn Green “+localgreen);

});

}

 

function yellow(){

$.getJSON(‘cgi-bin/yellow.py’,function(data){

localyellow = “”;

data.Status==”Off” ? localyellow=”On” : localyellow=”Off”;

$(“#yellowbutt”).html(“Turn Yellow “+localyellow);

});

}

 

function red(){

$.getJSON(‘cgi-bin/red.py’,function(data){

localred = “”;

data.Status==”Off” ? localred=”On” : localred=”Off”;

$(“#redbutt”).html(“Turn Red “+localred);

});

}

 

function off(){

fetch(‘cgi-bin/alloff.py’);

$(“#redbutt”).html(“Turn Red On”);

$(“#yellowbutt”).html(“Turn Yellow On”);

$(“#greenbutt”).html(“Turn Green On”);

}

 

function stoplight(){

off();

fetch(‘cgi-bin/stoplight.py’);

}

 

function stopstoplight(){

fetch(‘cgi-bin/stoppython.py’);

off();

}

 

 

</script>

</html>

 

Alloff.py

#!/usr/bin/python

 

import os

print(“Content-Type: text/plain”)

print

 

os.system(“gpio -g write 17 0”)

os.system(“gpio -g write 16 0”)

os.system(“gpio -g write 13 0”)

 

Green.py

#!/usr/bin/python

 

import os,json

print(“Content-Type: application/json”)

print

response = “”

 

results = os.popen(“gpio -g read 17”).read()

 

if(results==’1\n’):

os.system(“gpio -g write 17 0”)

response={‘Status’:’Off’}

else:

os.system(“gpio -g write 17 1”)

response={‘Status’:’On’}

 

print(json.JSONEncoder().encode(response))

 

Red.py

#!/usr/bin/python

 

import os,json

print(“Content-Type: application/json”)

print

response = “”

 

results = os.popen(“gpio -g read 13”).read()

 

if(results==’1\n’):

os.system(“gpio -g write 13 0”)

response={‘Status’:’Off’}

else:

os.system(“gpio -g write 13 1”)

response={‘Status’:’On’}

 

print(json.JSONEncoder().encode(response))

 

Status.py

#!/usr/bin/python

 

import os,json

print(“Content-Type: application/json”)

print

response = “”

 

green = os.popen(“gpio -g read 17”).read().replace(‘1\n’,’On’).replace(‘0\n’,’Off’)

yellow = os.popen(“gpio -g read 16”).read().replace(‘1\n’,’On’).replace(‘0\n’,’Off’)

red = os.popen(“gpio -g read 13”).read().replace(‘1\n’,’On’).replace(‘0\n’,’Off’)

response = {‘Green’:green,’Yellow’:yellow,’Red’:red}

print(json.JSONEncoder().encode(response))

 

Stoplight.py

#!/usr/bin/python

 

import os,json,time

print(“Content-Type: application/json”)

print

response = “”

 

while(1==1):

os.system(“gpio -g write 13 1”)

time.sleep(5)

os.system(“gpio -g write 13 0”)

os.system(“gpio -g write 17 1”)

time.sleep(7)

os.system(“gpio -g write 17 0”)

os.system(“gpio -g write 16 1”)

time.sleep(2)

os.system(“gpio -g write 16 0”)

 

Stoppython.py

#!/usr/bin/python

 

import os

 

print(“content-type: text/plain\n\n”)

 

os.system(“pkill -9 -f stoplight.py”)

 

Yellow.py

#!/usr/bin/python

 

import os,json

print(“Content-Type: application/json”)

print

response = “”

 

results = os.popen(“gpio -g read 16”).read()

 

if(results==’1\n’):

os.system(“gpio -g write 16 0”)

response={‘Status’:’Off’}

else:

os.system(“gpio -g write 16 1”)

response={‘Status’:’On’}

 

print(json.JSONEncoder().encode(response))