Dec 1, 2016

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 capacitor and 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.
Rev. 1 board. Click to enlarge
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. 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.
Click to enlarge
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.

Click to enlarge. Sensor module with 2300 uF capacitor(s) as a power supply. Low voltage detection off vs. on
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.

Raspberry Pi UPS from junk box

I've been using the Raspberry Pi 1 as an ssh shell for Irssi and as a web server for my IP cameras and self-made IoT gadgets. Maybe I had just a bad luck with the corrupting SD cards, but I ended up to put the Arch Linux and other files to 120 GB SSD (although the SD card is still needed for bootloader), which was connected to RPi via 2.5" USB HDD box. Some time ago the SSD died and I got a good reason to upgrade the whole system, so I bought the RPi 3 and replaced the SSD with an 250 GB Samsung 840 basic. The extra performance (1x 700 MHz vs. 4x 1.2 GHz ARM cores) is nice especially when rendering timelapse videos from my IP camera photos.

Click to enlarge
To get some extra reliability, I thought that some kind of UPS could be nice. There's plenty of complete kits on ebay, but I happened to have some suitable parts in my junk box, so I didn't bother to wait 2 weeks. It wouldn't need any fancy features, but obviously should have at least an overcharging protection and under-voltage cutoff if the power outage is long enough. So there's the plan:

Click to enlarge
To keep it simple, there's no separate charging circuit for the 12 V sealed lead acid battery. I had couple of 12 V power supplies so it could charge the battery up to 12 volts. However fully charged battery would sit around 14.2 volts, so charging it only to 12 volts would waste about half of it's full capacity (2.9 Ah). For me, that's not a problem because the RPi would stay on more than long enough even with 1.45 amp-hours. We can limit the charge current of the battery with the 47R resistor, but allow higher discharge currents through the schottky diode, when the primary power supply cuts off. Theres also a protection diode for the 12 V power brick, so it cannot draw current from the battery when the main PSU is down. At these voltages we don't have to care about overcharging the battery.

RPi requires 5 volts, so there's also a regulator. Because the voltage drop from 12 V to 5 V is quite large when considering the 400-1000 mA operating current, I chose a buck switch mode power supply module instead of regular LM7805 linear regulator. That Murata module is pin-compatible with LM7805 but the efficiency is a lot better as it's an SMPS.

The undervoltage cutoff prevents the output of 5 V SMPS module to fall down slowly by causing all kind of unwanted effects for the RPi. When the battery voltage reaches ~6 V, the relay disconnects the battery, which is connected again when the main 12 V supply returns. The coil of the relay is rated for 5 volts, so there must be a series resistor to limit the current. The value of the resistor sets the cutoff voltage. But why there's a capacitor in series with relays coil? I noticed that when the resistor value would be good in terms of cutoff voltage, the relay didn't switch on even at 12 volts. So the capacitor works as a high-pass filter which bypasses the 270R resistor and provides the "kick" to the relay coil when the main PSU turns on, but after that, the current passes only via the resistor, as the capacitor cannot pass DC current. After the transition, everything abouve 6 volts is enough to keep the relay switched on.

Click to enlarge

* The picture above still with the RPi 1 model B.