Hallo Leute!
Ich stehe gerade an einem Punkt an, wo ich nicht mehr ohne richtungsweisenden Tip weiterkomme.
Zur Vorgeschichte:
Habe für meine Frau zum Hochzeitstag LED-Herzen gebastelt. Insgesamt 16 LEDs an 2 Stück 74HC595 Schieberegister gesteuert über einen Arduino Nano.
Funktioniert alles prima und sieht meiner Meinung nach sehr schön aus. ABER: nach spätestens 4 Stunden ist der 9V-Block leer. 
Hier mal die Version 1:
//Schieberegister 74HC595 /Hearts
#define outputs 16 //Number of Outputs (74HC595)
int shiftPin = 2; //SH_CP
int storePin = 3; //ST_CP
int dataPin = 4; //DS
int heart1 = 9; //OutputEnableInput SR1 (active LOW)
int heart2 = 10; //OutputEnableInput SR2 (active LOW)
int registers[outputs];
void writeout() {
for (int i=0; i<outputs; i++) {
digitalWrite(shiftPin, LOW);
digitalWrite(dataPin, registers[i]);
digitalWrite(shiftPin, HIGH);
}
}
void loopup_on(int wait) {
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
for (int i=0; i<outputs; i++) {
digitalWrite(storePin, LOW);
registers[i] = 1;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopup_off(int wait) {
for (int i=0; i<outputs; i++) {
digitalWrite(storePin, LOW);
registers[i] = 0;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopdown_on(int wait) {
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
for (int i=outputs-1; i>=0; i--) {
digitalWrite(storePin, LOW);
registers[i] = 1;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopdown_off(int wait) {
for (int i=outputs-1; i>=0; i--) {
digitalWrite(storePin, LOW);
registers[i] = 0;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void heartbeat(int repeat) {
//for Schleife für Fade-Out
for (int i = 0; i<240; i++) {
analogWrite(heart1, i);
analogWrite(heart2, i);
delay(5);
}
delay(500);
//Heartbeat
for (int i = 0; i<repeat; i++) {
digitalWrite(heart1, LOW);
delay(100);
analogWrite(heart1, 240);
delay(50);
digitalWrite(heart2, LOW);
delay(100);
analogWrite(heart2, 240);
delay(1200);
}
}
void setup() {
pinMode(shiftPin, OUTPUT);
pinMode(storePin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(heart1, OUTPUT);
pinMode(heart2, OUTPUT);
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
//ADC ausschalten
ADCSRA = 0;
//Register leeren
for (int i=0; i<outputs; i++) {
registers[i] = 0;
}
}
void loop() {
loopdown_on(50); //LEDs nach der Reihe einschalten mit 50ms Verzögerung
delay(500);
heartbeat(3); //Heartbeat 3x wiederholen
delay(500);
loopdown_off(50);
delay(2000);
loopup_on(50);
delay(500);
heartbeat(3);
delay(500);
loopup_off(50);
delay(2000);
}
Display More
Hab jetzt mal einiges zu Energiesparen gelesen und fürs erste viele delays mit PowerDown aus der LowPower-library ersetzt und auch teilweise die Pausen erhöht.
Sieht dann so aus:
#include <LowPower.h>
// Schieberegister 74HC595 /Hearts
#define outputs 16 //Number of Outputs (74HC595)
int shiftPin = 2; //SH_CP
int storePin = 3; //ST_CP
int dataPin = 4; //DS
int heart1 = 9; //OutputEnableInput SR1 (active LOW)
int heart2 = 10; //OutputEnableInput SR2 (active LOW)
int registers[outputs];
void writeout() {
for (int i=0; i<outputs; i++) {
digitalWrite(shiftPin, LOW);
digitalWrite(dataPin, registers[i]);
digitalWrite(shiftPin, HIGH);
}
}
void loopup_on(int wait) {
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
for (int i=0; i<outputs; i++) {
digitalWrite(storePin, LOW);
registers[i] = 1;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopup_off(int wait) {
for (int i=0; i<outputs; i++) {
digitalWrite(storePin, LOW);
registers[i] = 0;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopdown_on(int wait) {
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
for (int i=outputs-1; i>=0; i--) {
digitalWrite(storePin, LOW);
registers[i] = 1;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void loopdown_off(int wait) {
for (int i=outputs-1; i>=0; i--) {
digitalWrite(storePin, LOW);
registers[i] = 0;
writeout();
digitalWrite(storePin, HIGH);
delay(wait);
}
}
void heartbeat(int repeat) {
//for Schleife für Fade-Out
for (int i = 0; i<240; i++) {
analogWrite(heart1, i);
analogWrite(heart2, i);
delay(5);
}
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
//Heartbeat
for (int i = 0; i<repeat; i++) {
digitalWrite(heart1, LOW);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
analogWrite(heart1, 240);
LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
digitalWrite(heart2, LOW);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
analogWrite(heart2, 240);
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
}
}
void sleepTenMinutes()
{
for (int i = 0; i < 75; i++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}
void setup() {
pinMode(shiftPin, OUTPUT);
pinMode(storePin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(heart1, OUTPUT);
pinMode(heart2, OUTPUT);
digitalWrite(heart1, LOW);
digitalWrite(heart2, LOW);
//ADC ausschalten
ADCSRA = 0;
//Register leeren
for (int i=0; i<outputs; i++) {
registers[i] = 0;
}
}
void loop() {
loopdown_on(50); //LEDs nach der Reihe einschalten mit 50ms Verzögerung
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
heartbeat(3); //Heartbeat 3x wiederholen
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
loopdown_off(50);
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
loopup_on(50);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
heartbeat(3);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
loopup_off(50);
sleepTenMinutes(); // 10 Minuten Pause
}
Display More
Damit sollte die Batterie schon einiges länger halten, hab ich aber noch nicht getestet.
Als nächsten Schritt werde ich die Power-on LED des Arduinos entfernen. Sollte nochmal ein paar mA sparen.
Und jetzt der Punkt an dem ich nicht weiterkomme:
Es müsste doch möglich sein, immer nur eine LED leuchten zu lassen. So wie das zB. bei 7-Segment Anzeigen gemacht wird.
Nur fehlt mir jetzt der Plan, wie ich das umsetze.
Zweiter Thread geht ja leider nicht. Also brauche ich eine while Schleife, die die LEDs durchläuft bis ... und genau da steh ich an. Auf was soll ich prüfen? Wenn ich auf millis() prüfe, wie weiß ich dann, wo ich im Programm stehe (also welche Sequenz als nächste laufen soll)? Und was passiert, wenn millis() überläuft?
Ich hoffe auf eure Hilfe und sage jetzt schon mal 
Liebe Grüße
Markus