KeHoSoftware
Published © GPL3+

CO2 monitoring with WioTerminal

WioTerminal with a CO2 sensor to measure the indoor air quality and remind to ventilate the room. Useful IoT device - 2020 Corona Pandemie.

IntermediateWork in progress250
CO2 monitoring with WioTerminal

Things used in this project

Hardware components

Grove - CO2 & Temperature & Humidity Sensor (SCD30)
Seeed 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.
×1
Seeed Wio Terminal
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

WioTerminal Stand

3D-Printer WioTerminal Stand

Schematics

Wiring SCD30 I2C Wio Terminal

Connect the Grove SCD30 to the I2C Port - left hand side underneath.

Code

WioTerminal_CO2_traffic_light

Arduino
Main source Wio Terminal - measure co2 value and display on TFT
/****************************************************************************
**                                                                         **
** 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;

/*
 * 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 = 30000;   
   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);
}

/*-------------------------------------------------------------------------------*/
/* 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(" "));

  // 3 Wio Terminal buttons
  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(WIO_KEY_B, INPUT_PULLUP);
  pinMode(WIO_KEY_C, INPUT_PULLUP);

  // 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();
  scd30.initialize();
  delay(3000);
  
  // read the co2 sensor */
  sensor_co2();  
}

/*-------------------------------------------------------------------------------*/
/* Function void loop()                                                          */
/*                                                                               */
/* TASK    : this runs forever                                                   */
/* UPDATE  : 23.10.2020                                                          */
/*-------------------------------------------------------------------------------*/
void loop() 
{
  // 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("Dining-Room", 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);    
    
  }
  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) 
  {
    Serial.println("[x] C Key pressed");
    tft_backlight = !tft_backlight;
     // Turning off the LCD backlight
    if (tft_backlight == false) { digitalWrite(LCD_BACKLIGHT, LOW);  }
     // Turning on the LCD backlight
    if (tft_backlight == true)  { digitalWrite(LCD_BACKLIGHT, HIGH); }
    delay(200);
  }
  
  /* 
   * 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();
  }
  
}

Free_Fonts.h

Arduino
provide FreeFonts to use on TFT Wio Terminal
// Attach this header file to your sketch to use the GFX Free Fonts. You can write
// sketches without it, but it makes referencing them easier.

// This calls up ALL the fonts but they only get loaded if you actually
// use them in your sketch.
//
// No changes are needed to this header file unless new fonts are added to the
// library "Fonts/GFXFF" folder.
//
// To save a lot of typing long names, each font can easily be referenced in the
// sketch in three ways, either with:
//
//    1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
//       an example being:
//
//       tft.setFreeFont(&FreeSansBoldOblique24pt7b);
//
//    2. FF# where # is a number determined by looking at the list below
//       an example being:
//
//       tft.setFreeFont(FF32);
//
//    3. An abbreviation of the file name. Look at the list below to see
//       the abbreviations used, for example:
//
//       tft.setFreeFont(FSSBO24)
//
//       Where the letters mean:
//       F = Free font
//       M = Mono
//      SS = Sans Serif (double S to distinguish is form serif fonts)
//       S = Serif
//       B = Bold
//       O = Oblique (letter O not zero)
//       I = Italic
//       # =  point size, either 9, 12, 18 or 24
//
//  Setting the font to NULL will select the GLCD font:
//
//      tft.setFreeFont(NULL); // Set font to GLCD

#define LOAD_GFXFF

#ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h

    // Use these when printing or drawing text in GLCD and high rendering speed fonts
    #define GFXFF 1
    #define GLCD  0
    #define FONT2 2
    #define FONT4 4
    #define FONT6 6
    #define FONT7 7
    #define FONT8 8

    // Use the following when calling setFont()
    //
    // Reserved for GLCD font  // FF0
    //

    #define TT1 &TomThumb

    #define FM9 &FreeMono9pt7b
    #define FM12 &FreeMono12pt7b
    #define FM18 &FreeMono18pt7b
    #define FM24 &FreeMono24pt7b

    #define FMB9 &FreeMonoBold9pt7b
    #define FMB12 &FreeMonoBold12pt7b
    #define FMB18 &FreeMonoBold18pt7b
    #define FMB24 &FreeMonoBold24pt7b

    #define FMO9 &FreeMonoOblique9pt7b
    #define FMO12 &FreeMonoOblique12pt7b
    #define FMO18 &FreeMonoOblique18pt7b
    #define FMO24 &FreeMonoOblique24pt7b

    #define FMBO9 &FreeMonoBoldOblique9pt7b
    #define FMBO12 &FreeMonoBoldOblique12pt7b
    #define FMBO18 &FreeMonoBoldOblique18pt7b
    #define FMBO24 &FreeMonoBoldOblique24pt7b

    #define FSS9 &FreeSans9pt7b
    #define FSS12 &FreeSans12pt7b
    #define FSS18 &FreeSans18pt7b
    #define FSS24 &FreeSans24pt7b

    #define FSSB9 &FreeSansBold9pt7b
    #define FSSB12 &FreeSansBold12pt7b
    #define FSSB18 &FreeSansBold18pt7b
    #define FSSB24 &FreeSansBold24pt7b

    #define FSSO9 &FreeSansOblique9pt7b
    #define FSSO12 &FreeSansOblique12pt7b
    #define FSSO18 &FreeSansOblique18pt7b
    #define FSSO24 &FreeSansOblique24pt7b

    #define FSSBO9 &FreeSansBoldOblique9pt7b
    #define FSSBO12 &FreeSansBoldOblique12pt7b
    #define FSSBO18 &FreeSansBoldOblique18pt7b
    #define FSSBO24 &FreeSansBoldOblique24pt7b

    #define FS9 &FreeSerif9pt7b
    #define FS12 &FreeSerif12pt7b
    #define FS18 &FreeSerif18pt7b
    #define FS24 &FreeSerif24pt7b

    #define FSI9 &FreeSerifItalic9pt7b
    #define FSI12 &FreeSerifItalic12pt7b
    #define FSI19 &FreeSerifItalic18pt7b
    #define FSI24 &FreeSerifItalic24pt7b

    #define FSB9 &FreeSerifBold9pt7b
    #define FSB12 &FreeSerifBold12pt7b
    #define FSB18 &FreeSerifBold18pt7b
    #define FSB24 &FreeSerifBold24pt7b

    #define FSBI9 &FreeSerifBoldItalic9pt7b
    #define FSBI12 &FreeSerifBoldItalic12pt7b
    #define FSBI18 &FreeSerifBoldItalic18pt7b
    #define FSBI24 &FreeSerifBoldItalic24pt7b

    #define FF0 NULL //ff0 reserved for GLCD
    #define FF1 &FreeMono9pt7b
    #define FF2 &FreeMono12pt7b
    #define FF3 &FreeMono18pt7b
    #define FF4 &FreeMono24pt7b

    #define FF5 &FreeMonoBold9pt7b
    #define FF6 &FreeMonoBold12pt7b
    #define FF7 &FreeMonoBold18pt7b
    #define FF8 &FreeMonoBold24pt7b

    #define FF9 &FreeMonoOblique9pt7b
    #define FF10 &FreeMonoOblique12pt7b
    #define FF11 &FreeMonoOblique18pt7b
    #define FF12 &FreeMonoOblique24pt7b

    #define FF13 &FreeMonoBoldOblique9pt7b
    #define FF14 &FreeMonoBoldOblique12pt7b
    #define FF15 &FreeMonoBoldOblique18pt7b
    #define FF16 &FreeMonoBoldOblique24pt7b

    #define FF17 &FreeSans9pt7b
    #define FF18 &FreeSans12pt7b
    #define FF19 &FreeSans18pt7b
    #define FF20 &FreeSans24pt7b

    #define FF21 &FreeSansBold9pt7b
    #define FF22 &FreeSansBold12pt7b
    #define FF23 &FreeSansBold18pt7b
    #define FF24 &FreeSansBold24pt7b

    #define FF25 &FreeSansOblique9pt7b
    #define FF26 &FreeSansOblique12pt7b
    #define FF27 &FreeSansOblique18pt7b
    #define FF28 &FreeSansOblique24pt7b

    #define FF29 &FreeSansBoldOblique9pt7b
    #define FF30 &FreeSansBoldOblique12pt7b
    #define FF31 &FreeSansBoldOblique18pt7b
    #define FF32 &FreeSansBoldOblique24pt7b

    #define FF33 &FreeSerif9pt7b
    #define FF34 &FreeSerif12pt7b
    #define FF35 &FreeSerif18pt7b
    #define FF36 &FreeSerif24pt7b

    #define FF37 &FreeSerifItalic9pt7b
    #define FF38 &FreeSerifItalic12pt7b
    #define FF39 &FreeSerifItalic18pt7b
    #define FF40 &FreeSerifItalic24pt7b

    #define FF41 &FreeSerifBold9pt7b
    #define FF42 &FreeSerifBold12pt7b
    #define FF43 &FreeSerifBold18pt7b
    #define FF44 &FreeSerifBold24pt7b

    #define FF45 &FreeSerifBoldItalic9pt7b
    #define FF46 &FreeSerifBoldItalic12pt7b
    #define FF47 &FreeSerifBoldItalic18pt7b
    #define FF48 &FreeSerifBoldItalic24pt7b

    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Now we define "s"tring versions for easy printing of the font name so:
    //   tft.println(sFF5);
    // will print
    //   Mono bold 9
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    #define sFF0 "GLCD"
    #define sTT1 "Tom Thumb"
    #define sFF1 "Mono 9"
    #define sFF2 "Mono 12"
    #define sFF3 "Mono 18"
    #define sFF4 "Mono 24"

    #define sFF5 "Mono bold 9"
    #define sFF6 "Mono bold 12"
    #define sFF7 "Mono bold 18"
    #define sFF8 "Mono bold 24"

    #define sFF9 "Mono oblique 9"
    #define sFF10 "Mono oblique 12"
    #define sFF11 "Mono oblique 18"
    #define sFF12 "Mono oblique 24"

    #define sFF13 "Mono bold oblique 9"
    #define sFF14 "Mono bold oblique 12"
    #define sFF15 "Mono bold oblique 18"
    #define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen

    #define sFF17 "Sans 9"
    #define sFF18 "Sans 12"
    #define sFF19 "Sans 18"
    #define sFF20 "Sans 24"

    #define sFF21 "Sans bold 9"
    #define sFF22 "Sans bold 12"
    #define sFF23 "Sans bold 18"
    #define sFF24 "Sans bold 24"

    #define sFF25 "Sans oblique 9"
    #define sFF26 "Sans oblique 12"
    #define sFF27 "Sans oblique 18"
    #define sFF28 "Sans oblique 24"

    #define sFF29 "Sans bold oblique 9"
    #define sFF30 "Sans bold oblique 12"
    #define sFF31 "Sans bold oblique 18"
    #define sFF32 "Sans bold oblique 24"

    #define sFF33 "Serif 9"
    #define sFF34 "Serif 12"
    #define sFF35 "Serif 18"
    #define sFF36 "Serif 24"

    #define sFF37 "Serif italic 9"
    #define sFF38 "Serif italic 12"
    #define sFF39 "Serif italic 18"
    #define sFF40 "Serif italic 24"

    #define sFF41 "Serif bold 9"
    #define sFF42 "Serif bold 12"
    #define sFF43 "Serif bold 18"
    #define sFF44 "Serif bold 24"

    #define sFF45 "Serif bold italic 9"
    #define sFF46 "Serif bold italic 12"
    #define sFF47 "Serif bold italic 18"
    #define sFF48 "Serif bold italic 24"

#else // LOAD_GFXFF not defined so setup defaults to prevent error messages

    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Free fonts are not loaded in User_Setup.h so we must define all as font 1
    // to prevent compile error messages
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    #define GFXFF 1
    #define GLCD  1
    #define FONT2 2
    #define FONT4 4
    #define FONT6 6
    #define FONT7 7
    #define FONT8 8

    #define FF0 1
    #define FF1 1
    #define FF2 1
    #define FF3 1
    #define FF4 1
    #define FF5 1
    #define FF6 1
    #define FF7 1
    #define FF8 1
    #define FF9 1
    #define FF10 1
    #define FF11 1
    #define FF12 1
    #define FF13 1
    #define FF14 1
    #define FF15 1
    #define FF16 1
    #define FF17 1
    #define FF18 1
    #define FF19 1
    #define FF20 1
    #define FF21 1
    #define FF22 1
    #define FF23 1
    #define FF24 1
    #define FF25 1
    #define FF26 1
    #define FF27 1
    #define FF28 1
    #define FF29 1
    #define FF30 1
    #define FF31 1
    #define FF32 1
    #define FF33 1
    #define FF34 1
    #define FF35 1
    #define FF36 1
    #define FF37 1
    #define FF38 1
    #define FF39 1
    #define FF40 1
    #define FF41 1
    #define FF42 1
    #define FF43 1
    #define FF44 1
    #define FF45 1
    #define FF46 1
    #define FF47 1
    #define FF48 1

    #define FM9  1
    #define FM12 1
    #define FM18 1
    #define FM24 1

    #define FMB9  1
    #define FMB12 1
    #define FMB18 1
    #define FMB24 1

    #define FMO9  1
    #define FMO12 1
    #define FMO18 1
    #define FMO24 1

    #define FMBO9  1
    #define FMBO12 1
    #define FMBO18 1
    #define FMBO24 1

    #define FSS9  1
    #define FSS12 1
    #define FSS18 1
    #define FSS24 1

    #define FSSB9  1
    #define FSSB12 1
    #define FSSB18 1
    #define FSSB24 1

    #define FSSO9  1
    #define FSSO12 1
    #define FSSO18 1
    #define FSSO24 1

    #define FSSBO9  1
    #define FSSBO12 1
    #define FSSBO18 1
    #define FSSBO24 1

    #define FS9  1
    #define FS12 1
    #define FS18 1
    #define FS24 1

    #define FSI9  1
    #define FSI12 1
    #define FSI19 1
    #define FSI24 1

    #define FSB9  1
    #define FSB12 1
    #define FSB18 1
    #define FSB24 1

    #define FSBI9  1
    #define FSBI12 1
    #define FSBI18 1
    #define FSBI24 1

#endif // LOAD_GFXFF

RawImage.h

Arduino
Provide loading bmp files to Wio Terminal
  #pragma once
#include<stdint.h>
#include<SD/Seeed_SD.h>


/*
USAGE:

    // when use 8bit color.
    Raw8 * img8 = newImage<uint8_t>("path to sd card image.");

    // when use 16bit color.
    Raw16 * img16 = newImage<uint16_t>("path to sd card image.");

    // do some drawing.
    // img8->draw();

    // remember release it
    img8->release();
    img16->release();
 */

