STACK & PLAY
Standard 5×5cm functionally stacking modularized components hardware system.
ESP32 microcontroller、 microSD card slot、USB-C、extension connectors.
The Stacking Functional MODULES Built for Customized Assembly.
Easy Deployment with multifunctional BASE.
STACK SERIES
5×5CM MODULAR STACKABLE
Standard Size
Better Display
User Friendly
For comprehensive application
STICK SERIES
COMPACT IoT SOLUTION
All-in-one
Best in Price
Low power consumption
For IoT edge application
ATOM SERIES
SMALL SIZE, BIG USE!
Smallest ESP32 devkit
IoT edge nodes
Miniature embedded device
For smart home and industry control application
FROM PROTOTYPING TO COMMERCIAL LEVEL
END TO END IoT EDGE SOLUTIONS
SMART FACTORY
Improving efficiency, preventing risks and delivering results with connected IoT devices.
SMART AGRICULTURE
Using sensors to collect data and using edge computing devices to analyze data, helps automate farming and breeding sectors.
SMART RETAIL
Obtain and analyze data about customer behavior; Automate shopping process and optimize shopping experience.
WEATHER STATION
Field ready data-collection solutions for environmental and meteorological monitoring.
WHY CHOOSE US?
FULL RANGE IoT MODULES
From the esp32-s3 controllers, arduino esp32, esp32 kits, esp32 camera, communication modules to the sensors including sensors like tof sensor and otherand actuators; high performance, high reliability, high scalability, and quick access to cloud platforms like Azure, AWS.
QUICK DEVELOPMENT AND VERIFICATION
Stackable standardization system to facilitate rapid concept proofing, rapid verification, and rapid shipment; ISO9001 international quality system certification, FCC, CE, TELEC product certifications to ensure timeline and quality.
TECHNICAL SERVICE
DOCS database, forums and etc provide technical services, UIFlow visual rapid development tools, complete API interfaces, greatly shorten the integration time, and help product mass production.
OPEN PLATFORM
Open-source hardware, open API interface, diverse cooperation forms, more cost-effective.
88
COUNTRIES
52668
GLOBAL DEVELOPERS
280
PRODUCTS
THE LATEST FROM M5STACK

With the continuous development of the Internet of Things (IoT) technology, an increasing number of devices require remote monitoring and control. In this context, RS485 communication, as a reliable communication protocol, is widely used for data transmission and communication connectivity between IoT devices.

RS485 communication, as a serial communication protocol, offers several prominent advantages:

1. Long-distance transmission: RS485 communication supports transmission over a maximum distance of 1200 meters, suitable for communication needs among IoT devices distributed over larger areas.
2. Strong anti-interference capability: RS485 communication uses differential signal transmission, exhibiting excellent anti-interference capability, ensuring stable and reliable data transmission in industrial environments.
3. Multi-point communication: RS485 supports multi-point communication, enabling the connection of multiple devices to form a network, meeting the inter-device connectivity requirements in IoT.
4. High-speed transmission: RS485 supports data transmission speeds of up to 10Mbps, meeting the data transfer speed requirements of IoT devices.

Applications of RS485 in IoT:

1. Industrial Automation:

In the field of industrial automation, RS485 communication is widely used for data transmission and control connectivity among various devices such as sensors, actuators, and PLCs. Through RS485 communication, these devices can achieve remote monitoring and control, enhancing production efficiency and work safety.

2. Smart Buildings:

In smart building systems, RS485 communication is used to connect various smart devices, such as lighting control systems, HVAC systems, and security systems, enabling data exchange and centralized management among devices. The stability and reliability of RS485 communication enable smart building systems to achieve efficient energy management and intelligent control.

3. Agricultural IoT:

In agricultural IoT applications, RS485 communication can be used to connect soil moisture sensors, weather stations, irrigation systems, and other devices, enabling remote monitoring of farmland environments and precision irrigation to improve crop yield and quality.

Future development of RS485 communication:

In conclusion, RS485 communication, as an important communication means in IoT, provides a reliable solution for data transmission and communication connectivity between different devices through its features such as long-distance transmission, strong anti-interference capability, and multi-point communication. As IoT continues to evolve, we have reason to believe that RS485 communication will continue to play an important role, building a solid bridge for interconnection among IoT devices.

Next, we will use the M5Stack device as an example to demonstrate the application of RS485 communication in IoT. Here we use RS485 HAT, RS485 HAT consists of a 485 automatic transceiver circuit and a DC-DC buck circuit which can drop an input 12V to 5V.

