Wireless Temperature Sensor (nrf24L01 & DS18B20)
As I mentioned about IoT Gadgets in the last blog post, I've been developing an "home automation basestation" and gadgets which connects to that. The basestation (BS) itself is connected to wlan and my server via ESP8266. The BS has an DS18B20 temperature sensor and IR led, which controls my AC unit. It also has an nrf24l01 RF module for external wireless sensors and controllers. For now, I have only one wireless temperature sensor, which also has that same temperature sensor and RF module. More of that, the sensor module has ATtiny2313A microcontroller, 1.5 F 5.5 V super capacitorand a solar cell.
The sensor module would run almost forever with AA batteries but that would have been way too boring, so I used a super cap & solar cell combination to learn something new about the power management optimization, sleep modes and current measurement techniques. I also wanted to use an 8-bit AVR microcontroller at least for this revision, although for ex. Gecko EFM32 would have provided a lot smaller current consumption. Just for simplicity, I also left out the energy harvesting IC with solar cell MPPT tracking and buck-boost SMPS output.
Just by looking at the operating voltage ranges of every component, the max. voltage of nrf24L01 is 3.3 V and min. voltage of DS18B20 is 3.0 V, so 3.0 V LDO regulator with a low quiescent current could power everything in this module. This sets the usable voltage range of the cap between 3 V and 5.5 V. The load acts as a constant current sink over the voltage range, if we average out the active and sleep state current consumptions. To calculate the time when the voltage of the super cap drops from 5.5 V to 3.0 V, we can use the formula: t = C * [(V1-V2)/I]. So for ex. 1.5 F and 20 uA would make 187 500 seconds, which is ~52 hours with the assumption that we don't put any charge in during that time.
The rev. 1 model was quite large because it had a jumper for every voltage rail, so I could measure the current consumption of any individual component. There was also 3 capacitors (1.5 F, 0.47 F and 330_uF) behind the jumpers so I was able to change the connected capacitance. Rev. 2 doesn't have these jumpers and has only one super capacitor, so it's a lot smaller.
Rev. 1 board. Click to enlarge |
The rev. 1 model was quite large because it had a jumper for every voltage rail, so I could measure the current consumption of any individual component. There was also 3 capacitors (1.5 F, 0.47 F and 330_uF) behind the jumpers so I was able to change the connected capacitance. Rev. 2 doesn't have these jumpers and has only one super capacitor, so it's a lot smaller.
Rev. 2 board. Click to enlarge |
As I programmed the first working scratch (1 MHz clock) without any sleep modes, the current consumption was approximately 750 uA, which would drain the cap in 83 minutes. As the MCU stays in sleep state most of the time, we want to use the lowest power sleep state, which is "power-down". Power-down disables timers, except the watchdog, which can be used as a wake-up source even in that deepest sleep mode. Watchdog interrupt function is used to cancel the reset flag before the MCU resets. Just by adding the power-down sleep mode, the average current consumption goes down to 130 uA, which is still 5 times too much.
By lowering the MCU clock from 1 MHz to 250_kHz, enabling the "power reduction register" features in ATtiny, reducing the temperature resolution of DS18B20 from 12 bits (0.0625 °C) to 10 bits (0.25 °C), using the deepest sleep mode of the nrf24l01 and by pulling down any unnecessary microcontrollers pins, the current consumption goes down to 27 uA. Further, we don't really need a temperature reading every 8 seconds (longest WDT range), so the final revision of the program reads the temperature in one interrupt cycle, puts the MCU to sleep already during the 250 ms temperature conversion of the DS18B20 and sends the result it in another cycle. That gives one temperature reading per 16 seconds, which is still well enough, but drops the average current consumption to 13_uA.
Download files:
Proteus 7.7 schematic & layout files (zip)
Atmel Studio 6.1 project / source code (zip)
As there is no step-up converter / energy harvesting IC, the open circuit voltage of the solar cell should go quite easily to 5 volts even in mediocre lighting, so the voltage would be higher than capacitor's voltage to allow the charging. The series schottky diode prevents the current from going in wrong direction when there is not enough light for charging. When there is lots of light, the charging voltage needs to be limited to 5.5 V, so the super cap won't blow up. That's done by using a voltage supervisor IC, which controls the mosfet and shorts the solar cell to ground through the 220 Ω resistor, if the voltage goes too high. Zener diode would have been a "single component solution" but they tend to be too leaky in non-conductive region, so it wasn't an option.
The recommended minimum input voltage range of 3.0 V LDO regulator is ~3.1 volts, but at that low currents, that specific LDO seems to works well above this, although the output voltage obviously starts to follow the input voltage when it goes above 3.0 volts. ATtiny2313A doesn't have an ADC which could be used for voltage monitoring, and the Brown Out Detector would be a bit too extreme, since there's no other option than resetting the whole MCU when it triggers. But there is an analog comparator, which can be used by connecting the internal bandgap reference (1.1 V) and comparing it to the operating voltage, divided with two resistors. I used 100k and 75k resistors, which makes 1.29_V when the operating voltage is 3.0 V. When the operating voltage dips below 2.56 V, the output of the resistor divider goes below 1.1 V and triggers the analog comparator. However, bandgap reference consumes a lot of current (~15 uA) so it's turned on only during the voltage test for a short period of time. If the voltage reaches that point, the DS18B20 doesn't work properly anymore, and measuring the temperature & sending the results are stopped to save some current. At that point we can also send a low voltage warning to the BS. There's also a routine which resetes the system occasionally if the low voltage is detected, so the memory of the MCU, RF module or the digital temperature sensor is refreshed to prevent corruption of the memory and malfunctioning of the system.
Currently I'm logging the temperature readings to my RPi 3 server (just for fun), and the module seems to work very well even in indoor lighting, without a direct sunlight. Next I'm going to put this outdoors when I'll find a good case for it.
Click to enlarge |
Proteus 7.7 schematic & layout files (zip)
Atmel Studio 6.1 project / source code (zip)
As there is no step-up converter / energy harvesting IC, the open circuit voltage of the solar cell should go quite easily to 5 volts even in mediocre lighting, so the voltage would be higher than capacitor's voltage to allow the charging. The series schottky diode prevents the current from going in wrong direction when there is not enough light for charging. When there is lots of light, the charging voltage needs to be limited to 5.5 V, so the super cap won't blow up. That's done by using a voltage supervisor IC, which controls the mosfet and shorts the solar cell to ground through the 220 Ω resistor, if the voltage goes too high. Zener diode would have been a "single component solution" but they tend to be too leaky in non-conductive region, so it wasn't an option.
Click to enlarge. Sensor module with 2300 uF capacitor(s) as a power supply. Low voltage detection off vs. on |
Currently I'm logging the temperature readings to my RPi 3 server (just for fun), and the module seems to work very well even in indoor lighting, without a direct sunlight. Next I'm going to put this outdoors when I'll find a good case for it.