CC Blog • Projects • Research & Design Hub

Another Matter-Enabled MCU: the ESP32-C6

Written by Brian Millier

The list of MCUs that support the Matter protocol continues to get longer. In this column, Brian goes in-depth on one of the newer Matter-enabled MCUs and shows just how it compares to some of the alternatives now on the market.

  • How does the ESP32-C6 compare to other Matter-enabled MCU platforms?
  • What is required to use Matter with the ESP32-C6 in the Arduino IDE?
  • How does the Matter commissioning process work with Amazon Alexa?
  • How can a Bosch BMA400 accelerometer be used in a Matter-based car alarm?
  • What power consumption and battery life can be achieved with an ESP32-C6 Matter device?
  • ESP32-C6
  • Matter
  • Thread
  • Wi-Fi
  • Bluetooth Low Energy (BLE)
  • Zigbee
  • Arduino IDE
  • Amazon Alexa
  • DFRobot DFR1117
  • Seeed Studio XIAO ESP32-C6
  • ESP32-C6-DEVKITC-1
  • Bosch BMA400
  • I2C
  • Qwiic
  • LiPo Battery
  • Deep Sleep Mode
  • GPIO Wake-up
  • ContactSensor Endpoint
  • OccupancySensor Endpoint
  • Motion Detection
  • Espressif | espressif.com
  • DFRobot | dfrobot.com
  • Seeed Studio | seeedstudio.com
  • SparkFun | sparkfun.com
  • Amazon | amazon.com
  • Bosch Sensortec | bosch-sensortec.com
  • Arduino | arduino.cc
  • Silicon Labs | silabs.com

In my Circuit Cellar #418 article, I introduced the Arduino Nano Matter board, as well as the Sparkfun Thing Plus Matter board. Both boards used the Silicon Labs MG24 MCU, which handles BLE and the Matter RF protocol. Just as important to me as the Matter-enabled MCUs themselves was the fact that both boards had Matter support libraries for the Arduino toolchain. I designed a working project with the Sparkfun Thing Plus board, which I also described in that article.

The MG24-based Arduino Nano Matter and Sparkfun Thing Plus Matter boards worked just fine but there were a few downsides:

  • These boards are somewhat expensive, particularly the Sparkfun model.
  • Another MG24-based board, now available, is the Seeed Studio XIAO-MG24 board. This is much lower in price and is tiny compared to the other two. Using its on-board chip antenna, I found its range to be quite limited. It also contains a u-FL micro jack for an external antenna, as well as a programmable RF switch to select between the two. Even using an external patch antenna, I found its RF range to be quite limited.
  • While the Arduino Matter library, included with the Silicon Labs MG24 board support package, has since been updated (V3.0.0), the initial versions of this library didn’t work well in my initial testing.

Since writing that article, I’ve discovered another common MCU that can handle the Matter protocol. One of the newer Espressif ESP32 MCUs is the ESP32-C6. This MCU handles Wi-Fi, BLE, Zigbee and Thread protocols. I had purchased some ESP32C6 boards a while back—primarily due to their low cost and small size. I was aware that they handled the Zigbee and Matter RF protocols, but at the time, these features were only available if you used Espressif’s custom IDF as your programming toolchain.

I don’t have any expertise with this IDF, but from past experience, I knew that many features first introduced in the Espressif IDF, were generally ported to the Arduino IDE quite quickly. Happily, I recently discovered that Matter support for the ESP32-C6 was now available for the Arduino IDE. I admit to a bias towards the ESP32 MCU family as they have a wealth of libraries available and have proven to be very capable RF-enabled MCUs in many of my past projects.

In this article, I’ll provide more details of the ESP32-C6 MCU and describe the first Matter-enabled project I made using it.

A Matter-enabled Car Alarm

While it’s easy to build a small device that can detect very small motions of the car, what do you do with that alarm signal? The first thing that comes to mind is a loud alarm siren, as that is what is used by many car theft alarms. However, if you are detecting a very small amount of motion in the car, as would happen if someone was trying to steal your catalytic converter, there are bound to be some false alarms occasionally, due to high winds, quick temperature changes, and more.