Setting up the Arduino Environment

First, please refer to the Arduino IDE setup tutorial to complete the basic software installation. And then install the `M5Unified and FastLED libraries` in the library manager, or manually clone and install them from the following GitHub links into the C:\Users\PC\Documents\Arduino\libraries  directory:

*M5Unified: (https://github.com/m5stack/M5Unified)

*FastLED: (https://github.com/FastLED/FastLED)

Setting up the Hardware Environment

Devices needed:

1.  ATOM Matrix x1
2. M5StickC Plus x1
3. RS485 HAT x1
4. Tail485 x1
5.120 Ohm plug-in resistor x1
6. RS485 cable x1
7. 12V power supply x1

Operational steps:

1.Connect the RS485 HAT to the M5stickc Plus.

2. Connect the ATOM Matrix to the Tail485.

 3. Connect a 120-ohm matching resistor is needed at the AB end of RS485.

4. Use a 12V power supply.

5. Connect using the RS485 cable.

RS485 Transmitter

Using the following code, we will utilize the M5stickc Plus + RS485 HAT to create an RS485 transmitter. Pressing button A will send control commands via RS485 to control the color of the receiving end's RGB light.

#include "M5Unified.h"

String command[3] = {"RED\n", "GREEN\n", "BLUE\n"};

uint8_t command_index = 0;

 

void setup() {

  M5.begin();

  M5.Display.setEpdMode(epd_mode_t::epd_fastest);

  M5.Display.setFont(&fonts::Font4);

  M5.Display.setTextColor(WHITE);

  if (M5.Display.width() < M5.Display.height())

  { /// Landscape mode.

    M5.Display.setRotation(M5.Display.getRotation() ^ 1);

  }

  M5.Display.startWrite();

  M5.Display.setTextSize(1);

  M5.Display.drawCenterString("M5Stack RS485", M5.Display.width()/2, M5.Display.height()/8);

  M5.Display.drawCenterString("Demo", M5.Display.width()/2, M5.Display.height()/8+20);

  M5.Display.setTextSize(1);

  M5.Display.drawCenterString("btnA send command", M5.Display.width()/2, M5.Display.height()/8+60);

  M5.Display.endWrite();

  Serial2.begin(115200, SERIAL_8N1, 26, 0);

  while (1)

  {

    M5.update();

    M5.Display.startWrite();

    if (M5.BtnA.wasClicked()) {

      command_index++;

      if (command_index > 2)

        command_index = 0;

      Serial2.printf("%s", command[command_index].c_str());

      switch (command_index)

      {

      case 0:

        M5.Display.clear(RED);

        break;

      case 1:

        M5.Display.clear(GREEN);

        break;

      case 2:

        M5.Display.clear(BLUE);

        break;

 

      default:

        break;

      }

 

      M5.Display.setTextSize(1);

      M5.Display.drawCenterString("M5Stack RS485", M5.Display.width()/2, M5.Display.height()/8);

      M5.Display.drawCenterString("Demo", M5.Display.width()/2, M5.Display.height()/8+20);

      M5.Display.setTextSize(2);

      M5.Display.drawCenterString(command[command_index], M5.Display.width()/2, M5.Display.height()/8+60);

      M5.Display.endWrite();

      break;      

    }

  }

}

 

void loop() {

  M5.update();

  M5.Display.startWrite();

  if (M5.BtnA.wasClicked()) {

    command_index++;

    if (command_index > 2)

      command_index = 0;

    Serial2.printf("%s", command[command_index].c_str());

    switch (command_index)

    {

    case 0:

      M5.Display.clear(RED);

      break;

    case 1:

      M5.Display.clear(GREEN);

      break;

    case 2:

      M5.Display.clear(BLUE);

      break;

 

    default:

      break;

    }

  }

 

  M5.Display.setTextSize(1);

  M5.Display.drawCenterString("M5Stack RS485", M5.Display.width()/2, M5.Display.height()/8);

  M5.Display.drawCenterString("Demo", M5.Display.width()/2, M5.Display.height()/8+20);

  M5.Display.setTextSize(2);

  M5.Display.drawCenterString(command[command_index], M5.Display.width()/2, M5.Display.height()/8+60);

  M5.Display.endWrite();  

}

RS485 Receiver

With the code below, we utilize the ATOM Matrix+Tail485 to create an RS485 receiver. The receiver waits for commands sent by the transmitter and changes the color of the RGB LED.

#include "Arduino.h"

#include <FastLED.h>

 

#define NUM_LEDS 25

 

#define DATA_PIN 27

 

CRGB leds[NUM_LEDS];

 

char terminateChar =  '\n';      

const int bufferLength = 100;    

char serialBuffer[bufferLength];

String rx_str;  

 

void setup() {

    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

 

    Serial2.begin(115200, SERIAL_8N1, 32, 26);

}

 

void loop() {

    if (Serial2.available()) {

        Serial2.readBytesUntil(terminateChar, serialBuffer, bufferLength);

        rx_str = serialBuffer;

        if (rx_str.indexOf("GREEN") != -1) {

            for (int i = 0; i < 25; i++)

                leds[i] = 0x001000;

            FastLED.show();

        }

        else if (rx_str.indexOf("RED") != -1) {

            for (int i = 0; i < 25; i++)

                leds[i] = 0x100000;

            FastLED.show();

        }

        else if (rx_str.indexOf("BLUE") != -1) {

            for (int i = 0; i < 25; i++)

                leds[i] = 0x000010;

            FastLED.show();

        }

    }

}

ESP32 CAM is an ESP32 development board with a built-in camera. It is powerful, compact, and suitable for Internet of Things (IoT) projects. It can meet the market's demands for device connectivity, data transmission, and security. The ESP32 CAM offers the following advantages:

Powerful processing capabilities and rich features: ESP32 CAM integrates a high-performance ESP32 chip, providing powerful processing capabilities and various functional modules such as Wi-Fi, Bluetooth, and a camera. This enables easy device connectivity and data processing, meeting the requirements of IoT projects.
Stable wireless connection: ESP32 CAM has a built-in robust Wi-Fi module, offering a stable and reliable wireless connection. This facilitates reliable communication between devices and supports remote monitoring and control functionality.
Flexible device integration: ESP32 CAM has ample GPIO pins and communication interfaces, allowing for flexible integration with other sensors, actuators, and external devices. This simplifies the expansion and customization process of IoT projects.
Security assurance: ESP32 CAM supports secure data transmission and communication protocols such as SSL/TLS. Additionally, being open-source and having an active developer community ensures timely fixes and updates for security vulnerabilities, providing reliable security assurance.

Due to the advantages of the ESP32 CAM, it has a wide range of applications in IoT projects. It can be used in areas such as smart homes, industrial automation, smart agriculture, and smart cities. For example, leveraging the high-performance camera and image processing capabilities of the ESP32 CAM, intelligent video surveillance and facial recognition systems can be implemented.

In the following, we'll use the M5Stack TimerCam as an example and provide a guide to help you set up your own video surveillance project.

We will provide tutorials for four different uses: Web camera, scheduled wake-up capture, push and pull RTSP streaming. However, before getting started, it is necessary to set up the Arduino working environment.

To set up the Arduino environment, we can complete the basic software installation by following the first step in the Arduino IDE environment setup tutorial. And then install the "M5Stack board management" and the "TimerCam-Arduino library" in the Library Manager, or manually clone it from the GitHub link and install it into the "C:\Users\PC\Documents\Arduino\libraries" directory.

1. Set up your webcam

1). Using the code below, we will explain how to initialize the camera, capture a frame of image data, and enable the Webserver Demo for image preview.

// Include the necessary header files

#include "battery.h"

#include "esp_camera.h"

#include <WiFi.h>

#include "soc/soc.h"

#include "soc/rtc_cntl_reg.h"

 

#include "camera_pins.h"

 

//Configure the Wi-Fi information for the camera to connect to

const char *ssid     = "******";

 

const char *password = "******";

 

void startCameraServer( );

 

void setup( ) {

 

    Serial.begin(115200);
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // disable   detector
    bat_init();
 
    // After starting the TimerCAM, set the power pin to a high level to maintain power supply.
    bat_hold_output();
 
    Serial.setDebugOutput(true);
    Serial.println();
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);

 

// Configuration of the camera includes settings for pins, image size, and compression format.
//Setting a large image size or high image quality may result in insufficient memory allocation, leading to initialization failure.
    camera_config_t config;
    config.ledc_channel = LEDC_CHANNEL_0;
    config.ledc_timer   = LEDC_TIMER_0;
    config.pin_d0       = Y2_GPIO_NUM;
    config.pin_d1       = Y3_GPIO_NUM;
    config.pin_d2       = Y4_GPIO_NUM;
    config.pin_d3       = Y5_GPIO_NUM;
    config.pin_d4       = Y6_GPIO_NUM;
    config.pin_d5       = Y7_GPIO_NUM;
    config.pin_d6       = Y8_GPIO_NUM;
    config.pin_d7       = Y9_GPIO_NUM;
    config.pin_xclk     = XCLK_GPIO_NUM;
    config.pin_pclk     = PCLK_GPIO_NUM;
    config.pin_vsync    = VSYNC_GPIO_NUM;
    config.pin_href     = HREF_GPIO_NUM;
    config.pin_sscb_sda = SIOD_GPIO_NUM;
    config.pin_sscb_scl = SIOC_GPIO_NUM;
    config.pin_pwdn     = PWDN_GPIO_NUM;
    config.pin_reset    = RESET_GPIO_NUM;
    config.xclk_freq_hz = 20000000;
    config.pixel_format = PIXFORMAT_JPEG;
    config.frame_size   = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count     = 2;
 
// Initialize the camera
    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK) {
        Serial.printf("Camera init failed with error 0x%x", err);
        return;
    }
 
    sensor_t *s = esp_camera_sensor_get();
 
