RadioHead
Public Member Functions | Protected Member Functions | List of all members
RH_ABZ Class Reference

Driver to send and receive unaddressed, unreliable datagrams via radio transceiver in a muRata cmwx1zzabz module, which includes an STM32L0 processor, a SX1276 LoRa radio and an antenna switch. More...

#include <RH_ABZ.h>

Inheritance diagram for RH_ABZ:
RH_RF95 RHSPIDriver RHGenericDriver

Public Member Functions

 RH_ABZ ()
 Constructor.
 
virtual bool init ()
 
bool deinit ()
 
- Public Member Functions inherited from RH_RF95
 RH_RF95 (uint8_t slaveSelectPin=SS, uint8_t interruptPin=2, RHGenericSPI &spi=hardware_spi)
 
virtual bool init ()
 
bool printRegisters ()
 
void setModemRegisters (const ModemConfig *config)
 
bool setModemConfig (ModemConfigChoice index)
 
virtual bool available ()
 
virtual bool recv (uint8_t *buf, uint8_t *len)
 
virtual bool send (const uint8_t *data, uint8_t len)
 
void setPreambleLength (uint16_t bytes)
 
virtual uint8_t maxMessageLength ()
 
bool setFrequency (float centre)
 
void setModeIdle ()
 
void setModeRx ()
 
void setModeTx ()
 
void setTxPower (int8_t power, bool useRFO=false)
 
virtual bool sleep ()
 
virtual bool isChannelActive ()
 
void enableTCXO (bool on=true)
 
int frequencyError ()
 
int lastSNR ()
 
void setSpreadingFactor (uint8_t sf)
 
void setSignalBandwidth (long sbw)
 
void setCodingRate4 (uint8_t denominator)
 
void setLowDatarate ()
 
void setPayloadCRC (bool on)
 
uint8_t getDeviceVersion ()
 
- Public Member Functions inherited from RHSPIDriver
 RHSPIDriver (uint8_t slaveSelectPin=SS, RHGenericSPI &spi=hardware_spi)
 
bool init ()
 
uint8_t spiRead (uint8_t reg)
 
uint8_t spiWrite (uint8_t reg, uint8_t val)
 
uint8_t spiBurstRead (uint8_t reg, uint8_t *dest, uint8_t len)
 
uint8_t spiBurstWrite (uint8_t reg, const uint8_t *src, uint8_t len)
 
void setSlaveSelectPin (uint8_t slaveSelectPin)
 
void spiUsingInterrupt (uint8_t interruptNumber)
 
- Public Member Functions inherited from RHGenericDriver
 RHGenericDriver ()
 Constructor.
 
virtual ~RHGenericDriver ()
 Generic destructor to prevent warnings when objects are dynamically allocated.
 
virtual bool init ()
 
virtual bool available ()=0
 
virtual bool recv (uint8_t *buf, uint8_t *len)=0
 
virtual bool send (const uint8_t *data, uint8_t len)=0
 
virtual uint8_t maxMessageLength ()=0
 
virtual void waitAvailable (uint16_t polldelay=0)
 
virtual bool waitPacketSent ()
 
virtual bool waitPacketSent (uint16_t timeout)
 
virtual bool waitAvailableTimeout (uint16_t timeout, uint16_t polldelay=0)
 
virtual bool waitCAD ()
 
void setCADTimeout (unsigned long cad_timeout)
 
virtual bool isChannelActive ()
 
virtual void setThisAddress (uint8_t thisAddress)
 
virtual void setHeaderTo (uint8_t to)
 
virtual void setHeaderFrom (uint8_t from)
 
virtual void setHeaderId (uint8_t id)
 
virtual void setHeaderFlags (uint8_t set, uint8_t clear=RH_FLAGS_APPLICATION_SPECIFIC)
 
virtual void setPromiscuous (bool promiscuous)
 
virtual uint8_t headerTo ()
 
virtual uint8_t headerFrom ()
 
virtual uint8_t headerId ()
 
virtual uint8_t headerFlags ()
 
virtual int16_t lastRssi ()
 
virtual RHMode mode ()
 
virtual void setMode (RHMode mode)
 Sets the operating mode of the transport. More...
 
virtual bool sleep ()
 
virtual uint16_t rxBad ()
 
virtual uint16_t rxGood ()
 
virtual uint16_t txGood ()
 

Protected Member Functions

virtual bool modeWillChange (RHMode mode)
 
virtual void selectSlave ()
 
