Project tutorial
Smart Ambient Lighting

Smart Ambient Lighting © GPL3+

Ambient lighting that smartly responds to your moods and needs.

  • 2,575 views
  • 0 comments
  • 2 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

About this project

Smart Ambient Lighting

Daniel Martin

Acknowledgements:

  • · Weather Underground
  • · Adafruit
  • · Sparkfun
  • · Cayenne

Introduction:

When you walk into a dark room, it’s nice to have an LED light strip automatically turn on. But wouldn’t it be cooler if it were controlled by a smartphone – that with a tap of a finger the light could change color? What if, with just a few sliders on your phone’s app, you could create virtually any color with varying intensity, for example sunrise colors in the morning and sunset colors in the evening? This Smart Ambient Lighting system would be able to detect where you are: if you’re simply walking by in the periphery of the room or if a baby is crawling in the hallway in another part of the house. Below is a schematic overview of the Smart Ambient Lighting project.

The Remote Control module (ESP8266 with motion sensor) communicates via Wi-Fi with the Light Control module (Arduino Yun with motion sensor, buzzer, and LED Strip). This system not only provides soothing ambient lighting in a family room, but can effectively be used for monitoring a baby or pet moving in the hallway. The possibilities are limitless! All these sensors can be easily accessed on the Cayenne dashboard from a smartphone or laptop. As an additional bonus, I added a Raspberry Pi which communicates with the Yun and takes pictures when motion is detected in the Family Room (not part of this project). Using Cayenne, I set up a schedule for the Ambient Lighting to go on at sunset. Cayenne also provides options for triggers and alerts to further enhance your lighting system.

ESP8266 Remote Control Module and Cayenne Dashboard on PC

Smart Ambient Lighting and Cayenne Dashboard on Smartphone

Instructions for the Yún Light Control Module:

The first step is to setup the LED strip with the Arduino. This link provides the tutorial for connecting the RBG LED strip to a microcontroller: https://learn.adafruit.com/rgb-led-strips?view=all. The section on “Wiring” shows how to solder four wires to the copper pads on one of the ends of the LED strip. I found that on one end of the strip the manufacturers had already done this, so you may be able to skip this step. However, since you might choose to have your microcontroller several feet away from the LED strip, you will need to solder the three wires from the Micro Connectors cable to the RGB ends from the strip. You will also need to solder the Shaxon wire to the +12V wire from the strip (this needs to be thick because it carries three times as much current as RGB wires, e.g. 14AWG). Connect up the wires as shown in the diagram.

The grounds from the three transistors must be connected to the Arduino Yún in addition to the ground of your 12V DC power adapter (the batteries indicate the 12V power supply – don’t actually use batteries). The thick wire you just soldered from the +12V of the LED strip should be soldered on the other end to the positive side of your 12V DC power adapter. The diagram shows the digital pins used: pin 3 for RED, pin 5 for GREEN, and pin 9 for BLUE. Use any GPIO pins that you want, just be sure to alter the code accordingly. If you choose to test using the code provided by Adafruit in the link above, power up your microcontroller, plug in the 12V adapter, and upload your program (using the Arduino IDE). It should work like in the video at the top of Adafruit’s tutorial. Now you’ve completed the first part!

Now, to make it motion controlled – you will need the PIR to detect motion. It is very easy to connect, just three wires: GND, VCC, and OUT (sometimes labeled on the back of the sensor itself). This link contains the tutorial on how to use this sensor: https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor?view=all. It’s a good read, but also long, so you can simply wire it up according to this diagram.

Once again, you can use any I/O pin, just make sure to change the code to match your wiring. The link provides an example code which you can use to test your work, which I have modified to make it simpler. Upload this program, and open the serial monitor. Wave your hand near the sensor, and “Motion detected!” should appear on your screen.

Next are the photocells – we only want the light to turn on when it is dark. I used four photocells in parallel with a 10k resistor connected in the same format as https://learn.adafruit.com/photocells?view=all, under “Using a Photocell”.

Once again, utilize their example code to test your work. Just upload the program as it is (and adjust your input pin to match your wiring) and open the Serial window to observe if your readings match your intuition (shine a light on the cells to see if values approach 1023, and cover them to watch the values drop toward 0).

To create some audio feedback, which is especially useful in alerts, connect a piezo speaker to the Arduino. The positive side goes to a digital output pin, and the negative side to ground.

With all the pieces together, the project looks like this (scroll through images):

The Light Control Module can also be made by replacing the Yún with another ESP8266 board, with alterations to the code. Since this part of the project uses only 1 analog pin and 5 digital pins, it is possible to use Sparkfun’s board as a substitute.

Instructions for the ESP8266 Remote Control Module:

The Sparkfun ESP8266 board will contain the following sensors:

· IR Receiver / Transmitter

· Some photoresistors

· RGB LED

The IR transmitter, which looks like an LED, sends out pulses at a frequency of 38 kHz. The positive (longer) leg is connected to the digital pin via a 2k Ohm resistor, and the negative side is hooked up to ground. The IR receiver has 3 pins: the left pin (when facing it) is connected to a digital pin via a 220 Ohm resistor. The middle pin is hooked up to GND, and the right pin receives +5V. Here, you can also use an IR distance sensor to adjust the intensity of the light based on the measured distance.

The next step is to add the RGB LED, so that when motion is detected we have a visual feedback. These LEDs are really cool – with only one digital pin you can control the red, green, and blue values, so you can create virtually any color! Since the ESP8266 has Wi-Fi capability, I was able to use Weather Underground’s API to get the outside temperature and color code it. If you want, you can use the LED’s color to update you if your favorite team won, or if you have unread emails in your inbox. The hardware is simple: one pin to ground, another to 5V, and a third to a digital pin. The LED has a tiny chip inside it, and it decodes a signal sent from the microcontroller to determine what color to display. This complex part is wrapped up in the Adafruit NeoPixel library.

The final part is to add some local photoresistors to detect lighting wherever you place your ESP board. We are going to use the ADC pin, which is also known as A0, to receive an analog value of the intensity of light present. I decided to use two photocells in series with a 10k Ohm resistor, but you may choose to hook up the cells in parallel, or use a different number of cells. Below is a schematic of the final ESP8266 circuit, with the added photocells.

With all the pieces together, the Remote Control Module looks like this:

Here are some screenshots of the Cayenne Dashboard:

Code

Arduino Yun's 32U4 CodeArduino
This is the Light Control Module which uses a PIR sensor, a buzzer, and some photocells to drive the LED strip. The 32U4 chip receives a code from the AR9331 processor via the Bridge.
/* This is the Arduino code for the Smart Ambient Lighting Project
 *  Upload this code to an Arduino Yun.
 *  
 *  The microcontroller is connected to an RGB LED Strip, a PIR
 *  Sensor, some photocells, and a buzzer. When motion is detected
 *  and the room is dimly lit, the LED strip will turn on until 
 *  motion is no longer detected. Then, the buzzer will sound and 
 *  the lights will turn off. If it receives a signal from the 
 *  Linux side of the Arduino through Bridge, the lights will turn 
 *  on according to the temperature outside. This program is also 
 *  compatible with Cayenne.
 *  
 * Created by Daniel Martin
 */

 
#define RED 3           // Pin connected to gate of Red Transistor (must be PWM)
#define GREEN 5         // Pin connected to gate of Green Transistor (must be PWM)
#define BLUE 9          // Pin connected to gate of Blue Transistor (must be PWM)

// Virtual Pins for Cayenne sliders to control the lights
#define REDVP 3
#define GREENVP 4
#define BLUEVP 5


int irDistance = 8;
int irDistPlus = 5;
int piezoPin = 4;       // pin for buzzer

// threshold for light intensity
// increase the value if you want the lights to turn on even if the room is lit
// decrease the value if you want the lights to turn on only if it's very dark
int threshold = 700;  
 
char Dvalue[2];     // variable to take in temp-range value from ESP8266


//When light is on, wait 60s 
//After time limit, wait 30s and check if the number of movements is greater than PIRNUM
int pirNum = 0;     // initialize pirNum to 0
unsigned long extraTimeLim = 30000;     
unsigned long timeLim = 60000;
int PIRNUM = 0;
int nextmode = 0;

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

#include <stdio.h>

#include <Console.h>
#include <CayenneYun.h>

// This token is found in the configuration of your Yn in cayenne.mydevices.com
char token[] = "**********";

unsigned long timer;
unsigned long extraTime;


int photoPin = 0;       // Analog pin connected to photocells
int photoReading = 0;
int pirPin = 7;         // Digital pin connected to PIR
int pirVal = 0;
bool isOn = false;      // Light is off

// Used in Cayenne's checkSensor function
int previousState = -1;
int currentState = -1;
unsigned long previousMillis = 0;

int bright = 255;


void setup() {

  memset(Dvalue, 0, 2);       //set memory for variable which will be received from ESP8266

  Cayenne.begin(token);       // Begin Cayenne

  Console.println("Connected!");
  timer = millis();
  extraTime = millis();

  //Set each digital pin as input or output
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(pirPin, INPUT);

  pinMode(piezoPin, OUTPUT);
  pinMode(irDistPlus, OUTPUT);

  //Initial "on and off" to show everything is working
  analogWrite(RED, bright);
  analogWrite(GREEN, bright);
  analogWrite(BLUE, bright);
  delay(2000);
  analogWrite(GREEN, 0);
  analogWrite(BLUE, 0);
  analogWrite(RED, 0);

}

void loop() {
  Cayenne.run();


  pirVal = PIR();       //Check the current state of the PIR

  
  PhotoCell(pirVal);    //Check if light needs to be turned on or off

  

}


// Check the PIR value -- uncomment to see the value in the monitor
int PIR() {
  pirVal = digitalRead(pirPin);
  // Console.print("PIR is ");
  // Console.println(pirVal);
  return pirVal;
}

// Check value of light, and determine if LED should be on or off
void PhotoCell(int pir) {
  int redBright, greenBright, blueBright;
  photoReading = analogRead(photoPin);      // Check light value
  ReceiveLightValue();                      // Receive temp range from ESP8266
  
  // If light is dim, there is movement, and LEDs are not already on, turn it on
  if((photoReading <= threshold) && (pir == HIGH) && !isOn) {
    isOn = true;
    timer = millis();
    //Console.println("Turn on");
    Sim();                                  // do a simulation and produce a random color
    RandColor(&redBright, &greenBright, &blueBright);
    delay(1000);
  }
  
  if(isOn) {      // In the first phase, do nothing -- just leave the light on for timeLim seconds

    if (millis() - timer > timeLim) {     // We must now enter the second phase

      pir = 0;
      nextmode = 1;
      
      extraTime = millis();
      timer = millis();
    }
    if (nextmode) {                   // Add all the values of the PIR during the second phase
      pirNum = PIR() + pirNum;        
      //Console.print("pirNum = ");
      //Console.println(pirNum);
    }

    if((nextmode) && (millis() - extraTime > extraTimeLim)) {
      Console.println("Checking if needs to be on.");
      if (pirNum <= PIRNUM) {     // If the number of movements is less than PIRNUM (default 1)
                                  // turn off; otherwise stay on
        isOn = false;
        nextmode = 0;
        Console.println("Turn off");
        digitalWrite(piezoPin, HIGH);     // buzzer signals that light will turn off
        delay(300);
        digitalWrite(piezoPin, LOW);
        delay(1000);
        analogWrite(RED, 0);
        analogWrite(GREEN, 0);
        analogWrite(BLUE, 0);
        delay(10);
      }
      extraTime = millis();     // reset all timers
      timer = millis();
      pirNum = 0;
    }
    
  }
  

  
  delay(500);
}

// Receive temperature range code from Linux side of Yn (using Bridge)
void ReceiveLightValue() {
  int Dint = 0;
  Bridge.begin();
  Bridge.get("D3", Dvalue, 2);
  Dint = atoi(Dvalue);
  int weatherTime = 10000;
  Console.println(Dint);
  switch (Dint) {
    case 0:
      //do nothing
      break;
    case 1:
      //Pink
      isOn = true;
      timer = millis();
      analogWrite(RED, 255);
      analogWrite(GREEN, 180);
      analogWrite(BLUE, 255);
      delay(weatherTime);
      break;
    case 2:
      //Red
      isOn = true;
      timer = millis();      
      analogWrite(RED, 255);
      analogWrite(GREEN, 0);
      analogWrite(BLUE, 0);
      delay(weatherTime);
      break;
    case 3:
      //Orange
      isOn = true;
      timer = millis();      
      analogWrite(RED, 255);
      analogWrite(GREEN, 80);
      analogWrite(BLUE, 0);
      delay(weatherTime);
      break;
    case 4:
      //Yellow
      isOn = true;
      timer = millis();      
      analogWrite(RED, 230);
      analogWrite(GREEN, 255);
      analogWrite(BLUE, 0);
      delay(weatherTime);
      break;
    case 5:
      //Green
      isOn = true;
      timer = millis();      
      analogWrite(RED, 0);
      analogWrite(GREEN, 255);
      analogWrite(BLUE, 0);
      delay(weatherTime);
      break;
    case 6:
      //Blue
      isOn = true;
      timer = millis();      
      analogWrite(RED, 0);
      analogWrite(GREEN, 0);
      analogWrite(BLUE, 255);
      delay(weatherTime);
      break;
    case 7:
      //Purple
      isOn = true;
      timer = millis();      
      analogWrite(RED, 225);
      analogWrite(GREEN, 0);
      analogWrite(BLUE, 255);
      delay(weatherTime);
      break; 
    case 8:
      //White
      isOn = true;
      timer = millis();
      analogWrite(RED, 255);
      analogWrite(GREEN, 255);
      analogWrite(BLUE, 255);
      delay(weatherTime);
      break;       
  }
  
}

// Run a simulation: first fade to red, then fade to yellow, then fade to white
void Sim() {
  int r, g, b;
  analogWrite(GREEN, 0);
  analogWrite(BLUE, 0);
  analogWrite(RED, 0);
  delay(200);
  for(r = 0; r < 255; r++) {
    analogWrite(RED, r);
    delay(5);
  }
  for(g = 0; g < 255; g++) {
    analogWrite(GREEN, g);
    delay(5);
  }
  for(b = 0; b < 255; b++) {
    analogWrite(BLUE, b);
    delay(5);
  }

  delay(500);  
}

// Produce a random color that is dim (between 1 and 25 out of 255)
void RandColor(int *redBright, int *greenBright, int *blueBright) {
  int randR = 0;
  int randG = 0;
  int randB = 0;
  int x, y, z;

  randomSeed(analogRead(1));
    
  randR = random(1, 25);
  randG = random(1, 25);
  randB = random(1, 25);

  
  for(int i = 100; i > 0; i--) {  //Fade backwards from white to random color in 100 intervals
    x = i;
    y = i;
    z = i;

    *redBright = map(x, 1, 100, randR, 255); 
    *greenBright = map(y, 1, 100, randG, 255); 
    *blueBright = map(z, 1, 100, randB, 255); 

    analogWrite(RED, *redBright);
    analogWrite(GREEN, *greenBright);
    analogWrite(BLUE, *blueBright);
    delay(50);
  }


}



// The following code has been auto-generated by Cayenne for its sliders to control the LED Strip
CAYENNE_IN(REDVP)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 255
  analogWrite(RED, currentValue); // analogWrite accepts a value from 0 to 255
}

CAYENNE_IN(GREENVP)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 255
  analogWrite(GREEN, currentValue); // analogWrite accepts a value from 0 to 255
}

CAYENNE_IN(BLUEVP)
{
  // get value sent from dashboard
  int currentValue = getValue.asInt(); // 0 to 255
  analogWrite(BLUE, currentValue); // analogWrite accepts a value from 0 to 255
}
ESP8266 CodeArduino
The Remote Control Module has some photocells, an IR Transmitter / Receiver pair, and an RGB LED. It senses motion in a remote location (e.g. hallway), indicates the outside temperature with the color of the RGB LED, and if it's dark, sends a code to the Arduino Yun's AR9331 processor via Wi-Fi. This compact module can be used to monitor the motion of a baby or pet.
/* This is the ESP8266 code for the Smart Ambient Lighting Project
 *  Uses Weather Underground API
 *  
 *  Uses code from the following website: https://gist.github.com/bbx10/149bba466b1e2cd887bf
 *  for utilizing the Weather Underground API.
 *  
 *  Instructions for establishing TCP connection to Yn:
 *  https://github.com/iot-playground/Arduino/blob/master/ESP8266ArduinoIDE/WiFiWebServer/WiFiWebServer.ino
 *  
 *  The ESP8266 board is connected to photocells, an IR Transmitter/Receiver, and
 *  an RGB LED. When motion is detected, the LED lights up according to the outside 
 *  temperature. If it is locally dark, the ESP sends a signal to Arduino Yn's
 *  Python program to turn on the Family Room Lights.
 *  
 * Created by Daniel Martin
 */

// To setup the board, follow these instructions:
// https://learn.sparkfun.com/tutorials/esp8266-thing-development-board-hookup-guide/all

// Go to https://www.wunderground.com/weather/api to create a free account and select a plan

// Install libraries:
// https://github.com/adafruit/Adafruit_NeoPixel
// https://github.com/myDevicesIoT/Cayenne-MQTT-ESP8266

#include <ESP8266WiFi.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>

#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>

#define WU_API_KEY "*************"  // From Weather Underground website

#define WU_LOCATION "90001"         // Change this to your zip code

int outTemp = 72;     // initial temperature (a placeholder until the real value is received)
long timer = millis();

long interval = 5*60*1000;   // 5 minute delay

#define DELAY_NORMAL    (5*60*1000)

#define DELAY_ERROR     (20*60*1000)

#define WUNDERGROUND "api.wunderground.com"

// HTTP request
const char WUNDERGROUND_REQ[] =
    "GET /api/" WU_API_KEY "/conditions/q/" WU_LOCATION ".json HTTP/1.1\r\n"
    "User-Agent: ESP8266/0.1\r\n"
    "Accept: */*\r\n"
    "Host: " WUNDERGROUND "\r\n"
    "Connection: close\r\n"
    "\r\n";
static char respBuf[4096];

int irRec = 12;               // IR Receiver digital pin number
int irLed = 13;               // IR Transmitter digital pin number
int maxNumIR = 5;             // Number of 1's received to trigger LED
int led = 14;                 // RGB LED pin
int photoPin = A0;            // ADC pin for photocells
bool irTrue = false;
unsigned long lastMillis = 0;

// Setup of RGB LED
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, led, NEO_RGB + NEO_KHZ400);


char s = ' ';
const char* host = "100.100.1.10";        // Change to your IP Address
char ssid[] = "*********";                // Change to your SSID
char wifiPassword[] = "***********";      // Change to your Wi-Fi password


// Go to cayenne.mydevices.com to setup your Sparkfun board
char username[] = "****-***-***-***-******";    // Username from Cayenne
char password[] = "****************";           // Password from Cayenne
char clientID[] = "******-***-***-***-********"; // Client ID from Cayenne

WiFiClient client;

void setup() {
  pinMode(irRec, INPUT);  pinMode(irLed, OUTPUT);   // IR LED & Receiver
  Serial.begin(9600);
  delay(10);
  Cayenne.begin(username, password, clientID, ssid, wifiPassword);
  pixels.begin();
  pixels.setPixelColor(0, pixels.Color(0, 0, 0));
  pixels.show();

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

   delay(5000);

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  // We are using port 5560 -- must be consist with Yn's python code
  const int port = 5560;        
  if (!client.connect(host, port)) 
  {
    Serial.println("connection failed");
    return;
  }

}

void loop() {
  Cayenne.loop();
  int photoval = analogRead(photoPin);          // Read the value of light intensity
  Serial.println(photoval);
  
  irTrue = IRSensor();                        // Check if there is motion
  
  if((irTrue) && (photoval >= 600)) {        // If there is enough light, only turn on LED
    OutTempRead();
  }
  else if ((irTrue) && (photoval < 600)) {   // If not enough light, send to Yun also

    OutTempRead();
    sendToYun();

    delay(1000);
  }

  if (millis() - lastMillis > 10000) {
    lastMillis = millis();

    Cayenne.fahrenheitWrite(1, outTemp);
    
    Cayenne.virtualWrite(2, photoval);
    Cayenne.virtualWrite(3, irTrue);

  }


  if(millis() - timer > interval) {     // Every 5 mins, check temperature
    WunderSetup();
    timer = millis();
  }
  delay(2000);

}

// Send a different number to Yn based on the outside temperature
void sendToYun() {
  Serial.println("Sending to Yun.");
  if (outTemp > 100) {
    client.print('8');
    delay(1000); 
    client.print('0');
  }
  else if (outTemp > 90) {
    client.print('1'); 
    delay(1000); 
    client.print('0');
  }
  else if (outTemp > 80) {
    client.print('2'); 
    delay(1000); 
    client.print('0');    
  }
  else if (outTemp > 70) {
    client.print('3');
    delay(1000); 
    client.print('0');     
  }
  else if (outTemp > 60) {
    client.print('4'); 
    delay(1000); 
    client.print('0');    
  }
  else if (outTemp > 50) {
    client.print('5'); 
    delay(1000); 
    client.print('0');    
  }
  else if (outTemp > 40) {
    client.print('6');
    delay(1000); 
    client.print('0');     
  }
  else if (outTemp <= 40) {
    client.print('7'); 
    delay(1000); 
    client.print('0');    
  }
}


int OutTempRead() {       // Set the RGB LED based on the outside temp

  if (outTemp < 60) {
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(100);
    pixels.setPixelColor(0, pixels.Color(0, 255, 0));
    pixels.show();
    delay(4000);
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(1000);
  }
  else if(outTemp >= 60 && outTemp <= 80) {
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(100);
    pixels.setPixelColor(0, pixels.Color(255, 0, 0));
    pixels.show();
    delay(4000);
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(1000);   
  }
  else {
    pixels.setPixelColor(0, pixels.Color(255, 255, 255));
    pixels.show();
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(4000);
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    delay(1000);   
  }
}

// Connect to Weather Underground -- modified from the website mentioned above
void WunderSetup() {
 // TODO check for disconnect from AP

  // Open socket to WU server port 80
  Serial.print(F("Connecting to "));
  Serial.println(WUNDERGROUND);

  // Use WiFiClient class to create TCP connections
  WiFiClient httpclient;
  const int httpPort = 80;
  if (!httpclient.connect(WUNDERGROUND, httpPort)) {
    Serial.println(F("connection failed"));
    delay(DELAY_ERROR);
    return;
  }

  // This will send the http request to the server
  Serial.print(WUNDERGROUND_REQ);
  httpclient.print(WUNDERGROUND_REQ);
  httpclient.flush();

  // Collect http response headers and content from Weather Underground
  // HTTP headers are discarded.
  // The content is formatted in JSON and is left in respBuf.
  int respLen = 0;
  bool skip_headers = true;
  while (httpclient.connected() || httpclient.available()) {
    if (skip_headers) {
      String aLine = httpclient.readStringUntil('\n');
      //Serial.println(aLine);
      // Blank line denotes end of headers
      if (aLine.length() <= 1) {
        skip_headers = false;
      }
    }
    else {
      int bytesIn;
      bytesIn = httpclient.read((uint8_t *)&respBuf[respLen], sizeof(respBuf) - respLen);
      Serial.print(F("bytesIn ")); Serial.println(bytesIn);
      if (bytesIn > 0) {
        respLen += bytesIn;
        if (respLen > sizeof(respBuf)) respLen = sizeof(respBuf);
      }
      else if (bytesIn < 0) {
        Serial.print(F("read error "));
        Serial.println(bytesIn);
      }
    }
    delay(1);
  }
  httpclient.stop();

  if (respLen >= sizeof(respBuf)) {
    Serial.print(F("respBuf overflow "));
    Serial.println(respLen);
    delay(DELAY_ERROR);
    return;
  }
  // Terminate the C string
  respBuf[respLen++] = '\0';


  showWeather(respBuf);

}

// Find out the current temperature -- modified from the website mentioned above
void showWeather(char *json)
{
  StaticJsonBuffer<3*1024> jsonBuffer;

  // Skip characters until first '{' found
  // Ignore chunked length, if present
  char *jsonstart = strchr(json, '{');
  //Serial.print(F("jsonstart ")); Serial.println(jsonstart);
  if (jsonstart == NULL) {
    Serial.println(F("JSON data missing"));
    //return false;
  }
  json = jsonstart;

  // Parse JSON
  JsonObject& root = jsonBuffer.parseObject(json);
  if (!root.success()) {
    Serial.println(F("jsonBuffer.parseObject() failed"));
    //return false;
  }

  // Extract weather info from parsed JSON
  JsonObject& current = root["current_observation"];
  const float temp_f = current["temp_f"];
  outTemp = round(temp_f);
  Serial.print(outTemp); Serial.print(F(" F"));

}

