diff --git a/components/images/sx127x-full.jpg b/components/images/sx127x-full.jpg new file mode 100644 index 0000000000..6c461d36f0 Binary files /dev/null and b/components/images/sx127x-full.jpg differ diff --git a/components/sx127x.rst b/components/sx127x.rst new file mode 100644 index 0000000000..8b715e1b6b --- /dev/null +++ b/components/sx127x.rst @@ -0,0 +1,282 @@ +SX1276/7/8/9 Component +================================================================ + +.. seo:: + :description: Instructions for setting up SX1276/SX1277/SX1278/SX1279 transceivers. + :image: sx127x.jpg + +The ``sx127x`` component allows you to configure the SX1276, SX1277, SX1278 and SX1279 transceivers +(`datasheet `__) in ESPHome. Transceivers are connected via the :ref:`SPI Bus `. Supported frequencies range from 137 MHz to 1020 MHz. Supported modulations include OOK, FSK, GFSK, MSK and GMSK. The LoRa modem is not supported by this component, only the FSK/OOK modem. + +.. figure:: images/sx127x-full.jpg + :align: center + :width: 40.0% + +.. code-block:: yaml + + # Example configuration entry + spi: + clk_pin: GPIO5 + mosi_pin: GPIO27 + miso_pin: GPIO19 + + sx127x: + nss_pin: GPIO18 + rst_pin: GPIO23 + frequency: 433920000 + modulation: OOK + rx_start: true + rx_bandwidth: 50_0kHz + rx_floor: -90 + pa_pin: BOOST + pa_power: 17 + shaping: NONE + fsk_fdev: 5000 + fsk_ramp: 40us + +Configuration variables: +------------------------ + +- **rst_pin** (**Required**, :ref:`Pin Schema `): Reset pin. +- **nss_pin** (**Required**, :ref:`Pin Schema `): SPI select pin. +- **dio0_pin** (**Optional**, :ref:`Pin Schema `): Digital IO pin 0. +- **dio2_pin** (**Optional**, :ref:`Pin Schema `): Digital IO pin 2. +- **frequency** (**Required**, int): Frequency in Hz of the transceiver. +- **modulation** (**Required**, enum): Modulation can be ``OOK`` or ``FSK``. +- **payload_length** (**Optional**, int): If set to a length greater than zero packet mode is enabled, otherwise continuous mode is used. In packet mode, packets are received with the on_packet trigger and sent via the send_packet automation. In continuous mode raw data appears on DIO2 and is handled by remote receiver / transmitter. +- **bitrate** (**Optional**, int): Bit rate of the signal. Required by packet mode and recommended in continuous mode, example 4800. +- **bitsync** (**Optional**, bool): Enables the rx bit syncronizer. +- **sync_value** (**Optional**, list): Synchronization bytes found after the preamble and before the payload. Required by packet mode. +- **preamble_size** (**Optional**, int): Length of the preamble in bytes. Preamble detector is disabled if the size is 0. Required by packet mode. +- **preamble_polarity** (**Optional**, int): Polarity of the preamble, either 0xAA or 0x55. +- **preamble_errors** (**Optional**, int): Number of chip errors tolerated over the preamble, 4 chips per bit. +- **rx_start** (**Optional**, bool): Start the receiver on boot or after transmit. +- **rx_bandwidth** (**Optional**, enum): Receive bandwidth can be ``2_6kHz``, ``3_1kHz``, ``3_9kHz``, ``5_2kHz``, ``6_3kHz``, ``7_8kHz``, ``10_4kHz``, ``12_5kHz``, ``15_6kHz``, ``20_8kHz``, ``25_0kHz``, ``31_3kHz``, ``41_7kHz``, ``50_0kHz``, ``62_5kHz``, ``83_3kHz``, ``100_0kHz``, ``125_0kHz``, ``166_7kHz``, ``200_0kHz`` or ``250_0kHz``. +- **rx_floor** (**Optional**, float): When receiving FSK in continuous mode, without a preamble configured, rx_floor is used to trigger the receiver. When receiving OOK in continuous mode rx_floor should be set appropriately for your environment / device / antenna. If the floor is set too high (ie closer to 0) the radio will ignore everything. If the floor is set too low (ie closer to -128) noise will overwhelm remote receiver. A good starting point is -90 dBm. +- **rx_duration** (**Optional**, int or :ref:`config-time`): Requires DIO0 and DIO2 to be configured in continuous mode. The FSK demodulator unlike OOK cannot be gated by signal strength. In order to reduce noise DIO2 can be automatically gated until the receiver is triggered by either rssi or a preamble detection. Once triggered DIO2 is ungated temporarily for ``rx_duration``. It is recommended to use ``rx_duration`` for debug only and instead use packet mode for FSK. +- **pa_pin** (**Optional**, enum): Transmitter output, can be ``BOOST`` or ``RFO``. +- **pa_power** (**Optional**, int): Transmitter power, range is 0 to 17 dBm. +- **shaping** (**Optional**, enum): Transmitter data shaping, valid values for OOK are ``CUTOFF_BR_X_2``, ``CUTOFF_BR_X_1`` or ``NONE``, valid values for FSK are ``GAUSSIAN_BT_0_3``, ``GAUSSIAN_BT_0_5``, ``GAUSSIAN_BT_1_0`` or ``NONE``. Note only recommended in packet mode, in continuous mode the data on DIO2 must to be synchronized with the bit clock on DIO1. +- **fsk_fdev** (**Optional**, int): Transmitter frequency deviation, valid values range from 0 to 100,000 Hz. +- **fsk_ramp** (**Optional**, enum): Transmitter PA ramp, valid values are ``10us``, ``12us``, ``15us``, ``20us``, ``25us``, ``31us``, ``40us``, ``50us``, ``62us``, ``100us``, ``125us``, ``250us``, ``500us``, ``1000us``, ``2000us`` or ``3400us``. + +.. note:: + + The config can be changed at runtime using lambdas. Settings, except for mode changes, will only be applied after calling configure. See :apiref:`sx127x/sx127x.h`. + +Automations: +------------ + +- **on_packet** (*Optional*, :ref:`Automation `): An automation to perform in packet mode when a packet has been decoded. A variable x of type std::vector is passed to the automation for use in lambdas. + +.. code-block:: yaml + + sx127x: + ... + on_packet: + then: + - lambda: |- + ESP_LOGD("lambda", "packet %s", format_hex(x).c_str()); + +Actions: +-------- + +``sx127x.set_mode_tx`` **Action** + +This :ref:`action ` sets the ``sx127x`` mode to tx, ``sx127x`` needs to be in continuous mode. If DIO2 is configured the pin mode will be set appropriately. + +.. code-block:: yaml + + on_...: + - sx127x.set_mode_tx + +``sx127x.set_mode_rx`` **Action** + +This :ref:`action ` sets the ``sx127x`` mode to rx. If DIO2 is configured the pin mode will be set appropriately. + +.. code-block:: yaml + + on_...: + - sx127x.set_mode_rx + +``sx127x.set_mode_standby`` **Action** + +This :ref:`action ` sets the ``sx127x`` mode to standby. If DIO2 is configured the pin mode will be set appropriately. + +.. code-block:: yaml + + on_...: + - sx127x.set_mode_standby + +``sx127x.send_packet`` **Action** + +This :ref:`action ` sends a packet, the ``sx127x`` needs to be in packet mode. + +.. code-block:: yaml + + on_...: + - sx127x.send_packet: + data: [0x1F, 0x3E, 0x06, 0x5F, 0x4F, 0x5F, 0xAC, 0xB1] + +Configuration variables: + +- **data** (**Required**, list): The packet to send, length should match the configured payload_length. + +Packet Mode: +------------ + +In packet mode the radio can be used as both a transmitter and receiver. Mode changes are handled transparently. + +.. code-block:: yaml + + # Example configuration entry + sx127x: + dio0_pin: GPIO26 + nss_pin: GPIO18 + rst_pin: GPIO23 + pa_pin: BOOST + pa_power: 17 + bitsync: true + bitrate: 4800 + frequency: 433920000 + modulation: FSK + rx_start: true + payload_length: 8 + sync_value: [0x33, 0x33] + preamble_size: 2 + preamble_errors: 8 + preamble_polarity: 0x55 + on_packet: + then: + - lambda: |- + ESP_LOGD("lambda", "packet %s", format_hex(x).c_str()); + + interval: + - interval: 60sec + then: + - sx127x.send_packet: + data: [0xC5, 0x51, 0x78, 0x82, 0xB7, 0xF9, 0x9C, 0x5C] + +Continuous Mode: +---------------- + +**As a Receiver:** + +The radio will output demodulated data onto DIO2, typically :doc:`remote_receiver ` is used to handle this. Remote Receiver can either decode the signal itself or pass the raw data to another component (or lambda). + +.. code-block:: yaml + + # Example configuration entry + sx127x: + nss_pin: GPIO18 + rst_pin: GPIO23 + frequency: 433920000 + modulation: OOK + rx_start: true + rx_bandwidth: 50_0kHz + rx_floor: -90 + + remote_receiver: + pin: GPIO32 + dump: raw + +.. note:: + + The pin used by remote receiver must be DIO2 not DIO0. + +**As a Transmitter:** + +The radio expects raw data to be sent on DIO2, typically :doc:`remote_transmitter ` is used to handle this. The radio transmitter must be enabled before transmit and disabled after. Ideally this is done using the remote transmitter triggers on_transmit and on_complete. + +.. code-block:: yaml + + # Example configuration entry + sx127x: + nss_pin: GPIO18 + rst_pin: GPIO23 + frequency: 433920000 + modulation: OOK + rx_start: false + pa_pin: BOOST + pa_power: 17 + + remote_transmitter: + pin: GPIO32 + carrier_duty_percent: 100% + on_transmit: + then: + - sx127x.set_mode_tx + on_complete: + then: + - sx127x.set_mode_standby + + interval: + - interval: 30sec + then: + - remote_transmitter.transmit_raw: + code: [614, -614, 600, -614, 614, -614, 601, -614] + +.. note:: + + The pin used by remote transmitter must be DIO2 not DIO0. + +**As a Transmitter & Receiver:** + +The radio can be used as both a transmitter and receiver. The same pin is used for both rx and tx. In order to make things work the gpio mode and radio mode must be set appropriately. The gpio mode will automatically be set if DIO2 is configured. + +.. code-block:: yaml + + # Example configuration entry + sx127x: + dio2_pin: + number: GPIO32 + allow_other_uses: true + nss_pin: GPIO18 + rst_pin: GPIO23 + frequency: 433920000 + modulation: OOK + rx_start: true + rx_bandwidth: 50_0kHz + rx_floor: -90 + pa_pin: BOOST + pa_power: 17 + + remote_receiver: + id: rx_id + pin: + number: GPIO32 + allow_other_uses: true + dump: raw + + remote_transmitter: + id: tx_id + pin: + number: GPIO32 + allow_other_uses: true + carrier_duty_percent: 100% + on_transmit: + then: + - sx127x.set_mode_tx + - lambda: id(tx_id)->setup(); // workaround + on_complete: + then: + - sx127x.set_mode_rx + + interval: + - interval: 30sec + then: + - remote_transmitter.transmit_raw: + code: [614, -614, 600, -614, 614, -614, 601, -614] + +.. note:: + + A workaround is currently needed in remote transmitter. Setup must be called again before transmitting after a gpio mode change. + +See Also +-------- + +- :doc:`index` +- :doc:`/components/remote_transmitter` +- :doc:`/components/remote_receiver` +- :apiref:`sx127x/sx127x.h` +- :ghedit:`Edit` diff --git a/images/sx127x.jpg b/images/sx127x.jpg new file mode 100644 index 0000000000..e7859ae313 Binary files /dev/null and b/images/sx127x.jpg differ diff --git a/index.rst b/index.rst index e14b79a9f8..5f3d2ba489 100644 --- a/index.rst +++ b/index.rst @@ -1109,6 +1109,7 @@ Wireless communication that is **not Wi-Fi.** Remote Transmitter, components/remote_transmitter, remote.svg, dark-invert RF Bridge, components/rf_bridge, rf_bridge.jpg SIM800L, components/sim800l, sim800l.jpg + SX1276/7/8/9, components/sx127x, sx127x.jpg Miscellaneous Components ------------------------