//  Initially flip the sensor vertically and adjust brightness and saturatio
 
    s->set_vflip(s, 1);        // flip it back
    s->set_brightness(s, 1);   // up the blightness just a bit
    s->set_saturation(s, -2);  // lower the saturation
 
    // Set Frame Size
    s->set_framesize(s, FRAMESIZE_QVGA);
 
    Serial.printf("Connect to %s, %s\r\n", ssid, password);
 
 
    // Connect WiFi
    WiFi.begin(ssid, password);
 
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
 
    // If you don't have access to a Wi-Fi network to connect to, you can switch to using the following code to enable the camera to create its own Access Point (AP)
    // WiFi.softAP(ssid, password);
    // IPAddress IP = WiFi.softAPIP();
    // Serial.print("AP IP address: ");
    // Serial.println(IP);
 
    // enable the Web server
    startCameraServer();
 

}

 

void loop() {

// After startup, you can view the IP address assigned to the camera by serial communication. Here's the code that will continuously print the IP address for easy viewing

 

    Serial.print("Camera Ready! Use 'http://");

    Serial.print(WiFi.localIP());

    Serial.println("' to connect");

 

    delay(1000);

    digitalWrite(2, HIGH);

    delay(1000);

    digitalWrite(2, LOW);

}

2). Modify the code with the WiFi information section, and compile and burn the program to the device. Then, you can use the serial monitor to view the IP address assigned to the camera.

