// Bedroom Clock (RWS) converted from Adafruit IO Time Topic Subscription Example
// and BME280 Example, and display example.
// This code is running on hardware with Adafruit ESP32 Feather processor,
// 7 seg display with I2C backpack, and BME280.
//
// Adafruit invests time and resources providing this open source code.
// Please support Adafruit and open source hardware by purchasing
// products from Adafruit!
//
// Written by Adam Bachman, Brent Rubell for Adafruit Industries
// Copyright (c) 2018 Adafruit Industries
// Licensed under the MIT license.
//
// All text above must be included in any redistribution.
/************************** Configuration ***********************************/
// edit the config.h tab and enter your Adafruit IO credentials
// and any additional configuration needed for WiFi, cellular,
// or ethernet clients.
#include "config.h"
/************************ Example Starts Here *******************************/
// set up the 'time/seconds' topic
AdafruitIO_Time *seconds = io.time(AIO_TIME_SECONDS);
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include "TimeLib.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Adafruit_7segment matrix = Adafruit_7segment();
Adafruit_BME280 bme; // I2C
int hhmm = 3333; // hours and minutes as a four digit number hhmm
int tz = -5; // time zone adjustment
int ts = 0; // daylight savings time adjustment
unsigned long lastBrightnessAdjustment = 0; // time in millis()
void setup() {
// start the serial connection
Serial.begin(115200);
// wait for serial monitor to open
while(! Serial);
Serial.print("BedroomClock V1.0\n\nStarting Display, init BME, and Connecting to Adafruit IO");
matrix.begin(0x70);
matrix.setBrightness(0);
unsigned status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
}
// start MQTT connection to io.adafruit.com
io.connect();
// attach message handler for the seconds feed
seconds->onMessage(handleSecs);
// wait for an MQTT connection
while(io.mqttStatus() < AIO_CONNECTED) {
Serial.print(".");
delay(500);
}
// we are connected
Serial.println();
Serial.println(io.statusText());
pinMode(14,INPUT_PULLUP);
pinMode(32,INPUT_PULLUP);
}
double temperature = 0.0, pressure = 0.0, humidity = 0.0;
void loop() {
static int userBrightness = 0;
// increase up to 15 in steps every 1/4 second if top button pressed
if(userBrightness < 15 && millis()-lastBrightnessAdjustment > 250 && !digitalRead(14)){
userBrightness++;
lastBrightnessAdjustment = millis();
Serial.printf("userBrightness raised to: %d\n",userBrightness);
}
// increase down to 0 in steps every 1/4 second if bottom button pressed
if(userBrightness > 0 && millis()-lastBrightnessAdjustment > 250 && !digitalRead(32)){
userBrightness--;
lastBrightnessAdjustment = millis();
Serial.printf("userBrightness lowered to: %d\n",userBrightness);
}
// if no past adjustment, or it's at least 12 hours in the past, make it bright/dim by time
if(lastBrightnessAdjustment == 0 || (millis()-lastBrightnessAdjustment)/3600000 > 12 ){
userBrightness = abs(1400-hhmm)/50; // 28 just past midnight, 20 just before, 14 at 7AM and 9PM
userBrightness = 14 - userBrightness; // 14 in the afternoon, dropping to 0 between 2100 and 0700
if(userBrightness < 0) userBrightness = 0; // don't go below zero
Serial.printf("userBrightness auto set to: %d\n",userBrightness);
}
matrix.setBrightness(userBrightness);
io.run();
temperature = bme.readTemperature();
pressure = bme.readPressure();
humidity = bme.readHumidity();
matrix.writeDigitNum(0, (hhmm / 1000), false); // draw digit by digit to force leading zeros
matrix.writeDigitNum(1, (hhmm / 100) % 10, false);
matrix.drawColon(true);
matrix.writeDigitNum(3, (hhmm / 10) % 10, false);
matrix.writeDigitNum(4, hhmm % 10, false);
if(!digitalRead(14)) matrix.print((int) (pressure/100));
if(!digitalRead(32)) matrix.print((int) (humidity+0.5));
matrix.writeDisplay();
//delay(1);
}
// message handler for the seconds feed
void handleSecs(char *data, uint16_t len) {
Serial.print("Seconds Feed: ");
Serial.println(data);
ts = dsAdjust(atoi(data) + tz *3600); // set daylight savings time status based on seconds since 1970 local standard time
hhmm = hhmmCalc(atoi(data) + (ts+tz)*3600); // set hours and minutes based on DST and zone
Serial.printf("Temp: %6.2f°C Press: %6.0f hPa Hum: %6.2f%%\n",temperature,pressure/100,humidity);
if(!digitalRead(14)) Serial.println("Green Button Pushed -- Pin 14 pulled low\n");
if(!digitalRead(32)) Serial.println("Red Button Pushed -- Pin 32 pulled low\n");
}
int hhmmCalc(time_t secs){ // return an integer like 1234 for 12:34
TimeElements els; // time library breakdown of latest time in elements
breakTime(secs, els); // secs as passed must be adjusted to local time, including DST if applicable
int hhmm = els.Hour*100 + els.Minute;
while(hhmm < 0) hhmm += 2400; // force back into 0-2359 if needed
while(hhmm >= 2400) hhmm -= 2400;
return hhmm;
}
int dsAdjust(time_t secs) { // Calculate the Daylight Savings Time adjustment for North America
TimeElements els; // time library breakdown of latest time in elements
breakTime(secs, els); // secs as passed must be adjusted to local standard time to get the moments of transition right
// Serial.printf("%d %d %d\n",els.Hour,els.Minute,els.Second);
if(els.Month > 3 && els.Month < 11) return 1; // April through October is daylight savings
if(els.Month == 3 && els.Wday == 1 && els.Day > 7 && els.Day < 15) // or if it is the second Sunday in March
if(els.Hour >= 2) return 1; // yes if after 2AM standard
else return 0; // otherwise not if before 2AM standard
if(els.Month == 3 && ((els.Day-els.Wday)-7) >= 0) return 1; // or if it is March on or after the second Sunday
if(els.Month == 11 && (els.Day-els.Wday) < 0) return 1; // or if it is November and before the first Sunday
if(els.Month == 11 && els.Wday == 1 && els.Day < 8 && els.Hour < 3) return 1; // or if it is the first Sunday in November and before 3AM standard (2AM DST)
return 0; // otherwise not
}