Candle Stick
Ich brauchte eine neue Stromversorgung für meine elektrifizierte Sturmlaterne, da ich die alte für ein anderes Projekt entwendet habe.
Da ich mich zu der Zeit mit der Programmierung von Mikrocontrollern beschäftigt habe, war es naheliegend, etwas “smartes” zu basteln.
Schnell wurde etwas Code geschrieben und ein Board gelötet.
Der Stick beherrscht die folgenden Funktionen:
- Button 1: 4 Helligkeitsstufen
- Button 2: Umschalten zu “Flackermodus”
- Button 3: Timer aktivieren, der die Lampe nach einer festgelegten Zeit ausschaltet.
Als Mikrocontroller kommt ein ATtiny85 zum Einsatz. Die Helligkeit wird per PWM über einen externen Transistor geregelt. Der Flackermodus lässt die LEDs wie eine Kerze aufflackern. Nach der Trennung vom Strom merkt sich der Stick die zuletzt gewählte Einstellung.
Der gemessene Stromverbrauch der Lampe beträgt maximal ca. 10 Milliwatt und ist somit kaum vorhanden.
Man kann an den Stick auch jede beliebige andere 3-5 Volt LED-Lampe oder Lichterkette anschließen und ihr somit dieselbe Funktionalität verleihen.
Der Source-Code für den Controller:
#include <AbleButtons.h>
#include <EEPROM.h>
using Button = AblePullupClickerButton;
using ButtonList = AblePullupClickerButtonList;
#define BUTTON_DIM_PIN A1
#define BUTTON_MODE_PIN A2
#define BUTTON_TIMER_PIN A3
#define LIGHT_PIN 0
#define EEPROM_INITILIAZED 42069
Button btnDim(BUTTON_DIM_PIN);
Button btnMode(BUTTON_MODE_PIN);
Button btnTimer(BUTTON_TIMER_PIN);
struct Settings {
int initialized = EEPROM_INITILIAZED;
int mode = 0;
int dim = 0;
};
Settings settings;
const float baseMax = 150;
const float baseMin = 50;
const float baseChangeSpeed = 10.0f;
const int maxFlicker = 100;
const int dimSteps = 4;
const int eeAddress = 0;
float baseValue = (baseMin + baseMax) / 2.0f;
float timerStart = 0;
bool isOn = true;
void setup() {
EEPROM.get(eeAddress, settings);
pinMode(LIGHT_PIN, OUTPUT);
btnMode.begin();
btnDim.begin();
btnTimer.begin();
if (settings.initialized != (int)EEPROM_INITILIAZED) {
settings.initialized = EEPROM_INITILIAZED;
settings.dim = 0;
settings.mode = 0;
EEPROM.put(eeAddress, settings);
}
}
void turnOn() {
isOn = true;
timerStart = 0;
}
void loop() {
btnMode.handle();
btnDim.handle();
btnTimer.handle();
if (btnMode.resetClicked()) {
if (!isOn) {
turnOn();
} else {
settings.mode = settings.mode ? 0 : 1;
EEPROM.put(eeAddress, settings);
}
}
if (btnDim.resetClicked()) {
if (!isOn) {
turnOn();
} else {
settings.dim = (settings.dim + 1) % dimSteps;
EEPROM.put(eeAddress, settings);
}
}
if (btnTimer.resetClicked()) {
if (!isOn) {
turnOn();
} else {
timerStart = millis();
}
}
if (timerStart > 0 && (millis() - timerStart > (1000 * 10))) {
isOn = false;
timerStart = 0;
}
if (isOn) {
if (settings.mode == 0) {
DimMode();
} else {
CandleMode();
}
} else {
digitalWrite(LIGHT_PIN, LOW);
delay(10);
}
}
void DimMode() {
analogWrite(LIGHT_PIN, 255 / (dimSteps - settings.dim));
delay(10);
}
void CandleMode() {
analogWrite(LIGHT_PIN, (baseValue + random(maxFlicker)) / (dimSteps - settings.dim));
baseValue += float(random(0, 5) - 2) / baseChangeSpeed;
baseValue = max(baseMin, min(baseValue, baseMax));
delay(10 + random(100));
}