This project was designed strictly for use when the car is parked at home. In that situation, my car is close enough to my house that a DFR1117 module, containing an ESP32-C6 MCU, can easily communicate with my Amazon Echo smart speakers. This gives it access to the Alexa smart home control functions. This eliminates the need for a dedicated “hub” device in the home, to listen for any alarm signals from either a car alarm, or any other alarms that I might design (water leak, window/door contact switches, etc.)

Such an alarm trigger message can be programmed in the Routines section of the Alexa app, to perform many different functions. A few such routines that I thought useful were:

  • Send a notification to my cellphone and iPad tablet.
  • Make a custom, meaningful voice announcement on one or all my Echo devices.
  • Turn on a “smart” light bulb or other “smart” electrical device.
  • I don’t use social media, but I suspect that Alexa routines can generate social media posts as well.

To implement Alexa triggers, the process is somewhat complicated. To start with, Amazon has wisely decided that it would not let its Echo devices respond directly to incoming messages from any random device connected to your Wi-Fi network. You can easily see that this could lead to bad outcomes—particularly if outside acters managed to gain access to your home Wi-Fi network.

In the past, the only way that I knew to generate Alexa triggers was to send the trigger message to the Amazon Alexa “cloud” server directly. For this message to be properly routed to your specific Echo device(s), the trigger message must include a “key” of some sort, to tell the server which specific Echo device(s) to send the trigger message to. To generate this key, your Amazon account information must be provided- preventing outside actors from being able to access your Echo devices maliciously.

Also, the Amazon “cloud” server must authenticate the source of this incoming trigger message—not just the validity of the message itself. In other words, the device sending the trigger message must be able to complete an authentication routine using credentials recognized in advance by Amazon.

In an earlier Circuit Cellar article, (issue 414) I described a water leak detector using an ESP32 MCU. To allow this circuit to access the Echo smart speaker, I used the mkZense cloud service. This service provides a “webhook” which, when accessed by the leak detector’s ESP32, sends a trigger signal to my Echo smart speaker. Upon receipt of that trigger, the Echo will execute a Routine, which alerts me to the condition using an announcement and notification message to my phone. More details of this arrangement can be found in that column.

However, since I wrote that article, Arduino introduced the Nano Matter board which can handle the Matter protocol. The MCU used on this board is the Silicon Labs MG24, which can handle the Thread RF protocol used by Matter. Soon thereafter, Sparkfun started selling their “Thing Plus Matter” board and Seeed Studios introduced the tiny XIAO-MG24 module. My article in Circuit Cellar issue 418 covered both the Arduino and Sparkfun boards in detail.

Once you have an MCU that can handle the Matter protocol, it’s possible to design many different IoT devices that can interact directly with Amazon Echo smart speakers or hubs, which contain a Matter controller. It’s best to refer to Amazon’s webpage to determine if a given Amazon speaker/hub is Matter-enabled.

In the Matter framework library, these different devices are referred to as “Endpoints”. Among the endpoints available are some that provide “triggers”: contact switches, occupancy detectors, motion detectors etc. Therefore, unlike the water leak alarm project that I described in my article in issue 414, there is no longer a need for a third-party cloud service like mkZense.

Some ESP32-C6 modules

The following are three ESP32-C6 modules that I have personally purchased and used in projects:

  • Espressif’s own offering is a full-sized module- the ESP32-C6-DEVKITC-1N8. This looks identical to their earlier ESP32-S3-DEVKITC modules in that they both contain two USB-C ports -one for Flash programming/debugging (via a CP2102 bridge chip) and the other for general USB port use. See Figure 1.
  • DF Robot’s DFR-1117 board is much smaller than the above module and uses a USB-C socket to connect to the ESP32-C6’s native USB port (no USB-Serial bridge chip is needed). It contains LiPo battery capability, including a charger and the battery pins are included as part of the 8-pin header connectors. See Figure 2.
  • Seeed Studio’s XIAO-ESP32-C6 module. This is even smaller than the DFR-1117 module and also contains LiPo capability, including charging. To achieve this smaller size, they chose to implement the battery connections as small pads on the underside of the module which is a bit of a nuisance, unless you are socketing the module. It contains a tiny chip antenna, a U-FL socket and an electronic RF switch to select between the two antennas. The BOOT select and RST switches extremely tiny- see if you can pick them out in Figure 3.