extern TFT_eSPI tft;

template<class type>
struct RawImage{
    type * ptr(){
        return (type *)(this + 1);
    }
    type get(int16_t x, int16_t y){
        return this->ptr()[y * width() + x];
    }
    void draw(size_t x = 0, size_t y = 0){
        tft.pushImage(x, y, width(), height(), ptr());
    }
    void release(){
        delete [] this;
    }
    int16_t width(){ return _width; }
    int16_t height(){ return _height; }
private:
    int16_t  _width;
    int16_t  _height;
};

typedef RawImage<uint8_t>  Raw8;
typedef RawImage<uint16_t> Raw16;

template<class type>
RawImage<type> * newImage(const char * path){
    typedef RawImage<type> raw;
    File f = SD.open(path, FILE_READ);
    if (!f){
        return nullptr;
    }
    int32_t size = f.size();
    raw   * mem = (raw *)new uint8_t[size];
    if (mem == nullptr){
        return nullptr;
    }
    f.read(mem, size);
    f.close();
    return mem;
}

template<class type>
void drawImage(const char * path, size_t x = 0, size_t y = 0){
    auto img = newImage<type>(path);
    img->draw(x, y);
    img->release();
}

co2-rgb565.zip

Arduino
bmp pictures sd card
No preview (download only).

Credits

KeHoSoftware

KeHoSoftware

3 projects • 0 followers

Comments