Many (mostly legacy) radio applications that receive OOK modulated signals quite often has an MCU which is responsible for decoding the radio packets. In such an application the radio receiver “only” has to feed the MCU with the raw demodulated signal.
More often than not the packet structures of these application are not suitable for using either preamble detection or packet handling within EZRadioPRO. Radio packets that have irregular bit times (i.e., PWM modulated data) and / or very short preambles at the beginning of the packets that does not allow for robust preamble detection all fall under this packet category. This article gives a guideline of how to configure EZRadioPRO for receiving such a legacy packet and forwarding the raw demodulated bit stream to the MCU.
The starting point for all these cases is a direct mode receive project from WDS’s RCA application. In direct mode the detector that demodulates the OOK bit stream is invariably the PEAK detector. The detector’s input is RSSI (Radio Signal Strength Indicator) that is proportional to the log of the input power level (of the signal that has already passed through the IF filter). The PEAK detector follows the envelope of the RSSI values with a fast attack slow decay dynamic behavior. Whenever there is a big jump upwards in the RSSI level the PEAK detector “charges up” to this level fast, whereas when there is drop in the RSSI level the detector starts “discharging” at a much slower rate. The charge up and down rates of the detector are adjustable in API property MODEM_OOK_PDTC. The PEAK detector develops the slicing threshold so many dBs below its current value. This value is by default 12 dB, but adjustable in API property MODEM_OOK_BLOPK.
The PEAK detector compares the current RSSI sample with the slicing threshold (developed as PEAK detector value - 12 dB) and decides on a logical one if the current RSSI sample is above the threshold and a logical zero if the current RSSI sample is below the threshold. See a drawing of the operation below.
Even though from the graph it may seem that the time resolution on the signals involved are rather high in reality the PEAK detector/slicer is clocking at a frequency typically 8 times the configured DR. The output signal of the detector is referred to as RX_RAW_DATA and is accessible on GPIOs (demodulated data on the graph). This is the signal that is recommended to be forwarded to the MCU for decoding purposes.
*Tip: The exact clock frequency of the detector can be measured by measuring the minimum “glitch” width on RX_RAW_DATA while receiving noise. The corresponding frequency will give the clock frequency of the PEAK detector.
*Note: RX_DATA which is also available on GPIOs only changes with the configured DR. This may as well be an option but only at cases where the DR in the packet does not change and has many transitions. RX_DATA is the output of the Bit Clock Recovery circuit that samples RX_RAW_DATA at the configured DR extracting the bit timing from the RX_RAW_DATA stream itself (hence the need for transitions).
There are a few interesting factors that are worth discussing on this graph. The first one is that the demodulated value right at the beginning of the time axis is a digital one while clearly there is just noise on the RSSI sample curve indicating so a digital zero level. This is an artifact of the working mechanisms of the PEAK detector. While only following noise the detector will charge up to the noise peaks and develops its slicing threshold 12 dB below this. Typically most RSSI samples taken on noise will be higher than this threshold therefore they will be demodulated as digital ones. So in most cases the demodulated raw data stream is biased towards digital ones while receiving noise with the PEAK detector. (Various Rx filter configurations may change this behavior, typically at narrower bandwidth filters this bias is less pronounced.)
** Disregard the PKT_TX_ST (aka PKT_TX_START) and TX_DATA traces.
The second point is that if after a successfully demodulated logical one symbol there are many logical zero symbols it may happen that the detector “hits” the noise floor and starts outputting ones before the next real logical one symbol arrived. In such a case the demodulated data stream will not be correct. Clearly there is a limitation here in the sense that the maximum number of logical zero symbols following logical one symbols must be less than a certain number for successful demodulation. An example is shown on the scope screenshot below where 20 byte worth of zeroes follow the 1st one symbol in a packet. The receiver was configured to 4.8 kbps DR and 200 kHz receive bandwidth at 868 MHz. The test packet power was set to -80 dBm.
The demodulated bit stream is clearly not correct from roughly 13 bytes after the initial one symbol. Note that this time window will even get narrower with ever lower test signal power levels and ultimately has an adverse effect on sensitivity if a long zero trail has to be demodulated.
The cure to the issue could be configuring a slower discharge rate in API property MODEM_OOK_PDTC and can still be extended further by configuring field “OOK_DISCHG_DIV” in API property MODEM_OOK_MISC that enables further extensions by a factor of 2, 4 and 8. As an example find a screenshot below with the same configuration as above with only the discharge rate maxed out in API property MODEM_OOK_PDTC.
Now, the reception is clean and the “slow down extend feature” did not even have to be engaged. As the decay changes exponentially with the API property value a few code difference can have a huge impact.
The only slight disadvantage of slowing down the detector’s discharge rate is that it will become more prone to making mistakes during demodulation if the power changes during the packet (i.e., in a multipath fading environment). If a logical one symbol following another logical one symbol has a lower power level the detector may not discharge to its power level by the time it arrives, so it will get demodulated as a logical zero. So for a robust solution only extend the discharge rate as much as needed, don’t just max it out! You can do this by examining a similar scope screenshot at the expected sensitivity level and tuning the discharge rate parameter until the reception is acceptable.
Note also that changing the discharge rate on the detector will also alter its behavior on noise. As the threshold is staying at a higher level for more time (because of the slower decay) the demodulated data stream will have more 0 symbols in it. You can capture this behavior at the beginning of the scope screenshots.
Now, if you only have a short preamble but solid DR, you are pretty much done at this point. After tuning the decay parameter for the longest zero trail in your packet simply feed RX_DATA to the MCU.
If, however you have irregular and or multiple data rates in the packet you must make the detector oversample to a rate where the resolution in time on the output RX_RAW_DATA stream makes it possible that all the various bit times in the packet can be “composed”. In such cases it is not recommended to use the RX_DATA output since it can only ever change with the configured DR.
Let’s take an example! Suppose we have two bit times t1 = 57 us and t2 = 32 us. If you calculate the greatest common divisor of the two bit times you get 1 us meaning a 1MHz clock rate on the detector to be able to exactly synthesize above bit times. The highest you can achieve on the part is the maximum DR of 120 kbps multiplied by the detector’s oversampling rate of 8 = 960 kHz. So configuring the DR to 120 kbps could be one solution. Note that exact timings still won’t be guaranteed.
Increasing the DR (and therefore) the oversampling ratio in the detector has one disadvantage though. You can only select filter BWs in WDS that are at least twice the DR, therefore increasing the DR to ever higher values will put a limit on the minimum filter bandwidth which in turn could have a degrading effect on sensitivity. A nicer way would be using the least oversampling we could get away with.
Consider again the above example with the addition that the MCU can tolerate +/- 10% bit timing errors at decoding. Calculating this timing tolerance on the shorter time we get 3.2 us. The corresponding clock frequency is 312.5 kHz. Dividing this by the typical oversampling rate of the detector we get 39.0625 kHz. So a DR of at least this much will ensure that the timing resolution on RX_RAW_DATA will be adequate for decoding purposes in the MCU.
The detector’s charge and discharge rates are proportional to the DR. It follows than that if oversampling is applied charge and discharge rates will become faster from the net data rate’s point of view. For example if a net 20 kbps stream is demodulated with a 40 kbps configuration decay times will seem twice as fast at the 20 kbps rate. This may mean that the detector’s decay time must be slowed even further with the technique discussed earlier here.
To sum it up after you have decided that you cannot do preamble detection on the packet you must use the direct mode application. If your DR is fixed you can use the RX_DATA output and the only thing you need to tune is the discharge rate on the PEAK detector to match the longest zero trail in your packet at sensitivity level.
If you have irregular / and or multiple DRs in the packet you must apply oversampling at the least possible rate than you have to do the decay tuning on the PEAK detector as in the previous case.
This is a great reference article for those of us dealing with legacy OOK systems. Thanks for this.
Great reference for legacy OOK radio applications. Very usefull!!