Project #15: Environment – RTC – Mk50

——

#DonLucElectronics #DonLuc #RTC #C4002 #BME280 #ENS160 #Environment #FireBeetle2ESP32E #ESP32 #Display #IoT #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant

——

RTC

——

RTC

—

RTC

——

Gravity: I2C SD2405 RTC Module

The I2C SD2405 RTC module features accurate real-time clock, dual power supply, low power consumption, periodic interrupts, and a high precision time trimming circuit. The SD2405AL is dual power supply system. When the primary power supply goes down to an assigned value or resumes from low power, the system can switch between the primary power supply and battery automatically. Even there is no external power, it can still work for 5~8 years, 1uA ultra-low power consumption.

DL2609Mk03

1 x DFRobot FireBeetle 2 ESP32-E
1 x Fermion: 3.5” 480×320 TFT LCD Capacitive
1 x GDL Line 10 CM
1 x Gravity: I2C SD2405 RTC Module
1 x Fermion: C4002 mmWave Human Presence Sensor
1 x Fermion: ENS160+BME280 Envirotal Sensor
1 x Gravity: IO Shield for FireBeetle 2
1 x Terminal Block Board for FireBeetle 2 ESP32-E IoT
1 x Lithium Ion Battery – 1000mAh
1 x USB 3.0 to Type-C Cable

DL2609Mk03p

DL2609Mk03p.ino

/****** Don Luc Electronics © ******
Software Version Information
Project #15: Environment – RTC – Mk50
15-50
DL2609Mk03p.ino
DL2609Mk03
1 x DFRobot FireBeetle 2 ESP32-E
1 x Fermion: 3.5” 480x320 TFT LCD Capacitive
1 x GDL Line 10 CM
1 x Gravity: I2C SD2405 RTC Module
1 x Fermion: C4002 mmWave Human Presence Sensor
1 x Fermion: ENS160+BME280 Envirotal Sensor
1 x Gravity: IO Shield for FireBeetle 2
1 x Terminal Block Board for FireBeetle 2 ESP32-E IoT
1 x Lithium Ion Battery - 1000mAh
1 x USB 3.0 to Type-C Cable
*/

// Include the Library Code
// DFRobot Display GDL API
#include <DFRobot_GDL.h>
// C4002 mmWave Human Presence
#include "DFRobot_C4002.h"
// BME280 Environmental
#include <DFRobot_BME280.h>
// ENS160 Air Quality Sensor
#include <DFRobot_ENS160.h>
// RTC (Real-Time Clock)
#include "GravityRtc.h"

// RTC Initialization
GravityRtc rtc;
// Date and Time
String dateRTC = "";
String timeRTC = "";

// ENS160 Air Quality Sensor
// I2C communication.
#define I2C_COMMUNICATION  
// I2C address is 0x53
DFRobot_ENS160_I2C ENS160(&Wire, 0x53);
// Status
uint8_t Status;
// AQI
uint8_t AQI;
// TVOC
uint16_t TVOC;
// ECO2
uint16_t ECO2;

// BME280 Environmental
typedef DFRobot_BME280_IIC BME;
// Wire
BME   bme(&Wire, 0x76);
// Sea Level Pressure
#define SEA_LEVEL_PRESSURE 1015.0f
// Temperature
float   temp = bme.getTemperature();
// Pressure
uint32_t    press = bme.getPressure();
// Altitude
float alti;
// Humidity
float humi;

// C4002 mmWave Human Presence
DFRobot_C4002 c4002(&Serial1, 115200, /*D0*/ D11, /*D1*/ D10);
//float light;
String sLight;
// Get Target State
String sTarget;
// Get Presence distance gate target info
String sPreDis;
// Get motion distance gate index
String sMot;

// Defined ESP32
#define TFT_DC  D2
#define TFT_CS  D6
#define TFT_RST D3

/*dc=*/ /*cs=*/ /*rst=*/
// DFRobot Display 320x480
DFRobot_ILI9488_320x480_HW_SPI screen(TFT_DC, TFT_CS, TFT_RST);

// Software Version Information
String sver = "15-50";

void loop() {
  
  // isBME280
  isBME280();

  // isENS160
  isENS160();
  
  // isC4002
  isC4002();

  // RTC (Real-Time Clock)
  isRTC();
  
  // isDisplay C4002
  isDisplayC4002();

  // Delay 0.1 Second
  delay( 100 );
  
}

getBME280.ino