Figure 1
This is Espressif’s ESP32-C6 development board. It contains a programming USB-C port as well as a Host USB port.
Figure 1
This is Espressif’s ESP32-C6 development board. It contains a programming USB-C port as well as a Host USB port.
Figure 2
This is the DF Robot ESP32-C6 board. This is the board I used for the example project I did for the article.
Figure 2
This is the DF Robot ESP32-C6 board. This is the board I used for the example project I did for the article.
Figure 3
The Seeed Studio Xiao-ESP32C6 board is even smaller than the DF Robot board but it does not provide easy access to battery pins and its RST and Boot switches are extremely tiny. They are barely visible on either side of the USB-C socket.
Figure 3
The Seeed Studio Xiao-ESP32C6 board is even smaller than the DF Robot board but it does not provide easy access to battery pins and its RST and Boot switches are extremely tiny. They are barely visible on either side of the USB-C socket.

The Matter-based projects that I am doing are LiPo battery-powered and basically depend upon the ESP32C6 being in a deep-sleep mode most of the time. Both the DF Robot and the Seeed Studio modules are ideal since they contain almost no current-drawing circuitry, apart from the ESP32-C6 itself. Also, the number of GPIO pins I needed were minimal- just an I2C port and/or 1-2 GPIO pins to wake up the ESP32-C6 when a trigger condition existed. Both the DF Robot and the Seeed modules had at least 10 GPIO pins available on the 0.1” header connectors. Both the DF Robot and Seeed Studio ESP32-C6 modules cost around $5 USD.

The ESP32 Matter support framework for Arduino

To compile any programs for the ESP32-C6, you must be using the Arduino 2.x.x IDE—I use 2.3.6, the latest. Then, using the Boards Manager, install “ESP32 by Espressif” version 3.3.0 (or newer). After that, you need to select the proper board. The Espressif ESP32-C6-DEVKITC is labelled “ESP32C6 DEV module. The DF Robot DFR-1117 is labelled “DF Robot Beetle ESP32C6”. Seeed Studio’s XIAO-ESP32-C6 is labelled “XIAO_ESP32C6”.

The Espressif ESP32-C6-DEVKITC module has all its GPIO pinouts labelled using the Espressif GPIOxx convention. This board uses a CP2102 USB-UART bridge chip. Therefore, if you are using this module, picking the proper board in the Tools menu, as described above, will allow the device to be flashed automatically (no buttons need to be pressed in advance). It will also allow you to use Espressif GPIO pin #s directly in your Arduino sketch.

The DFR-1117 also uses the Espressif GPIOxx convention. It does NOT however contain a USB-UART bridge device. What this means is that, in the Tools menu, you must set “USB-CDC on Boot” to Enabled. I don’t recall what, if any program was loaded into my modules, from the factory, or whether this option is enabled by default from the factory.

However, if you do flash your first program and leave this parameter in the default “Disabled” mode, you won’t be able to do any further flashing unless you first place the ESP32-C6 into download mode manually. This is done by holding the BOOT button down while you press/release the RST button. You won’t see any Serial.println() messages either until CDC is enabled.

The Xiao-ESP32-C6 doesn’t contain a USB-UART bridge either. Therefore, the considerations described above, also apply. However, the Xiao BOOT (B) and RST (R) buttons are very tiny! I must use a small non-conductive rod to actually press these buttons, as my fingers won’t work. So, it’s wise to not forget to set the “USB-CDC on Boot” to Enabled, right from the start. Doing so will allow you to program the device automatically- with no need to press these tiny buttons.

The XIAO-ESP32-C6 labels its GPIO pins using the original Arduino M328 board conventions: D0-D10 and A0-A2. If you have selected the proper board in the Tools menu, the board support package for the XIAO-ESP32-C6 will allow you to use these Arduino port names in your sketch. However, in the Getting Started section of the product Wiki for this module, Seeed has provided a diagram which shows both the Arduino port names and the Espressif GPIOxx names, for all the available GPIO pins.

I tend to stick to the Espressif GPIOxx port names, but when using libraries, and their associated examples, you may run across the Arduino port names being used.

When writing a sketch that is Matter-enabled, you must place #include <Matter.h> at the beginning of the sketch. This incorporates the Matter framework into your sketch, but it also makes your sketch very large in terms of flash memory used. The default ESP32 partition “4 MB with spiffs (1.2 MB APP, 1.5 SPIFFS)” won’t cut it for Matter-enabled projects. You will get a rather cryptic message stating that the text space in your sketch won’t fit into memory. So, you’ll have to select the Huge APP (3 MB APP no OTA 1MB SPIFFS) in the Partition Scheme option of the Tools menu.

