RadioHead
RH_ABZ.h
1// RH_ABZ.h
2//
3// Definitions for SX1276 radio in muRata CMWX1ZZABZ (TypeABZ) module
4// as used in GrumpyOldPizza Grasshopper-L082CZ, EcoNode SmartTrap etc with
5// GrumpyOldPizza / ArduinoCore-stm32l0 installed per https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0
6//
7// For data refer to muRata Application note: AN-ZZABZ-001
8// muRata Preliminary Specification Number : SP-ABZ-093-E
9// $p/EcoNode
10//
11// Author: Mike McCauley (mikem@airspayce.com)
12// Copyright (C) 2020 Mike McCauley
13// $Id: RH_ABZ.h,v 1.1 2020/06/15 23:39:39 mikem Exp $
14//
15#ifndef RH_ABZ_h
16#define RH_ABZ_h
17
18#include <RH_RF95.h>
19
20/////////////////////////////////////////////////////////////////////
21/// \class RH_ABZ RH_ABZ.h <RH_ABZ.h>
22/// \brief Driver to send and receive unaddressed, unreliable datagrams via
23/// radio transceiver in a muRata cmwx1zzabz module, which includes an STM32L0 processor,
24/// a SX1276 LoRa radio and an antenna switch.
25///
26/// Requires the Grumpy Old Pizza Arduino Core installed per https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0
27///
28/// Works with EcoNode SmartTrap, Tlera Grasshopper and family. Almost any board equipped with a muRata cmwx1zzabz module
29/// should work. Tested with EcoNode SmartTrap, Arduino 1.8.9, GrumpyOldPizza Arduino Core for STM32L0.
30/// When building for EcoNode SmartTrap in Arduino IDE, select board type Grasshopper-L082CZ.
31/// This chip and GrumpyOldPizza Arduino Core for STM32L0 are now supported by PlatformIO:
32/// https://docs.platformio.org/en/latest/platforms/ststm32.html#arduino-stm32l0-configuration-system
33///
34/// \par Overview
35///
36/// This class is a specialisation of the RH_RF95 class, but with overridden functions to ensure that RH_RF95 communicates
37/// with the SX1276 radio on the correct SPI interface (STM32L0_SPI_INSTANCE_SPI1). The class configures the SPI and
38/// interfaces with the radio using native stm32l0 calls. It also uses stm32l0 calls to intialise the radio interface pins,
39/// antenna interface pins, and to toggle the radio NSS pin for SPI communicaitons. The reason for this speicalisaiton is that
40/// all the STM32L0 variants in the Grumpy Pizzas Arduino Core define the Arduino compatible SPI interface and the
41/// Arduino compatible IO pins in varying and inconsistent ways. So we use native stm32l0 calls to make _sure_ we get the right
42/// pins and interfaces.
43///
44/// All the comments in the RH_RF95 class concerning modulation, packet formats etc apply equally to this module.
45///
46/// \par Temperature Controlled Crystal Oscillator (TCXO)
47///
48/// The muRata cmwx1zzabz module includes a TCXO. Pins to enable the TCXO and to connect to 32MHz output to the radio
49/// are exposed on the module. Some boards (Econode SmartTrap for example) permanently power the TCXO and permanenetly
50/// connect it to the radio. Other boards (Grasshopper for example) have the TCXO enable connected to a GPIO pin, allowing
51/// the TCXO to be controlled by software. Different boards may use different GPIO pins to control the TCXO.
52///
53/// The SX1276 radio can be configured to use the TCXO, and the Arduino Core defaults the radio to using TCXO.
54/// Therefore it is important that you ensure the TCXO is powered up, at least when you want the radio to operate.
55/// If the TCXO is not powered, the radio will not work.
56///
57/// On the Tlera boards supported the Arduino Core, you can call SX1276SetBoardTcxo() to enable or disable the TCXO
58/// by controlling the correct pin for your board.
59/// By default the core disables TCXO at the end of initialisation, so by the time your sketch starts to run
60/// the TCXO is powered off.
61/// You will almost certainly need to call
62/// \code
63/// SX1276SetBoardTcxo(true);
64/// \endcode
65/// in your setup() or at other times when you want the radio to operate.
66///
67/// If you have a board where the TCXO is permanently powered, this is unnecessary.
68///
69/// \par Connecting and configuring the radio
70///
71/// There is no special configuration for the SX1276 radio in the muRata cmwx1zzabz module: the CPU, radio and
72/// antenna switch are all hardwired within the module can, and cannot be changed. Initialise the radio like this
73/// with the default constructor:
74/// \code
75/// RH_ABZ driver;
76/// \endcode
77///
78/// \par Range
79///
80/// We made some primitive range tests with 2 identical EcoNode SmartTrap at 868MHz, 20dBm transmit power with
81/// modem config RH_RF95::Bw125Cr45Sf2048, using the abz_client and abz_server sketches included in this distribution.
82/// We monitored for reliabilty of 2-way communications (ie how reliably can the client get a reply from the server,
83/// which is a 2-way comms that depends on both send and receive. The SmartTrap has a simple small helical antenna.
84/// The environment was a beach in a developed area, one node was stationary
85/// 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.
86///
87/// \code
88/// Location Distance (km) % successful round trip
89/// Elephant Rock 0 100
90/// Dune St 1.48 100
91/// Shell St 1.71 100
92/// Sand St 1.93 100
93/// Sea St 2.15 0
94/// Short St 2.36 50
95/// John St 2.59 50
96/// Surf St 2.80 100
97/// Matters St 2.98 100
98/// Mills St 3.92 100
99/// North Kirra 4.62 0
100/// North Kirra SLSC 4.81 80
101/// Haig St 5.20 0
102/// Kirra SLSC 5.91 0
103/// \endcode
104///
105/// \par Transmitter Power
106///
107/// We have made some actual power measurements against
108/// programmed power on an EcoNode SmartTrap.
109/// - EcoNode SmartTrap at 868MHz
110/// - 15cm RG316 soldered direct to SmartTrap antenna pin
111/// - SMA/BNC connector
112/// - 12db attenuator (calibrated as 13.5dB at 868MHz)
113/// - SMA/BNC connector
114/// - 30cm RG316
115/// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
116/// - Tektronix TDS220 scope to measure the Vout from power head
117/// \code
118/// useRFO==false (ie uses PA_BOOST for higher power)
119/// Program power Measured Power
120/// dBm dBm
121/// 2 2.7
122/// 5 5
123/// 7 6.5
124/// 10 9.5
125/// 13 12.5
126/// 15 14.5
127/// 16 15.5
128/// 17 16.5
129/// 18 17.2
130/// 19 17.6
131/// 20 18.2
132///
133/// useRFO==true (ie no PA_BOOST)
134/// Program power Measured Power
135/// dBm dBm
136/// 0 -5.5
137/// 2 -2.5
138/// 4 -0.5
139/// 6 2
140/// 8 4
141/// 10 6.5
142/// 12 9
143/// 13 10.5
144/// 14 11.5
145/// 15 12.5
146/// \endcode
147
148/// In the the Grumpy Old Pizza Arduino Core, there is a function for turning the
149/// TCXO power source on and off, which depends on exactly which board is being compiled for
150/// If the Radio in your boards has its TCXO connected to a programmable power pin,
151/// and if you enable TCXO on the radio (by default it is on these boards)
152/// then this function needs to be called to enable the TCXO before the radio will work.
153extern "C" void SX1276SetBoardTcxo( bool state );
154
155class RH_ABZ : public RH_RF95
156{
157public:
158 /// Constructor
160
161 /// Initialise the Driver transport hardware and software. Leaves the radio in idle mode,
162 /// with default configuration of: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
163 /// \return true if initialisation succeeded.
164 virtual bool init();
165
166 /// Deinitialise the interrupt handler, allowing the radio to be temporarily used by another stack.
167 /// If you wish to use the radio again after this call, you wil need to call init() again.
168 /// \return true if deinitialisation succeeded.
169 bool deinit();
170
171protected:
172 /// Called by RH_RF95 when the radio mode is about to change to a new setting.
173 /// Configures the antenna switch to connect to the right radio pin.
174 /// \param[in] mode RHMode the new mode about to take effect
175 /// \return true if the subclasses changes successful
177
178 /// Called by RHSPIDriver when the SPI is about to talk to the radio.
179 /// Uses native spi32l0 calls to enable the radio NSS pin
180 virtual void selectSlave();
181
182 /// Called by RHSPIDriver when the SPI is finished talking to the radio.
183 /// Uses native spi32l0 calls to disable the radio NSS pin
184 virtual void deselectSlave();
185
186private:
187 /// Glue code between the DIO0 interrupt the interrupt handler in RH_RF95
188 static void RH_INTERRUPT_ATTR isr();
189
190 /// Pointer to the one and only instance permitted, for interrupt linkage
191 static RH_ABZ* _thisDevice;
192
193};
194
195/// @example abz_client.ino
196/// @example abz_server.ino
197
198#endif
RHMode
Defines different operating modes for the transport hardware.
Definition RHGenericDriver.h:49
virtual RHMode mode()
Definition RHGenericDriver.cpp:165
Driver to send and receive unaddressed, unreliable datagrams via radio transceiver in a muRata cmwx1z...
Definition RH_ABZ.h:156
RH_ABZ()
Constructor.
bool deinit()
virtual void selectSlave()
virtual bool init()
virtual void deselectSlave()
virtual bool modeWillChange(RHMode mode)
Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver.
Definition RH_RF95.h:573