陈年
Published

Office Environmental Monitor

This is a project about how to make an Office Environmental Monitor

BeginnerFull instructions provided1.5 hours76
Office Environmental Monitor

Things used in this project

Story

Read more

Code

CO2.ino

C/C++
/****************************************************************************
**                                                                         **
** Name:        WioTerminal_CO2_traffic_light                              **
** Author:      Achim Kern                                                 **
** Interpreter: Arduino IDE 1.8.13                                         **
** Licence:     Freeware                                                   **
** Function:    measure air quality CO2 and show actual state on TFT       **
**                                                                         **
** Notes:       based on idea from SEEED STUDIO and LCARS SmartHome        **
**                                                                         **
** History:                                                                **
**                                                                         **
** 1.00        - 23.10.2020 - initial release                              **
**                          - GROVE SCD30                                  **
**                          - Buzzer                                       **
**                          - 3 Buttons                                    **
**                          - 5 status bmp pictures                        **
**                                                                         **
****************************************************************************/

/*
 * WIO Terminal TFT Display
 * 
 */
   // TFT library
   #include"TFT_eSPI.h"
   // TFT display
   TFT_eSPI tft;
   // Control Pin of LCD
   #define LCD_BACKLIGHT (72Ul)
   bool tft_backlight = true;
    #include "lcd_backlight.hpp"
    #include <cstdint>
    #include "RTC_SAMD51.h"
    #include "DateTime.h"
 
  RTC_SAMD51 rtc;
  static LCDBackLight backLight;
/*
 * libraries
 * 
 */
   #include <Arduino.h>
   // SD card library
   #include "Seeed_FS.h"  
   // image processing library
   #include "RawImage.h"
   // smooth fonts library
   #include "Free_Fonts.h"       

 /*
 * GROVE CO2 & Temperature & Humidity Sensor (SCD30)
 * -------------------------------------------------
 * The Grove - CO2 & Temperature & Humidity Sensor (SCD30) is a high precision carbon dioxide sensor, 
 * which is based on Sensirion SCD30. The measuring range of this sensor is 0 ppm-40'000 ppm, 
 * and the measurement accuracy can reach to (30 ppm + 3%) between 400ppm to 10'000ppm.
 * In addition to the Non-Dispersive Infrared(NDIR) measurement technology for CO2 detection, 
 * the SCD30 integrates Sensirion humidity and temperature sensors on the same sensor module. 
 * 
 */

   #include "SCD30.h"
   int grove_scd30_co2   = 0;
   int grove_scd30_temp  = 0;
   int grove_scd30_humi  = 0;
   int scd30_temp_offset = -4;
   int scd30_humi_offset = 13;
   
   /*-----------------------------------------*/
   /* Function void sensor_co2()              */
   /*                                         */
   /* TASK    : read out air sensor data      */
   /* UPDATE  : 23.10.2020                    */
   /*-----------------------------------------*/   
   void sensor_co2()
   {
     // read the sensor
     float result[3] = {0};
       
     if (scd30.isAvailable()) 
     {
      scd30.getCarbonDioxideConcentration(result);
      grove_scd30_co2  = result[0];
      grove_scd30_temp = result[1];
      grove_scd30_humi = result[2];
      // serial print of all sensor values
      Serial.print(F("[?] GROVE SCD30 CO2 --> "));
      Serial.print("SCD30-CO2:"); Serial.print(grove_scd30_co2); 
      Serial.print("  SCD30-T:"); Serial.print(grove_scd30_temp+scd30_temp_offset);  
      Serial.print("  SCD30-H:"); Serial.println(grove_scd30_humi+scd30_humi_offset);
      // display co2 pictures on TFT
      const char* list[] = {"co2-low-rgb565.bmp", "co2-mid1-rgb565.bmp", "co2-mid2-rgb565.bmp", "co2-high1-rgb565.bmp", "co2-high2-rgb565.bmp"};
      // rgb traffic light (planned)
      int r,g,b;
      uint8_t cnt = 0;
      if (grove_scd30_co2<700)   { r=0;   g=127; b=0; cnt=0; }
      if (grove_scd30_co2>=700)  { r=0;   g=127; b=0; cnt=1; }
      if (grove_scd30_co2>=1000) { r=127; g=127; b=0; cnt=2; }
      if (grove_scd30_co2>=1300) { r=127; g=0;   b=0; cnt=3; }
      if (grove_scd30_co2>=1500) { r=127; g=0;   b=0; cnt=4; } 
      drawImage<uint16_t>(list[cnt],0,0); 
      tft.setTextColor(TFT_BLACK,TFT_WHITE);
      tft.setFreeFont(FMB18);
      tft.drawNumber(grove_scd30_co2,80,190);                 
     }
   }
 
