// eDOT: Versatile precision weather station and clock
//HISTORY
// 11/12/2105 Added measurement calibration coefficients
// 09/06/2016 Added automatic display brightness
// 09/06/2016 Added task scheduler
// 07/08/2016 Added eDOT splashscreen
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <Average.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "RTClib.h"
#include <EasyScheduler.h>
Adafruit_BME280 bme; // I2C
RTC_DS3231 rtc;
int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 7;
int numberOfVerticalDisplays = 1;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
#define TEMPERATURE 0
#define HUMIDITY 1
#define PRESSURE 2
#define TIME 3
#define DAY 4
#define DATE 5
float temp;
float tempavg;
char tempf[8];
float hum;
float humavg;
char humf[8];
float press;
float pressavg;
char pressf[8];
int screen = 0; // initial screen
long previousLEDMillis = 0; // for LED display update
long LEDInterval = 5000; // delay between screens
int screenMax = 5; // maximum number of screen
bool screenChanged = true; // screen status
float lightsens;
float screenBrt = 0;
float lightsensavg;
Average<float> avetemp(60); //Average for temperature (80 samples)
Average<float> avehum(60); //Average for humidity (80 samples)
Average<float> avepress(60); //Average for pressure (80 samples)
Average<float> avelightsens(40); //Average for pressure (80 samples)
//Calibration coefficients
float temp_o = -1.70;
float temp_s = 1.0;
float temp_lin;
float hum_o = 2.45;
float hum_s = 1.0;
float hum_lin;
float press_o = 0.0;
float press_s = 1.0;
float press_lin;
//Brightness sensor correction
float brt_o = -4;
float brt_s = 1.35;
Schedular Task1;
Schedular Task2;
void setup() {
Task1.start();
Task2.start();
Wire.begin(); // Start I2C
bme.begin(0x76);
matrix.setIntensity(screenBrt); // Use a value between 0 and 15 for brightness
// Adjust to your own needs
// matrix.setPosition(0, 0, 0); // The first display is at <0, 0>
// matrix.setPosition(1, 1, 0); // The second display is at <1, 0>
matrix.setRotation(0, 1); // Adjust display orientation
matrix.setRotation(1, 1); // Adjust display orientation
matrix.setRotation(2, 1); // Adjust display orientation
matrix.setRotation(3, 1); // Adjust display orientation
matrix.setRotation(4, 1); // Adjust display orientation
matrix.setRotation(5, 1); // Adjust display orientation
matrix.setRotation(6, 1); // Adjust display orientation
matrix.setRotation(7, 1); // Adjust display orientation
/*
matrix.setRotation(8, 1); // Adjust display orientation
matrix.setRotation(9, 1); // Adjust display orientation
*/
rtc.begin();
// matrix.setRotation(3, 2); // The same hold for the last display
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// rtc.adjust(DateTime(2016, 02, 28, 16, 44, 0));
//Serial.begin(9600);
//eDOT SPLASHSCREEN
matrix.fillScreen(0);
matrix.write();
matrix.setCursor(12,0);
matrix.print("eDOT");
for(screenBrt = 0; screenBrt <=15; screenBrt++){
delay(25);
matrix.setIntensity(screenBrt); // Use a value between 0 and 15 for brightness
matrix.write();
}
delay(250);
for(screenBrt = 15; screenBrt >= 0; screenBrt--){
delay(50);
matrix.setIntensity(screenBrt); // Use a value between 0 and 15 for brightness
matrix.write();
}
delay(500);
matrix.fillScreen(0);
matrix.write();
delay(1000);
}
void loop() {
Task1.check(acq1,500);
Task2.check(acq2,20);
}
void acq1(){
// DATA ACQUISITION AND AVERAGING
temp = bme.readTemperature();
avetemp.push(temp);
tempavg = avetemp.mean();
hum = bme.readHumidity();
avehum.push(hum);
humavg = avehum.mean();
press = bme.readPressure();
avepress.push(press);
pressavg = avepress.mean();
DateTime now = rtc.now();
outSec = now.second();
outMin = now.minute();
outHour = now.hour();
outday = now.day();
outmonth = now.month();
outyear = now.year() - 2000;
dow = now.dayOfTheWeek();
}
void acq2(){
lightsens = analogRead(A3);
avelightsens.push(lightsens);
lightsensavg = avelightsens.mean();
screenBrt = constrain(((lightsensavg /1023 * 15 ) * brt_s + brt_o), 0 , 15);
matrix.setIntensity(screenBrt);
// DATA LINEARISATION
temp_lin = tempavg * temp_s + temp_o;
hum_lin = humavg * hum_s + hum_o;
press_lin = pressavg * press_s + press_o;
unsigned long currentLEDMillis = millis();
//Serial.println(screenBrt);
if(currentLEDMillis - previousLEDMillis > LEDInterval) // save the last time you changed the display
{
previousLEDMillis = currentLEDMillis;
screen++;
if (screen > screenMax) screen = 0; // reset to initial screen once cycle is completed
screenChanged = true;
}
// if (screenChanged) // update measurement upon screen change
// {
// screenChanged = false; // reset for next iteration
switch(screen){
case TEMPERATURE:
dtostrf(temp_lin,4, 2, tempf); // format to five digits with two decimals
matrix.setCursor(6,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(tempf); // print current temperature
matrix.drawRect(37,0,2,2,255); // draw grade symbol
matrix.setCursor(40,0);
matrix.print("C");
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
case HUMIDITY:
dtostrf(hum_lin,4, 2, humf); // format to five digits with two decimals
matrix.setCursor(6,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(humf); // print current temperature
matrix.setCursor(37,0);
matrix.print("%");
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
case PRESSURE:
dtostrf(press_lin,6, 0, pressf); // format to five digits with two decimals
matrix.setCursor(0,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(pressf); // print current temperature
matrix.setCursor(37,0);
matrix.print("Pa");
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
case TIME:
// dtostrf(press_lin,6, 0, pressf); // format to five digits with two decimals
matrix.setCursor(0,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
if (outHour < 10){
matrix.print("0");
}
matrix.print(outHour,0); // print current hours
matrix.print(":");
if (outMin < 10){
matrix.print("0");
}
matrix.print(outMin,0); // print current minutes
matrix.print(":");
if (outSec < 10){
matrix.print("0");
}
matrix.print(outSec,0); // print current seconds
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
case DATE:
// dtostrf(press_lin,6, 0, pressf); // format to five digits with two decimals
matrix.setCursor(0,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
if (outday < 10){
matrix.print("0");
}
matrix.print(outday,0); // print current hours
matrix.print("/");
if (outmonth < 10){
matrix.print("0");
}
matrix.print(outmonth,0); // print current minutes
matrix.print("/");
matrix.print(outyear,0); // print current seconds
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
case DAY:
// dtostrf(press_lin,6, 0, pressf); // format to five digits with two decimals
matrix.setCursor(15,0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(daysOfTheWeek[dow]);
matrix.write(); // write current data to display
matrix.fillScreen(0); // clear display
break;
}
}
Comments