antiElectron
Published © CC BY

eDOTcore: A Portable Altimeter, Weather Station And Clock

eDOTcore: A portable altimeter, weather station and clock.

BeginnerShowcase (no instructions)1 hour2,264
eDOTcore: A Portable Altimeter, Weather Station And Clock

Things used in this project

Hardware components

Microchip ATMEGA 328-PU
×1
BME280
×1
AdafruitOLED Breakout Board - 16-bit Color
×1
eDOTcore
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

SSD1351_BME280_DS3231.ino

Arduino
Code uses FTOLED library
//HISTORY
// 23/04/2016 Added day of week 
// 23/04/2016 Added tenths of seconds
// 23/04/2016 Added dew poin calculation
// 25/04/2016 Corrected bug preventing to save current SLP value
// 26/04/2016 Corrected bug shifting the temperature value for values < 10.00C
// 01/05/2016 NOTE: Disable SD.h (SD card management) before compiling the sketch

const byte pin_cs = 10;
const byte pin_dc = 7;
const byte pin_reset = 8;

#include <EasyScheduler.h>
#include <Wire.h>
#include <SPI.h>
//#include <SD.h>
#include "FTOLED.h"
#include "fonts/SystemFont5x7.h"

/*
#include <fonts/CP437_8x8.h>
#include <fonts/Arial14.h>
#include <fonts/Arial_Black_16.h>
#include <fonts/Droid_Sans_16.h>
#include <fonts/Droid_Sans_24.h>
#include <fonts/Droid_Sans_36.h>
*/

#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Average.h>
#include <EEPROM.h>                      //include EEPROM library
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;

Adafruit_BME280 bme; // I2C

OLED oled(pin_cs, pin_dc, pin_reset);


float Temp = 0;

float tempavg = 0;
float hum = 0;
float humavg = 0;
float Press = 1013.25;
float pressavg = 0;
float altr = 10000;
float dp = 0;
float vp = 0;
float vpe = 0;

float referencePressure = 1013.25;
float altPressure = 1013.25;
int year;
byte month, day, hour, minute, second, tents;
//byte dow;
char tempf[6];
char rhf[6];
char pressf[8];
char altrf[5];
char dpf[6];
char rpf[8];
char st[11];
char sd[11];
//char dw[4];

static int oldsecond;
static long oldmicros;

int zero;
int qnh_inc;
int qnh_dec;
int qne;
int stat = 1;
int address = 0;                        //set EEPROM memory start address location


//CALIBRATION COEFFICIENTS
float temp_o = -1.7;
float temp_s= 1.0;
float temp_lin;
float hum_o = 4.5;
float hum_s = 1.0;
float hum_lin;
float press_o = 0.0;
float press_s = 1.0;
float press_lin;

// CONSTANTS FOR SATURATED VAPOR PRESSURE CALCULATION
const float a0 PROGMEM = 6.107799961;
const float a1 PROGMEM = 0.4436518521;
const float a2 PROGMEM = 0.01428945805;
const float a3 PROGMEM = 0.0002650648471;
const float a4 PROGMEM = 0.000003031240396;
const float a5 PROGMEM = 0.00000002034080948;
const float a6 PROGMEM = 0.00000000006136820929;

Average<float> avepress(30);
Average<float> avetemp(30);
Average<float> avehum(30);

Schedular Task1;
Schedular Task2;
Schedular Task3;
Schedular Task4;


