Showing posts with label low-power. Show all posts
Showing posts with label low-power. Show all posts

Thursday, 24 September 2020

Tinysensors Redux

 

Raspberry Pi Zero-W with Tinysensor Hat

It is often instructive to revisit an old project: you never know what you might see with fresh eyes. Such is the case with Tinysensors, which has featured here several times over the years. Since it lives in Github I use that platform's Issues feature to collect ideas which pop into my head when I am otherwise occupied. This provides a nice context from which to start revisiting.

Among the issues addressed since the last time we featured this project are:

  • Switching to the ATTinyCore. From my point of view, the most important feature of this great project is its support for Optiboot. This decreased the testing time for changes to the Tinysensor sketch by an order of magnitude. No more external programmers!
  • Removing the RF24Network library. This supports a very versatile model of organising nRF24L01+ radios into a fully-connected 5-way tree. However it necessarily limits the number of leaf sensors to 5, requiring bridges to interconnect different levels. A star topology removes this limitation, and also reduces the code footprint enough to support debugging via SoftwareSerial.
  • Reducing power-drain. With the above improvements in testability, it didn't take long before a gotcha in power consumption was spotted: a voltage divider made with a built-in pullup resistor consumes current even during SLEEP_MODE_PWR_DOWN!
  • Moving the hub to Raspberry Pi Zero W. This has more memory and more processor for smaller footprint; in addition to built-in WiFi and Bluetooth. Once that was complete, a proper Hat was designed to hold the nRF24L01+ radio and status LEDs... and a power button, just 'cos.
  • Outsourcing the RF24 library to nRF24. These guys have put a lot of work into improving the performance of Maniacbug's excellent original library, which means I don't have to!
Future work? A nice next step might be to redesign the sensor PCB for a coin-cell and surface-mount components. However I'm pleased enough with these changes to park it for another couple of years!

Monday, 11 May 2015

Interrupted

Interrupted is a new approach to developing low-power, low-latency Arduino sketches, which was motivated by two observations:
  • That the default mode of programming for Arduino is busy-waiting, and
  • The runtime support for power management provided by avr-libc is basic, being charitable to it.
Taken together, these two points mean that Arduino sketches aren't easily battery-powered, while the second results in a cargo-cult of code copying. Lastly, timed sleep in Arduino is provided by delay(), which itself is busy-waiting. This increases latency, the response time to external events such as button-presses.

And so to an example; the sketch below manages a very simple hardware configuration composed of an ATtiny85, an LED and a button: the button turns the LED on and a timer turns it off again. (You could imagine such a sketch driving a Useless Machine.)

In the main loop, the CPU sleeps in select(), waking up when an event occurs on one of the devices it manages. Three events are possible here:
  • An external interrupt which occurs when the button drives pin PB2 low,
  • A pin-change when the LED on PB0 is turned on or off,
  • When the watchdog timer fires, one second after the LED comes on.
The value returned from select() indicates which event has woken it up, allowing the concise construction of state-machines. If more than one event source is ready, the one added earlier in setup() is returned, implementing a crude form of priority.

The sleep-mode entered by select() is the maximum which makes sense for the devices currently active. In this little example, SLEEP_MODE_PWR_DOWN will be chosen because external and watchdog interrupts still work in this mode.

Much credit is due to Nick Gammon, for the great work contained in his Interrupts and Power Saving Techniques for Microprocessors forum-pages.

Very similar techniques were employed in the runtimes of the Conic and Regis environments developed at Imperial College (as well as the select system call, of course).

The library has been ported to ATtiny84, ATtiny85 and ATMega328 processors and is, as always, at GitHub. Its code footprint varies, depending on the functionality required by individual sketches, but the little example above comes in at 2.5kB.

Work remains to be done on this library including porting it to Energia (i.e., the msp430 family), porting existing sketches to use it and completing the repertoire of supported devices (e.g., SPI handling).