LED strip dimmer - Software v. 1.3

Zápisník experimentátora

Hierarchy: Stmievač LED pásika pomocou ATtiny85

In this article I will explain the principle of LED strip dimmer. This is the fourth of a series of articles to show you how the program progresses and how the resulting program may be diametrically different. This text describes the current version of code 1.3.

In the ideal world you will write the ideal program right away for the first time and will not make any mistakes and will do exactly what you imagined. And now welcome to the real world, where I tried to program the dimming logic to suit the kitchen.

Arduino IDE

The code was developed for version 1.0.6, but it can be easily compiled in 1.6.13 or 1.8.2. After compilation it occupies 3038 (6254 with debugging turned on) bytes. You must have installed support for ATtiny85 programming.

Programming

In this program, I focused on reducing energy consumption. Most of the time, the program only waits for a sensor signal and does not need a lot of machine time. Therefore, the program sleeps to 64 ms time blocks during which the power consumption of the microcontroller is minimized. The whole development was on the development board for ATtiny85, which I already described in the previous article.

A watchdog timer is usually used to put out the microcontroller. In order for the whole sleep to work, it is necessary to add the following lines to the program.

  • At the beginning of the program, we will attach two header files. These help us find support for convenient bit operations and microcontroller sleep functions.
  • We define enum wdtimer, where we create all the symbolic possibilities for sleeping. In order for the program to be swift, we will use a 64 ms.
  • In setup, we turn off the ADC because it also consumes some energy and we do not need it in the program. Then we set the watchdog timer in function setup_watchdog.
  • The entire logic of sleeping is hidden in function LightDark. The system_sleep function is called, which sleeps the microcontroller. It does this every time it does not have a sensor signal. In practice, the microcontroller spends practically all of the time in this function because most of the day no signals from the PIR sensor will come in.
  • The system_sleep function serves to sleep the microcontroller. After awakening, the code begins at the end of the function, which is exactly what we need. We wake up from sleep, check the PIR sensor, and if nothing goes happens, we'll sleep again.
  • The setup_watchdog function is used to set the correct bits for the watchdog timer.
  • We do not need interrupt from watchdog timer basically from this code, but I admit without torture that I have taken the last two functions from Internet and I did not want to change anything. But if you also need some interrupt service, it gives you a signal to the signal_wdt variable.
#include "wiring_private.h"
#include <avr/sleep.h>

enum wdtimer {wdt16ms=0, wdt32ms, wdt64ms, wdt128ms, wdt250ms, wdt500ms, wdt1s, wdt2s, wdt4s, wdt8s};
volatile boolean signal_wdt = 1;

void setup() {               
  // disable adc
  cbi(ADCSRA, ADEN);
  setup_watchdog(wdt64ms);
 ...
}

void LightDark() {
  int p=digitalRead(dig);
  if(p)
    state=stOn;
  else
    system_sleep();
}

void system_sleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
  sleep_mode();                        // System sleeps here
  sleep_disable();                     // System continues execution here when watchdog timed out
}

void setup_watchdog(byte t) {
  byte bb;
  int ww;
  if(t>wdt8s)
    t=wdt8s;
  bb=t&7; // WDP[2:0]
  if(t>wdt2s)
    sbi(bb,WDP3);
  sbi(bb,WDCE);
  ww=bb;

  cbi(MCUSR,WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  sbi(WDTCR,WDIE);
}

ISR(WDT_vect) {
  signal_wdt=1;  // set global flag
}

Source code

The source code is located on GitHub.


28.06.2017


Menu