antiElectron
Published © CC BY-NC-SA

eDOT - Arduino Based Precision Clock and Weather Station

eDOT is an Arduino based precision clock and weather station with built in IR remote receiver and automatic brightness adjustment.

IntermediateFull instructions providedOver 1 day24,168
eDOT - Arduino Based Precision Clock and Weather Station

Things used in this project

Hardware components

Microchip ATMEGA 328P-PU
×1
MAXIM MAX7219
×6
BOSCH BME280 - GY-BMEP breakout board
×1
Adafruit Luckylight 8x8 dot matrix LED display - M1603095
×6
DS3231
RTC CLOCK
×1
Arduino Nano R3
Arduino Nano R3
×1
Arduino UNO
Arduino UNO
×1
eDOTcore
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Flashforge Dreamer

Story

Read more

Code

eDOT: Versatile precision weather station and clock

Arduino
// 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;

 }
 }

Credits

antiElectron

antiElectron

20 projects • 115 followers

Comments