Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SX127x Component Docs #4278

Open
wants to merge 23 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added components/images/sx127x-full.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
282 changes: 282 additions & 0 deletions components/sx127x.rst
Original file line number Diff line number Diff line change
@@ -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 <https://www.semtech.com/products/wireless-rf/lora-connect/sx1278#documentation>`__) in ESPHome. Transceivers are connected via the :ref:`SPI Bus <spi>`. 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 <config-pin_schema>`): Reset pin.
- **nss_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): SPI select pin.
- **dio0_pin** (**Optional**, :ref:`Pin Schema <config-pin_schema>`): Digital IO pin 0.
- **dio2_pin** (**Optional**, :ref:`Pin Schema <config-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 <automation>`): An automation to perform in packet mode when a packet has been decoded. A variable x of type std::vector<uint8_t> 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 <config-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 <config-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 <config-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 <config-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 </components/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 </components/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`
Binary file added images/sx127x.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------------
Expand Down
Loading