Environment Setup: Refer to the Arduino IDE Getting Started Guide to complete IDE installation, and install the corresponding board manager and required driver libraries based on the development board being used.
Required Driver Libraries:
Required Hardware Products:
#include <driver/rmt.h>
#include <M5Unified.h>
#define RF433TX
#define RMT_TX_CHANNEL (RMT_CHANNEL_0)
#define RMT_RX_CHANNEL (RMT_CHANNEL_1)
#define RTM_TX_GPIO_NUM (21)
#define RTM_BLOCK_NUM (1)
#define RMT_CLK_DIV (80) /*!< RMT counter clock divider */
#define RMT_1US_TICKS (80000000 / RMT_CLK_DIV / 1000000)
#define RMT_1MS_TICKS (RMT_1US_TICKS * 1000)
rmt_item32_t rmtbuff[2048];
#define T0H 670
#define T1H 320
#define T0L 348
#define T1L 642
#define RMT_CODE_H {670, 1, 320, 0}
#define RMT_CODE_L {348, 1, 642, 0}
#define RMT_START_CODE0 {4868, 1, 2469, 0}
#define RMT_START_CODE1 {1647, 1, 315, 0}
void initRMT()
{
#ifndef RF433RX
rmt_config_t txconfig;
txconfig.rmt_mode = RMT_MODE_TX;
txconfig.channel = RMT_TX_CHANNEL;
txconfig.gpio_num = gpio_num_t(RTM_TX_GPIO_NUM);
txconfig.mem_block_num = RTM_BLOCK_NUM;
txconfig.tx_config.loop_en = false;
txconfig.tx_config.carrier_en = false;
txconfig.tx_config.idle_output_en = true;
txconfig.tx_config.idle_level = rmt_idle_level_t(0);
txconfig.clk_div = RMT_CLK_DIV;
esp_err_t err1 = rmt_config(&txconfig);
esp_err_t err2 = rmt_driver_install(txconfig.channel, 0, 0);
if (err1 != ESP_OK || err2 != ESP_OK) {
Serial.printf("RMT init failed: %d, %d\n", err1, err2);
return;
}
#else
rmt_config_t rxconfig;
rxconfig.rmt_mode = RMT_MODE_RX;
rxconfig.channel = RMT_RX_CHANNEL;
rxconfig.gpio_num = gpio_num_t(RTM_RX_GPIO_NUM);
rxconfig.mem_block_num = 6;
rxconfig.clk_div = RMT_CLK_DIV;
rxconfig.rx_config.filter_en = true;
rxconfig.rx_config.filter_ticks_thresh = 200 * RMT_1US_TICKS;
rxconfig.rx_config.idle_threshold = 3 * RMT_1MS_TICKS;
esp_err_t err1 = rmt_config(&rxconfig);
esp_err_t err2 = rmt_driver_install(rxconfig.channel, 1024, 0);
if (err1 != ESP_OK || err2 != ESP_OK) {
Serial.printf("RMT init failed: %d, %d\n", err1, err2);
}
#endif
}
/*
uint8_t databuff1[5] = {0xdd,0x41,0x53,0x80,0x9f};
uint8_t databuff2[5] = {0xdd,0x41,0x5a,0x80,0x96};
uint8_t databuff3[5] = {0xdd,0x41,0x58,0x80,0x95};
*/
uint8_t data[5] = {0xAA, 0x55, 0x01, 0x02, 0x03};
void send(uint8_t* buff, size_t size)
{
rmtbuff[0] = (rmt_item32_t){RMT_START_CODE0};
rmtbuff[1] = (rmt_item32_t){RMT_START_CODE1};
for (int i = 0; i < size; i++) {
uint8_t mark = 0x80;
for (int n = 0; n < 8; n++) {
rmtbuff[2 + i * 8 + n] = ((buff[i] & mark)) ? ((rmt_item32_t){RMT_CODE_H}) : ((rmt_item32_t){RMT_CODE_L});
mark >>= 1;
}
}
for (int i = 0; i < 8; i++) {
esp_err_t err1 = rmt_write_items(RMT_TX_CHANNEL, rmtbuff, 42, false);
if (err1 != ESP_OK) {
Serial.printf("RMT write error: %d\n", err1);
return;
}
esp_err_t err2 = rmt_wait_tx_done(RMT_TX_CHANNEL, pdMS_TO_TICKS(1000));
if (err2 != ESP_OK) {
Serial.printf("RMT wait error: %d\n", err2);
return;
}
}
}
void setup()
{
M5.begin();
Serial.begin(115200);
Serial.println("WAIT");
M5.Display.fillRect(0, 0, 320, 240, WHITE);
M5.Display.setTextColor(BLACK);
M5.Display.setFont(&fonts::FreeMonoBold12pt7b);
M5.Display.setCursor(0, 0);
Serial.print("initRMT OK");
M5.Display.println("Unit RF433T init...");
pinMode(RTM_TX_GPIO_NUM, OUTPUT);
initRMT();
delay(100);
M5.Display.println("Click Btn A send data");
// rf.begin<PT2262>(26,27).arg<int>(1000);
}
void loop()
{
M5.update();
if (M5.BtnA.wasPressed()) {
Serial.println("SEND");
send(data, 5);
for (int i = 0; i < 5; i++) {
Serial.printf("%02x ", data[i]);
M5.Display.printf("%02x ", data[i]);
}
M5.Display.println("");
}
delay(10);
}
#include <M5Unified.h>
#define RX_PIN 1
#define MAX_PULSES 512
volatile unsigned long pulseTimes[MAX_PULSES];
volatile int pulseCount = 0;
volatile unsigned long lastTime = 0;
// START_CODE0: {4868, 1, 2469, 0}
#define START_CODE0_HIGH_MIN 4600
#define START_CODE0_HIGH_MAX 5100
#define START_CODE0_LOW_MIN 2200
#define START_CODE0_LOW_MAX 2700
// START_CODE1: {1647, 1, 315, 0}
#define START_CODE1_HIGH_MIN 1400
#define START_CODE1_HIGH_MAX 1900
#define START_CODE1_LOW_MIN 200
#define START_CODE1_LOW_MAX 450
// RMT_CODE_H (1): {670, 1, 320, 0}
// RMT_CODE_L (0): {348, 1, 642, 0}
#define BIT_TOTAL_MIN 800
#define BIT_TOTAL_MAX 1200
#define BIT_HIGH_THRESHOLD 500
uint8_t receivedData[256];
int receiveCount = 0;
unsigned long lastReceiveTime = 0;
void IRAM_ATTR pulseInterrupt() {
if (pulseCount < MAX_PULSES) {
unsigned long currentTime = micros();
pulseTimes[pulseCount] = currentTime - lastTime;
lastTime = currentTime;
pulseCount++;
}
}
void setup() {
M5.begin();
Serial.begin(115200);
M5.Display.fillRect(0, 0, 320, 240, WHITE);
M5.Display.setTextColor(BLACK);
M5.Display.setFont(&fonts::FreeMonoBold12pt7b);
M5.Display.setCursor(0, 0);
M5.Display.println("Unit RF433R init...");
Serial.println("Unit RF433R init...");
pinMode(RX_PIN, INPUT);
Serial.println("attachInterrupt ...");
attachInterrupt(digitalPinToInterrupt(RX_PIN), pulseInterrupt, CHANGE);
M5.Display.print("Serial to view data");
Serial.println("RF433 Receiver ready");
lastTime = micros();
}
int parseData() {
if (pulseCount < 8) return -1;
int dataIndex = 0;
uint8_t data = 0;
uint8_t bitCount = 0;
int pulseIndex = 0;
if (pulseTimes[0] >= START_CODE0_HIGH_MIN && pulseTimes[0] <= START_CODE0_HIGH_MAX &&
pulseTimes[1] >= START_CODE0_LOW_MIN && pulseTimes[1] <= START_CODE0_LOW_MAX) {
Serial.println("Found START_CODE0");
pulseIndex = 2;
if (pulseIndex < pulseCount - 1 &&
pulseTimes[pulseIndex] >= START_CODE1_HIGH_MIN && pulseTimes[pulseIndex] <= START_CODE1_HIGH_MAX &&
pulseTimes[pulseIndex + 1] >= START_CODE1_LOW_MIN && pulseTimes[pulseIndex + 1] <= START_CODE1_LOW_MAX) {
Serial.println("Found START_CODE1");
pulseIndex = 4;
while (pulseIndex < pulseCount - 1) {
unsigned long highTime = pulseTimes[pulseIndex];
unsigned long lowTime = pulseTimes[pulseIndex + 1];
unsigned long totalTime = highTime + lowTime;
if (totalTime >= BIT_TOTAL_MIN && totalTime <= BIT_TOTAL_MAX) {
// RMT_CODE_H (1)
// RMT_CODE_L (0)
if (highTime > BIT_HIGH_THRESHOLD) {
data = (data << 1) | 1;
} else {
data = (data << 1) | 0;
}
bitCount++;
if (bitCount >= 8) {
receivedData[dataIndex] = data;
Serial.printf("%02x ", data);
dataIndex++;
data = 0;
bitCount = 0;
if (dataIndex >= 5) break;
}
pulseIndex += 2;
} else {
pulseIndex++;
}
}
}
if (dataIndex > 0) {
Serial.println(" END");
return dataIndex;
}
}
return -1;
}
void loop() {
if (millis() - lastReceiveTime > 50) {
noInterrupts();
int currentPulseCount = pulseCount;
interrupts();
if (currentPulseCount > 0) {
int dataSize = parseData();
if (dataSize >= 5 &&
receivedData[0] == 0xAA &&
receivedData[1] == 0x55 &&
receivedData[2] == 0x01 &&
receivedData[3] == 0x02 &&
receivedData[4] == 0x03 ) {
receiveCount++;
Serial.printf("\r\nValid packet received! Count: %d\r\n", receiveCount);
for (int i = 0; i < dataSize; i++) {
M5.Display.printf("%02x ", receivedData[i]);
}
M5.Display.println("");
if (receiveCount >= 4) {
M5.Display.fillRect(0, 20, 320, 220, TFT_GREEN);
M5.Display.setTextColor(BLACK);
M5.Display.setCursor(10, 50);
M5.Display.printf("Received: %d", receiveCount);
}
} else if (dataSize > 0) {
Serial.printf("Received %d bytes but not matching expected pattern\r\n", dataSize);
}
noInterrupts();
pulseCount = 0;
interrupts();
lastReceiveTime = millis();
} else {
if (receiveCount != 0 && millis() - lastReceiveTime > 2000) {
Serial.printf("Reset after receiving %d packets\r\n", receiveCount);
M5.Display.fillRect(0, 20, 320, 220, TFT_RED);
receiveCount = 0;
}
}
}
delay(10);
}
Download Mode: Different devices require entering download mode before program burning. This process may vary depending on the main controller device. For details, please refer to the device programming tutorial list at the bottom of the Arduino IDE Getting Started Guide page for specific operations.
For CoreS3: Press and hold the reset button (about 2 seconds) until the internal green LED lights up, then release. The device will now enter download mode and wait for programming.