In the previous post I presented the results of my experiments with the
nRF51822-based RFDuino as infrared-to-Bluetooth Low Energy gateway,
accompanied by an Android client app. The outcome of that experiment was
that the nRF51822 BLE soft stack and the purely software-based IR
receiver is not a good match as the BLE soft stack "steals" enough
cycles from the Cortex M0 CPU so that the IR reading becomes very
unreliable no matter which implementation alternative we go for (3
different alternatives were attempted). I promised an improved hardware
that overcomes this limitation and this post is about this improved
hardware.
The essence of our problems with the BLE soft stack was that in case of very tight timings that the IR receiver requires, the main CPU is not suitable anymore for measuring time periods. Typical IR timing is in the 500 microsec-2 millisec range, this is the time period we should be able to measure reliably. With the BLE soft stack in operation, delays are introduced into the time measurement code by the background interrupt routine serving the soft stack and time measurement of this precision will be wildly off. I considered two options.
A 74HC4060 is set up as oscillator and counter. The frequency of the oscillator is about 350 kHz, yielding about 43 microsec time resolution for one counter step, making it convenient to measure between 43 microsec and 5.5 sec with 7-bit resolution. An MCP23008 GPIO-extender with I2C interface provides the conversion to I2C two-wire connection and also has a capture logic. This means that whenever the output level of the IR receiver changes, the MCP23008 stores the current value of the counter in its capture register and raises an interrupt. This way the MCU is not doing any time measurements and the time measurement hardware is able to survive about 1 msec autonomously without service from the MCU.
Click here to download the schematic in Eagle SCH format.
Click here to download the updated RFDuino gateway sources.
As with the previous version, edit the Makefile in the irblegw2/sketch directory and update the RFDUINO_BASE_DIR and the AVRDUDE_COM_OPTS variables according to the layout of the file system and the USB port mapping of the RFDuino USB shield. Then you can simply say "make upload" and the gateway is installed into the RFDuino. The Android client code and its usage is unchanged, check it out in the previous post.
The gateway code represents a step in the right direction. The I2C support library ("Wire") coming with the RFDuino gets stuck when invoked from interrupt handler so this time the MCP23008 interrupt signal is handled by means of polling. The result is that when BLE is active, occasionally there are still lost IR codes even though the quality of the recognition has improved considerably. I intend to turn the I2C access interrupt-driven but that requires going deep into the nRF51822 that I was not yet able to accomplish in this iteration.
The essence of our problems with the BLE soft stack was that in case of very tight timings that the IR receiver requires, the main CPU is not suitable anymore for measuring time periods. Typical IR timing is in the 500 microsec-2 millisec range, this is the time period we should be able to measure reliably. With the BLE soft stack in operation, delays are introduced into the time measurement code by the background interrupt routine serving the soft stack and time measurement of this precision will be wildly off. I considered two options.
- The most evident option is to drop the integrated MCU-BLE radio combo that the nRF51822 is and go for a separate MCU-BLE modem option. For example an Arduino Pro Mini with a BLE121LR modem would have been a perfect fit as there are both of these modules in my drawer. While this hardware would have been definitely more hassle-free than the nRF51822, setting it up would have required two different programming tools (I have both but that's not necessarily true for the general blog reader out there) and I am still uneasy about soldering the BLE121LR - those pads are smaller than my capabilities.
- Extending the RFDuino with a dedicated hardware for time period
measurement sounded more attractive for me as this was less evident. The
functionality we expect is that the MCU is not doing any time
measurement. The external hardware must be capable of measuring the time
periods between the edges of the TSOP1738 output signal and deliver
these measurements to the MCU. The measuring range is about 500
microsec-2 msec. Larger time periods are still measured by the MCU but
in this case the disturbances caused by the soft stack are not that
relevant.
A 74HC4060 is set up as oscillator and counter. The frequency of the oscillator is about 350 kHz, yielding about 43 microsec time resolution for one counter step, making it convenient to measure between 43 microsec and 5.5 sec with 7-bit resolution. An MCP23008 GPIO-extender with I2C interface provides the conversion to I2C two-wire connection and also has a capture logic. This means that whenever the output level of the IR receiver changes, the MCP23008 stores the current value of the counter in its capture register and raises an interrupt. This way the MCU is not doing any time measurements and the time measurement hardware is able to survive about 1 msec autonomously without service from the MCU.
Click here to download the schematic in Eagle SCH format.
Click here to download the updated RFDuino gateway sources.
As with the previous version, edit the Makefile in the irblegw2/sketch directory and update the RFDUINO_BASE_DIR and the AVRDUDE_COM_OPTS variables according to the layout of the file system and the USB port mapping of the RFDuino USB shield. Then you can simply say "make upload" and the gateway is installed into the RFDuino. The Android client code and its usage is unchanged, check it out in the previous post.
The gateway code represents a step in the right direction. The I2C support library ("Wire") coming with the RFDuino gets stuck when invoked from interrupt handler so this time the MCP23008 interrupt signal is handled by means of polling. The result is that when BLE is active, occasionally there are still lost IR codes even though the quality of the recognition has improved considerably. I intend to turn the I2C access interrupt-driven but that requires going deep into the nRF51822 that I was not yet able to accomplish in this iteration.
No comments:
Post a Comment