/*
 * Timer
 * Generally, you should use "unsigned long" for variables that hold time.
 * The value will quickly become too large for an int to store
 */
   // this timer is used to update tft display
   unsigned long previousMillis = 0;
   // send every 10 minutes
   // unsigned long interval = 600000;  
   // send every 3 minutes
   // unsigned long interval = 180000;
   // send every 30 seconds
   unsigned long interval = 10000;   
   unsigned long counter  = 0; 

/*-------------------------------------------------------------------------------*/
/* Function void tft_display_status_bar(String room_name, long int room_bg)      */
/*                                                                               */
/* TASK    : show tft display status bar                                         */
/* UPDATE  : 22.09.2020                                                          */
/*-------------------------------------------------------------------------------*/
void tft_display_status_bar(String room_name, long int room_bg) 
{
  tft.fillRect(0,0,320,50,room_bg);
  tft.setFreeFont(FMB18);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor((320 - tft.textWidth(room_name)) / 2, 32);
  tft.print(room_name); 
}

/*-------------------------------------------------------------------------------*/
/* Function void tft_display_room_screen(String room_name, long int room_bg)     */
/*                                                                               */
/* TASK    : show tft display room screen                                        */
/* UPDATE  : 22.09.2020                                                          */
/*-------------------------------------------------------------------------------*/
void tft_display_room_screen(String room_name, long int room_bg) 
{
  tft.fillScreen(TFT_WHITE);
  tft.fillRect(0,0,320,50,room_bg);
  tft.setFreeFont(FMB18);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor((320 - tft.textWidth(room_name)) / 2, 32);
  tft.print(room_name);
  // drawing verticle line
  tft.drawFastVLine(150,50,190,TFT_DARKGREEN);
  // drawing horizontal line
  tft.drawFastHLine(0,140,320,TFT_DARKGREEN);  
}

/*-------------------------------------------------------------------------------*/
/* Function void tft_display_sensor_temperature(void)                            */
/*                                                                               */
/* TASK    : show tft display sensor temperature                                 */
/* UPDATE  : 22.09.2020                                                          */
/*-------------------------------------------------------------------------------*/
void tft_display_sensor_temperature(int temperature) 
{
  // setting the temperature
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB9);
  tft.drawString("Temperature",15,65);
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB18);
  tft.drawNumber(temperature,50,95);
  //tft.drawNumber(21,50,95);
  tft.setFreeFont(FMB12);
  tft.drawString("C",100,95);  
}

/*-------------------------------------------------------------------------------*/
/* Function void tft_display_sensor_humidity(int humidity)                       */
/*                                                                               */
/* TASK    : show tft display sensor humidity                                    */
/* UPDATE  : 22.09.2020                                                          */
/*-------------------------------------------------------------------------------*/
void tft_display_sensor_humidity(int humidity) 
{
  // setting the humidity
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB9);
  tft.drawString("Humidity",30,160);
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB18);
  tft.drawNumber(humidity,50,190);
  tft.setFreeFont(FMB12);
  tft.drawString("%",100,190);
}



void tft_display_time(int timer) 
{
  DateTime now = DateTime(F(__DATE__), F(__TIME__));
  // setting the humidity
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB9);
  tft.drawString("Time",220,65);
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB12);
  tft.drawNumber(now.hour(),180,95);
  tft.setFreeFont(FMB12);
  tft.drawString(":",210,95);
  tft.setFreeFont(FMB12);
  tft.drawNumber(now.minute(),230,95);
}




/*-------------------------------------------------------------------------------*/
/* Function void tft_display_sensor_co2(int co2)                                 */
/*                                                                               */
/* TASK    : show tft display sensor co2                                         */
/* UPDATE  : 22.09.2020                                                          */
/*-------------------------------------------------------------------------------*/
void tft_display_sensor_co2(int co2) 
{ 
  // setting the CO2
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB9);
  tft.drawString("CO2",220,160);
  tft.setTextColor(TFT_BLACK);
  tft.setFreeFont(FMB18);
  tft.drawNumber(co2,160,190);
  tft.setFreeFont(FMB12);
  tft.drawString("ppm",250,190);
}