Unlike the Arduino/Sparkfun Silicon Labs MG24 board support package, you don’t have to select a framework in the Tools menu (BLE or Matter in either Silicon Labs or Arduino versions). Just adding the include <matter.h> is all that is necessary, in this regard.

Once your Arduino IDE is set up as described above, and you have selected the appropriate ESP32-C6 MCU, if you navigate to File → Examples → Examples for <your ESP32C6 board> → Matter, you will find examples of many Matter-enabled IoT devices that you can build with the ESP32-C6 MCU. In Table 1, I show all these devices, properly termed “endpoints” in Matter jargon.

Table 1
These are the Matter endpoints supported by the Arduino Matter framework for the ESP32C6 MCU. Those marked with a “*” provide “trigger” inputs to the Matter host controller.
Table 1
These are the Matter endpoints supported by the Arduino Matter framework for the ESP32C6 MCU. Those marked with a “*” provide “trigger” inputs to the Matter host controller.

Like Matter-based projects using the Arduino Silicon Labs MG24 framework, when using an ESP32-C6, the device you are implementing must first go through a commissioning process. The first time your Matter sketch is run, it will check the contents of a specific structure found in the ESP32-C6’s flash memory. The flash partition used for this structure is not a part of the program partition. Therefore, it will not get erased when a sketch is being uploaded to the ESP32-C6. Until the ESP32-C6 has been commissioned by a Matter hub/controller, such as my Alexa Echo smart speaker, this structure will be empty. The example sketches will realize this and do the following:

  • Send out a message via the serial port stating the above and giving both an identification number and a website containing a QR code (which includes basically the same information)
  • Enter a routine that sends out a BLE message to a Matter controller within BLE range, establishing a connection through which the Matter controller can exchange all necessary authentication certificates, keys, etc.

After the commissioning procedure has been performed, in my case using the Amazon Alexa app on my phone/tablet, all necessary certification credentials and keys will be stored in the ESP32-C6’s flash memory structure. The next time the ESP32-C6 is booted up, it will recognize that it has been commissioned by examining this structure in the flash partition and will attempt to establish a connection to the Matter hub/controller that commissioned it. The detailed procedure to commission a Matter IOT device, with an Amazon Alexa smart home system, is described in my article in issue #418.

If you are experimenting with demos for various Matter-based IoT devices, you should note the following:

  • If you are modifying an example sketch, you don’t have to de-commission/re-commission the ESP32-C6 whenever you make changes to the sketch.
  • If you are using a specific ESP32-C6 and wish to change the type of endpoint that is being used in your sketch, you should de-commission/recommission the ESP32-C6 when you make that change.

The Matter implementation on the Arduino Silicon Labs MG24 devices allowed you to de-commission the Silicon Labs MG24 MCU using the “Burn Bootloader” command in the Arduino Tools menu. There was also a specific de-commissioning function which you could call to do this. However, I found it easier to use the Burn Bootloader command, personally.

In the case of the ESP32-C6’s Matter framework, the Burn Bootloader command does not de-commission the ESP32-C6. In the Matter examples supplied with the ESP32-C6 Matter framework, de-commissioning is done by pressing the Boot button for five or more seconds while the demo sketch is executing. This calls the matter.decommission()routine and re-boots the ESP32-C6 when finished.

You might be interested to know that the ID# that is provided by the ESP32-C6 Matter-based example sketch(es), for commissioning purposes, is 34970112332. I first assumed this was some unique ID#, like the UUID#s that are used to identify Bluetooth devices. This is not the case- several of my Arduino Nano Matter modules, a Sparkfun Thing Plus module, and the ESP32-C6 module all present you with the same ID#. Therefore it’s not associated with some unique number stored in Flash or write-only memory within a specific MCU (although these MCUs do contain such unique ID numbers). Instead, it is some “catch-all” number assigned by the Matter control association, for “unknown vendors”. On occasions, I saw this designation pop up during the commissioning process.

Using the ESP32-C6 Matter framework is quite straightforward. You pick out an endpoint type from those shown in Table 1. In this column I am focusing on various alarm devices, and can use endpoints like:

  • ContactSensor
  • Occupancy Sensor
  • Motion Sensor

