TTNmon was intentended to be used as a tool to monitor the connection quality of LoRaWAN nodes. To monitor possible environmental influences, I wanted to build a node which can be put onto hills or into the forest and send a packet in intervals of 15 minutes and more. This node has to be low power to send over a long time on battery. For this node I used an AVR 32u4 on the BSFrance 32u4 LoRa board.
During most of the time the node can save power by going to sleep mode. Using this mode a microcontroller like the 32u4 needs only a few µA. To return from sleep mode you will need to wake the controller again. This happens in order of an interrupt like an external pin change or a timer. As I want to send a message every 15 minutes, this implies that I should use the timer. And here I ran into trouble.
The 32U4 has two 8 Bit and one 16 Bit timer. The 16 Bit timer seems to be used by the Arduino LMIC library. Whenever I started to use it, LMIC stopped to work. We might be able to use this timer if it is released properly after returning from sleep. We would need to backup the registers values before configuring the timer to go to sleep and restore them after waking up. But some calculations tell us not to do this.
A 16 Bit timer can count up to 2^16 – 1. After reaching this value, the timer will overflow and start to count from 0 again. You can register an interrupt which causes the program to be interrupted whenever the timer overflows and execute special code. If your controller has been put to sleep, it will wake up.
The BSFrance board is clocked with a 8 MHz crystal. As the timer value is increased with every cycle, the overflow will be reached after about 8µS. To use a timer over a longer timespan, timers have a register to configure a prescaler. This prescaler divides the crystals frequency by its value. The highest possible prescaler has a value of 1024. This means that the timer value will be increased by one after 1024 clock cycles. To increment the value it would take 128µS. To count up to 2^16 – 1 it would take about 8 seconds. As you remember I want to send every 15 minutes. However this means that my controller would wake up every 8 seconds. Within 15 minutes the controller would wake up 112 times. With each wake up, my program could increment an additional counter and check if it reached 112. If it is smaller the controller would be put to sleep again. Otherwise it would start the transmission.
This would work, but isn’t be a good idea. The power consumption of the board would significantly increase and result in a shorter lifetime of the batteries.
My first idea was to add an external RTC (RealTimeClock) to the board. I decided to put all components onto a breadbord. I added also a voltage divider to measure the battery voltage and a DHT11 temperature and humidity sensor.
The RTC can be configured via I2C to fire interrupts on it’s SQW pin when reaching the specified time. This interrupt causes my controller to wake up from sleep. The power consumption was decreased and it worked great after fixing some intial bugs.
I performed first tests on the Haarberg near to Aachen. The node was hidden in a waterproof box.
The End? No! The board is currently very big and can’t be hidden very well. AVR microcontrollers don’t fit the purpose for low power nodes. Requiring an external RTC means a lot of space consumption and as well increased costs and power consumption. So I decided to develop my own LoRa board. Read all articles here.
to be continued…