/*-------------------------------------------------------------------------------*/
/* Function void setup()                                                         */
/*                                                                               */
/* TASK    : setup all needed requirements                                       */
/* UPDATE  : 23.10.2020                                                          */
/*-------------------------------------------------------------------------------*/ 
void setup() 
{
  Serial.begin(9600);
  delay(3000);
  Serial.println(F(" "));
  Serial.println(F(" "));
  Serial.println(F("Starting..."));
  // WIO_TERMINAL
  Serial.println(F("WioTerminal CO2 Traffic Light Version 1.00"));
  Serial.println(F("GROVE SCD30 connected via I2C"));
  Serial.println(F(" "));
  Serial.println("initializing backlight...");
  backLight.initialize();
  static std::uint8_t brightness = 5;
  backLight.setBrightness(brightness);
  // 3 Wio Terminal buttons
  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(WIO_KEY_B, INPUT_PULLUP);
  pinMode(WIO_KEY_C, INPUT_PULLUP);
  pinMode(WIO_LIGHT, INPUT);
  // Initialise SD card
  Serial.println(F("[?] SD card initialize.."));
  if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI)) 
  {
    while (1);
  }
  
  // initialize the TFT display
  tft.begin();
  tft.setRotation(3);

  // initialize the scd30 sensor
  Serial.println(F("[?] GROVE SCD30 CO2 sensor initialize.."));
  Wire.begin();
  rtc.begin();
  scd30.initialize();
  delay(1000);
  
  // read the co2 sensor */
  sensor_co2();  


   DateTime now = DateTime(F(__DATE__), F(__TIME__));
    Serial.println("adjust time!");
    rtc.adjust(now);
 
    now = rtc.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
 
    DateTime alarm = DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second() + 15);
 
    rtc.setAlarm(0,alarm); // match after 15 seconds
    rtc.enableAlarm(0, rtc.MATCH_HHMMSS); // match Every Day
 
    rtc.attachInterrupt(alarmMatch); // callback whlie alarm is match
}

/*-------------------------------------------------------------------------------*/
/* Function void loop()                                                          */
/*                                                                               */
/* TASK    : this runs forever                                                   */
/* UPDATE  : 23.10.2020                                                          */
/*-------------------------------------------------------------------------------*/
void loop() 
{

  DateTime now = DateTime(F(__DATE__), F(__TIME__));
  // check if some one has pressed a button
  if (digitalRead(WIO_KEY_A) == LOW) 
  {
    Serial.println("[x} A Key pressed");   
    delay(200);
    // display room screen
    tft_display_room_screen("OFFICE", TFT_BLUE);
    // display temperature sensor
    tft_display_sensor_temperature(grove_scd30_temp+scd30_temp_offset);
    // display humidity sensor
    tft_display_sensor_humidity(grove_scd30_humi+scd30_humi_offset);  
    // display co2 sensor
    tft_display_sensor_co2(grove_scd30_co2);
    tft_display_time(now.year());
        
    DateTime now = rtc.now();
  }
  else if (digitalRead(WIO_KEY_B) == LOW) 
  {
    Serial.println("[x] B Key pressed");     
    delay(200);
    // read the co2 sensor */
    sensor_co2();
  }
  else if (digitalRead(WIO_KEY_C) == LOW) 
  {
    delay(100);
    if(digitalRead(WIO_KEY_C) == LOW)
    {
    Serial.println("[x] C Key pressed");
    tft_backlight = !tft_backlight;
    Serial.println(tft_backlight);
    if(tft_backlight==0)
    {
      backLight.setBrightness(0);
    Serial.println("Turning off the LCD backlight");      
    }
    else if(tft_backlight==1)
    {
      backLight.setBrightness(5);
      }
    //if (tft_backlight == false) { digitalWrite(LCD_BACKLIGHT, LOW);  }
     // Turning on the LCD backlight
    //if (tft_backlight == true)  { digitalWrite(LCD_BACKLIGHT, HIGH); }
    delay(200);
    }
    else
    {
      };
  }
   
  /* 
   * It is checked whether the time for the transmission interval has already expired
   * If the time difference between the last save and the current time is greater
   * as the interval, the following function is executed.
  */
  if (millis() - previousMillis > interval)
  {
    // correct timer
    previousMillis = millis();
    // read the co2 sensor */
    sensor_co2();
   int light = analogRead(WIO_LIGHT);
   Serial.print("Light value: ");
   Serial.println(light);
  }
  
}
void alarmMatch(uint32_t flag)
{
 
    Serial.println("Alarm Match!");
    DateTime now = rtc.now();
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
}

Credits

陈年

陈年

0 projects • 0 followers

Comments