// Check if there is motion
bool IRSensor() {
  int irvals = 0;
  for (int i = 0; i < 20; i++) {      // Check 20 times to account for random detection
    irvals = irvals + irDetect(irLed, irRec, 38000);       // Check for object
    //delay(15);
  }
  Serial.println(irvals);                    

  if(irvals > maxNumIR) {     // If 5/20 are 1's, then we know for sure there is motion
    return true;
  }
  else {
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.show();
    return false;
  }
  
  

}

// Send and receive an IR signal
int irDetect(int irLedPin, int irReceiverPin, long frequency)
{
  tone(irLedPin, frequency, 8);              // IRLED 38 kHz for at least 1 ms
  delay(1);                                  // Wait 1 ms
  int ir = digitalRead(irReceiverPin);       // IR receiver -> ir variable
  delay(1);                                  // Down time before recheck
  return !(ir);                                 // Return 1 no detect, 0 detect
}  

//The following function is taken from Cayenne
//Default function for processing actuator commands from the Cayenne Dashboard.
//You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
Arduino Yun's AR9331 CodePython
The AR9331 processor receives a code via Wi-Fi from the ESP8266 and passes it on to the 32U4 processor via the Bridge.
# This is the Python code for the Smart Ambient Lighting Project
# Runs on Linux side of Arduino Yún

# Using TCP communication to the ESP8266, this program receives 
# a value based on the outside temperature and sends it to the 
# Arduino side of the board through Bridge

# Modified by Daniel Martin
# Majority of this code was created by Alexander Baran-Harper
# using this tutorial: https://www.youtube.com/watch?v=PYBZtV2-sLQ



import socket
import time

import sys
sys.path.insert(0, '/usr/lib/python2.7/bridge')

from bridgeclient import BridgeClient as bridgeclient
value = bridgeclient()

host = ''
port = 5560



def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created.")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    print("Socket bind complete.")
    return s

def setupConnection():
    s.listen(1) # Allows one connection at a time.
    conn, address = s.accept()
    print("Connected to: " + address[0] + ":" + str(address[1]))
    return conn



def dataTransfer(conn):
    # A big loop that sends/receives data until told not to.
    while True:
        # Receive the data
        time.sleep(1)
        data = conn.recv(20) # receive the data
        data = data.decode('utf-8')
        # Split the data such that you separate the command
        # from the rest of the data.
        dataMessage = data.split(' ', 1)
        command = dataMessage[0]

        print(command)
        value.put('D3', command)

    conn.close()
        

s = setupServer()

while True:
    try:
        conn = setupConnection()
        dataTransfer(conn)
    except:
        break

Comments

Author

Default
Daniel Martin
  • 3 projects
  • 1 follower

Additional contributors

  • Weather api by Weather Underground
  • Python code by Alexander Baran-Harper
  • Tutorials and components by Adafruit
  • Tutorials and components by Sparkfun
  • App and tutorials by Cayenne

Published on

October 26, 2017

Members who respect this project

Default

and 1 other

See similar projects
you might like

Similar projects you might like

Smart Home - Smart Rules using ARTIK Cloud & Photon

Project tutorial by Raghavendra Ponuganti

  • 3,864 views
  • 2 comments
  • 12 respects

SMART Home LED Lighting System and More

Project in progress by Joey Pongallo

  • 5,947 views
  • 4 comments
  • 13 respects

Smart Home Automation And Security System Using 1Sheeld

Project tutorial by Team SADEE

  • 5,511 views
  • 3 comments
  • 25 respects

Scent-terrific Smart Candle

Project tutorial by Darian Johnson

  • 2,894 views
  • 0 comments
  • 32 respects

IoT Smart Socket Arduino And Cayenne

Project tutorial by Giovanni Gentile

  • 1,478 views
  • 0 comments
  • 5 respects

Smart Home Mini Arduino - In 30 Minutes - Posting in Ubidots

Project tutorial by Andre Mendes

  • 15,142 views
  • 2 comments
  • 29 respects
Add projectSign up / Login