// BME280 Environmental
// isBME280
void isBME280(){

  // Temperature
  temp = bme.getTemperature();
  // Pressure
  press = bme.getPressure();
  // Altitude
  alti = bme.calAltitude(SEA_LEVEL_PRESSURE, press);
  // Humidity
  humi = bme.getHumidity();

}

getC4002.ino

// C4002 mmWave Human Presence
// isSetupC4002
void isSetupC4002(){

  // C4002 mmWave Human Presence
  // Initialize the C4002 sensor
  while (c4002.begin() != true) {
    Serial.println("C4002 begin failed!");
    delay(1000);
  }
  //Serial.println("C4002 begin success!");
  delay(50);

  // Set the run led to On

  if (c4002.setRunLedState(eLedOn)) {
    //Serial.println("Set run led success!");
  } else {
    Serial.println("Set run led failed!");
  }
  delay(50);

  // Set the out led to On
  if (c4002.setOutLedState(eLedOn)) {
    //Serial.println("Set out led success!");
  } else {
    Serial.println("Set out led failed!");
  }
  delay(50);

  // Set the Resolution mode to 20cm.
  // eResolution20Cm: This indicates that the resolution of the "distance gate"
  // is 20cm. With a resolution of 20 cm, it supports up to 25 distance gates, 
  //with a maximum distance of 4.9 meters
  //c4002.setResolutionMode(eResolution20Cm);
  if (c4002.setResolutionMode(eResolution20Cm)) {
    //Serial.println("Set resolution mode success!");
  } else {
    Serial.println("Set resolution mode failed!");
  }
  delay(50);

  // Set the detect range to 0-200 cm
  uint16_t clostRange = 0;
  uint16_t farRange   = 200;
  if (c4002.setDetectRange(clostRange, farRange)) {    // Max detect range(0-1100cm)
    //Serial.println("Set detect range success!");
  } else {
    Serial.println("Set detect range failed!");
  }

  // Set the light threshold to 0 lux.range: 0-50 lux
  if (c4002.setLightThresh(0)) {
    //Serial.println("Set light threshold success!");
  } else {
    Serial.println("Set light threshold failed!");
  }
  delay(50);

  // Resolution mode:eResolution20Cm
  // Enable the 'distance gate'
  // Resolution mode:eResolution20Cm,This means that the number of 'distance gates' 
  // we can operate is 25
  //disable : C4002_DISABLE, enable: C4002_ENABLE
  uint8_t gateState[25] = { C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, 
  C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE,
   C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, 
   C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE,
   C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE, C4002_ENABLE };

  // Operation motion distance gate
  if (c4002.configureGate(eMotionDistGate, gateState)) { 
    //Serial.println("Enable motion distance gate success!");
  }

  // Delay
  delay(50);

  // Operation presence distance gate
  if (c4002.configureGate(ePresenceDistGate, gateState)) { 
    //Serial.println("Enable presence distance gate success!");
  }
  
  // Delay
  delay(50);

  // Set the target disappear delay time to 1s,range: 0-65535s
  if (c4002.setTargetDisappearDelay(1)) {
    //Serial.println("Set target disappear delay time success!");
  } else {
    Serial.println("Set target disappear delay time failed!");
  }
 
  // Delay
  delay(50);

  // Set the report period to 10 * 0.1s = 1s
  if (c4002.setReportPeriod(10)) {
    //Serial.println("Set report period success!");
  } else {
    Serial.println("Set report period failed!");
  }

}
// isC4002
void isC4002(){

  // Get all the results of the C4002 sensor
  sRetResult_t retResult = c4002.getNoteInfo();

  if (retResult.noteType == eResult) {
    //Serial.println("------- Get all results --------");
    // get the light intensity
    float light = c4002.getLightIntensity();
    //Serial.print("Light: ");
    //Serial.print(light);
    //Serial.println(" lux");
    sLight = light;

    // get Target state
    eTargetState_t targetState = c4002.getTargetState();
    //Serial.print("Target state: ");
    if (targetState == eNoTarget) {

      //Serial.println("No Target");
      sTarget = "No Target";

    } else if (targetState == ePresence) {
      
      //Serial.println("Static Presence");
      sTarget = "Static Presence";

    } else if (targetState == eMotion) {
      
      //Serial.println("Motion");
      sTarget = "Motion";

    }

    // Get Presence distance gate target info
    sPresenceTarget_t presenceTarget = c4002.getPresenceTargetInfo();
    //Serial.print("Presence distance: ");
    //Serial.print(presenceTarget.distance);
    sPreDis = presenceTarget.distance;
    //Serial.println(" m");

    // Get motion distance gate index
    sMotionTarget_t motionTarget = c4002.getMotionTargetInfo();

    //Serial.print("Motion direction: ");
    if (motionTarget.direction == eAway) {
      
      //Serial.println("Away!");
      sMot = "Away!";

    } else if (motionTarget.direction == eNoDirection) {
      
      //Serial.println("No Direction!");
      sMot = "No Direction!";

    } else if (motionTarget.direction == eApproaching) {
      
      //Serial.println("Approaching!");
      sMot = "Approaching!";

    }
  }

}

