CC1101 Module
This library is the driver for Module CC1101, a low-cost sub-1 GHz transceiver designed for very low-power wireless applications. It operates in the 855-928 MHz frequency bands and provides excellent performance at very low current consumption.
The module features a highly configurable baseband modem supporting various modulation formats and has a flexible data rate from 0.6 to 6.0 kbps. It includes built-in support for packet handling, data buffering, burst transmissions, clear channel assessment, link quality indication, and wake-on-radio functionality.
Support the following products:
UiFlow2 Example
Transmit Data
Open the m5cores3_cc1101_tx_example.m5f2 project in UiFlow2.
This example shows how to send data using the CC1101 module. The module will continuously send messages with incrementing counter values.
UiFlow2 Code Block:
Example output:
None
Receive Data with IRQ
Open the m5cores3_cc1101_rx_example.m5f2 project in UiFlow2.
This example shows how to receive data using interrupt-based reception. The module will display received messages, RSSI values on the screen.
UiFlow2 Code Block:
Example output:
None
MicroPython Example
Transmit Data
This example shows how to send data using the CC1101 module. The module continuously sends messages with incrementing counter values every second.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8import m5ui 9import lvgl as lv 10from module import CC1101Module 11import time 12 13 14page0 = None 15lable_title = None 16label_tx = None 17label_time = None 18btn_ctrl = None 19module_cc1101_0 = None 20send_flag = None 21last_time = None 22count = None 23tx = None 24 25 26def btn_ctrl_clicked_event(event_struct): 27 global \ 28 page0, \ 29 lable_title, \ 30 label_tx, \ 31 label_time, \ 32 btn_ctrl, \ 33 module_cc1101_0, \ 34 send_flag, \ 35 last_time, \ 36 count, \ 37 tx 38 send_flag = not send_flag 39 if send_flag: 40 btn_ctrl.set_btn_text(str("Stop")) 41 else: 42 btn_ctrl.set_btn_text(str("Start")) 43 Speaker.tone(666, 100) 44 45 46def btn_ctrl_event_handler(event_struct): 47 global \ 48 page0, \ 49 lable_title, \ 50 label_tx, \ 51 label_time, \ 52 btn_ctrl, \ 53 module_cc1101_0, \ 54 send_flag, \ 55 last_time, \ 56 count, \ 57 tx 58 event = event_struct.code 59 if event == lv.EVENT.CLICKED and True: 60 btn_ctrl_clicked_event(event_struct) 61 return 62 63 64def setup(): 65 global \ 66 page0, \ 67 lable_title, \ 68 label_tx, \ 69 label_time, \ 70 btn_ctrl, \ 71 module_cc1101_0, \ 72 send_flag, \ 73 last_time, \ 74 count, \ 75 tx 76 77 M5.begin() 78 Widgets.setRotation(1) 79 m5ui.init() 80 page0 = m5ui.M5Page(bg_c=0xFFFFFF) 81 lable_title = m5ui.M5Label( 82 "ModuleCC1101 Tx", 83 x=58, 84 y=2, 85 text_c=0x0000FF, 86 bg_c=0xFFFFFF, 87 bg_opa=0, 88 font=lv.font_montserrat_24, 89 parent=page0, 90 ) 91 label_tx = m5ui.M5Label( 92 "Tx:", 93 x=5, 94 y=64, 95 text_c=0x0000FF, 96 bg_c=0xFFFFFF, 97 bg_opa=0, 98 font=lv.font_montserrat_16, 99 parent=page0, 100 ) 101 label_time = m5ui.M5Label( 102 "Timestamp:", 103 x=5, 104 y=210, 105 text_c=0x0000FF, 106 bg_c=0xFFFFFF, 107 bg_opa=0, 108 font=lv.font_montserrat_16, 109 parent=page0, 110 ) 111 btn_ctrl = m5ui.M5Button( 112 text="Stop", 113 x=127, 114 y=130, 115 bg_c=0x2196F3, 116 text_c=0xFFFFFF, 117 font=lv.font_montserrat_14, 118 parent=page0, 119 ) 120 121 btn_ctrl.add_event_cb(btn_ctrl_event_handler, lv.EVENT.ALL, None) 122 123 page0.screen_load() 124 module_cc1101_0 = CC1101Module( 125 pin_cs=5, 126 pin_gdo0=7, 127 pin_gdo2=10, 128 freq_khz=868000, 129 bitrate_kbps=3, 130 freq_dev_khz=25.4, 131 rx_bw_khz=58, 132 output_power=10, 133 preamble_length=16, 134 sync_word_h=0x12, 135 sync_word_l=0xAD, 136 ) 137 count = 0 138 send_flag = True 139 btn_ctrl.set_size(100, 60) 140 btn_ctrl.align_to(page0, lv.ALIGN.CENTER, 0, 30) 141 Speaker.begin() 142 Speaker.setVolumePercentage(0.8) 143 Speaker.tone(666, 100) 144 145 146def loop(): 147 global \ 148 page0, \ 149 lable_title, \ 150 label_tx, \ 151 label_time, \ 152 btn_ctrl, \ 153 module_cc1101_0, \ 154 send_flag, \ 155 last_time, \ 156 count, \ 157 tx 158 M5.update() 159 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 1000: 160 last_time = time.ticks_ms() 161 label_time.set_text(str((str("Timestamp: ") + str((time.ticks_ms()))))) 162 if send_flag: 163 tx = str("Hello M5 - ") + str(count) 164 count = (count if isinstance(count, (int, float)) else 0) + 1 165 print(tx) 166 if module_cc1101_0.send(tx): 167 label_tx.set_text(str((str("Tx: ") + str(tx)))) 168 else: 169 label_tx.set_text(str("Send failed!")) 170 171 172if __name__ == "__main__": 173 try: 174 setup() 175 while True: 176 loop() 177 except (Exception, KeyboardInterrupt) as e: 178 try: 179 m5ui.deinit() 180 from utility import print_error_msg 181 182 print_error_msg(e) 183 except ImportError: 184 print("please update to latest firmware")
Example output:
None
Receive Data with IRQ
This example shows how to receive data using interrupt-based reception. The module will display received messages, RSSI values on the screen.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8import m5ui 9import lvgl as lv 10from module import CC1101Module 11import time 12 13 14page0 = None 15label_title = None 16label_rssi = None 17label_rx = None 18label_time = None 19module_cc1101_0 = None 20cc1101_data = None 21last_time = None 22 23 24def module_cc1101_0_receive_event(received_data): 25 global \ 26 page0, \ 27 label_title, \ 28 label_rssi, \ 29 label_rx, \ 30 label_time, \ 31 module_cc1101_0, \ 32 cc1101_data, \ 33 last_time 34 cc1101_data = received_data 35 if cc1101_data.crc_ok: 36 label_rx.set_text(str((str("Rx: ") + str((cc1101_data.decode()))))) 37 else: 38 print("CRC error") 39 label_rssi.set_text(str((str("RSSI: ") + str((str((cc1101_data.rssi)) + str(" dBm")))))) 40 41 42def setup(): 43 global \ 44 page0, \ 45 label_title, \ 46 label_rssi, \ 47 label_rx, \ 48 label_time, \ 49 module_cc1101_0, \ 50 cc1101_data, \ 51 last_time 52 53 M5.begin() 54 Widgets.setRotation(1) 55 m5ui.init() 56 page0 = m5ui.M5Page(bg_c=0xFFFFFF) 57 label_title = m5ui.M5Label( 58 "ModuleCC1101 Rx", 59 x=56, 60 y=2, 61 text_c=0x0000FF, 62 bg_c=0xFFFFFF, 63 bg_opa=0, 64 font=lv.font_montserrat_24, 65 parent=page0, 66 ) 67 label_rssi = m5ui.M5Label( 68 "RSSI:", 69 x=5, 70 y=95, 71 text_c=0x0000FF, 72 bg_c=0xFFFFFF, 73 bg_opa=0, 74 font=lv.font_montserrat_16, 75 parent=page0, 76 ) 77 label_rx = m5ui.M5Label( 78 "Rx:", 79 x=5, 80 y=65, 81 text_c=0x0000FF, 82 bg_c=0xFFFFFF, 83 bg_opa=0, 84 font=lv.font_montserrat_16, 85 parent=page0, 86 ) 87 label_time = m5ui.M5Label( 88 "Timestamp:", 89 x=5, 90 y=210, 91 text_c=0x0000FF, 92 bg_c=0xFFFFFF, 93 bg_opa=0, 94 font=lv.font_montserrat_16, 95 parent=page0, 96 ) 97 98 page0.screen_load() 99 module_cc1101_0 = CC1101Module( 100 pin_cs=5, 101 pin_gdo0=7, 102 pin_gdo2=10, 103 freq_khz=868000, 104 bitrate_kbps=3, 105 freq_dev_khz=25.4, 106 rx_bw_khz=58, 107 output_power=10, 108 preamble_length=16, 109 sync_word_h=0x12, 110 sync_word_l=0xAD, 111 ) 112 module_cc1101_0.set_rx_irq_callback(module_cc1101_0_receive_event) 113 module_cc1101_0.start_recv() 114 115 116def loop(): 117 global \ 118 page0, \ 119 label_title, \ 120 label_rssi, \ 121 label_rx, \ 122 label_time, \ 123 module_cc1101_0, \ 124 cc1101_data, \ 125 last_time 126 M5.update() 127 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 1000: 128 last_time = time.ticks_ms() 129 label_time.set_text(str((str("Timestamp: ") + str((time.ticks_ms()))))) 130 131 132if __name__ == "__main__": 133 try: 134 setup() 135 while True: 136 loop() 137 except (Exception, KeyboardInterrupt) as e: 138 try: 139 m5ui.deinit() 140 from utility import print_error_msg 141 142 print_error_msg(e) 143 except ImportError: 144 print("please update to latest firmware")
Example output:
None
API
class CC1101Module
- class module.cc1101.CC1101Module(pin_cs=5, pin_gdo0=7, pin_gdo2=10, freq_khz=868000, bitrate_kbps=2.4, freq_dev_khz=25.4, rx_bw_khz=58.0, output_power=10, preamble_length=16, sync_word_h=0x12, sync_word_l=0xAD)
Create a CC1101Module object.
- Parameters:
pin_cs (int) – (CS) Chip select pin number.
pin_gdo0 (int) – (GDO0) Interrupt pin number.
pin_gdo2 (int) – (GDO2) Optional interrupt pin number.
freq_khz (int) – CC1101 RF frequency in kHz, with a range of 855000 kHz to 928000 kHz.
bitrate_kbps (float) – Data rate in kbps, range from 0.6 to 6.0 kbps.
freq_dev_khz (float) – Frequency deviation in kHz, range from 1.6 to 380 kHz.
rx_bw_khz (float) – Receiver bandwidth in kHz, range from 58 to 812 kHz.
output_power (int) – Output power in dBm, range from -30 to 10 dBm.
preamble_length (int) – Preamble length in bits, options: 16, 24, 32, 48, 64, 96, 128, 192.
sync_word_h (int) – High byte of sync word (0x00 to 0xFF).
sync_word_l (int) – Low byte of sync word (0x00 to 0xFF).
UiFlow2 Code Block:

MicroPython Code Block:
from module import CC1101Module module_cc1101_0 = CC1101Module(5, 7, 10, 868000, 2.4, 25.4, 58.0, 10, 16, 0x12, 0xAD)
- set_freq(freq_khz)
Set frequency in kHz.
- Parameters:
freq_khz (int) – Frequency in kHz (855000 ~ 928000), default is 868000.
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_freq(868000)
- set_bitrate(bitrate_kbps)
Set data rate in kbps.
- Parameters:
bitrate_kbps (float) – Data rate in kbps (0.6 ~ 6.0)
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_bitrate(2.4)
- set_freq_dev(freq_dev_khz)
Set frequency deviation in kHz.
- Parameters:
freq_dev_khz (float) – Frequency deviation in kHz (1.6 ~ 380)
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_freq_dev(25.4)
- set_rx_bw(rx_bw_khz)
Set receiver bandwidth in kHz.
- Parameters:
rx_bw_khz (float) – Receiver bandwidth in kHz (58 ~ 812)
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_rx_bw(58.0)
- set_output_power(output_power)
Set output power in dBm.
- Parameters:
output_power (int) – Output power in dBm (-30 ~ 10)
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_output_power(10)
- set_preamble_length(preamble_length)
Set preamble length in bits.
- Parameters:
preamble_length (int) – Preamble length in bits, must be one of: 16, 24, 32, 48, 64, 96, 128, 192.
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_preamble_length(16)
- set_sync_word(sync_word_h, sync_word_l)
Set sync word.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.set_sync_word(0x12, 0xAD)
- send(packet)
Send data.
- Parameters:
packet (str | list | tuple | int | bytearray) – The data to be sent.
- Returns:
True if successful, False otherwise
- Return type:
Send a data packet and return True if successful.
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.send("Hello World")
- recv(timeout_ms)
Receive data.
- Parameters:
timeout_ms (int) – Timeout in milliseconds (optional). Default is None.
- Returns:
Received packet instance or None if timeout
- Return type:
CC1101Packet | None
Attempt to receive a CC1101 packet. Returns None if timeout occurs, or returns the received packet instance.
UiFlow2 Code Block:

MicroPython Code Block:
packet = module_cc1101_0.recv() if packet: if packet.crc_ok: print(f"Received: {packet.decode()}") print(f"RSSI: {packet.rssi} dBm") print(f"LQI: {packet.lqi}") else: print("CRC error")
- start_recv()
Start receive data.
This method initiates the process to begin receiving data.
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.start_recv()
- set_rx_irq_callback(callback)
Set the receive interrupt callback function to be executed on IRQ.
- Parameters:
callback – The callback function to be invoked when the interrupt is triggered. The callback should take a CC1101Packet parameter and return nothing.
UiFlow2 Code Block:

MicroPython Code Block:
def on_packet_received(packet): print(f"Received: {packet.decode()}") module_cc1101_0.set_rx_irq_callback(on_packet_received)
- set_tx_irq_callback(callback)
Set the transmit interrupt callback function to be executed on IRQ.
- Parameters:
callback – The callback function to be invoked when the interrupt is triggered. The callback should take one parameter (pin object, can be ignored) and return nothing.
UiFlow2 Code Block:

MicroPython Code Block:
def on_packet_sent(_): print("Packet sent successfully") module_cc1101_0.set_tx_irq_callback(on_packet_sent)
- standby()
Set module to standby mode.
Puts the CC1101 module into standby mode, consuming less power.
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.standby()
- rx_irq_triggered()
Check RX IRQ trigger.
- Returns:
Returns True if an interrupt service routine (ISR) has been triggered since the last send or receive started.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
module_cc1101_0.rx_irq_triggered()