void setup() {
  Task1.start();
  Task2.start();
  Task3.start();
  Task4.start(); 
  
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP); 

  referencePressure = (EEPROMreadlong(address));       //read calibration factor from EEPROM
  altPressure = referencePressure;
 
  bme.begin(0x76);
  oled.begin();
  oled.selectFont(SystemFont5x7);
  oled.setDisplayMode(DISPLAY_NORMAL);

  oled.drawBox(110, 126, 111,125,1, AZURE);  
  oled.drawString(114, 120, "C", AZURE, BLACK);
  oled.drawString(0, 120, "Temp.", AZURE, BLACK);
  oled.drawBox(110, 110, 111,109,1, AZURE); 
  oled.drawString(114, 104, "C", AZURE, BLACK);
  oled.drawString(0, 104, "Dew", AZURE, BLACK);
  oled.drawString(110, 88, "%", AZURE, BLACK);
  oled.drawString(0, 88, "RH", AZURE, BLACK);
  oled.drawString(110, 72, "hPa", AZURE, BLACK);
  oled.drawString(0, 72, "Baro", AZURE, BLACK);
  oled.drawString(110, 52, "m", AZURE, BLACK);
  oled.drawString(0, 52, "Altitude", AZURE, BLACK);
  oled.drawString(0, 36, "SLP", AZURE, BLACK);  
  oled.drawString(110, 36, "hPa", AZURE, BLACK);

  oled.drawLine(0,64,127,64,DARKGRAY);
  oled.drawLine(0,29,127,29,DARKGRAY);
  oled.drawLine(0,12,105,12,DARKGRAY);
  oled.drawLine(105,12,105,127,DARKGRAY);

  oled.drawString(0, 17, "Time", AZURE, BLACK);
  oled.drawString(0, 0, "Date", AZURE, BLACK);
  clock.begin();
//  clock.setDateTime(__DATE__, __TIME__);
//  clock.setDateTime(DateTime(2016, 04, 23, 20, 34, 0));
}