In your sketch you first need to initialize the endpoint- for example:

ContactSensor.begin();

followed by:

Matter.begin();

After that, your sketch needs to monitor some condition that you are interested in reporting to the Matter hub. Whenever that condition happens, you issue a :

ContactSensor.setContact(true);

This will send a “contact closed” message to the Matter hub/controller that you used to commission your ESP32C6 device. It will be associated with the specific device that you defined during commissioning, using that Matter hub/controller. In my case, the Matter hub/controller is an Alexa smart speaker and I set up devices on that controller using the Alexa app on my Android cellphone or my Apple iPad.

The ContactSensor endpoint has one other function:

ContactSensor.getContact();

Which returns a Boolean variable corresponding to the state of the contact sensor variable currently stored in the Matter hub/controller. In my sketches, I use this function to read back the state of the contact sensor variable currently held by my Alexa smart speaker/Matter controller. That way, I can be sure that the message sent by the ESP32C6 has gotten through to the Alexa controller/hub. It’s possible that such a verification is performed by the setContact() routine itself, but I found no documentation to confirm this.

— ADVERTISMENT—

—Advertise Here—

The ContactSensor endpoint is a latched value within the Matter hub/controller. That is, once your device sends the setContact(true) message, the Matter hub/controller will stay in the closed state forever- or until it receives a setContact(false) message.

Therefore, when programming your alarm device, you should send a setContact(false)when the unit is powered up, and probably also send one a short time after any alarm condition, to “re-arm” the Matter hub/controller for any subsequent alarm messages.

If you are interested in using any of the other endpoints shown in Table 1, you may wonder what routines are available for that specific endpoint, since they may differ from the two simple contactSensor endpoints described above. In Windows 11, version 2.3.6 of the Arduino IDE, which I use, allows you to easily examine the various functions available in a Class- either using the Intellisense context help or right clicking an item and selecting “Go to Definition”. However, on my Ubuntu Linux PC, the same version of the Arduino IDE does not provide these “helper” functions.

To find the ESP32C6 Matter library source files on a Linux PC, you must navigate down through the following deep file hierarchy:

Home/.arduino15/packages/espP32/hardware/esp32/3.3.0/libraries/Matter

Note that .arduino15 is a hidden file. Within the Matter folder is a subfolder src which contains a lower subfolder MatterEndpoints. The latter is where the routines for the various endpoints are defined.

A Car Disturbance Alarm

When I bought an Arduino Nano Matter board, one of the ideas I had was to design a car alarm using the Matter protocol to communicate with my Amazon smart speakers. This would only work when the car was parked at home, of course. Even though my car is parked within 10’ of one side of the house, I didn’t get a reliable Matter connection when the Nano Matter board was sitting inside of the car.

I also had a Sparkfun Thing Plus Matter board but it was tied up in another project. Although all three of my Matter-enabled boards use the 2.4GHz Wi-Fi band, the Matter sketches do not require you to enter your Wi-Fi Access Point’s SSID and password. Therefore, it seems that these Matter-enabled boards make an RF connection directly to my Amazon smart speaker(s). One of my Amazon smart speakers is less than 10’ away from the side of the house where the car is parked, and this short range was unexpected. It should be noted that during initial commissioning BLE is used, but thereafter Wi-Fi is used.

I had much better luck with the DFR-1117 ESP32-C6 module, even though it had a tiny ceramic antenna similar to that found on the Arduino Nano Matter module. Although I didn‘t know how to obtain an RSSI signal strength reading when using the Matter protocol, the DFR-1117 module worked reliably inside the car under the same conditions that the Arduino Nano Matter and the Xiao MG24 modules, had proven to be un-reliable.

Inertial Measurement Unit (IMU)

The concept for the car alarm was to detect any tiny movement in the vehicle, using an accelerometer chip. Specifically, there have been reports of many catalytic converter thefts in many parts of the country, in the last year or so. To remove a catalytic converter, you need at least some access to the underside of the car. Thieves usually jack up the car to some extent to get access. The three- or six-axes IMU devices currently available are able to readily detect even the small change caused by tilting the car in this manner. In fact, they can be programmed to detect even smaller movements in any of the three axes that they measure.