WiFi connected

Camera Ready! Use 'http://192.168.31.11' to connect

For devices on the same network, you can access 192.168.31.11 through a web browser to access the control page, where  can obtain real-time images and adjust image properties.

(Note: You need replace the IP address with the actual IP address printed on the serial monitor).

 webcam

2. Scheduled wake-up capture

To achieve scheduled wake-up and capture using the RTC (Real-Time Clock) functionality for extended battery life, you can refer the code below. It captures an image during the period between camera startup and entering sleep mode. You can then transmit the image data to another location using a method such as HTTP POST for scheduled capture.

#include "battery.h"

#include "esp_camera.h"

#include <WiFi.h>

#include "soc/soc.h"

#include "soc/rtc_cntl_reg.h"

#include "led.h"

#include "camera_pins.h"

#include "bmm8563.h"

 

void setup() {

    Serial.begin(115200);

    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // disable   detector

 

    bat_init();

    led_init(CAMERA_LED_GPIO);

    bmm8563_init();

 

    // Configuration of the camera includes settings for pins, image size, and compression format.

// Setting a large image size or high image quality may result in insufficient memory allocation, leading to initialization failure.

    camera_config_t config;

    config.ledc_channel = LEDC_CHANNEL_0;

    config.ledc_timer   = LEDC_TIMER_0;

    config.pin_d0       = Y2_GPIO_NUM;

    config.pin_d1       = Y3_GPIO_NUM;

    config.pin_d2       = Y4_GPIO_NUM;

    config.pin_d3       = Y5_GPIO_NUM;

    config.pin_d4       = Y6_GPIO_NUM;

    config.pin_d5       = Y7_GPIO_NUM;

    config.pin_d6       = Y8_GPIO_NUM;

    config.pin_d7       = Y9_GPIO_NUM;

    config.pin_xclk     = XCLK_GPIO_NUM;

    config.pin_pclk     = PCLK_GPIO_NUM;

    config.pin_vsync    = VSYNC_GPIO_NUM;

    config.pin_href     = HREF_GPIO_NUM;

    config.pin_sscb_sda = SIOD_GPIO_NUM;

    config.pin_sscb_scl = SIOC_GPIO_NUM;

    config.pin_pwdn     = PWDN_GPIO_NUM;

    config.pin_reset    = RESET_GPIO_NUM;

    config.xclk_freq_hz = 20000000;

    config.pixel_format = PIXFORMAT_JPEG;

    config.frame_size   = FRAMESIZE_UXGA;

    config.jpeg_quality = 10;

    config.fb_count     = 2;

 

// Initialize the camera

    esp_err_t err = esp_camera_init(&config);

    if (err != ESP_OK) {

        Serial.printf("Camera init failed with error 0x%x", err);

        return;

    }

 

    sensor_t *s = esp_camera_sensor_get();

 

//  Initially flip the sensor vertically and adjust brightness and saturatio

s->set_vflip(s, 1);        // flip it back

    s->set_brightness(s, 1);   // up the blightness just a bit

    s->set_saturation(s, -2);  // lower the saturation

 

    // Set Frame Size

    s->set_framesize(s, FRAMESIZE_QVGA);

 

    camera_fb_t *fb = NULL;

    esp_err_t res   = ESP_OK;

 

    // Get a frame of image data

    fb = esp_camera_fb_get();

 

    if (!fb) {

        Serial.println("Camera capture failed");

    }

    Serial.println("Camera capture OK");

    // Acquired image data

    uint8_t *data_buffer = fb->buf;

    size_t data_len      = fb->len;

 

    //...................

 

    // You can perform data processing in this section and send it to the server using the HTTP method.

 

    //...................

 

    // Set a 5-second wake-up interval.

    bmm8563_setTimerIRQ(5);

    delay(1000);

}

 