getDisplay.ino

// DFRobot Display 320x480
// DFRobot Display 320x480 - UID
void isDisplayUID(){

  // DFRobot Display 240x320
  // Text Display
  // Text Wrap
  screen.setTextWrap(false);
  // Rotation
  screen.setRotation(3);
  // Fill Screen => black
  screen.fillScreen(0x0000);
  // Text Color => white
  screen.setTextColor(0xffff);
    // Font => Free Sans Bold 12pt
  screen.setFont(&FreeSansBold12pt7b);
  // TextSize => 1.5
  screen.setTextSize(1.5);
  // Don Luc Electronics
  screen.setCursor(0, 30);
  screen.println("Don Luc Electronics");
  // BME280 Environmental
  screen.setCursor(0, 60);
  screen.println("Real-Time Clock");
  // Version
  screen.setCursor(0, 90);
  screen.println("Version");
  screen.setCursor(0, 120);
  screen.println( sver );

}
// isDisplay C4002
void isDisplayC4002(){

  // DFRobot Display 320x480
  // Text Display
  // Text Wrap
  screen.setTextWrap(false);
  // Rotation
  screen.setRotation(3);
  // Fill Screen => white
  screen.fillScreen(0xffff);
  // Text Color => blue
  screen.setTextColor(0x001F);
    // Font => Free Sans Bold 12pt
  screen.setFont(&FreeSansBold12pt7b);
  // TextSize => 1.5
  screen.setTextSize(1.5);
  // ENS160 Air Quality Sensor
  screen.setCursor(0, 30);
  screen.println("Real-Time Clock");
  // Status
  screen.setCursor(0, 60);
  screen.print("Light ");
  screen.setCursor(70, 60);
  screen.print( sLight );
  screen.setCursor(250, 60);
  screen.println("lux");
  // Target
  screen.setCursor(0, 90);
  screen.print("Target ");
  screen.setCursor(90, 90);
  screen.println( sTarget );
  // Presence
  screen.setCursor(0, 120);
  screen.print("Presence: ");
  screen.setCursor(130, 120);
  screen.println( sPreDis );
  screen.setCursor(250, 120);
  screen.println( "CM" );
  // Motion
  screen.setCursor(0, 150);
  screen.print("Motion: ");
  screen.setCursor(110, 150);
  screen.println( sMot );
  // Temperature
  screen.setCursor(0, 180);
  screen.print("Temperature: ");
  screen.setCursor(170, 180);
  screen.println( temp );
  screen.setCursor(250, 180);
  screen.println( "C" );
  // Humidity
  screen.setCursor(0, 210);
  screen.print("Humidity: ");
  screen.setCursor(170, 210);
  screen.println( humi );
  screen.setCursor(250, 210);
  screen.println( "%" );
  // TVOC - Return value range: 0–65000, unit: ppb
  screen.setCursor(0, 240);
  screen.print("TVOC: ");
  screen.setCursor(140, 240);
  screen.println( TVOC );
  screen.setCursor(250, 240);
  screen.println( "ppb" );
  // ECO2 = Return value range: 400–65000, unit: ppm
  // Five levels: Excellent(400 - 600), Good(600 - 800), Moderate(800 - 1000), 
  // Poor(1000 - 1500), Unhealthy(> 1500)
  screen.setCursor(0, 270);
  screen.print("ECO2: ");
  screen.setCursor(140, 270);
  screen.println( ECO2 );
  screen.setCursor(250, 270);
  screen.println( "ppb" );
  // Real-Time Clock
  screen.setCursor(0, 300);
  screen.print( dateRTC );
  screen.setCursor(250, 300);
  screen.println( timeRTC );
  //screen.setCursor(250, 270);
  //screen.println( "ppb" );

}

getENS160.ino