Since I was planning on powering the car alarm with a small LiPo battery, the current consumption of both the ESP32-C6 and the accelerometer would need to be quite low for an extended battery life. Although I had experimented a bit with an earlier generation MPU6050 IMU, this device wasn’t particularly low power, drawing 3.9mA when its Digital Motion Processor was enabled. My idea was to use whatever digital processor was present in the chosen IMU, to sense excess motion and wake up the ESP32-C6 from a deep sleep state. The MPU6050 drew too much current for this to work as planned. It was a bit of an unfair test for the MPU6050 as it also contained a three-axes gyroscope which was not needed here.

I decided to use the Bosch BMA400 three-axes ultra-low power accelerometer. It features a very low current consumption of 14uA in operating mode and that includes a digital processor which can be programmed to send an interrupt signal to the ESP32-C6, when user-defined motion thresholds have been exceeded.

The BMA400 comes in a tiny 12-pin LGA package. Luckily, Sparkfun sells a breakout board for the BMA400 ( p/n SEN-21207) that contains Sparkfun’s Qwiic Connect System. Figure 4 shows this breakout board. Although the Qwiic connector only handles power and I2C connections, Sparkfun was clever enough to add a pinout for the INT line, which is needed in this project to wake up the ESP32C6. Another good reason for me to buy their breakout board is that Sparkfun provides an Arduino library for this device

Figure 4
This is the Bosch BMA400 Inertial Measurement Unit mounted on a Sparkfun breakout board. It uses the Sparkfun QUICC connector to provide power and I2C signals.
Figure 4
This is the Bosch BMA400 Inertial Measurement Unit mounted on a Sparkfun breakout board. It uses the Sparkfun QUICC connector to provide power and I2C signals.

The BMA400 has ranges of ±2g / ±4g / ±8g /±16g. For this project, I use the most sensitive ±2g range. To set up the motion thresholds, used to trigger an interrupt on the BMA400’s INT pin, you need to populate a configuration structure and then call a routine with a pointer to that structure. Listing 1 shows that structure, as defined for this project. Most of the relevant parameters are self-explanatory. I am basically monitoring all three axes, with an interrupt sensitivity of 16mg, a duration of at least 50ms and using the recommended digital Filter 2. The last line of the listing shows the routine that is called with this parameter structure passed to it, using a pointer.

The program flow is shown in Figure 5. When the unit is first turned on, it checks to see the source of the reset. If it was not caused by an INT pin wake-up from deep sleep, it means the user has just switched the unit on, to monitor for movement. It will check to see whether the ESP32-C6 has been commissioned and will enter the commissioning routine is it has not. This commissioning process would only happen once.

Figure 5
This is the flowchart showing the operation on the auto alarm project described in this article.
Figure 5
This is the flowchart showing the operation on the auto alarm project described in this article.

The contactSensor class, as well as the Matter framework must then be initialized using the begin() function. A message is then sent to the Matter controller/hub to set the contact sensor’s state to open (false), as it is the transition from open to closed that triggers the Alexa routine. After checking that this message was received, the sketch then initializes the BMA400 with the parameters shown in Listing 1.After a delay of 30 seconds (explained later) the ESP32-C6 is configured for deep-sleep mode with its wake-up source being the GPIO7 pin going high. GPIO7 is connected to the BMA400 INT pin.