void loop( ) {

    // Power off.

    // The device enters sleep mode and wakes up after 5 seconds to start executing the program from the beginning. (This only applies when powered by a battery.)

    bat_disable_output();

}

3. Push and pull RTSP streaming

RTSP, short for Real-Time Streaming Protocol, is a network transmission protocol used to control the real-time transmission of data in multimedia applications. It is commonly used in conjunction with streaming media servers and clients to achieve real-time streaming and playback of audio and video content. Here is a brief description of the applications of RTSP and the meanings related to push and pull:

RTSP Applications:

Streaming Media Transmission: RTSP is widely used in streaming media applications such as online video streaming, video-on-demand, and video conferencing. It enables clients to work collaboratively with streaming media servers by negotiating session parameters, controlling playback status, and data transmission methods, thus achieving real-time media data transmission and playback.
Surveillance Systems: RTSP is commonly used in surveillance cameras and camera systems, allowing users to remotely monitor video streams over the network. This is particularly useful for home security, enterprise security, and public safety.
Video Conferencing: RTSP is used in video conferencing applications, allowing multiple participants to share audio and video data in real-time, enabling remote collaboration.
Audio Streaming: RTSP not only supports video streaming but also facilitates the transmission of audio streams. This is important for applications such as audio broadcasting and audio conferences.

Push and Pull

Push: Push refers to the process of sending multimedia data (typically audio and video) from a source to the network, allowing other devices or users to access and play it in real-time. Typically, the media source generates data and then pushes it to a streaming media server using a streaming media transfer protocol (such as RTSP, RTMP, HLS, etc.). The process from the source to the server is called "push".
Pull: Pull refers to the process of retrieving multimedia data from a streaming media server and decoding and playing it at the receiving end. Users or client devices request specific media content from the streaming media server using the same streaming media transfer protocol. This process is called "pull".

In summary, RTSP is an essential protocol for real-time streaming transmission widely used in the multimedia domain, enabling users to transmit and play audio and video data in real-time over the internet. Push involves sending media data to the network, while pull involves retrieving and playing media data from the network. Together, they form the core of streaming media services.

Using the Camera as an RTSP Server

By running the examples -> rtsp_stream code, you can configure the device as an RTSP server. Devices on the same network can access the real-time image by using a media player (such as VLC Player) and accessing rtsp://192.168.xxx.xxx:8554/mjpeg/1 (Note: Please replace the IP address with the actual IP address obtained from the serial monitor).