// ENS160 Air Quality Sensor
// isENS160
void isENS160(){

  // Status - Return value: 0-Normal operation 1-Warm-Up phase 
  // 2-Initial Start-Up phase
  Status = ENS160.getENS160Status();

  // AQI - Return value: 1-Excellent, 2-Good, 3-Moderate, 4-Poor, 5-Unhealthy
  AQI = ENS160.getAQI();

  // TVOC - Return value range: 0–65000, unit: ppb
  TVOC = ENS160.getTVOC();

  // ECO2 = Return value range: 400–65000, unit: ppm
  // Five levels: Excellent(400 - 600), Good(600 - 800), Moderate(800 - 1000), 
  // Poor(1000 - 1500), Unhealthy(> 1500)
  ECO2 = ENS160.getECO2();

}

getRTC.ino

// Real-Time Clock
// Date and Time RTC
void isRTC () {

  // Date and Time
  dateRTC = "";
  timeRTC = "";
  rtc.read();
  
  // Date
  dateRTC = rtc.year; 
  dateRTC = dateRTC + "/";
  dateRTC = dateRTC + rtc.month;
  dateRTC = dateRTC + "/";
  dateRTC = dateRTC + rtc.day;

  // Time
  timeRTC = rtc.hour;
  timeRTC = timeRTC + ":";
  timeRTC = timeRTC + rtc.minute;
  timeRTC = timeRTC + ":";
  timeRTC = timeRTC + rtc.second;
  
}

setup.ino

// Setup
void setup()
{
 
  // Delay
  delay(100);

  Serial.begin(115200);

    // Delay
  delay( 100 );

  // C4002 mmWave Human Presence
  isSetupC4002();

  // Delay
  delay(100);

  // BME280 Environmental
  bme.begin();

  // Delay
  delay(100);

  // ENS160 Air Quality Sensor
  ENS160.begin();
  /**
   * Set power mode
   * mode Configurable power mode:
   * ENS160_SLEEP_MODE: DEEP SLEEP mode (low power standby)
   * ENS160_IDLE_MODE: IDLE mode (low-power)
   * ENS160_STANDARD_MODE: STANDARD Gas Sensing Modes
   */
  ENS160.setPWRMode(ENS160_STANDARD_MODE);

  /**
   * Users write ambient temperature and relative humidity into ENS160 for
   * calibration and compensation of the measured gas data.
   * ambientTemp Compensate the current ambient temperature, float type, unit: C
   * relativeHumidity Compensate the current ambient humidity, float type, unit: %rH
   * Temperature
   * Humidity=
   */
  ENS160.setTempAndHum(temp, humi);

  // Delay
  delay( 100 );

  // Setup RTC
  rtc.setup();

  //Set the RTC time automatically: Calibrate RTC time by your computer time
  rtc.adjustRtc(F(__DATE__), F(__TIME__));

  // Delay
  delay( 100 );

  // DFRobot Display 320x480
  screen.begin();

  // Delay
  delay( 100 );

  // DFRobot Display 320x480 - UID
  // Don Luc Electronics
  // Versioc
  isDisplayUID();
  
  // Delay
  delay( 5000 );

}

——

People can contact us: https://www.donluc.com/?page_id=1927

Consultant, R&D, Electronics, IoT, Teacher and Instructor

  • Programming Language
  • Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi, Arm, Silicon Labs, Espressif, Etc…)
  • IoT
  • Wireless (Radio Frequency, Bluetooth, WiFi, Etc…)
  • Robotics
  • Automation
  • Camera and Video Capture Receiver Stationary, Wheel/Tank , Underwater and UAV Vehicle
  • Unmanned Vehicles Terrestrial, Marine and UAV
  • Machine Learning
  • Artificial Intelligence (AI)
  • RTOS
  • Sensors, eHealth Sensors, Biosensor, and Biometric
  • Research & Development (R & D)
  • Consulting

Follow Us

Luc Paquin – Curriculum Vitae – 2026
https://www.donluc.com/luc/LucPaquinCVEng2026Mk01.pdf
https://www.donluc.com/luc/

Web: https://www.donluc.com/
Web: https://www.jlpconsultants.com/
Facebook: https://www.facebook.com/neosteam.labs.9/
YouTube: https://www.youtube.com/@thesass2063
DFRobot: https://learn.dfrobot.com/user-10186.html
TikTok: https://www.tiktok.com/@luc.paquin8
Hackster: https://www.hackster.io/luc-paquin
LinkedIn: https://www.linkedin.com/in/jlucpaquin/

Don Luc

Leave a Comment