virtual void deselectSlave ()
 
- Protected Member Functions inherited from RH_RF95
bool setupInterruptHandler ()
 Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs.
 
void handleInterrupt ()
 
void validateRxBuf ()
 Examine the revceive buffer to determine whether the message is for this node.
 
void clearRxBuf ()
 Clear our local receive buffer.
 
virtual bool modeWillChange (RHMode)
 
- Protected Member Functions inherited from RHSPIDriver
virtual void beginTransaction ()
 
virtual void endTransaction ()
 
virtual void selectSlave ()
 
virtual void deselectSlave ()
 

Additional Inherited Members

- Public Types inherited from RH_RF95
enum  ModemConfigChoice {
  Bw125Cr45Sf128 = 0 , Bw500Cr45Sf128 , Bw31_25Cr48Sf512 , Bw125Cr48Sf4096 ,
  Bw125Cr45Sf2048
}
 
- Public Types inherited from RHGenericDriver
enum  RHMode {
  RHModeInitialising = 0 , RHModeSleep , RHModeIdle , RHModeTx ,
  RHModeRx , RHModeCad
}
 Defines different operating modes for the transport hardware. More...
 
- Static Public Member Functions inherited from RHGenericDriver
static void printBuffer (const char *prompt, const uint8_t *buf, uint8_t len)
 
- Protected Attributes inherited from RH_RF95
bool _useRFO
 
- Protected Attributes inherited from RHSPIDriver
RHGenericSPI_spi
 Reference to the RHGenericSPI instance to use to transfer data with the SPI device.
 
uint8_t _slaveSelectPin
 The pin number of the Slave Select pin that is used to select the desired device.
 
- Protected Attributes inherited from RHGenericDriver
volatile RHMode _mode
 The current transport operating mode.
 
uint8_t _thisAddress
 This node id.
 
bool _promiscuous
 Whether the transport is in promiscuous mode.
 
volatile uint8_t _rxHeaderTo
 TO header in the last received mesasge.
 
volatile uint8_t _rxHeaderFrom
 FROM header in the last received mesasge.
 
volatile uint8_t _rxHeaderId
 ID header in the last received mesasge.
 
volatile uint8_t _rxHeaderFlags
 FLAGS header in the last received mesasge.
 
uint8_t _txHeaderTo
 TO header to send in all messages.
 
uint8_t _txHeaderFrom
 FROM header to send in all messages.
 
uint8_t _txHeaderId
 ID header to send in all messages.
 
uint8_t _txHeaderFlags
 FLAGS header to send in all messages.
 
volatile int16_t _lastRssi
 The value of the last received RSSI value, in some transport specific units.
 
volatile uint16_t _rxBad
 Count of the number of bad messages (eg bad checksum etc) received.
 
volatile uint16_t _rxGood
 Count of the number of successfully transmitted messaged.
 
volatile uint16_t _txGood
 Count of the number of bad messages (correct checksum etc) received.
 
volatile bool _cad
 Channel activity detected.
 
unsigned int _cad_timeout
 Channel activity timeout in ms.
 

Detailed Description

Driver to send and receive unaddressed, unreliable datagrams via radio transceiver in a muRata cmwx1zzabz module, which includes an STM32L0 processor, a SX1276 LoRa radio and an antenna switch.

Requires the Grumpy Old Pizza Arduino Core installed per https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0

Works with EcoNode SmartTrap, Tlera Grasshopper and family. Almost any board equipped with a muRata cmwx1zzabz module should work. Tested with EcoNode SmartTrap, Arduino 1.8.9, GrumpyOldPizza Arduino Core for STM32L0. When building for EcoNode SmartTrap in Arduino IDE, select board type Grasshopper-L082CZ. This chip and GrumpyOldPizza Arduino Core for STM32L0 are now supported by PlatformIO: https://docs.platformio.org/en/latest/platforms/ststm32.html#arduino-stm32l0-configuration-system

Overview

This class is a specialisation of the RH_RF95 class, but with overridden functions to ensure that RH_RF95 communicates with the SX1276 radio on the correct SPI interface (STM32L0_SPI_INSTANCE_SPI1). The class configures the SPI and interfaces with the radio using native stm32l0 calls. It also uses stm32l0 calls to intialise the radio interface pins, antenna interface pins, and to toggle the radio NSS pin for SPI communicaitons. The reason for this speicalisaiton is that all the STM32L0 variants in the Grumpy Pizzas Arduino Core define the Arduino compatible SPI interface and the Arduino compatible IO pins in varying and inconsistent ways. So we use native stm32l0 calls to make sure we get the right pins and interfaces.