« ..WiFi connected

RTSP URL: rtsp://192.168.2.175:8554/mjpeg/1

LinkedListElement (0x3ffdb9ac)->(0x3ffdb9ac)->(0x3ffdb9ac)

Creating TSP streamer

Created streamer width=640, height=480

Relevant Links

 rtsp_stream relies on the Micro-RTSP library, which can be installed by following the dependency prompts when installing the TimerCam-arduino library. Alternatively, you can manually clone and install it using the GitHub link provided. VLC Player is a powerful media player that we will use for pulling/streaming tests in the subsequent testing phase.

- Micro-RTSP

- VLC player

VLC Player Pull Streaming

Configuration of Streaming Relay Server

Distributing HTTP Streaming Sources

In the previous demo, we used the camera as an RTSP server, but there are limitations in terms of performance, especially when multiple clients want to pull the stream, it can be challenging. In some cases, you may want to distribute media resources to external servers or live streaming platforms, or achieve stronger multi-device access capabilities. In the following, we will use an open-source RTSP server project combined with the ffmpeg tool to implement streaming (forwarding TimerCAM data to the server) and pulling (clients pulling video resources from the server).

Here we need to burn the camera with the first web_cam demo program mentioned at the beginning of the article, and we can directly access the image stream through http://IP:81/stream.

Visit EasyDarwin - Github releases, download the release version to your local machine, and extract it. Run it as a service and start the server. (Note: Please use the sudo command to run it, otherwise, you may not have permission to open the port.)

cd EasyDarwin

sudo ./start.sh

#sudo ./stop.sh 

Then please use ffmpeg to configure forwarding, and use the IP and port used in the previous demo for TimerCAM's running port and IP. The latter is the IP of the RTSP server (EasyDarwin) (default port 554, followed by a customizable ID number).

Note: Before executing this command, make sure to start the camera and ensure that the image can be previewed correctly on the webpage.

ffmpeg -re -i http://192.168.2.175:81/stream -rtsp_transport tcp -vcodec h264 -f rtsp rtsp://192.168.2.89:554/666

After completing the previous configuration, open a browser and enter http://IP:10008 to access the EasyDarwin control page. The default username and password are admin/admin. (Replace IP with the IP address of the Linux host).

By refreshing the page, we can see a new streaming address added to the control page. We can use general media player software such as VLC to fill in the corresponding streaming address to pull the video and locally cache the recording. Additionally, you can use multiple clients simultaneously for streaming playback.

 

Distributing Pull Sources

If the camera is being used as an RTSP server, you can also directly configure the pull forwarding in the EasyDarwin backend. For more details, please refer to the EasyDarwin GitHub repository.

 

The biggest contributor to indoor air pollution is not formaldehyde or PM2.5 but the often-overlooked carbon dioxide. Once carbon dioxide reaches a certain level, it can pose a serious health risk, and no air purifier can effectively filter it. It is crucial to understand the health hazards, normal ranges, and solutions regarding indoor carbon dioxide concentrations.

What are the typical indoor and outdoor carbon dioxide concentrations? Within the normal range, carbon dioxide is harmless to the human body. In the natural environment, the concentration of carbon dioxide is approximately 0.04% (400 PPM), which may reach around 500 PPM in urban areas. In unoccupied indoor environments, the carbon dioxide concentration usually ranges from 500 to 700 PPM.

At what PPM level does carbon dioxide become harmful to health? The human body is highly sensitive to increases in carbon dioxide, with every 0.5% increase noticeably affecting the body. When the concentration reaches 1% (1000 PPM), individuals may experience stuffiness, lack of concentration, and palpitations. At 1500-2000 PPM, symptoms such as breathlessness, headaches, and dizziness may occur. Concentrations exceeding 5000 PPM can lead to cognitive impairment and confusion.

In real-life scenarios, carbon dioxide concentrations often exceed safe levels. For instance, when two individuals sleep overnight in a sealed bedroom, carbon dioxide concentrations can easily reach 2000 PPM. When the carbon dioxide concentration in an office space reaches 2000 PPM, employees may experience fatigue, lack of concentration, and mental exhaustion. Beyond 2000 PPM, individuals may even feel disinclined to continue working, and their cognitive abilities can significantly decline.