void loop(){
    Task1.check(acq1,500);
    Task2.check(acq2,50);
    Task3.check(acq3,3);
    Task4.check(acq4,2); 
}
  

  void acq1(){  
   Temp = bme.readTemperature();
   hum = bme.readHumidity();

   avetemp.push(Temp);
   tempavg = avetemp.mean();
   avehum.push(hum);
   humavg = avehum.mean();

 // CALCULATIONS
  vp = a0 + tempavg * (a1 + tempavg * ( a2 + tempavg * (a3 + tempavg * ( a4 + tempavg * (a5 + a6 * tempavg)))));
  vpe = (humavg * vp) / 100.00; 
  dp = (-430.22 + 237.70 * log(vpe)) / (-log(vpe) + 19.08) ;            // Dew point


 // DATA LINEARISATION
   temp_lin = tempavg * temp_s + temp_o;
   hum_lin = humavg * hum_s + hum_o;


// DATA FORMATTING
  dtostrf(temp_lin,2, 2, tempf);
  dtostrf(hum_lin,2, 2, rhf);
  dtostrf(dp,2, 2, dpf);


if ((temp_lin >= 0) && (temp_lin < 10)){
  oled.drawString(71, 120, " ", BLACK, BLACK);
  oled.drawString(77, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}
 else { 
  oled.drawString(71, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}


if ((dp >= 0) && (dp < 10)){
  oled.drawString(71, 104, " ", BLACK, BLACK);
  oled.drawString(77, 104, dpf, MEDIUMSPRINGGREEN, BLACK);   
}
 else { 
  oled.drawString(71, 104, dpf, MEDIUMSPRINGGREEN, BLACK); 
}   
  oled.drawString(71, 88, rhf, MEDIUMSPRINGGREEN, BLACK);  

}  

 
void acq2(){
   Press = bme.readPressure() / 100.000;
//   Press = 101325 / 100.000;
   altr = bme.readAltitude(referencePressure);
//   altr = 2500;
   avepress.push(Press);
   pressavg = avepress.mean();

// DATA LINEARISATION 
   press_lin = pressavg * press_s + press_o;

// DATA FORMATTING 

   dtostrf(press_lin,4, 2, pressf);
   dtostrf(altr,4, 0, altrf);
   dtostrf(referencePressure,6, 2, rpf);

if (press_lin < 1000.00){
  oled.drawString(60, 72, " ", BLACK, BLACK);
  oled.drawString(66, 72, pressf, MEDIUMSPRINGGREEN, BLACK);
}
 else {  
  oled.drawString(60, 72, pressf, MEDIUMSPRINGGREEN, BLACK);
 }


  oled.drawString(78, 52, altrf, STEELBLUE, BLACK);


if (referencePressure < 1000.00){
  oled.drawString(60, 36, " ", BLACK, BLACK);
  oled.drawString(66, 36, rpf, MEDIUMSLATEBLUE, BLACK);
}
 else {
  oled.drawString(60, 36, rpf, MEDIUMSLATEBLUE, BLACK); 
 }
   
if (stat == 0){
 
  oled.drawString(30, 36, "QFE", MEDIUMSLATEBLUE, BLACK);
}
if (stat == 1){
 
  oled.drawString(30, 36, "QNH", MEDIUMSLATEBLUE, BLACK);
}
if (stat == 2){

  oled.drawString(30, 36, "QNE", MEDIUMSLATEBLUE, BLACK);
}     

}  

void acq3(){
   zero = digitalRead(6);
   qnh_inc = digitalRead(5);
   qnh_dec = digitalRead(4);
   qne = digitalRead(3);

  if (zero == LOW){
    referencePressure = pressavg;
    stat = 0;
  }

  if (qnh_inc == LOW){
    stat = 1;
    referencePressure = altPressure;   
    referencePressure = referencePressure + 0.01;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }
  
  if (qnh_dec == LOW){ 
    stat = 1;
    referencePressure = altPressure;      
    referencePressure = referencePressure - 0.01;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }

  if (qne == LOW){
    referencePressure = 1013.25;
    stat = 2;
  }  
}

void acq4(){
  dt = clock.getDateTime();
//  dow = clock.dateFormat("D", dt);
  
  hour = dt.hour;
  minute = dt.minute;
  second = dt.second;
  day = dt.day;
  month = dt.month;
  year = dt.year;



  if ( second != oldsecond ) {
    oldmicros = micros();
    oldsecond = second; 
  }
  tents = ((micros()-oldmicros)/100000)%10;

 sprintf(st, "%02d:%02d:%02d.%01d", hour, minute, second, tents);
 sprintf(sd, "%02d/%02d/%02d", day, month, year);
// sprintf(dw, "%03d", dow);
  
  oled.drawString(42, 17, st, ORANGE, BLACK);
  oled.drawString(42, 0, sd, ORANGE, BLACK);  
//  oled.drawString(110, 0, dw, ORANGE, BLACK);  
//  oled.drawString(110, 0, (clock.dateFormat("D", dt)), ORANGE, BLACK);
//  oled.drawString(110, 17, (clock.dateFormat("z", dt)), ORANGE, BLACK);
}


//Routine to write a 4 byte (32 bit) long to EEPROM at specified addresses
void EEPROMwritelong(int address, long value)    
    {
    byte four = (value & 0xFF);            //four = least significant byte
    byte three = ((value>>8) & 0xFF);
    byte two = ((value>>16) & 0xFF);
    byte one = ((value>>24) & 0xFF);       //one = most significant byte
    
    EEPROM.write(address, four);           //write the four bytes into EEPROM
    EEPROM.write(address +1, three);
    EEPROM.write(address +2, two);
    EEPROM.write(address +3, one);
    }

//routine to read back 4 bytes and return with (32 bit) long as value
long EEPROMreadlong(long address)
    {
      long four = EEPROM.read(address);    //read the 4 bytes from EEPROM
      long three = EEPROM.read(address + 1);
      long two = EEPROM.read(address + 2);
      long one = EEPROM.read(address + 3);
      return (four)+(three << 8)+(two << 16)+(one << 24);
    }

SSD1351_BME280_DS3231_REV2.ino

Arduino
Alternate code using FTOLED library
//HISTORY
// 23/04/2016 Added day of week 
// 23/04/2016 Added tenths of seconds
// 23/04/2016 Added dew poin calculation
// 25/04/2016 Corrected bug preventing to save current SLP value
// 26/04/2016 Corrected bug shifting the temperature value for values < 10.00C
// 01/05/2016 NOTE: Disable SD.h (SD card management) before compiling the sketch

const byte pin_cs = 10;
const byte pin_dc = 7;
const byte pin_reset = 8;

#include <EasyScheduler.h>
#include <Wire.h>
#include <SPI.h>
//#include <SD.h>
#include "FTOLED.h"
#include "fonts/SystemFont5x7.h"
/*
#include <fonts/Arial14.h>
#include <fonts/Arial_Black_16.h>
#include <fonts/Droid_Sans_16.h>
#include <fonts/Droid_Sans_24.h>
#include <fonts/Droid_Sans_36.h>
#include <fonts/CP437_8x8.h>
*/
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Average.h>
#include <EEPROM.h>                      //include EEPROM library
#include "RTClib.h"

RTC_DS3231 rtc;

Adafruit_BME280 bme; // I2C

OLED oled(pin_cs, pin_dc, pin_reset);
// Text box takes up bottom 32 characters of the display (ie 4 rows)


float Temp = 0;
float tempavg = 0;
float hum = 0;
float humavg = 0;
float Press = 1013.25;
float pressavg = 0;
float altr = 10000;
float dp = 0;
float vp = 0;
float vpe = 0;

float referencePressure = 1013.25;
float altPressure = 1013.25;


int outHour = 0;      // Variable for hours
int outMin = 0;       // Variable for minutes
float outSec = 0;       // Variable for seconds
float outday = 0;
float outmonth = 0;
float outyear = 0;
int dow = 3;

byte hourval, minuteval, secondval, tents;

char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
 
char tempf[8];
char rhf[8];
char pressf[8];
char altrf[8];
char dpf[8];
char rpf[8];
char st[10];
char sd[12];

static int oldsecond;
static long oldmicros;

int zero;
int qnh_inc;
int qnh_dec;
int qne;
int stat = 1;
long address = 0;                        //set EEPROM memory start address location


//Calibration coefficients
float temp_o = -1.7;
float temp_s = 1.0;
float temp_lin;
float hum_o = 4.5;
float hum_s = 1.0;
float hum_lin;
float press_o = 0.0;
float press_s = 1.0;
float press_lin;

// CONSTANTS FOR SATURATED VAPOR PRESSURE CALCULATION
const float a0 PROGMEM = 6.107799961;
const float a1 PROGMEM = 0.4436518521;
const float a2 PROGMEM = 0.01428945805;
const float a3 PROGMEM = 0.0002650648471;
const float a4 PROGMEM = 0.000003031240396;
const float a5 PROGMEM = 0.00000002034080948;
const float a6 PROGMEM = 0.00000000006136820929;

Average<float> avepress(30);
Average<float> avetemp(30);
Average<float> avehum(30);

Schedular Task1;
Schedular Task2;
Schedular Task3;
Schedular Task4;

void setup() {
  Task1.start();
  Task2.start();
  Task3.start();
  Task4.start(); 
  
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);  

  bme.begin(0x76);
  oled.begin();
  oled.selectFont(SystemFont5x7                                                                    );
  oled.setDisplayMode(DISPLAY_NORMAL);
  
  oled.drawBox(110, 126, 111,125,1, AZURE);  
  oled.drawString(114, 120, "C", AZURE, BLACK);
  oled.drawString(0, 120, "Temp.", AZURE, BLACK);
  oled.drawBox(110, 110, 111,109,1, AZURE); 
  oled.drawString(114, 104, "C", AZURE, BLACK);
  oled.drawString(0, 104, "Dew", AZURE, BLACK);
  oled.drawString(110, 88, "%", AZURE, BLACK);
  oled.drawString(0, 88, "RH", AZURE, BLACK);
  oled.drawString(110, 72, "hPa", AZURE, BLACK);
  oled.drawString(0, 72, "Baro", AZURE, BLACK);
  oled.drawString(110, 52, "m", AZURE, BLACK);
  oled.drawString(0, 52, "Altitude", AZURE, BLACK);
  oled.drawString(0, 36, "SLP", AZURE, BLACK);  
  oled.drawString(110, 36, "hPa", AZURE, BLACK);

  oled.drawLine(0,64,127,64,DARKGRAY);
  oled.drawLine(0,29,127,29,DARKGRAY);
  oled.drawLine(0,12,105,12,DARKGRAY);
  oled.drawLine(105,12,105,127,DARKGRAY);

  oled.drawString(0, 17, "Time", AZURE, BLACK);
  oled.drawString(0, 0, "Date", AZURE, BLACK);
  rtc.begin();
//  clock.setDateTime(__DATE__, __TIME__);
}

void loop() {
    Task1.check(acq1,500);
    Task2.check(acq2,50);
    Task3.check(acq3,3);
    Task4.check(acq4,1); 
}
  

  void acq1(){  
   Temp = bme.readTemperature();
   hum = bme.readHumidity();

   avetemp.push(Temp);
   tempavg = avetemp.mean();
   avehum.push(hum);
   humavg = avehum.mean();

 // CALCULATIONS
  vp = a0 + tempavg * (a1 + tempavg * ( a2 + tempavg * (a3 + tempavg * ( a4 + tempavg * (a5 + a6 * tempavg)))));
  vpe = (humavg * vp) / 100.00; 
  dp = (-430.22 + 237.70 * log(vpe)) / (-log(vpe) + 19.08) ;            // Dew point


 // DATA LINEARISATION
   temp_lin = tempavg * temp_s + temp_o;
   hum_lin = humavg * hum_s + hum_o;


// DATA FORMATTING
  dtostrf(temp_lin,2, 2, tempf);
  dtostrf(hum_lin,2, 2, rhf);
  dtostrf(dp,2, 2, dpf);


if ((temp_lin >= 0) && (temp_lin < 10)){
  oled.drawString(71, 120, " ", BLACK, BLACK);
  oled.drawString(77, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}
 else { 
  oled.drawString(71, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}


if ((dp >= 0) && (dp < 10)){
  oled.drawString(71, 104, " ", BLACK, BLACK);
  oled.drawString(77, 104, dpf, MEDIUMSPRINGGREEN, BLACK);   
}
 else { 
  oled.drawString(71, 104, dpf, MEDIUMSPRINGGREEN, BLACK); 
}   
  oled.drawString(71, 88, rhf, MEDIUMSPRINGGREEN, BLACK);  

}  

 
void acq2(){
   Press = bme.readPressure() / 100.000;
//   Press = 101325 / 100.000;
   altr = bme.readAltitude(referencePressure);
//   altr = 2500;
   avepress.push(Press);
   pressavg = avepress.mean();

// DATA LINEARISATION 
   press_lin = pressavg * press_s + press_o;

// DATA FORMATTING 

   dtostrf(press_lin,4, 2, pressf);
   dtostrf(altr,4, 0, altrf);
   dtostrf(referencePressure,6, 2, rpf);

if (press_lin < 1000.00){
  oled.drawString(60, 72, " ", BLACK, BLACK);
  oled.drawString(66, 72, pressf, MEDIUMSPRINGGREEN, BLACK);
}
 else {  
  oled.drawString(60, 72, pressf, MEDIUMSPRINGGREEN, BLACK);
 }


  oled.drawString(78, 52, altrf, STEELBLUE, BLACK);


if (referencePressure < 1000.00){
  oled.drawString(60, 36, " ", BLACK, BLACK);
  oled.drawString(66, 36, rpf, MEDIUMSLATEBLUE, BLACK);
}
 else {
  oled.drawString(60, 36, rpf, MEDIUMSLATEBLUE, BLACK); 
 }
   
if (stat == 0){
 
  oled.drawString(30, 36, "QFE", MEDIUMSLATEBLUE, BLACK);
}
if (stat == 1){
 
  oled.drawString(30, 36, "QNH", MEDIUMSLATEBLUE, BLACK);
}
if (stat == 2){

  oled.drawString(30, 36, "QNE", MEDIUMSLATEBLUE, BLACK);
}     

}  

void acq3(){
   zero = digitalRead(6);
   qnh_inc = digitalRead(5);
   qnh_dec = digitalRead(4);
   qne = digitalRead(3);

  if (zero == LOW){
    referencePressure = pressavg;
    stat = 0;
  }

  if (qnh_inc == LOW){
    stat = 1;
    referencePressure = altPressure;   
    referencePressure = referencePressure + 0.01;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }
  
  if (qnh_dec == LOW){ 
    stat = 1;
    referencePressure = altPressure;      
    referencePressure = referencePressure - 0.01;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }

  if (qne == LOW){
    referencePressure = 1013.25;
    stat = 2;
  }
  
}

void acq4(){
  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(); 

    if ( outSec != oldsecond ) {
    oldmicros = micros();
    oldsecond = outSec; 
  }
  tents = ((micros()-oldmicros)/100000)%10;


    sprintf(st, "%02d:%02d:%02d.%01d %03d", outHour, outMin, outSec,tents,dow);
//    sprintf(sd, "%02d/%02d/%02d", outday, outmonth, outyear);
  
   oled.drawString(42, 17, st, ORANGE, BLACK);
//  oled.drawString(42, 0, sd, ORANGE, BLACK);  
  
 //   oled.drawString(110, 0, (clock.dateFormat("D", dt)), ORANGE, BLACK);
 // oled.drawString(110, 17, (clock.dateFormat("z", dt)), ORANGE, BLACK); 





}


//Routine to write a 4 byte (32 bit) long to EEPROM at specified addresses
void EEPROMwritelong(int address, long value)    
    {
    byte four = (value & 0xFF);            //four = least significant byte
    byte three = ((value>>8) & 0xFF);
    byte two = ((value>>16) & 0xFF);
    byte one = ((value>>24) & 0xFF);       //one = most significant byte
    
    EEPROM.write(address, four);           //write the four bytes into EEPROM
    EEPROM.write(address +1, three);
    EEPROM.write(address +2, two);
    EEPROM.write(address +3, one);
    }

//routine to read back 4 bytes and return with (32 bit) long as value
long EEPROMreadlong(long address)
    {
      long four = EEPROM.read(address);    //read the 4 bytes from EEPROM
      long three = EEPROM.read(address + 1);
      long two = EEPROM.read(address + 2);
      long one = EEPROM.read(address + 3);
      return (four)+(three << 8)+(two << 16)+(one << 24);
    }

SSD1351_BME280_DS3231_UGCLIB.ino

Arduino
Code uses UCGLIB for the display
//HISTORY
// 23/04/2016 Added day of week 
// 23/04/2016 Added tenths of seconds
// 23/04/2016 Added dew poin calculation
// 25/04/2016 Corrected bug preventing to save current SLP value
// 26/04/2016 Corrected bug shifting the temperature value for values < 10.00C

#include <EasyScheduler.h>
#include <Wire.h>
#include <SPI.h>
//#include <SD.h>
#include "Ucglib.h"



#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Average.h>
#include <EEPROM.h>                      //include EEPROM library
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;

Adafruit_BME280 bme; // I2C

Ucglib_SSD1351_18x128x128_HWSPI ucg(/*cd=*/ 7 , /*cs=*/ 10, /*reset=*/ 8);


// Text box takes up bottom 32 characters of the display (ie 4 rows)

/*OLED_TextBox box1(oled, 47, 109, 45, 20);
//OLED_TextBox box1(oled, 0, 96, 70, 32);
OLED_TextBox box2(oled, 47, 91, 45, 20);
OLED_TextBox box3(oled, 33, 73, 55, 20);
OLED_TextBox box4(oled, 52, 55, 40, 20);
OLED_TextBox box5(oled, 33, 37, 55, 20);
*/

float Temp = 0;
// float tempK = 0;
// float tempF = 0;
float tempavg = 0;
float hum = 0;
float humavg = 0;
float Press = 1013.25;
float pressavg = 0;
float altr = 10000;
float dp = 0;
float vp = 0;
float vpe = 0;
// float ah = 0;
// float ad = 0;
// float addry = 0;
// float adwet = 0;
// float heat = 0;
float referencePressure = 1013.25;
float altPressure = 1013.25;
int year;
byte month, day, hour, minute, second;
char tempf[6];
char rhf[6];
char pressf[8];
char altrf[5];
char dpf[6];
//char ahf[8];
//char adf[8];
//char heatf[8];
char rpf[8];
char st[11];
char sd[11];

static int oldsecond;
static long oldmicros;

int zero;
int qnh_inc;
int qnh_dec;
int qne;
int stat = 1;
long address = 0;                        //set EEPROM memory start address location


//CALIBRATION COEFFICIENTS
float temp_o = -1.7;
float temp_s = 1.0;
float temp_lin;
float hum_o = 4.5;
float hum_s = 1.0;
float hum_lin;
float press_o = 0.0;
float press_s = 1.0;
float press_lin;

// CONSTANTS FOR SATURATED VAPOR PRESSURE CALCULATION
const float a0 PROGMEM = 6.107799961;
const float a1 PROGMEM = 0.4436518521;
const float a2 PROGMEM = 0.01428945805;
const float a3 PROGMEM = 0.0002650648471;
const float a4 PROGMEM = 0.000003031240396;
const float a5 PROGMEM = 0.00000002034080948;
const float a6 PROGMEM = 0.00000000006136820929;

Average<float> avepress(1);
Average<float> avetemp(1);
Average<float> avehum(1);

Schedular Task1;
Schedular Task2;
Schedular Task3;
Schedular Task4;


void setup() {
  Task1.start();
  Task2.start();
  Task3.start();
  Task4.start(); 
  
  pinMode(6, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP); 

  referencePressure = (EEPROMreadlong(address));       //read calibration factor from EEPROM
  altPressure = referencePressure;
 

  bme.begin(0x76);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
    ucg.clearScreen();

  ucg.setFont(ucg_font_7x13_mr);
  ucg.setColor(255, 255, 255);
  ucg.setPrintPos(0,13);
  ucg.print("Temp."); 
  ucg.setPrintPos(108,13);
  ucg.print("C");
  ucg.setPrintPos(0,28);
  ucg.print("Dew"); 
  ucg.setPrintPos(108,28);
  ucg.print("C");
  ucg.setPrintPos(0,43);
  ucg.print("RH"); 
  ucg.setPrintPos(108,43);
  ucg.print("%");
  ucg.setPrintPos(0,58);
  ucg.print("Press."); 
  ucg.setPrintPos(108,58);
  ucg.print("hPa");
  ucg.setPrintPos(0,73);
  ucg.print("Alt.");  
  ucg.setPrintPos(108,73);
  ucg.print("m");
  ucg.setPrintPos(108,88);
  ucg.print("hPa");
  

  clock.begin();
//  clock.setDateTime(__DATE__, __TIME__);
//  clock.setDateTime(DateTime(2016, 04, 23, 20, 34, 0));
}

void loop(){
    Task1.check(acq1,500);
    Task2.check(acq2,50);
    Task3.check(acq3,3);
    Task4.check(acq4,50); 
}
  

  void acq1(){  
   Temp = bme.readTemperature();
   hum = bme.readHumidity();

   avetemp.push(Temp);
   tempavg = avetemp.mean();
   avehum.push(hum);
   humavg = avehum.mean();

 // CALCULATIONS
  vp = a0 + tempavg * (a1 + tempavg * ( a2 + tempavg * (a3 + tempavg * ( a4 + tempavg * (a5 + a6 * tempavg)))));
  vpe = (humavg * vp) / 100.00; 
  dp = (-430.22 + 237.70 * log(vpe)) / (-log(vpe) + 19.08) ;            // Dew point


 // DATA LINEARISATION
   temp_lin = tempavg * temp_s + temp_o;
   hum_lin = humavg * hum_s + hum_o;


// DATA FORMATTING

  dtostrf(temp_lin,2, 2, tempf);
  dtostrf(hum_lin,2, 2, rhf);
  dtostrf(dp,2, 2, dpf);
//  dtostrf(heat,2, 2, heatf);
//  dtostrf(ah,1, 3, ahf);
//  dtostrf(ad,1, 4, adf);

  ucg.setFontMode(UCG_FONT_MODE_SOLID);
  ucg.setPrintPos(70,13);
  ucg.print(tempf);
  ucg.setPrintPos(70,28);
  ucg.print(dpf);  
  ucg.setPrintPos(70,43);
  ucg.print(rhf);




if ((temp_lin >= 0) && (temp_lin < 10)){
//  oled.drawString(73, 120, " ", BLACK, BLACK);
//  oled.drawString(79, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}
 else { 
//  oled.drawString(73, 120, tempf, MEDIUMSPRINGGREEN, BLACK);
}


if ((dp >= 0) && (dp < 10)){
//  oled.drawString(73, 104, " ", BLACK, BLACK);
//  oled.drawString(79, 104, dpf, MEDIUMSPRINGGREEN, BLACK);   
}
 else { 
//  oled.drawString(73, 104, dpf, MEDIUMSPRINGGREEN, BLACK); 
}   
//  oled.drawString(73, 88, rhf, MEDIUMSPRINGGREEN, BLACK);  


  ucg.setPrintPos(35,118);
  ucg.print(sd);

  ucg.setPrintPos(108,118);
  ucg.print(clock.dateFormat("D", dt));


}  

 
void acq2(){
   Press = bme.readPressure() / 100.000;
//   Press = 101325 / 100.000;
   altr = bme.readAltitude(referencePressure);
//   altr = 2500;
   avepress.push(Press);
   pressavg = avepress.mean();

// DATA LINEARISATION 
   press_lin = pressavg * press_s + press_o;

// DATA FORMATTING 

   dtostrf(press_lin,4, 2, pressf);
   dtostrf(altr,4, 0, altrf);
   dtostrf(referencePressure,6, 2, rpf);


  ucg.setPrintPos(76,73);
  ucg.print(altrf);

if (press_lin < 1000){
  ucg.setPrintPos(56,58);
  ucg.print(" ");
  ucg.print(pressf);
}
 else {  
  ucg.setPrintPos(56,58);
  ucg.println(pressf);
 }



if (referencePressure < 1000){
  ucg.setPrintPos(56,88);
  ucg.print(" ");
  ucg.print(rpf);
}
 else {
  ucg.setPrintPos(56,88);
  ucg.print(rpf);
 }
   
if (stat == 0){ 
  ucg.setPrintPos(0,88);
  ucg.print("QFE");
}
if (stat == 1){ 
  ucg.setPrintPos(0,88);
  ucg.print("QNH");
}
if (stat == 2){ 
  ucg.setPrintPos(0,88);
  ucg.print("QNE");
} 


}  

void acq3(){
   zero = digitalRead(6);
   qnh_inc = digitalRead(5);
   qnh_dec = digitalRead(4);
   qne = digitalRead(3);

  if (zero == LOW){
    referencePressure = pressavg;
    stat = 0;
  }

  if (qnh_inc == LOW){
    stat = 1;
    referencePressure = altPressure;   
    referencePressure = referencePressure + 0.1;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }
  
  if (qnh_dec == LOW){ 
    stat = 1;
    referencePressure = altPressure;      
    referencePressure = referencePressure - 0.1;
    altPressure = referencePressure;
    EEPROMwritelong(address,altPressure);          //store calibration factor in EEPROM
  }

  if (qne == LOW){
    referencePressure = 1013.25;
    stat = 2;
  }  
}

void acq4(){
  dt = clock.getDateTime();

  hour = dt.hour;
  minute = dt.minute;
  second = dt.second;
  day = dt.day;
  month = dt.month;
  year = dt.year;


  if ( second != oldsecond ) {
    oldmicros = micros();
    oldsecond = second; 
  }
//  tents = ((micros()-oldmicros)/100000)%10;

   sprintf(st, "%02d:%02d:%02d", hour, minute, second);
   sprintf(sd, "%02d/%02d/%02d", day, month, year);

  ucg.setPrintPos(49,103);
  ucg.print(st);

 
}


//Routine to write a 4 byte (32 bit) long to EEPROM at specified addresses
void EEPROMwritelong(int address, long value)    
    {
    byte four = (value & 0xFF);            //four = least significant byte
    byte three = ((value>>8) & 0xFF);
    byte two = ((value>>16) & 0xFF);
    byte one = ((value>>24) & 0xFF);       //one = most significant byte
    
    EEPROM.write(address, four);           //write the four bytes into EEPROM
    EEPROM.write(address +1, three);
    EEPROM.write(address +2, two);
    EEPROM.write(address +3, one);
    }

//routine to read back 4 bytes and return with (32 bit) long as value
long EEPROMreadlong(long address)
    {
      long four = EEPROM.read(address);    //read the 4 bytes from EEPROM
      long three = EEPROM.read(address + 1);
      long two = EEPROM.read(address + 2);
      long one = EEPROM.read(address + 3);
      return (four)+(three << 8)+(two << 16)+(one << 24);
    }

Credits

antiElectron
20 projects • 120 followers

Comments