bma400_gen_int_conf config = {  .gen_int_thres = 2, // 8mg resolution (eg. gen_int_thres=5 results in 40mg)  .gen_int_dur = 5, // 10ms resolution (eg. gen_int_dur=5 results in 50ms)  .axes_sel = BMA400_AXIS_XYZ_EN, 			// Which axes to evaluate for interrupts (X/Y/Z in any combination)  .data_src = BMA400_DATA_SRC_ACCEL_FILT_2, 			// Which filter to use (must be 100Hz, datasheet recommends filter 2)  .criterion_sel = BMA400_ACTIVITY_INT, // Trigger interrupts when active or inactive  .evaluate_axes = BMA400_ANY_AXES_INT, 			// Logical combining of axes for interrupt condition (OR/AND)  .ref_update = BMA400_UPDATE_EVERY_TIME, // Whether to automatically update reference values  .hysteresis = BMA400_HYST_96_MG, // Hysteresis acceleration for noise rejection  .int_thres_ref_x = 0, // Raw 12-bit acceleration value not used here  .int_thres_ref_y = 0, // Raw 12-bit acceleration value not used here  .int_thres_ref_z = 0,			// Raw 12-bit acceleration value (at 4g range (default), 512 = 1g) not used here  .int_chan = BMA400_INT_CHANNEL_1 // Which pin to use for interrupts }; accelerometer.setGeneric1Interrupt(&config);

Listing 1
This is the configuration structure that must be populated in order to initialize the BMA400 IMU device. The last line in the listing is the command that loads these parameters into the BMA400.

It turns out that only a limited number of GPIO lines can be used to wake up the ESP32-C6. Of those, only GPIO7 is pinned out on the DFR-1117 module.

Configuring wake-up from a GPIO pin is handled with:

esp_sleep_enable_ext1_wakeup_io(BUTTON_PIN_BITMASK(WAKEUP_GPIO), ESP_EXT1_WAKEUP_ANY_HIGH);

In this case, WAKEUP_GPIO is defined as 7 and the function BUTTON_PIN_BITMASK evaluates to 1 shifted left by the WAKEUP_GPIO pin number. In other words, the GPIO pin # is translated into a bit position in a 32-bit register associated with the wake-up logic.

Placing the ESP32-C6 in a deep-sleep mode is done as follows:

— ADVERTISMENT—

—Advertise Here—

esp_deep_sleep_start();

With the ESP32-C6 in deep sleep, the BMA400 is fully configured and checking for movement. If that movement exceeds the thresholds in Listing 1, the ESP32-C6 wakes.

Referring again to Figure 5, if the wake-up source is determined to be an INT pin, a Matter message is sent which sets the contactSensor variable to closed (true). This causes my Amazon Echo smart speaker (my Matter hub/controller) to run an Alexa routine that I have defined. After 10 seconds, a second Matter routine is sent returning the contact Sensor variable in the Matter hub/controller to open (false). It is the transition from open to closed that causes Alexa to run the routine, so the variable should be returned to the open( false) state after this alarm trigger has been received. After the alarm message is sent to the Matter hub, the sketch continues as if no alarm condition had been detected. That is, it re-configures the BMA400 and then returns to a Deep-Sleep mode. While not shown in Figure 5, I actually send the alarm message twice, at 10 second intervals to increase the chances it will be noticed.

When this project is being commissioned by the Echo hub/controller, at the end of the process, you are prompted to give this device a user-friendly name. This name is used when defining the routine(s) that will be run when that device triggers an alarm condition. Therefore, you could build several ESP32-C6 matter-based devices and give each one a distinct name and matching routine.

Note that you should be somewhat careful in your code regarding when you put the ESP32-C6 into Deep Sleep mode. Once it is in Deep Sleep mode, you can’t easily re-flash the device with new software, since it will be asleep and non-responsive to your PC’s flashing program. For this project, when the sketch first boots up, if it was not caused by a BMA400 interrupt, the sketch will delay for the number of seconds defined by STARTUP_DELAY, near the top of the sketch (I use 30 seconds for testing but it could be longer for actual use conditions). This delay allows time to (re)-compile the sketch and start the download process, before the ESP32-C6 goes into Deep Sleep mode. The DF Robot Beetle ESP32C6 module contains a BOOT switch, which you can hold down in advance of toggling the RES switch. This places the ESP32-C6 in the download mode. This is the only way of flashing the ESP32-C6, if your sketch puts the ESP32C6 into Deep Sleep mode shortly after reset.

Note that the even smaller Xiao ESP32-C6 module could probably be used for this project. However, its Boot and RST buttons are extremely tiny and hard to activate by hand. It can handle an external antenna, which might allow for a greater range than the DFR-1117 module. It doesn’t provide a GPIO7 pinout but if my memory is correct, the GPIO0,GPIO1 and GPIO2 pins provided would also work for the purpose of Deep Sleep wake-up- with a small change to the program code used for the deep-sleep configuration command.

The Circuit

Electrically, the circuitry is almost trivial in its simplicity. See Figure 6. The BMA400 is powered from the 3.3V regulated supply provided by the LDO aboard the DFR-1117 (ESP32-C6) module. It communicates with the EPS32-C6 via I2C, and the necessary 2.2k pull-up resistors are contained on the Sparkfun BMA400 breakout board. The BMA400’s interrupt output pin, INT, is connected to the ESP32-C6’s GPIO7 pin (the only GPIO pin present that can trigger a Wake-up). GPIO21 powers an LED to indicate, at power-up, that a connection to the Matter hub has been achieved.

Figure 6
This is the schematic of the auto alarm project.
Figure 6
This is the schematic of the auto alarm project.

Power is provided by a small 3.7V LiPo battery. Figure 7 shows the complete unit.

Figure 7
This is the completed auto alarm project. As you would expect from seeing the schematic, it’s very simple.
Figure 7
This is the completed auto alarm project. As you would expect from seeing the schematic, it’s very simple.
Power Consumption

Being battery-powered, power consumption is a consideration. From the respective datasheets, the ESP32-C6 is supposed to draw about 14µA in Deep sleep. Looking at the schematic for the DFR-1117 module, there is nothing much else to draw current on this module, apart from the LDO, which has very low quiescent current.

In operational mode, the BMA400 is rated to draw a similar 14µA current. This can be reduced even further if you put it into a lower-speed measurement mode, but I wasn’t interested in doing that.

Using my Joulescope Power analyser, I measured the following current consumption:

  • During a normal power up: 31mA (the duration of which depends primarily on how long you set the STARTUP_DELAY value in the sketch- assume 60 secs).
  • During Deep-sleep: 24µA. (This is a little better than the sum of the ESP32C6 and BMA400 device’s current ratings from their datasheets)
  • During an alarm condition: 31mA baseline but with numerous 400mA spikes when the ESP32C6 is transmitting the Matter messages.

Assuming that the alarm condition is a rare occurrence, and that the unit is turned on once each day, for roughly 12 hours, the power consumption, per day, is:

31mA x 60secs/3600secs = .516mA-H <operating>

24µA x 12 hr = 288 x 10-3 mA-H or 0.288mA-H <deep sleep>

This works out to 0.8mA-H. Even a small 200mA-H LiPo battery would last for at least 6 months of normal use before requiring re-charging.

— ADVERTISMENT—

—Advertise Here—

Variations

You could use the identical circuit for window and door alarms in a house by monitoring for motion. However, it would be more practical to use the common magnetically activated reed switches found in regular alarm systems. In that case, you would merely connect that reed switch to the Wake-up GPIO pin on the ESP32-C6 and use a pull-up resistor. The BMA400 IMU would not be needed and none of the BMA400 configuration code would be needed. In this case, the power consumption would drop to that required by the ESP32-C6 in Deep-Sleep alone and the battery life would be about 3x longer than the figures shown earlier.

big results from small antennas

The addition of the Matter protocol, as well as Zigbee, is a welcome addition to the ESP32 family of Wi-Fi enabled MCUs. I don’t have a Zigbee hub running at home, so I was not able to test that capability. However, the Matter protocol worked fine, and I was impressed that the ESP32-C6, sporting only a small chip antenna, was able to achieve much better range than I had been able to get with the MG24-based boards (covered in my article in issue 418). Although I had encountered numerous problems with the initial Arduino Matter library for the MG24 MCU, that has been resolved in subsequent releases. However, the ESP32-C6 Matter examples worked for me right away, which was encouraging. It was also encouraging to see that new features, introduced first in the Espressif IDF, were quickly ported to the Arduino IDE. 

RESOURCES
Bosch | https://www.bosch-sensortec.com
Espressif | https://www.espressif.com
Seeedstudio | https://www.seeedstudio.com
Espressif ESP32C6 MCU:
https://documentation.espressif.com/esp32-c6-wroom-1_wroom-1u_datasheet_en.pdf
Xiao-ESP32C6 Matter tutorial using Espressif’s ESP-IDF:
https://wiki.seeedstudio.com/xiao_esp32_matter_env
Bosch BMA400 3-Axis IMU:
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bma400-ds000.pdf

Code and Supporting Files

PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MARCH 2026 #428 – Get a PDF of the issue

Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.


Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
+ posts

Brian Millier runs Computer Interface Consultants. He was an instrumentation engineer in the Department of Chemistry at Dalhousie University (Halifax, NS, Canada) for 29 years.

Supporting Companies

Upcoming Events


Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2026 KCK Media Corp.

Another Matter-Enabled MCU: the ESP32-C6

by Brian Millier time to read: 25 min