Maintaining good ventilation, regularly opening windows for fresh air and using air purifiers are effective methods of reducing indoor carbon dioxide levels. Among these methods, the carbon dioxide sensor is an important tool.

Today, we are introducing two CO2 measuring sensors for detecting carbon dioxide concentrations: CO2L Unit and TVOC/eCO2 Unit.

CO2L Unit is a digital CO2 concentration detection unit with a low-power mode designed for single-shot measurements. It features the Sensirion SCD41 sensor and a voltage regulator circuit, and communicates via I2C. This unit is suitable for measuring environmental conditions, with a typical accuracy of ±(40 ppm + 5% of the reading) for CO2 measurements. The measurement range for CO2 is 400 ppm to 5000 ppm, and it can also measure ambient temperature and humidity simultaneously.

TVOC/eCO2 mini Unit is a digital multi-pixel gas sensor unit that integrates the SGP30 sensor internally. It is primarily designed for measuring the concentrations of various volatile organic compounds (VOCs) and H2 in the air. Through programming, it allows for the measurement of TVOC (Total Volatile Organic Compounds) and eCO2 (Equivalent Carbon Dioxide) concentrations. The typical measurement accuracy within the measurement range is 15%. The SGP30 sensor communicates using the I2C protocol and has an on-chip humidity compensation feature that can be enabled with an external humidity sensor. The SGP30 also has a built-in calibration function, allowing users to calibrate it based on known measurement sources. Once internally calibrated, the SGP30 provides stable long-term output. Additionally, it's important to note that eCO2 is derived from H2 concentration, so the TVOC/eCO2 mini Unit cannot fully replace a CO2 sensor.

CO2 Monitoring Solution:

Here, we will introduce three methods to monitor the CO2 levels in the environment using the CO2L Unit and TVOC/eCO2 Unit and display the data on M5Stack Basic.

Method one: Use EasyLoader to get started.

This is the simplest and fastest way, let’s get it started!

Steps:

1. Open the documentation for the CO2L Unit  and  TVOC/eCO2 Unit .

2. Download the Easyloader program for each unit, which is a quick verification program.

3. Click to install when the download is complete. 

4. Select the port (here we choose COM34, but it's worth noting that different computers may display different COM ports, so please select the appropriate port), then click "burn" to start the program burning process.

 

It’s downloading and burning now.  Once completed, the screen will display "Successfully".

Then, the sensor will begin collecting carbon dioxide data from the air and display it on the Basic. The display effect will be as shown in the following image.

Method two: using source code in Arduino IDE

Next, I’ll lead the way to burn the firmware using the source code. We will use Arduino IDE as the programming environment.

Program CO2L Unit in Arduino IDE

1. The first step is to install the M5Stack development board in the Arduino IDE, which has been covered in our previous article.

2. Open the official documentation for the CO2L Unit , where we provide information about CO2L Unit and its relative code.

3. At the bottom of the documentation page, there are links to download the Arduino sample code. Since we are using the Core series Basic host today, please click on the first link.

4. Open the link and go to the entire project file.

5. Please click on the "Code" here to download the compressed file.

6. Please extract the compressed file into the "libraries" folder within the Arduino installation directory.

7. Open Arduino IDE, and click File>Examples>M5Unit-ENV>Unit_CO2_M5Core

8. Select the board

Select M5Stack-Core-ESP32 and the corresponding port (in this case, it is COM34, but the COM port may differ on different computers). Click OK.

9. Click the right arrow icon to upload the code.

When the upload is complete, we can see that the M5Stack Basic host screen is already displaying the CO2 concentration, as shown in the picture.

ProgramTVOC/eCO2 Unit in Arduino IDE

Next, we will continue to use the TVOC/eCO2 Unit to display the CO2 concentration.

1. Similarly, the first step is to install the M5Stack development board in the Arduino IDE, which has been covered in our previous article .

2. Open the documentation for the TVOC/eCO2 Unit. You can find information about the product and related code. 

3. At the bottom of the documentation, there is a link to download the code.

4. Open the link and go to the entire project file.

5. Please click on the "Code" here to download the compressed file.

6. Please extract the downloaded installation package into the "libraries" folder within the Arduino installation directory.

7. Open Arduino IDE, and click File>Examples>M5Stack>Unit>TVOC-SGP30

8. Select the board

Select M5Stack-Core-ESP32 and the corresponding port (in this case, it is COM34, but the COM port may differ on different computers). Click OK.

9. Click the right arrow icon to upload the code.

When the upload is complete, we can see that the M5Stack Basic host screen is already displaying the CO2 concentration, as shown in the picture.

Method three: using EasyLoader to get started

Finally, we introduce M5Stack’s graphical programming software UIFlow. It is convenient for those who are not familiar with coding.

1.To begin with, you need to install the firmware burning tool "Burner".

Note that different operating systems require different versions of Burner to be downloaded.

M5Burner_Windows: https://m5burner.m5stack.com/app/M5Burner-v3-beta-win-x64.zip

M5Burner_MacOS: https://m5burner.m5stack.com/app/M5Burner-v3-beta-mac-x64.zip

M5Burner_Linux: https://m5burner.m5stack.com/app/M5Burner-v3-beta-linux-x64.zip

Note:

For macOS users, after installing Burner, please move the application to the "Applications" folder as shown in the following image.

For Linux users, navigate to the extracted file directory and run "./M5Burner" in the terminal to launch the application.

2. Firmware Burning

Double-click to open the Burner firmware burning tool. In the left-side menu, select the corresponding device category and choose the firmware that matches your device, and click the“Download”button.

Connect the device to your computer using a Type-C data cable. Burner will automatically select the corresponding COM port. You can use the default configuration for the baud rate in M5Burner. Click "Burn" to start the burning process.

During the firmware burning stage, you need to enter the WiFi information in the WiFi configuration box. The WiFi information will be burned and saved to your M5Stack device along with the firmware.

Then, click "Start" to begin the burning process. Note: If a timeout occurs during the burning process, you can try lowering the baud rate to 115200.

When the burning log displays "Burn Successfully," it indicates that the firmware has been successfully burned.

If this is the first time burning or if the firmware program is running abnormally, you can click on "Erase" in the top right corner to erase the flash memory. In subsequent firmware updates, there is no need to erase again. However, please note that erasing the flash memory will delete the saved Wi-Fi information and refresh the API key.

3. Obtaining API Key

Please connect your M5Stack device to the computer using a Type-C data cable and select the corresponding COM port.

1). Click on "Configuration" to view the API Key information, which will appear in the configuration box. (Please copy and save the API Key as it will be used as credentials for UIFlow communication going forward).

2). Set the "Start Mode" to "Internet Mode." After completing this configuration, the device will automatically restart and enter online programming mode.

3). For further explanation of other configuration options in the configuration box, please refer to the configuration instructions below.

4. M5Burner Configuration Instructions

If you need to modify the configuration file, please connect your M5 device to the computer using a Type-C data cable and select the corresponding COM port. Then, you can click on "Configuration" to make the modifications.

APIKEY: The communication credentials for M5Stack device when using UIFlow web programming.

Start Mode: Configurable startup mode after booting.

Quick Start: Option to enable quick start to skip the startup interface.

Server: Selection of the server.

WiFi: Configuration of WiFi SSID and password.

COMX: Option to enable COMX.LTE network (this feature requires stacking the COMX.LTE module, for detailed instructions, please refer to the "Network Over COM.LTE Tutorial").

APN: Configuration of APN access point for COMX.LTE module. 

5. After completing the above steps, you can now start using UIFlow for programming.

Enter the UIFlow website URL in your browser: https://flow.m5stack.com/

Here, we will choose UIFlow 1.0 for now, as the list of supported devices for UIFlow 2.0 is still being expanded.

① In Step 3, we have got an API Key, and here we enter it in the bottom-left corner of the screen.

Then the screen will display “Connected”.

② At the "Add Units" section, add the "CO2L Unit" and select "OK."

Click “Load Examples”

④ Click on "Run" or "Download" (running is for testing the code and you can see the results on the host, but the code will not be saved on the device if power is disconnected. Downloading, on the other hand, will save the code on the device, and it will be retained even if power is disconnected. Choose based on your needs. If you choose to modify the code and upload it again, you will need to re-burn the firmware, which is discussed in Step 2).

The device will now start working as shown in the following image.

For the TVOC/eCO2 mini Unit, just follow the same steps as mentioned above, with the difference being the sensor selection during the unit addition. After completing the addition, select the example code, click "Run," and the device will start functioning normally.

Today's tutorial is complete here.

For an introduction to UIFlow statements, you can refer to https://docs.m5stack.com/en/quick_start/m5core/uiflow.

In the future, we will have a dedicated section specifically for explaining UIFlow statements. Stay tuned for that!

batktop