|
| 1 | +--- |
| 2 | +title: CC1101 Low-Power Sub-1 GHz RF Transceiver |
| 3 | +description: Instructions for setting up CC1101 RF Transceiver in ESPHome. |
| 4 | +image: /components/images/cc1101-full.webp |
| 5 | +keywords: [cc1101] |
| 6 | +--- |
| 7 | + |
| 8 | +The **CC1101** component provides a driver for the **Texas Instruments CC1101** Sub-1 GHz RF Transceiver |
| 9 | +([datasheet](https://www.ti.com/lit/ds/symlink/cc1101.pdf)). The CC1101 is a low-cost, low-power radio |
| 10 | +chip commonly used for wireless communication in the 300-928 MHz frequency bands, including the popular |
| 11 | +315 MHz, 433 MHz, 868 MHz, and 915 MHz ISM bands. |
| 12 | + |
| 13 | +The **CC1101** supports multiple modulation schemes (ASK/OOK, 2-FSK, 4-FSK, GFSK, MSK), configurable data |
| 14 | +rates from 600 to 500,000 baud, and adjustable output power from -30 dBm to +11 dBm. It connects to |
| 15 | +ESPHome via the [SPI Bus](/components/spi) and integrates with the |
| 16 | +[Remote Transmitter](/components/remote_transmitter) and |
| 17 | +[Remote Receiver](/components/remote_receiver) components for encoding and decoding RF protocols. |
| 18 | + |
| 19 | +{{< img src="cc1101-full.webp" alt="CC1101 Module" width="50.0%" class="align-center" >}} |
| 20 | + |
| 21 | +## Component Configuration |
| 22 | + |
| 23 | +```yaml |
| 24 | +# Minimal Example |
| 25 | +cc1101: |
| 26 | + cs_pin: GPIOXX |
| 27 | + frequency: 433.92MHz |
| 28 | +``` |
| 29 | +
|
| 30 | +## Configuration Variables |
| 31 | +
|
| 32 | +### Hardware Settings |
| 33 | +
|
| 34 | +- **cs_pin** (**Required**, [Pin](/guides/configuration-types/#pin)): |
| 35 | + The SPI Chip Select (CSN) pin connected to the module. |
| 36 | +
|
| 37 | +### General Settings |
| 38 | +
|
| 39 | +- **frequency** (*Optional*, frequency): The operating frequency. |
| 40 | + Range: `300MHz` to `928MHz`. Defaults to `433.92MHz`. |
| 41 | +- **output_power** (*Optional*, float): The transmission power in dBm. |
| 42 | + Range: `-30` to `11`. Defaults to `10`. |
| 43 | +- **modulation_type** (*Optional*, enum): The modulation format. |
| 44 | + Options: `ASK/OOK` (default), `2-FSK`, `4-FSK`, `GFSK`, `MSK`. |
| 45 | +- **symbol_rate** (*Optional*, int): The symbol rate in Baud. |
| 46 | + Range: `600` to `500000`. Defaults to `5000`. |
| 47 | +- **rx_attenuation** (*Optional*, enum): Internal RX attenuation. |
| 48 | + Options: `0dB`, `6dB`, `12dB`, `18dB`. Defaults to `0dB`. |
| 49 | +- **dc_blocking_filter** (*Optional*, boolean): Enable the digital DC blocking filter. Defaults to `true`. |
| 50 | + |
| 51 | +### Tuner Settings |
| 52 | + |
| 53 | +- **filter_bandwidth** (*Optional*, frequency): The receive filter bandwidth. |
| 54 | + Range: `58kHz` to `812kHz`. Defaults to `203kHz`. |
| 55 | +- **fsk_deviation** (*Optional*, frequency): Frequency deviation for FSK/GFSK modulation. |
| 56 | +- **channel** (*Optional*, int): Channel number (added to base frequency). Defaults to `0`. |
| 57 | +- **channel_spacing** (*Optional*, frequency): Spacing between channels. Defaults to `200kHz`. |
| 58 | +- **if_frequency** (*Optional*, frequency): Intermediate Frequency. Defaults to `153kHz`. |
| 59 | +- **pktlen** (*Optional*, int): Packet length configuration. Sets the expected packet size for |
| 60 | + fixed-length packet mode. Range: `1` to `255`. Not typically needed for OOK/ASK modulation. |
| 61 | + |
| 62 | +### AGC (Automatic Gain Control) Settings |
| 63 | + |
| 64 | +Advanced users can fine-tune the AGC dynamics. The AGC automatically adjusts receiver gain to handle |
| 65 | +signals of varying strength. These settings control how aggressively and quickly the gain adapts. |
| 66 | +See the [CC1101 Datasheet](https://www.ti.com/lit/ds/symlink/cc1101.pdf) for detailed information. |
| 67 | + |
| 68 | +- **magn_target** (*Optional*, dB): Target signal amplitude for the AGC loop. Higher values increase |
| 69 | + sensitivity but may cause clipping on strong signals. |
| 70 | + Range: `24dB` to `42dB` in increments of 3 (e.g., `33dB`). Defaults to `42dB`. |
| 71 | +- **max_lna_gain** (*Optional*, dB): Limits the maximum LNA (Low Noise Amplifier) gain. Use to prevent |
| 72 | + saturation in high-signal environments. Defaults to `Default`. |
| 73 | + Options: `Default`, `2.6dB`, `6.1dB`, `7.4dB`, `9.2dB`, `11.5dB`, `14.6dB`, `17.1dB`. |
| 74 | +- **max_dvga_gain** (*Optional*, enum): Limits the maximum DVGA (Digital Variable Gain Amplifier) gain. |
| 75 | + Options: `Default`, `-1`, `-2`, `-3`. Defaults to `-3`. |
| 76 | +- **lna_priority** (*Optional*, boolean): If true, reduce LNA gain before DVGA gain when decreasing |
| 77 | + overall gain. Useful for optimizing noise figure. Defaults to `false`. |
| 78 | +- **carrier_sense_abs_thr** (*Optional*, int): Absolute RSSI threshold for carrier sense. The radio |
| 79 | + considers a carrier present when RSSI exceeds this level. |
| 80 | +- **carrier_sense_rel_thr** (*Optional*, enum): Relative RSSI threshold for carrier sense, compared |
| 81 | + to the current noise floor. Options: `Default`, `+6dB`, `+10dB`, `+14dB`. |
| 82 | +- **filter_length_fsk_msk** (*Optional*, enum): Averaging length for AGC in FSK/MSK modes. |
| 83 | + Longer values provide more stable gain but slower response. Options: `8`, `16`, `32`, `64`. |
| 84 | +- **filter_length_ask_ook** (*Optional*, enum): Averaging length for AGC in ASK/OOK modes. |
| 85 | + Longer values provide more stable gain but slower response. Options: `4dB`, `8dB`, `12dB`, `16dB`. |
| 86 | +- **freeze** (*Optional*, enum): Controls when AGC gain is frozen (held constant). |
| 87 | + Options: `Default`, `On Sync`, `Analog Only`, `Analog And Digital`. |
| 88 | +- **wait_time** (*Optional*, enum): Time to wait after a gain change before allowing another adjustment. |
| 89 | + Options: `8`, `16`, `24`, `32`. Defaults to `32`. |
| 90 | +- **hyst_level** (*Optional*, enum): Hysteresis level to prevent gain oscillation on borderline signals. |
| 91 | + Options: `None`, `Low`, `Medium`, `High`. |
| 92 | + |
| 93 | +## Actions |
| 94 | + |
| 95 | +This component provides actions to control the radio state, primarily used for coordinating transmission. |
| 96 | + |
| 97 | +- **cc1101.begin_tx**: Puts the radio into TX mode. Must be called before transmitting. |
| 98 | +- **cc1101.begin_rx**: Puts the radio into RX mode. Call after transmitting to resume receiving. |
| 99 | +- **cc1101.set_idle**: Puts the radio into an idle state. In single-pin configurations, this should be |
| 100 | + called before switching between TX and RX modes to ensure clean state transitions. |
| 101 | +- **cc1101.reset**: Resets the CC1101 chip and re-applies configuration. |
| 102 | + |
| 103 | +## Integration with Remote Receiver/Transmitter |
| 104 | + |
| 105 | +The component automatically configures the GDO pins to support both dual and single pin wiring schemes |
| 106 | +without any extra configuration. |
| 107 | + |
| 108 | +### 1. Dual Pin Wiring (Recommended) |
| 109 | + |
| 110 | +This is the simplest and recommended wiring scheme. It uses separate pins for transmitting and receiving data. |
| 111 | + |
| 112 | +- **GDO0 (Module Pin 3)**: Connect to the MCU pin used by `remote_transmitter`. |
| 113 | +- **GDO2 (Module Pin 8)**: Connect to the MCU pin used by `remote_receiver`. |
| 114 | + |
| 115 | +```yaml |
| 116 | +cc1101: |
| 117 | + cs_pin: GPIOXX |
| 118 | +
|
| 119 | +remote_transmitter: |
| 120 | + pin: GPIOXX # Must match GDO0 |
| 121 | + carrier_duty_percent: 100% |
| 122 | + on_transmit: |
| 123 | + then: |
| 124 | + - cc1101.begin_tx |
| 125 | + on_complete: |
| 126 | + then: |
| 127 | + - cc1101.begin_rx |
| 128 | +
|
| 129 | +remote_receiver: |
| 130 | + pin: GPIOXX # CC1101 GDO2 |
| 131 | + dump: all |
| 132 | +``` |
| 133 | + |
| 134 | +### 2. Single Pin Wiring |
| 135 | + |
| 136 | +This wiring scheme uses a single MCU pin for both transmitting and receiving data, connected to GDO0. |
| 137 | +This requires careful configuration of the `remote_transmitter` and `remote_receiver` to avoid conflicts. |
| 138 | +Using an open-drain pin mode is recommended to simplify the setup. |
| 139 | + |
| 140 | +- **GDO0 (Module Pin 3)**: Connect to a single MCU GPIO pin. |
| 141 | +- **GDO2 (Module Pin 8)**: Leave disconnected. |
| 142 | + |
| 143 | +#### Single Pin with Open-Drain |
| 144 | + |
| 145 | +ESP32 must use this method when using single-pin wiring. The shared pin should be set to open-drain with a |
| 146 | +pullup. The `eot_level` option (from `remote_transmitter`) controls the pin state after transmission |
| 147 | +completes - setting it to `false` keeps the pin low until explicitly released. In addition to setting the |
| 148 | +CC1101 mode in `on_transmit`/`on_complete`, the pin should be driven low before `begin_tx` and released |
| 149 | +before `begin_rx`. |
| 150 | + |
| 151 | +```yaml |
| 152 | +cc1101: |
| 153 | + cs_pin: GPIOXX |
| 154 | +
|
| 155 | +remote_receiver: |
| 156 | + pin: |
| 157 | + number: GPIOXX # Must match GDO0 |
| 158 | + mode: |
| 159 | + input: true |
| 160 | + output: true |
| 161 | + pullup: true |
| 162 | + open_drain: true |
| 163 | + allow_other_uses: true |
| 164 | + dump: all |
| 165 | +
|
| 166 | +remote_transmitter: |
| 167 | + pin: |
| 168 | + number: GPIOXX # Must match GDO0 |
| 169 | + mode: |
| 170 | + input: true |
| 171 | + output: true |
| 172 | + pullup: true |
| 173 | + open_drain: true |
| 174 | + allow_other_uses: true |
| 175 | + eot_level: false |
| 176 | + carrier_duty_percent: 100% |
| 177 | + on_transmit: |
| 178 | + then: |
| 179 | + - cc1101.set_idle |
| 180 | + - remote_transmitter.digital_write: false |
| 181 | + - cc1101.begin_tx |
| 182 | + on_complete: |
| 183 | + then: |
| 184 | + - cc1101.set_idle |
| 185 | + - remote_transmitter.digital_write: true |
| 186 | + - cc1101.begin_rx |
| 187 | +``` |
| 188 | + |
| 189 | +#### Single Pin with Mode Switching |
| 190 | + |
| 191 | +This method requires lambdas to manually switch the pin mode between input and output around transmissions. |
| 192 | +On boot, the pin must be set to input mode so the receiver can operate. |
| 193 | + |
| 194 | +```yaml |
| 195 | +esphome: |
| 196 | + on_boot: |
| 197 | + - priority: 0 |
| 198 | + then: |
| 199 | + - lambda: id(rx_pin)->pin_mode(gpio::FLAG_INPUT); |
| 200 | +
|
| 201 | +cc1101: |
| 202 | + cs_pin: GPIOXX |
| 203 | +
|
| 204 | +remote_receiver: |
| 205 | + pin: |
| 206 | + id: rx_pin |
| 207 | + number: GPIOXX # Must match GDO0 |
| 208 | + allow_other_uses: true |
| 209 | + dump: all |
| 210 | +
|
| 211 | +remote_transmitter: |
| 212 | + pin: |
| 213 | + id: tx_pin |
| 214 | + number: GPIOXX # Must match GDO0 |
| 215 | + allow_other_uses: true |
| 216 | + carrier_duty_percent: 100% |
| 217 | + on_transmit: |
| 218 | + then: |
| 219 | + - cc1101.set_idle |
| 220 | + - lambda: id(tx_pin)->pin_mode(gpio::FLAG_OUTPUT); |
| 221 | + - cc1101.begin_tx |
| 222 | + on_complete: |
| 223 | + then: |
| 224 | + - cc1101.set_idle |
| 225 | + - lambda: id(rx_pin)->pin_mode(gpio::FLAG_INPUT); |
| 226 | + - cc1101.begin_rx |
| 227 | +``` |
| 228 | + |
| 229 | +## Troubleshooting |
| 230 | + |
| 231 | +### "FF0F was found" Error |
| 232 | + |
| 233 | +If you see a log entry stating `FF0F`, `0000`, or `FFFF` during setup, this indicates an SPI |
| 234 | +communication failure. Check your wiring (MISO/MOSI/CS). |
| 235 | + |
| 236 | +### No Signal during Transmit |
| 237 | + |
| 238 | +- **Check Pinout**: For all modes, the data line must be connected to GDO0 (Module Pin 3), |
| 239 | + as the CC1101 chip only supports transmission input via the GDO0 pin. |
| 240 | +- **Check Pin Mode**: If using the Single Pin with Mode Switching method, |
| 241 | + ensure your `on_transmit`/`on_complete` logic correctly flips the pin mode. |
| 242 | + |
| 243 | +## See Also |
| 244 | + |
| 245 | +- [Remote Receiver](/components/remote_receiver) |
| 246 | +- [Remote Transmitter](/components/remote_transmitter) |
| 247 | +- [SPI Component](/components/spi) |
| 248 | +- [CC1101 Datasheet](https://www.ti.com/lit/ds/symlink/cc1101.pdf) |
0 commit comments