All the comments in the RH_RF95 class concerning modulation, packet formats etc apply equally to this module.

Temperature Controlled Crystal Oscillator (TCXO)

The muRata cmwx1zzabz module includes a TCXO. Pins to enable the TCXO and to connect to 32MHz output to the radio are exposed on the module. Some boards (Econode SmartTrap for example) permanently power the TCXO and permanenetly connect it to the radio. Other boards (Grasshopper for example) have the TCXO enable connected to a GPIO pin, allowing the TCXO to be controlled by software. Different boards may use different GPIO pins to control the TCXO.

The SX1276 radio can be configured to use the TCXO, and the Arduino Core defaults the radio to using TCXO. Therefore it is important that you ensure the TCXO is powered up, at least when you want the radio to operate. If the TCXO is not powered, the radio will not work.

On the Tlera boards supported the Arduino Core, you can call SX1276SetBoardTcxo() to enable or disable the TCXO by controlling the correct pin for your board. By default the core disables TCXO at the end of initialisation, so by the time your sketch starts to run the TCXO is powered off. You will almost certainly need to call

SX1276SetBoardTcxo(true);

in your setup() or at other times when you want the radio to operate.

If you have a board where the TCXO is permanently powered, this is unnecessary.

Connecting and configuring the radio

There is no special configuration for the SX1276 radio in the muRata cmwx1zzabz module: the CPU, radio and antenna switch are all hardwired within the module can, and cannot be changed. Initialise the radio like this with the default constructor:

RH_ABZ driver;
Driver to send and receive unaddressed, unreliable datagrams via radio transceiver in a muRata cmwx1z...
Definition: RH_ABZ.h:156
Range

We made some primitive range tests with 2 identical EcoNode SmartTrap at 868MHz, 20dBm transmit power with modem config RH_RF95::Bw125Cr45Sf2048, using the abz_client and abz_server sketches included in this distribution. We monitored for reliabilty of 2-way communications (ie how reliably can the client get a reply from the server, which is a 2-way comms that depends on both send and receive. The SmartTrap has a simple small helical antenna. The environment was a beach in a developed area, one node was stationary on a rock about 1m above sand level. The mobile node was handl-held at 1 m above ground level. All measurements were line-of-sight.

Location Distance (km) % successful round trip
Elephant Rock 0 100
Dune St 1.48 100
Shell St 1.71 100
Sand St 1.93 100
Sea St 2.15 0
Short St 2.36 50
John St 2.59 50
Surf St 2.80 100
Matters St 2.98 100
Mills St 3.92 100
North Kirra 4.62 0
North Kirra SLSC 4.81 80
Haig St 5.20 0
Kirra SLSC 5.91 0
Transmitter Power

We have made some actual power measurements against programmed power on an EcoNode SmartTrap.

Member Function Documentation

◆ deinit()

bool RH_ABZ::deinit ( )

Deinitialise the interrupt handler, allowing the radio to be temporarily used by another stack. If you wish to use the radio again after this call, you wil need to call init() again.

Returns
true if deinitialisation succeeded.

◆ deselectSlave()

virtual void RH_ABZ::deselectSlave ( )
protectedvirtual

Called by RHSPIDriver when the SPI is finished talking to the radio. Uses native spi32l0 calls to disable the radio NSS pin

Reimplemented from RHSPIDriver.

◆ init()

virtual bool RH_ABZ::init ( )
virtual

Initialise the Driver transport hardware and software. Leaves the radio in idle mode, with default configuration of: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

Returns
true if initialisation succeeded.

Reimplemented from RH_RF95.

◆ modeWillChange()

virtual bool RH_ABZ::modeWillChange ( RHMode  mode)
protectedvirtual

Called by RH_RF95 when the radio mode is about to change to a new setting. Configures the antenna switch to connect to the right radio pin.

Parameters
[in]modeRHMode the new mode about to take effect
Returns
true if the subclasses changes successful

Reimplemented from RH_RF95.

◆ selectSlave()

virtual void RH_ABZ::selectSlave ( )
protectedvirtual

Called by RHSPIDriver when the SPI is about to talk to the radio. Uses native spi32l0 calls to enable the radio NSS pin

Reimplemented from RHSPIDriver.


The documentation for this class was generated from the following file: