News
M5Stack News.

Meshtastic is an open-source, off-grid communication project that uses LoRa (Long Range) radio technology to enable secure, long-distance messaging without the internet or cellular networks. It leverages point-to-point(P2P) and mesh communication in areas with no internet or cellular access by forming a self-sufficient network of devices. Utilizing ultra-low power hardware and license-free frequency bands, it enables long-range message transmission, making it ideal for outdoor adventures, emergency rescue, rural connectivity, and low-power IoT applications.

In this guide, we'll walk you through building your very own Meshtastic LoRa node using Module LoRa868 and ESP32-based M5Stack Core series controllers.

What You’ll Need

Step 1: Flashing the Meshtastic Firmware

The easiest way to install Meshtastic firmware on your M5Stack device is with M5Burner, a simple and free intuitive firmware flashing tool developed by M5Stack.

1.    Locate the Meshtastic Firmware

Open M5Burner > Select ALL from the list in the left column > Input "Meshtastic" into the search bar and choose the firmware that match your device > Click Download.

Find meshtastic firmware in M5Burner

If you haven’t installed M5Burner, click here and follow the installation steps to download it to your computer.

    2. Connect Your Device and Start Flashing

         Connect the main controller to your computer via USB data cable > Click Burn > Select the correct USB port and set baud rate to 1500000 > Click Start to begin flashing.

    Download meshtastic firmware from M5Burner

         Wait for the message "Burn successfully" > Click "Click here to return" > When the Meshtastic logo "//\" appears on the screen, disconnect the device from your computer.

    Note: if flashing fails, try installing the USB driver on your computer or long-press the reset button on the main controller to enter download mode. For more information, refer to your device’s documentation page.

    Step 2: Configure the Module LoRa868 v1.2 and Connect Antenna

    After the firmware successfully downloaded on the device:

         Check M5Burner firmware for pin info and set DIP switches by following Module LoRa868 v1.2 DIP Switch Guide (for Core1/Core2: long pins 2,5,7 and short pin 1 ON).

         Remove red dust cap > Install antenna > Connect the module to the device.

         Power on the device, then the Meshtastic logo "//\" will appear.

    Safety Warning

    Do NOT connect or power on the device without installing the antenna, as this may cause permanent hardware damage!

    Step 3: Install the Meshtastic App on your iOS or Android device

    1.     Install the Meshtastic app on Your Phone

    Download the Meshtastic app from the Google Play or Download APK from GitHub(for Android) or App Store(for IOS).

    2.   Pair the Device

    Open the Meshtastic app and follow the on-screen instructions to pair your device via Bluetooth—nearby devices will be detected automatically. The iOS and Android Meshtastic apps offer similar features but have different interfaces, so setup steps and screenshots are shown separately for each platform.

    iOS Setup

       

    3. Configure Device Settings

    After pairing, you could set the Lora region, select the appropriate region (e.g., EU 868MHz), username in the app.

    When running Meshtastic, the ESP32 can't use Wi-Fi and Bluetooth simultaneously. Bluetooth is enabled by default. If you turn on Wi-Fi, Bluetooth will be disabled. To re-enable it, connect the device to your computer via USB and use the Meshtastic Web Client in Chrome to disable Wi-Fi.

    Step 4: Add GPS To Your Meshtastic Node

    Core1/Core2 with LoRa868 v1.2 doesn’t have built-in GPS, but you can share your smartphone’s GPS location with the device. It's useful for team members to track each other during outdoor activities.

    iOS Setup

     

    Step 5: Send and Receive Message

    With other nodes show up in the list, you're connected to the mesh and can start messaging via the Meshtastic app. 

    iOS Chat

     

    Is Meshtastic Legal?

    Yes, it’s legal. Meshtastic operates on license-free frequency bands such as 433 / 470 / 868 / 915 MHz which is in full compliance with FCC regulations. 

    How far does Meshtastic work?

    The estimated range of this Meshtastic setup is around 4 km (2.49 miles). But the range between two Meshtastic nodes varies based on antenna setup, and environmental conditions. You may try moving the device around to test the range, check the signal to ensure stable connectivity.

    2025-06-04

    For those exploring what hardware ChatGPT runs on, the traditional answer involves large-scale cloud infrastructure. However, with the OpenAI API and lightweight microcontrollers like the M5Stack ESP32-based AtomS3R, it’s now possible to build a compact, connected ChatGPT AI device. Paired with the Atomic Echo Base for audio I/O, this setup enables a tiny AI voice assistant capable of real-time voice interaction via Wi-Fi.

    In this article, we’ll walk you through how to build your own AI-powered voice assistant using OpenAI—no coding required.

    M5Stack AtomS3R

    The M5Stack AtomS3R is a compact microcontroller powered by the ESP32-S3 chip, measuring just 24 × 24 mm. It supports Wi-Fi, Bluetooth, and offline voice wake-up, making it ideal for building portable AI voice assistant and IoT applications.

    Required Hardware

    Download OpenAI Voice Assistant for AtomS3R Firmware from M5Burner

    M5Burner is a tool that enables creators to upload firmware and allows users to flash it onto M5Stack devices. If you haven’t downloaded it before, please select the version compatible with your operating system to proceed.

    Software Version Download Link
    M5Burner_Windows Download
    M5Burner_MacOS Download
    M5Burner_Linux Download

     

    1.     Download the OpenAI Firmware

    Double click M5Burner > Locate the OpenAI Voice Assistant for AtomS3R Firmware > Click Download.

    2.   Get Your OpenAI API Key

    An API key is required after clicking Download. Visit OpenAI's platform > Complete registration and login > Review pricing for Realtime API and select the package > Navigate to the API Keys section and create a new key

    3.   Firmware Flashing

    I.              Input your Wi-Fi connection information and OpenAI API keys in the pop-up window > Hit Next

    II.            Connect your AtomS3R via USB-C > Press and hold the Reset button for ~2 seconds until the green LED turns on, then release to enter the download mode.

    III.         Select the correct COM port and click “Start” to start flashing.

    Talking to Your AI Assistant

    Once completed, your device will reboot and connect to OpenAI for real-time voice interaction. You could speak directly to your assistant and receive instant responses.

    If you prefer a more customizable approach to integrate the OpenAI into your project instead of downloading the prebuilt firmware from M5Burner, you could visit GitHub for the original source code.

    2025-05-22

    May 9, 2025 – M5Stack, a leader in modular IoT and embedded development platforms, unveils Tab5, a next-generation 5-inch smart touch terminal powered by the advanced 400MHz ESP32-P4 dual-core RISC-V processor. Designed for industrial control, smart home hubs, edge intelligence, and IoT applications, Tab5 offers high performance, versatile interfaces, and seamless connectivity through Wi-Fi 6 and Bluetooth 5.2 in one compact tablet. Combining multimedia capabilities with modular expandability, Tab5 empowers developers to create flexible, scalable solutions for a wide range of industries.

    High-Performance Core for Embedded Intelligence

    At the heart of Tab5 is the ESP32-P4 dual-core RISC-V processor, running at 400MHz and backed by 32MB of PSRAM and 16MB Flash, delivering robust performance for embedded applications and edge computing. While the ESP32-P4 handles processing tasks, wireless connectivity is provided by the onboard ESP32-C6-MINI-1U module, which supports Wi-Fi 6 and Bluetooth 5.2. Equipped with 3D internal antennas, this module ensures high-throughput, low-latency communication across a wide range of IoT scenarios.

    Immersive Display and Interactive Design

    Tab5 features a 5-inch IPS touchscreen with a 1280×720 resolution and a GT911 capacitive multi-touch panel, providing responsive touch interaction and high-resolution visuals for an intuitive user experience. Built-in 2MP camera (1600×1200 resolution) and dual microphones with a speaker enable intelligent interactions such as facial recognition, image processing, and voice commands. The camera interface uses MIPI-CSI to enable HD video capture and edge AI tasks such as object tracking.

    Additional onboard features including RESET/BOOT buttons, a BMI270 six-axis IMU for motion sensing, and a Micro SD card slot provide enhanced control, motion tracking, and local data storage—empowering developers to create multi-modal edge applications.

    Rich Interfaces and Modular Expandability

    Tab5 is designed for flexibility and scalability with a comprehensive suite of I/O interfaces:

    • RS485, Grove, M5Bus, GPIO.EXT
    • USB-A (Host) and USB-C (USB 2.0 OTG)
    • 3.5mm audio jack
    • Support for UART, I2C, and ADC protocols
    • STAMP solder pads for easy integration of communication modules like Cat.M, NB-IoT, or LoRaWAN

    These interfaces ensure seamless integration with the M5Stack hardware ecosystem, enabling plug-and-play expansion through a wide range of functional modules.

    Battery Support & Deployment Options

    Tab5 is available in two variants:

    • Tab5 Kit – Includes a removable 2S NP-F550 7.4V 2000mAh lithium-ion battery
    • Tab5 – Battery not included

    Both models support external NP-F550 lithium batteries, offering flexible deployment options for fixed installations or mobile applications.

    Versatile Applications Across Industries

    Tab5 is engineered to address diverse application scenarios across industries. In industrial settings, it functions as an effective HMI for control panels and data visualization. Its multi-protocol wireless support makes it ideal for smart home hubs and gateways. In education and maker spaces, it supports UIFlow 2.0, Arduino IDE, ESP-IDF and PlatformIO, enabling flexibility for both beginners and advanced developers. With a built-in camera and dual microphones, it also enables AI vision and voice interaction for use cases like smart kiosks and voice-controlled terminals.

    “Designed for seamless development, the Tab5 delivers innovation and usability, empowering creators to turn ideas into reality,” said Jimmy Lai, Founder and CEO of M5Stack.

    Built to Expand

    To further enhance Tab5’s utility, a dedicated keyboard accessory is in development — stay tuned for the full reveal. Designed for seamless integration with the M5Stack ecosystem, Tab5 supports a broad range of functional modules, offering developers the flexibility to tailor solutions across diverse application needs.

    Tab5 is now available through M5Stack’s official store and global distributors. For more details, please visit www.m5stack.com.

    2025-05-08

    Today, we’re checking out another great device for running our assistant with excellent performance, and learning how to activate Assist using the M5Stack CoreS3SE.

     

    Index

    • M5Stack CoreS3SE
    • M5Stack CoreS3SE vs ESP32-S3-BOX-3
    • Prerequisites
    • Configuring the M5Stack CoreS3SE
    • Custom support

    M5Stack CoreS3SE

    Well, let's start with the basics. M5Stack is the brand behind well-known devices like the Atom Echo. As I mentioned before, this was the first external device used to interact with Home Assistant. I’m convinced that if you're getting into the world of local assistants, you’re already familiar with it.

    But Atom Echo isn’t the only option. M5Stack also makes a variety of ESP-based devices that are easy to integrate with Home Assistant. Think of them like custom ESPHome builds, but without the hassle of soldering, wiring, or configuring components from scratch.

    Now that the introduction is done, today I want to introduce you to the M5Stack CoreS3SE, a device that’ll definitely remind you of the ESP32-S3-BOX-3 we looked at recently, as we can also activate Assist with the M5Stack CoreS3SE.

    M5Stack CoreS3SE vs ESP32-S3-BOX-3

    Since the goal of this guide is to activate Assist using the M5Stack CoreS3SE, I’ll go over the differences and similarities I’ve found between the two devices.

    • Both run on the ESP32-S3 chip and are fully compatible with ESPHome.
    • Both come with two microphones for better voice recognition.
    • Both have a built-in speaker and a touchscreen display.
    • The setup process is nearly identical for both.
    • The CoreS3SE is about €10 cheaper than the BOX-3B.
    • The CoreS3SE has a black frame, while the BOX-3B comes in white.
    • The CoreS3SE is a bit smaller and more square in shape compared to the BOX-3B.
    • The M5Stack CoreS3SE doesn’t come with a stand or USB-C cable by default, whereas the ESP32-S3-BOX-3B does (which we’ll actually turn to our advantage, as you’ll see at the end of this article).

    Prerequisites


    To activate Assist on the M5Stack CoreS3SE, you’ll need:

    • You have set up Assist in Home Assistant.
    • A M5Stack CoreS3SE device.
    • A USB-C data cable to power the DATA board (with a charging cable you will not be able to install the software) .

    🥑 If you're setting up Assist, I highly recommend checking out the workshop from the academy to get the most out of it!

    Configuring the M5Stack CoreS3SE

    Follow these preparation steps to get your M5Stack CoreS3SE up and running:

    1.  In Home Assistant, go to your ESPHome add-on, click on “New Device”, then “Continue”.

    2.  Give your device a name (e.g., “Assist”) and click “Next”.

    3.  For the device type, select “ESP32-S3”. You’ll see a new block for your device appear in the background.

    4.  Click “Skip”, then click “Edit” on your device’s card. Copy the code that appears and keep it handy — you’ll need part of it later.

    5.  Head over to the GitHub page linked in the guide, copy the provided code, and replace the original ESPHome code with it.

    6.  Important: This new code doesn’t include your Wi-Fi or Home Assistant credentials, so you’ll need to manually add them. Specifically, look for the lines from the original code that you copied in step 4 and insert them into the new code.

    # Enable Home Assistant API
    api:
      encryption:
        key: "bg6hash6sjdjsdjk02hh0qnQeYVwm123vdfKE8BP5"
    
    ota:
      - platform: esphome
        password: "asddasda27aab65a48484502b332f"
    
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Assist Fallback Hotspot"
        password: "ZsasdasdHGP2234"

     

    7.  What you need to do is find the corresponding lines in the code  (it's at the beginning)  and  add the corresponding information . This code snippet would look like this:

    # Enable Home Assistant API
    api:
      encryption:
        key: "1fPr5BBxCfGiLLPgu/OEILB1T4XUdXN4Sh2pic4mgQk="
      on_client_connected:
        - script.execute: draw_display
      on_client_disconnected:
        - script.execute: draw_display
    
    ota:
      - platform: esphome
        password: "a048862eecd273b682fde5d1a93acc36"
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "M5Stack-Cores3Se"
        password: "uCh6BjJ34Tnl"
      on_connect:
        - script.execute: draw_display
        - delay: 5s # Gives time for improv results to be transmitted 
      on_disconnect:
        - script.execute: draw_display

     

    8.  Now click “Save” and then “Install.” Select “Manual download” and wait for the code to compile. It might take a while, so feel free to do something else in the meantime.

    9.  Once it’s finished, choose the “Modern format” option to download the corresponding .bin file.

    10.  Connect the M5Stack CoreS3SE to your computer using a USB-C data cable, plugging it into the port on the left side of the device.

    11.  Go to the ESPHome page and click “Connect.” In the pop-up window, select your device and click “Connect” again.

    12.  Click “Install” and select the .bin file you downloaded in step 9. Then click “Install” again to upload it to the device.

    13.  You may see a message saying “HA not found.” Don’t worry — this is normal. In Home Assistant, go to Settings > Devices & Services, where the device should appear as discovered. Click “Configure” and then “Submit.”

    14. That’s it! You can now activate Assist with the M5Stack CoreS3SE. By default, just say “Ok, Nabu,” and it’ll respond using your preferred assistant settings.

    Personalized support

    As I mentioned in the comparison, the M5Stack CoreS3SE doesn't come with a standard stand, which gives us the opportunity to create one to our liking. For example, this time I wanted to create a simple and elegant stand, taking advantage of the black frame.

    If you have a 3D printer, you can download this stand I designed for FREE from our Patreon page

     

    Source: AguacaTEC
    Author: TitoTB
    2025-04-30

    If you've ever needed to update firmware on an STM32-based device, you know the struggle—setting up an debugger, dealing with drivers, and ensuring proper connections. What if you could do it all without a dedicated programmer, using just your M5Stack Core2 or CoreS3? Enter M5 DAPLink, a powerful solution that transforms your M5 device into a standalone offline programmer.

    Why Use M5 DAPLink?

    Imagine being able to flash firmware anywhere, anytime—without needing a PC connection or extra hardware. Whether you're in the field, a classroom, or a factory line, M5 DAPLink makes firmware updates seamless. Just load your firmware onto a MicroSD card (for Core2) or a virtual USB drive (for CoreS3), and you're ready to go!

    1. Preparations

    Required hardware:
    • Core2 / CoreS3
    • Module Bus
    • MicroSD card
    • Card reader
    • Male-to-female Dupont wires
    • Female-to-female Dupont wires

    2. Flashing the DAPLink Firmware

    M5Burner
    Download the M5Burner firmware flashing tool for your operating system from the links below. Extract and launch the application.

    Software Version

    Download Link

    M5Burner_Windows

     Download

    M5Burner_MacOS

     Download

    M5Burner_Linux

     Download

    Open the burner tool, select the corresponding device type from the left menu, and download the matching firmware for your device.

    CoreS3 DAPLink

    Download the firmware for CoreS3: CoreS3 → CoreS3 DAPLink. Refer to the CoreS3 documentation to learn how to enter download mode. Once the device is detected by your computer, proceed with flashing.

    CoreS2 DAPLink

    Download the firmware for Core2: Core2 → Core2 DAPLink. Refer to the Core2 documentation to install the required USB driver. Once the device is detected, proceed with flashing.

     

    3. Importing Flashing Algorithms and Firmware

    Download the algorithm package below. This package, along with the firmware, is imported into the host device and used to match different chip models during flashing. Some algorithms are preloaded in the firmware, while manual import allows for additional algorithm support. Import methods vary by device—refer to the details below.

    algorithm


    • Virtual USB Drive Import
    This method is currently only supported for CoreS3.
    Extract the algorithm package and copy it to the CoreS3 virtual USB drive. Create a program folder in the root directory to store the firmware files (hex/bin) for flashing.

    • MicroSD Import
    This method is currently only supported for Core2.
    Extract the algorithm package and copy it to the MicroSD card. Create a program folder in the root directory to store the firmware files (hex/bin). The directory structure is the same as the CoreS3 virtual USB method.

    • Web Import
    This method works for both Core2 and CoreS3. Imported data is automatically saved to the device's flash storage partition. (Note: For Core2 with an SD card, files are stored on the SD card. For CoreS3, safely eject the virtual USB drive before importing via the web.)
    Power on the device to enable its AP hotspot. Connect your computer to the hotspot and visit 192.168.4.1 in a browser. Click Program to navigate to the file upload page, then upload the algorithm and firmware files.

    4. Device Connection

    The DAPLink pin mappings for the firmware are as follows:

    For example, to update the firmware of a Unit EXT.IO2, locate the programming pads after opening the device casing and connect them according to the pin mapping above. If contact is unstable, tilt the Dupont wire pins to ensure proper connection.

    5. Starting the Flashing Process

    After importing the algorithms and firmware, the device will display available options upon startup. Select the algorithm and firmware matching your target device. Click Idle, then Busy to begin flashing. (Note: Some chips, like STM32F0xx series, may require pressing Busy twice.)

    6. Using with Module Bus

    For daily DAPLink debugging, the Module Bus is highly recommended for easier wiring. It extends the MBus interface to the board's edge and includes two sets of 2.54-15P 90° headers for seamless Dupont wire connections.

    Why M5 DAPLink is a Game-Changer

    • No extra hardware needed – Your M5 device becomes a portable STM32 programmer.
    • Works offline – No need for a PC once set up.
    • Flexible import methods – USB, SD card, or web upload.
    • Perfect for fieldwork and education – Quick firmware updates anywhere.

    With M5 DAPLink, you turn ideas into reality faster—no hassle, no complicated setups. Ready to give it a try? Download the firmware today and start flashing like a pro!

    2025-04-08

    In this article, we will integrate the M5Stack Air Quality Kit with Home Assistant to monitor air quality.

    Index

    • Air Quality Sensor
    • M5Stack Air Quality Kit
    • Prerequisites
    • Configuration in ESPHome
    • Device Information

    Air Quality Sensor

    While air quality may not be a concern for everyone, those of us living in large cities or near industrial areas are increasingly worried about the air we breathe at home. This concern is not unfounded—numerous studies have shown that long-term exposure to pollutants can lead to respiratory diseases such as asthma and bronchitis. Over time, it can also shorten lifespan and increase the risk of chronic illnesses like lung cancer.

    From this perspective, home automation can help mitigate these effects by monitoring air quality, sending alerts when pollution levels rise, or even activating ventilation or air purification systems. If you're concerned about overall environmental pollution, you can refer to indexes like the World Air Quality Index.

    However, whether you distrust external data (for instance, if monitoring stations are conveniently placed in green zones) or simply want to measure the specific data in your own home, an air quality sensor is essential. When it comes to finding a sensor that is comprehensive, integrable, and reasonably priced, debates always arise.

    M5Stack Air Quality Kit

    M5Stack is a well-known brand that offers devices like the M5Stack CoreS3SE and the historically significant Atom Echo. In this case, we’ll integrate the M5Stack Air Quality Kit with Home Assistant. This device is based on the ESP32S3FN8 chip and can measure CO2, VOCs, PM1.0, PM2.5, PM4, and PM10 particles, along with temperature and humidity (though some reviews suggest the accuracy of the latter two may be questionable). It also features an e-ink display and a built-in battery.

     

    By the way, while this article focuses on integrating the M5Stack  Air Quality Kit with Home Assistant, you can also use it directly with your mobile device to monitor its readings. The video below explains the setup process.

    Prerequisites

    To integrate the M5Stack Air Quality Kit into Home Assistant, you will need:

    • M5Stack Air Quality Kit 
    • ESPHome installed in Home Assistant.
    • A USB-C cable to power the DATA board (a charging-only cable will not allow software installation).

    🥑 If you’re new to ESPHome, I recommend checking out the Academy workshop to get the most of it!

    Configuration in ESPHome

    Follow these steps to integrate the M5Stack Air Quality Kit into Home Assistant:

    1. In Home Assistant, go to your ESPHome plugin, click “New Device,” and then click “Continue.”

    2. Name your device (e.g., “ Air Quality Kit”) and click “Next.”

    3. Select “ESP32-S3” as the device type. You'll notice that a new block has been created for your device in the background.

    4. Click “Skip” and click “Edit” on the device block above. Copy the code that appears and save it, as you will need some parts of it later.

    5. Copy the following code (which I found on reddit and edited slightly) and replace the above code in ESPHome.

    substitutions:
      devicename: lounge-airq
      friendlyname: Lounge AirQ
      location: Lounge
      sensor_interval: 10s
    
    esphome:
      name: ${devicename}
      friendly_name: ${friendlyname}
      area: ${location}
      platformio_options:
        board_build.mcu: esp32s3
        board_build.name: "M5Stack StampS3"
        board_build.upload.flash_size: 8MB
        board_build.upload.maximum_size: 8388608
        board_build.vendor: M5Stack
      on_boot:
      - priority: 800
        then:
          - output.turn_on: enable
      - priority: 800
        then:
          - pcf8563.read_time
    
    esp32:
      board: esp32-s3-devkitc-1 #m5stack-stamps3
      variant: esp32s3
      framework:
        type: arduino
    
    # Enable logging
    logger:
    
    # Enable Home Assistant API
    api:
      encryption:
        key: REDACTED
    
    ota:
      - platform: esphome
        password: REDACTED
    
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Lounge-Airq Fallback Hotspot"
        password: REDACTED
    
    captive_portal:
    
    output:
      - platform: gpio
        pin: GPIO10
        id: enable
    
    web_server:
       port: 80
       include_internal: true
    
    i2c:
      sda: GPIO11
      scl: GPIO12
      scan: true
      frequency: 100kHz
      id: bus_a
    
    spi:
      clk_pin: GPIO05
      mosi_pin: GPIO06
    
    time:
      - platform: pcf8563
        address: 0x51
        update_interval: 10min
      - platform: homeassistant
        id: esptime
    
    light:
      - platform: esp32_rmt_led_strip
        rgb_order: GRB
        pin: GPIO21
        num_leds: 1
        rmt_channel: 0
        chipset: SK6812
        name: "LED"
        restore_mode: ALWAYS_OFF
        id: id_led
    
    text_sensor:
      - platform: wifi_info
        ip_address:
          name: IP
        ssid:
          name: SSID
        bssid:
          name: BSSID
        mac_address:
          name: MAC
        dns_address:
          name: DNS
    
      - platform: template
        name: "VOC IAQ Classification"
        id: iaq_voc
        icon: "mdi:checkbox-marked-circle-outline"
        lambda: |-
          if (int(id(voc).state) < 100.0) {
            return {"Great"};
          }
          else if (int(id(voc).state) <= 200.0) {
            return {"Good"};
          }
          else if (int(id(voc).state) <= 300.0) {
            return {"Light"};
          }
          else if (int(id(voc).state) <= 400.0) {
            return {"Moderate"};
          }
          else if (int(id(voc).state) <= 500.0) {
            return {"Heavy"};
          }
          else {
            return {"unknown"};
          }
    
      - platform: template
        name: "NOX IAQ Classification"
        id: iaq_nox
        icon: "mdi:checkbox-marked-circle-outline"
        lambda: |-
          if (int(id(nox).state) < 100.0) {
            return {"Great"};
          }
          else if (int(id(nox).state) <= 200.0) {
            return {"Good"};
          }
          else if (int(id(nox).state) <= 300.0) {
            return {"Light"};
          }
          else if (int(id(nox).state) <= 400.0) {
            return {"Moderate"};
          }
          else if (int(id(nox).state) <= 500.0) {
            return {"Heavy"};
          }
          else {
            return {"unknown"};
          }
    
    sensor:
      - platform: scd4x
        co2:
          name: CO2
          id: CO2
          filters:
            - lambda: |-
                float MIN_VALUE = 300.0;
                float MAX_VALUE = 2500.0;
                if (MIN_VALUE <= x && x <= MAX_VALUE) return x;
                else return {};         
        temperature:
          name: CO2 Temperature
          id: CO2_temperature
          filters:
            - lambda: |-
                float MIN_VALUE = -40.0;
                float MAX_VALUE = 100.0;
                if (MIN_VALUE <= x && x <= MAX_VALUE) return x;
                else return {};      
        humidity:
          name: CO2 Humidity
          id: CO2_humidity
          filters:
            - lambda: |-
                float MIN_VALUE = 0.0;
                float MAX_VALUE = 100.0;
                if (MIN_VALUE <= x && x <= MAX_VALUE) return x;
                else return {};      
        altitude_compensation: 0m
        address: 0x62
        update_interval: $sensor_interval
    
      - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
        name: "Wifi Signal dB"
        id: wifi_signal_db
        update_interval: 60s
        entity_category: "diagnostic"
    
      - platform: sen5x
        id: sen55
        pm_1_0:
          name: "PM 1"
          id: PM1_0
          accuracy_decimals: 2
        pm_2_5:
          name: "PM 2.5"
          id: PM2_5
          accuracy_decimals: 2
        pm_4_0:
          name: "PM 4"
          id: PM4_0
          accuracy_decimals: 2
        pm_10_0:
          name: "PM 10"
          id: PM10_0
          accuracy_decimals: 2
        temperature:
          name: "SEN55 Temperature"
          id: sen55_temperature
          accuracy_decimals: 2
        humidity:
          name: "SEN55 Humidity"
          id: sen55_humidity
          accuracy_decimals: 2
        voc:
          name: VOC
          id: voc
          accuracy_decimals: 2
          algorithm_tuning:
            index_offset: 100
            learning_time_offset_hours: 12
            learning_time_gain_hours: 12
            gating_max_duration_minutes: 180
            std_initial: 50
            gain_factor: 230
        nox:
          name: NOX
          id: nox
          accuracy_decimals: 2      
          algorithm_tuning:
            index_offset: 100
            learning_time_offset_hours: 12
            learning_time_gain_hours: 12
            gating_max_duration_minutes: 180
            std_initial: 50
            gain_factor: 230
        temperature_compensation:
          offset: 0
          normalized_offset_slope: 0
          time_constant: 0
        acceleration_mode: low
        store_baseline: true
        address: 0x69
        update_interval: $sensor_interval
    
      - platform: template
        name: Temperature
        id: temperature
        lambda: |-
          return (( id(sen55_temperature).state + id(CO2_temperature).state ) / 2 ) - id(temperature_offset).state;
        unit_of_measurement: "°C"
        icon: "mdi:thermometer"
        device_class: "temperature"
        state_class: "measurement"
        update_interval: $sensor_interval
        accuracy_decimals: 2
    
      - platform: template
        name: Humidity
        id: humidity
        lambda: |-
          return (( id(sen55_humidity).state + id(CO2_humidity).state ) / 2) - id(humidity_offset).state;
        unit_of_measurement: "%"
        icon: "mdi:water-percent"
        device_class: "humidity"
        state_class: "measurement"    
        update_interval: $sensor_interval
        accuracy_decimals: 2
    
    binary_sensor:
      - platform: gpio
        name: Button A
        pin:
          number: GPIO0
          ignore_strapping_warning: true
          mode:
            input: true
          inverted: true
        on_press:
          then:
            - component.update: disp
          
      - platform: gpio
        pin:
          number: GPIO08
          mode:
            input: true
            pullup: true
          inverted: true
        name: Button B
        
      - platform: gpio
        pin:
          number: GPIO46
          ignore_strapping_warning: true
        name: Button Hold
    
      - platform: gpio
        pin: 
          number: GPIO42
        name: Button Power
    
    button:
      - platform: restart
        name: Restart
        
      - platform: template
        name: "CO2 Force Manual Calibration"
        entity_category: "config"
        on_press:
          then:
            - scd4x.perform_forced_calibration:
                value: !lambda 'return id(co2_cal).state;'
    
      - platform: template
        name: "SEN55 Force Manual Clean"
        entity_category: "config"
        on_press:
          then:
            - sen5x.start_fan_autoclean: sen55
    
    number:
      - platform: template
        name: "CO2 Calibration Value"
        optimistic: true
        min_value: 400
        max_value: 1000
        step: 5
        id: co2_cal
        icon: "mdi:molecule-co2"
        entity_category: "config"
    
      - platform: template
        name: Humidity Offset
        id: humidity_offset
        restore_value: true
        initial_value: 0.0
        min_value: -70.0
        max_value: 70.0
        entity_category: "CONFIG"
        unit_of_measurement: "%"
        optimistic: true
        update_interval: never
        step: 0.1
        mode: box
    
      - platform: template
        name: Temperature Offset
        id: temperature_offset
        restore_value: true
        initial_value: 0.0
        min_value: -70.0
        max_value: 70.0
        entity_category: "CONFIG"
        unit_of_measurement: "°C"
        optimistic: true
        update_interval: never
        step: 0.1
        mode: box
    
    display:
      - platform: waveshare_epaper
        model: 1.54inv2
        id: disp
        cs_pin: GPIO04
        dc_pin: GPIO03
        reset_pin: GPIO02
        busy_pin:
          number: GPIO01
          inverted: false
        full_update_every: 6
        reset_duration: 2ms
        update_interval: 10s
        lambda: |-
          auto now = id(esptime).now().strftime("%H:%M %d/%m/%y").c_str();
          it.printf(it.get_width()/2, 0, id(f12), TextAlign::TOP_CENTER, "${location} @ %s", now);
    
          it.print(0, 23, id(f24), TextAlign::TOP_LEFT, "PM 1: "); 
          it.print(0, 48, id(f24), TextAlign::TOP_LEFT, "PM 2.5: "); 
          it.print(0, 73, id(f24), TextAlign::TOP_LEFT, "PM 4: "); 
          it.print(0, 98, id(f24), TextAlign::TOP_LEFT, "PM 10: "); 
          it.print(0, 123, id(f24), TextAlign::TOP_LEFT, "CO2: "); 
          it.print(0, 148, id(f24), TextAlign::TOP_LEFT, "VOC: ");
          it.print(0, 173, id(f24), TextAlign::TOP_LEFT, "NOX: ");
    
          it.printf(it.get_width(), 23, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(PM1_0).state);
          it.printf(it.get_width(), 48, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(PM2_5).state);
          it.printf(it.get_width(), 73, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(PM4_0).state); 
          it.printf(it.get_width(), 98, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(PM10_0).state);
          it.printf(it.get_width(), 123, id(f24), TextAlign::TOP_RIGHT, "%.0fppm", id(CO2).state);
          it.printf(it.get_width(), 148, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(voc).state);
          it.printf(it.get_width(), 173, id(f24), TextAlign::TOP_RIGHT, "%.0f", id(nox).state);
    
    font:
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
        id: f16
        size: 16
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
        id: f18
        size: 18
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f12
        size: 12
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f24
        size: 24
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f36
        size: 36
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f48
        size: 48
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f32
        size: 32
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
    
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 500
        id: f64
        size: 64
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
    
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 800
        id: f64b
        size: 64
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
    
      - file:
          type: gfonts
          family: Noto Sans Display
          weight: 800
        id: f55b
        size: 55
        glyphs: ['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/', 'µ', '³', '’']
    
      - file: 
          type: gfonts
          family: Material Symbols Sharp
          weight: 400
        id: font_weather_icons_xsmall
        size: 20
        glyphs:
          - "\U0000F159" # clear-night
          - "\U0000F15B" # cloudy
          - "\U0000F172" # partlycloudy
          - "\U0000E818" # fog      
          - "\U0000F67F" # hail
          - "\U0000EBDB" # lightning, lightning-rainy
          - "\U0000F61F" # pouring
          - "\U0000F61E" # rainy
          - "\U0000F61C" # snowy
          - "\U0000F61D" # snowy-rainy
          - "\U0000E81A" # sunny
          - "\U0000EFD8" # windy, windy-variant
          - "\U0000F7F3" # exceptional
      - file: 
          type: gfonts
          family: Material Symbols Sharp
          weight: 400
        id: font_weather_icons_small
        size: 32
        glyphs:
          - "\U0000F159" # clear-night
          - "\U0000F15B" # cloudy
          - "\U0000F172" # partlycloudy
          - "\U0000E818" # fog      
          - "\U0000F67F" # hail
          - "\U0000EBDB" # lightning, lightning-rainy
          - "\U0000F61F" # pouring
          - "\U0000F61E" # rainy
          - "\U0000F61C" # snowy
          - "\U0000F61D" # snowy-rainy
          - "\U0000E81A" # sunny
          - "\U0000EFD8" # windy, windy-variant
          - "\U0000F7F3" # exceptional
    
      - file:
          type: gfonts
          family: Open Sans
          weight: 700    
        id: font_clock
        glyphs: "0123456789:"
        size: 70
      - file:
          type: gfonts
          family: Open Sans
          weight: 700    
        id: font_clock_big
        glyphs: "0123456789:"
        size: 100
      - file: "gfonts://Roboto"
        id: font_temp
        size: 28
      - file:
          type: gfonts
          family: Open Sans
          weight: 500    
        id: font_small
        size: 30
        glyphs: "!\"%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz→»"
      - file:
          type: gfonts
          family: Open Sans
          weight: 500    
        id: font_medium
        size: 45
        glyphs: "!\"%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz→»"
      - file:
          type: gfonts
          family: Open Sans
          weight: 300    
        id: font_xsmall
        size: 16  
        glyphs: "!\"%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz→»"
    
    
    
        

     

    6. Important: This code does not include the credentials for connecting the device to your Wi-Fi and Home Assistant instance, so you will need to enter them manually. Specifically, I am referring to the following lines of code that you copied in step 4.

    # Enable Home Assistant API
    api:
      encryption:
        key: "bg6hash6sjdjsdjk02hh0qnQeYVwm123vdfKE8BP5"
    
    ota:
      - platform: esphome
        password: "asddasda27aab65a48484502b332f"
    
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Assist Fallback Hotspot"
        password: "ZsasdasdHGP2234"
    
    
    
        

     

    7. What you need to do is find the corresponding lines in the code (at the beginning) and add the necessary information.

    8. Now, click “Save” and “Install.” Select “Manual download” and wait for the code to compile.

    9. When finished, select the “Modern format” option to download the corresponding .bin” file.

    10. Connect the M5Stack Air Quality Kit to your computer using the USB-C data cable via the port on the bottom.

    11. Now go to the ESPHome page   and click "Connect." In the pop-up window, select your board and click "Connect."

    12. Now click on “Install” and select the '.bin' file obtained in step 9. Again, click on “Install”.

    13. Go back to Home Assistant and navigate to Settings > Devices & Services. Your device should be discovered and appear at the top, ready for you to click the “Configure” button. If not, click the “Add Integration” button, search for "ESPHome," and enter your board’s IP address in the "Host" field.

    Device information

    If you navigate to Settings > Devices & Services > ESPHome and select the M5Stack Air Quality Kit, you'll find several entities providing information about air quality.

    Additionally, the buttons on the device's top-left corner have also been exposed as entities. This means you can create an automation to trigger an action when you press them, such as activating your ventilation system.

    To set this up, go to Settings > Automations and Scenes > Create Automation. In the "When" section, add a "State" trigger. In the entity field, select the one corresponding to your device (e.g., 'binary_sensor.airq_button_a'), and in the "To" field, choose "On." Then, simply add the desired actions.

    Source: AguacaTEC
    Author: TitoTB

    2025-03-31

    On November 18, 2024, M5Stack opened its doors to individual visitors for the first time. More than 70 visitors from all around the world attended the event, with some showcasing their projects built with M5 products or sharing their stories with M5Stack.

    M5Stack Open Day 2024

    The event began at 3:00 PM, with many visitors checking in and receiving their gifts—custom T-shirts featuring the M5Stack logo. After a group photo, the first agenda kicked off: The Factory and Office Tour.

    M5Stack Factory and Office Tour

    The visitors were divided into three groups, with introductions provided in Chinese, English, and Japanese. M5Stack operates an all-in-one facility where product design, production, packaging, quality control, marketing, and shipping are seamlessly managed under one place. Visitors could take a close look at the whole flow.

    Factory of M5Stack

    In the show board area, we display all the products we've created so far, including the classic 5x5 stack series—such as M5Basic Core, M5Core2, M5Core3, and Stick series—like the M5StickC, along with the Stamp Series (M5Cardputer, M5StampFly), and the Atom series (M5Atom Echo), among others. M5Stack’s CEO, Jimmy Lai, also explains "What is M5Stack?"

    M5Stack product show board

    M5Stack is an open-source hardware IoT solution provider, primarily focused on products built around the ESP32. We also offer a range of accessories and our own visual programming platform, UIFlow. The "M" in M5Stack stands for Module, "5" represents the 5x5 cm size, and "Stack" refers to their stackable design. 

    M5Stack is committed to delivering convenient, stackable and easy-to-use development components and tools, with at least one new product every Friday, we launch over 50 new products every year. We provide not only standard products, also customized products. Our partner includes Amazon, Microsoft, Arduino, SONY, etc.

    Projects or Stories with M5Stack

    After the tour, it’s time for the Meetup. This year, we have 9 speakers. Jimmy began by sharing the company’s history, followed by presentations from the speakers. TAKASU Masakazu shared the success stories of M5Stack in Japan, where the Japanese market accounts for 35% of M5Stack’s global sales. Many companies and schools in Japan use M5Stack products, and you can even find books on how to use M5Stack products on Amazon. 

    TAKASU Masakazu share the M5Stack's successful story in Japan

    Other speakers introduced their innovative projects, including the Creative Dot Matrix Clock, the M5Unified Library, M5Cuffbox, and the Blue Tears Incubator, how to make stack-chan bigger, etc.

    speaker shows his 3 projects using M5stack's product

    It was a truly enjoyable experience to come together with M5Stack fans from all over. We appreciate everyone’s enthusiasm and participation, and we’re already looking forward to welcoming you again next year. See you then!

    M5Stack Open Day 2024

    2024-11-28

    Time flies, and 2023 has come to an end. M5Stack's products and services have accompanied users worldwide throughout the year. 2023 was a year of continuous innovation for M5Stack, with 76 new products released at a rate of one per week. As we set sail for 2024, let's look back at the brilliance of the past year and unveil the top 10 best-selling products of 2023!

     1. ATOM LITE

    Once again, Atom Lite tops this year's list of best-selling products, following on from last year's success. Launched in 2020, Atom Lite's outstanding features and enduring vitality have won over a wide range of users worldwide.

    Atom Lite user case @Peter Neufeld

    Atom Lite is a compact development board, measuring only 24 * 24mm, which provides more GPIO pins for users to customize freely. It is particularly suitable for embedded smart hardware development.

    This development board uses the ESP32-PICO-D4 solution as the main controller, integrating Wi-Fi module and built-in 3D antenna. It has 4MB of SPI flash memory, as well as Infra-Red (IR) infrared, RGB LED, buttons, and GROVE/HY2.0 interfaces. Additionally, the onboard Type-C interface enables fast program uploading and downloading, and there is an M2 screw hole on the back for fixation.

    2. ATOM ECHO

    Also released in 2020, Atom Echo has undoubtedly become a dark horse product this year. In 2023, with the power of Home Assistant and ChatGPT, the Atom Echo has sold out again and again. The ability to connect to ChatGPT, act as a personal voice assistant with customisable wake words, and do it all for just $13 makes it a must-have smart home device.

    Atom Echo voice assistant use case @Home Assistant

    Atom Echo is a programmable smart speaker. Despite its small size of only 24 * 24 * 17mm, it boasts impressive functionality. With the built-in wireless capabilities of the ESP32, it can easily connect to devices such as smartphones and tablets for seamless music playback. It can also stream specified media music via Wi-Fi.

    To facilitate voice functionality, Atom Echo integrates an STT (Speech-to-Text) service internally. Users only need to burn specified firmware to enable this feature and perform various operations through voice commands. Users can also write code to integrate Atom Echo with cloud platforms like AWS and Google, utilizing the built-in microphone and speaker for voice interaction, enabling certain AI capabilities, such as voice control, intelligent conversations, and IoT functionalities.

    The speaker has a built-in RGB LED (SK6812) that visually displays the connection status. In addition to being used as a smart speaker, it still retains the control capabilities of the ATOM series and can be connected to external devices via the GROVE interface. The M2 screw hole on the back facilitates secure installation.

    3. M5STICKC PLUS

    M5StickC Plus is a powerful, portable and expandable development board. Since its release in 2020, it has consistently been at the top of various best-seller lists. At the end of 2022, we welcomed M5StickC Plus2 and officially said goodbye to M5StickC Plus.

    M5StickC Plus is a powerful microcontroller module that is compact and easy to carry. Despite its small size, M5StickC Plus integrates rich hardware resources, including infrared, RTC, microphone, LED, IMU, buttons, buzzers, and PMU.

    M5StickC Plus is equipped with the ESP32-PICO-D4 processor, providing powerful computing and communication capabilities. It features a 1.14-inch color TFT display that can show images, text, and user interfaces, offering a good interactive experience. Additionally, M5StickC Plus has a built-in battery for standalone use, eliminating the need for an external power source.

    The module is equipped with various sensors, including an accelerometer, gyroscope, and magnetometer, enabling it to sense and measure object motion and environmental conditions. It also has Wi-Fi and Bluetooth connectivity, allowing data transmission and remote control with other devices. The interface supports HAT and Unit series products. This compact and exquisite development tool inspires endless creative possibilities.

    4. M5CORE2

    M5Core2 is the second-generation host of the M5Stack Core series, featuring an ESP32 chip and a touchscreen. It is known for its easy stacking, expandability, and rapid development capabilities. Since its release in 2020, Core2 has consistently been a hot seller in both domestic and international markets, loved by a large number of users. Amazon Web Services (AWS) and M5Stack have collaborated to launch Core2 for AWS. Now, we have the Core2 V1.1 version.

    M5Core2 is a versatile development kit with a 2-inch IPS touchscreen display. It is built around the ESP32 microcontroller, which provides Wi-Fi and Bluetooth connectivity. The Core2 module offers a variety of built-in features, including an accelerometer, gyroscope, magnetometer, speaker, microphone, and more.

    The development kit supports UIFlow, a graphical programming interface, as well as Arduino and MicroPython. This allows users to choose their preferred programming language and easily develop applications. The modular design of M5Core2 enables stacking of additional modules, called Units, on top of the base module, expanding its capabilities and creating custom projects.

    M5Core2 also includes a built-in 390mAh battery, enabling portable and standalone use. It has a USB Type-C interface for charging and programming, as well as an SD card slot for extended storage.

    5. ULTRASONIC I2C Unit

    Ultrasonic I2C Unit is an ultrasonic ranging sensor with an I2C communication interface. The hardware features the RCWL-9620 ultrasonic ranging chip paired with a 16mm probe, enabling precise ranging within a range of 2cm to 450cm (with an accuracy of ±2%). As an I2C slave device, the sensor can share the bus resources with other I2C devices, allowing for efficient use of IO pins. It is ideal for applications such as obstacle avoidance in robots and liquid-level detection.

     

    6. ENVIII Unit

    ENV III is an environmental sensor that integrates the SHT30 and QMP6988 sensors, used for detecting temperature, humidity, and atmospheric pressure data. The SHT30 is a high-precision, low-power digital temperature and humidity sensor that supports the I2C interface (SHT30: 0x44, QMP6988: 0x70). The QMP6988 is an absolute pressure sensor designed for mobile applications, known for its high accuracy and stability, making it suitable for environmental data collection and monitoring projects.

     

    7. AtomS3

    AtomS3 is a highly integrated programmable controller based on the ESP32-S3 main controller. It features an ESP32-S3 main controller with built-in Wi-Fi capability and an 8M onboard flash memory. The controller also includes a 0.85-inch IPS screen with programmable buttons below it. Additionally, it is equipped with a 5V to 3.3V circuit, a 6-axis gyroscope sensor (MPU6886), an onboard Type-C interface (for power and firmware download), an HY2.0-4P expansion port, and six GPIO pins and power pins reserved at the bottom for easy expansion of various applications.

    With a product size of only 24x24x13mm, the AtomS3 is perfect for various embedded smart device applications. It provides powerful functionality and flexible expandability, making it suitable for developing a wide range of embedded systems and smart devices.

    8. PIR Motion Unit

    PIR Motion Unit is a human infrared sensor unit. It belongs to the "passive infrared detector" category and works by detecting the infrared radiation emitted or reflected by humans or objects. When infrared radiation is detected, it outputs a high-level signal and maintains a delay for a certain period (keeping the signal high and allowing for repeated triggering) until the trigger signal disappears (returns to a low level). The PIR Motion Unit is suitable for various applications that require detecting human activity and motion, including security, automation, energy management, and people counting.

    9. BASIC V2.7

    Basic is the first-generation host of M5Stack, offering high cost-effectiveness and a rich collection of case resources. Through continuous optimization and development, it has now iterated to the V2.7 version.

    Basic V2.7 features a 2.0-inch color TFT LCD screen with a resolution of 320x240, which can display graphical interfaces and text information. It is also equipped with three programmable buttons, a programmable touchscreen, a speaker, and a set of expansion pins to support the connection and expansion of various peripheral devices.

    This development board uses the ESP32 Internet of Things chip, integrates Wi-Fi capability, and has 16MB of SPI flash memory. As a low-power dual-core processor, it performs exceptionally well in various application scenarios.

    10. ATOM U

    ATOM U is a compact and flexible Internet of Things voice recognition development board. It uses the Espressif ESP32 main control chip with two low-power Xtensa® 32-bit LX6 microprocessors, operating at a high frequency of up to 240MHz. ATOM U integrates USB-A interface, IR emitter, and programmable LED lights, allowing for plug-and-play convenience for program uploading, downloading, and debugging. It also includes a Wi-Fi module and a built-in digital microphone (SPM1423 PDM) for clear audio recording, making it suitable for various IoT human-machine interaction and speech-to-text (STT) input recognition scenarios.

    ATOM U supports low-code development and provides features such as UIFlow graphical programming platform, script programming, no-compilation execution, and cloud pushing. It is fully compatible with mainstream development platforms such as Arduino and ESP32-IDF.

    ATOM U has a high level of integration, including USB-A programming/power interface, IR emitter, programmable RGB light, and buttons. The professionally tuned RF circuit ensures stable and reliable wireless communication quality.

    M5Stack's success is inextricably linked to our community's support, and we thank you for it. We wish you a Happy New Year! We will continue to provide more and better services to meet your needs in the coming year.

    2024-01-03

     The Build2gether Inclusive Innovation Challenge, hosted by Europe's top university ETH Zurich and organised by the world-renowned hardware community Hackster.io, recently concluded. The competition, in collaboration with partners M5Stack, Google, Blues, PCBWay and Useful Sensors, offered a total prize pool of $40,000.

    This global competition aimed to encourage people to use innovative technology to help individuals with physical disabilities overcome challenges in their daily lives and build a more inclusive and equitable future. The competition received a total of 194 submissions, with many participants choosing M5Stack products. In this blog post, we have selected some of the award-winning projects to explore the development stories behind them!

     1.Haptic Vision Assist

    This project uses M5Stack's controllers and sensors to provide simple, cost-effective and efficient obstacle warnings using infrared laser and haptic technology to visually impaired users to aid their mobility.

    The author, Colonel Panic, witnessed the daily challenges faced by visually impaired people while living with his fiancée and her son, both of whom have inherited Retinitis Pigmentosa, a genetic eye disease. Motivated to help improve the lives of visually impaired people, Colonel Panic learned to use M5Stack products and UIFlow within a year. To quickly become proficient in the use of M5Stack, he challenged himself to create a prototype for a new idea every day.

    Project link: https://www.hackster.io/colonelpanic/haptic-vision-assist-ac670f

     

    2. Wall Early Warning System for Swimming Laps

    This project uses Bluetooth beacon technology to warn visually impaired users when approaching the pool wall, preventing accidental collisions due to poor visibility while swimming.

    Have you ever hit a wall while swimming? What about doing the backstroke? Ouch! Now imagine having poor eyesight; everything becomes even more challenging! Inspired by personal experience and discussions with disabled mentors after joining a competitive group, author David Barrett came up with the idea for this project.

    Project link: https://www.hackster.io/3DPrinterDoctor/wall-early-warning-system-for-swimming-laps-4ba356

     3.Intercom and Smart Controller Mounted on Wheelchair and Roll

    This project allows people who use wheelchairs or walkers to receive real-time doorbell notifications via Telegram, see who is at the door, and remotely control door access.

    Imagine hearing the doorbell ring and feeling nervous. You might even rush to open the door. These actions may seem simple for able-bodied people, but they are inconvenient for people who use wheelchairs. This project effectively addresses this pain point.

    Project link:

    https://www.hackster.io/ecasti/intercom-and-smart-controller-mounted-on-wheelchair-and-roll-9a4691

     4. Motion Controller for People with Limited Arm Function

    This project focuses on developing a motion controller for gaming purposes specifically designed for individuals with limited arm function due to conditions such as muscular dystrophy. For PC gamers, the mouse is a crucial peripheral device. However, mice require a flat surface to function properly and demand users to sit in front of a desk, constantly extending their arms, which can be challenging for some individuals with disabilities.

    Therefore, Yahya Khalid created a simple controller using the compact AtomS3, which can effectively replace a mouse. With this device, users can adjust sensitivity to meet their specific needs, and hand position or orientation is not limited, accommodating individuals with restricted hand movements.

    Project link: https://www.hackster.io/yahya-khalid/motion-controller-for-people-with-limited-arm-function-4e15d3

     5. Cracked road detection for better travel

    This project can help people who use wheelchairs to be aware of road potholes in advance to avoid accidental falls while travelling.

    One of the challenges faced by wheelchair users is encountering cracked roads, where if the user is not concentrating, they could fall into a pothole and potentially injure themselves. Hendra Kusumah aims to create a solution that is easy to build and program, requires no soldering, and costs less than $50.

    Project link:

    https://www.hackster.io/hendra/cracked-road-detection-for-better-travel-e00340

    6. Cheza Pona

    This project is an innovative gaming platform that redefines inclusive skill development, specifically designed for people with disabilities such as cerebral palsy and muscular dystrophy. Cheza Pona provides dynamic and adaptive gaming experiences.

    According to a 2017 study by the World Health Organization, only 1 in 10 people with disabilities in low-income countries have access to the assistive technology they need. In response to this challenge, Ryan Kiprotich and Mergery Wanjiru proposed a solution called Cheza Pona, which means "play better" in Swahili. They transformed the typically monotonous physical therapy into an enjoyable gaming experience. Using the low-cost M5StickC, they created a game where players can use the built-in inertial measurement unit sensor to move sideways and avoid blocks in the game to score points.

    Project link: https://www.hackster.io/512307/cheza-pona-2d0c47

    7. Move-It!

    This project turns M5StickC int to an IMU-based gaming device - a small wearable device whose movement can provide input to games.

    The project was mainly aimed at developing something small which can help people with Muscular Dystrophy play games without over-exerting and tiring out faster. I won the M5Stack Gift card and ordered the M5StickC and a mini dual button unit. The idea was to use IMU input from the M5StickC as serial data and process it as keyboard input.

    Project link: https://www.hackster.io/nvraghavendra2000/move-it-2371ed

     

    2023-12-26

    Modular IoT system construction offers high flexibility and scalability as the developers can quickly build prototype systems using existing modules to save time in design and development. It assists developers in swiftly developing and validating their concepts and works directly from idea to product, allowing developers to create various types of devices and solutions more quickly and economically.

    M5Stack’s products have a stackable design, providing standardized interfaces for easy construction of the system, when combined with the intuitive visual programming interface of UIFlow, it significantly reduces the technical barriers of system design and development. Even developers with limited hardware and software knowledge can quickly build powerful IoT devices.

    Setting up the UIFlow Environment

    Taking the MStack Basic as an example, the first step is to refer to the UIFlow firmware burning tutorial and download M5Burner to burn the UIFlow firmware to the controller.

    Building an IoT System

    If we need to detect air quality. We can stack the PM2.5 Air Quality Module  to the MStack Basic.

    Then, in UIFlow, click on "PM2.5" and select "Load Examples" to open the sample code.

    Click "Run," and we will see the air quality displayed on the screen.

    When we want to drive a stepper motor to actuate certain mechanisms when the PM2.5 concentration is high. We can stack the GRBL  Module.

     

    Next, find the code blocks corresponding to the GRBL module in UIFlow.

    Set the motor drive mode at the beginning of the code, here we set it to distance mode.

    In the main loop of the program, add a condition based on the PM2.5 concentration, using the value stored in SP for simplicity. When the concentration exceeds 55 (μg/m³), the stepper motor starts rotating. When it falls below 55, the stepper motor stops rotating.

    Click "Run," and the system will operate as we set.

    Conclusion

    In summary, the stackable modular design provides a flexible, efficient, and scalable approach to IoT system development. When combined with the visual and user-friendly programming environment of UIFlow, it makes system construction easier, reduces development costs and risks, and facilitates rapid prototyping and feature expansion.

    2023-12-14

    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();

            }

        }

    }

    2023-11-24

    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.

     

    2023-10-26