benjixx
February 11, 2022, 6:01pm
1
Servus,
Ich würde gerne zwei LEDs blinken lassen und die Einschalt bzw Ausschaltzeiten unterschiedlich gestalten. Das funktioniert auch teilweise. Problem ist nur das die Leds manchmal korrekt blinken und zeitweise nur kurz aufblitzen. Wo liegt der Fehler?...ich komm einfach nicht drauf ...
(Leds sind korrekt angeschlossen mit 200ohm Wiederstand an der Anode. Blink Sketch mit delay funktioniert auch einwandfrei)
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;
void setup() {
pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}
void loop() {
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 1000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, HIGH);}
aktzeit2 = millis ();
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
digitalWrite (ledgelb, LOW);}
}
void blinkgruen()
{
aktzeit3 = millis();
if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
digitalWrite (ledgruen, HIGH);}
aktzeit4 = millis();
if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
digitalWrite (ledgruen, LOW);}
}
Hallo benjixx
Schaue dir dazu am Besten das BLINKWITHOUTDELAY Beispiel aus dem IDE an.
Ich wünsche einen geschmeidigen Abend und viel Spass beim Programmieren in C++.
Hallo benjixx,
aktzeitX=ergzeitX=millis(); im setup() aufrufen um eine gemeinsame Systemzeit zu setzen.
Probier das man und bedenke der millis läuft in ca 55 Tagen über.
bei mir sieht das dann immer so aus:
// Prüfe ob BH1750 Timer Speicherzelle einen Überlauf hatte? Passiert ca alle 50 Tage
if (SYS_tiActBH1750 >= SYS_tiOldBH1750) //KEIN Überlauf der unsigned long Timer Speicherzelle vorhanden
{
if (SYS_tiActBH1750 - SYS_tiOldBH1750 >= SYS_TIDELTA_BH1750) // Prüfen ob Detazeit vergangen ist
{
BH_stTimerElapst = true; // Timerzeit ist erreicht
}
}
else // Überlauf der unsigned long Timer Speicherzelle hat stattgefunden: SYS_tiAct ist kleiner als SYS_tiOld
{
if ((ULONGMAX - SYS_tiOldBH1750 + SYS_tiActBH1750) >= SYS_TIDELTA_BH1750) // Prüfe ob Detazeit vergabgen. Berechnung: max Zählerstand 2^32-1 - letzte System + aktuelle Systemzeit ergibt die vergangene Systemzeit
{
BH_stTimerElapst = true; // Timerzeit ist erreicht
}
Gruß Mascho
Tommy56
February 11, 2022, 6:51pm
4
Setze Deinen Code bitte in Codetags. Wie das geht, steht hier .
Gruß Tommy
benjixx
February 11, 2022, 6:58pm
5
OK, Sorry Bin neu hier und irgendwie geht des mit den millis nicht in meinen Schädel
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;
void setup() {
pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}
void loop() {
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 5000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, HIGH);}
aktzeit2 = millis ();
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
digitalWrite (ledgelb, LOW);}
}
void blinkgruen()
{
aktzeit3 = millis();
if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
digitalWrite (ledgruen, HIGH);}
aktzeit4 = millis();
if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
digitalWrite (ledgruen, LOW);}
}
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;
void setup() {
pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}
void loop() {
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
aktzeit1 = millis ();
if (aktzeit1 - vergzeit1 >= 5000)
{
vergzeit1 = aktzeit1;
digitalWrite (ledgelb, !digitalRead(ledgelb));
}
}
void blinkgruen()
{
aktzeit3 = millis();
if (aktzeit3 - vergzeit3 >= 5000)
{
vergzeit3 = aktzeit3;
digitalWrite (ledgruen, !digitalRead(ledgruen));
}
}
benjixx
February 11, 2022, 7:06pm
7
Meinst du so?
Dann geht gar nix mehr
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
unsigned long aktzeit3;
unsigned long vergzeit3 = 0;
unsigned long aktzeit4;
unsigned long vergzeit4 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;
void setup() {
pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
aktzeit1 = millis ();
aktzeit2 = millis ();
aktzeit3 = millis();
aktzeit4 = millis();
}
void loop() {
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
if (aktzeit1-vergzeit1 >= 5000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, HIGH);}
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2=aktzeit2;
digitalWrite (ledgelb, LOW);}
}
void blinkgruen()
{
if (aktzeit3-vergzeit3 >= 5000)
{vergzeit3 = aktzeit3;
digitalWrite (ledgruen, HIGH);}
if (aktzeit4-vergzeit4 >= 5000)
{vergzeit4 = aktzeit4;
digitalWrite (ledgruen, LOW);}
}
benjixx
February 11, 2022, 7:12pm
8
Danke. Aber mit dem Sketch kann ich die An bzw Ausphasen nicht steuern. Ich will eine led z.B. 3 sec anschalten und 5 sec auschalten.
Rentner
February 11, 2022, 7:13pm
9
Hallo
Wenn du unterschiedliche Ein und Aus Zeiten haben willst, dann must du eine Abfrage mit einbauen ob die LED Grade ein oder aus ist damit du auf die richtige Zeit abfragen kannst.
If LED ein
Abfrage auf Hellzeit
Else
Abfrage auf Dunkelzeit
In etwa so
Ersetze:
void blinkgelb()
{
aktzeit1 = millis ();
if ((aktzeit1 - vergzeit1 >= 5000) && (digitalRead(ledgelb) == LOW))
{ vergzeit1 = aktzeit1;
digitalWrite (ledgelb, HIGH);
}
if ((aktzeit1 - vergzeit1 >= 5000) && (digitalRead(ledgelb) == HIGH))
{ vergzeit1 = aktzeit1;
digitalWrite (ledgelb, LOW);
}
}
Baue Deine Zeiten.
geht?
Hallo benjixx
Bist du vertraut mit der Formulierung eigner Datentypen?
Diese Aufgabenstellung läßt sich sehr gut über ein Objekt, für die Led und Zeiten, und einem Timerservice abfrühstücken.
Ich wünsche einen geschmeidigen Abend und viel Spass beim Programmieren in C++.
benjixx
February 11, 2022, 8:05pm
12
benjixx:
Ich will es verstehen
#10 probiert?
Die Zeiten (5000) für an und aus verändert?
Fragen dazu?
benjixx
February 11, 2022, 8:14pm
14
Danke für die Antwort. Dein Code hat Funktioniert
Hab auch noch eine andere Lösung
unsigned long aktzeit1;
unsigned long vergzeit1 = 0;
unsigned long aktzeit2;
unsigned long vergzeit2 = 0;
int taster = 2;
int tasterst;
int ledgruen = 8;
int ledgelb = 4;
int ledrot = 6;
void setup() {
pinMode (taster, INPUT);
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
pinMode (ledrot, OUTPUT);
Serial.begin (9600);
}
void loop() {
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
if (digitalRead (ledgelb) == LOW){
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 1000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, HIGH);}}
else {
aktzeit1 = millis ();
if (aktzeit1-vergzeit1 >= 5000)
{vergzeit1=aktzeit1;
digitalWrite (ledgelb, LOW);}}
}
void blinkgruen()
{
if (digitalRead (ledgruen) == LOW){
aktzeit2 = millis();
if (aktzeit2-vergzeit2 >= 5000)
{vergzeit2 = aktzeit2;
digitalWrite (ledgruen, HIGH);}}
else {
aktzeit2 = millis();
if (aktzeit2-vergzeit2 >= 1000)
{vergzeit2 = aktzeit2;
digitalWrite (ledgruen, LOW);}}
}
agmue
February 11, 2022, 11:16pm
15
benjixx:
Deswegen Step by Step
Lust auf lokale Variablen?
const uint16_t EINZEIT_GELB = 1000;
const uint16_t AUSZEIT_GELB = 5000;
const uint16_t EINZEIT_GRUEN = 5000;
const uint16_t AUSZEIT_GRUEN = 1000;
const byte ledgruen = 8;
const byte ledgelb = 4;
void setup()
{
pinMode (ledgruen, OUTPUT);
pinMode (ledgelb, OUTPUT);
}
void loop()
{
blinkgelb();
blinkgruen();
}
void blinkgelb()
{
unsigned long aktzeit = millis();
static unsigned long vergzeit = 0;
static bool ausEIN = false;
if (ausEIN)
{
if (aktzeit - vergzeit >= EINZEIT_GELB)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (ledgelb, ausEIN);
}
} else {
if (aktzeit - vergzeit >= AUSZEIT_GELB)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (ledgelb, ausEIN);
}
}
}
void blinkgruen()
{
unsigned long aktzeit = millis();
static unsigned long vergzeit = 0;
static bool ausEIN = false;
if (ausEIN)
{
if (aktzeit - vergzeit >= EINZEIT_GRUEN)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (ledgruen, ausEIN);
}
} else {
if (aktzeit - vergzeit >= AUSZEIT_GRUEN)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (ledgruen, ausEIN);
}
}
}
Lust auf Felder und Funktionsparameter?
enum {GELB, GRUEN};
const byte FARBEN = 2;
const uint16_t EINZEIT[FARBEN] = {1000, 5000};
const uint16_t AUSZEIT[FARBEN] = {5000, 1000};
const byte led[FARBEN] = {4, 8}; // GELB, GRUEN
void setup()
{
pinMode (led[GELB], OUTPUT);
pinMode (led[GRUEN], OUTPUT);
}
void loop()
{
blinken(GELB);
blinken(GRUEN);
}
void blinken(const byte farbe)
{
unsigned long aktzeit = millis();
static unsigned long vergzeit[FARBEN] = {0, 0};
static bool ausEIN[FARBEN] = {false, false};
if (ausEIN[farbe])
{
if (aktzeit - vergzeit[farbe] >= EINZEIT[farbe])
{
vergzeit[farbe] = aktzeit;
ausEIN[farbe] = !ausEIN[farbe];
digitalWrite (led[farbe], ausEIN[farbe]);
}
} else {
if (aktzeit - vergzeit[farbe] >= AUSZEIT[farbe])
{
vergzeit[farbe] = aktzeit;
ausEIN[farbe] = !ausEIN[farbe];
digitalWrite (led[farbe], ausEIN[farbe]);
}
}
}
benjixx
February 12, 2022, 7:32am
16
agmue
February 12, 2022, 10:05am
17
benjixx:
sieht interessant aus
Wenn man möchte, daß zusammengehörige Informationen auch zusammenstehen, bieten sich anstelle von Funktionen Methoden in Klassen an:
class Blink {
const byte led;
const unsigned long EINZEIT, AUSZEIT;
unsigned long vergzeit;
bool ausEIN = false;
public:
Blink(const byte led, const unsigned long EINZEIT, const unsigned long AUSZEIT) :
led(led), EINZEIT(EINZEIT), AUSZEIT(AUSZEIT) {}
void init()
{
pinMode (led, OUTPUT);
}
void blinken()
{
unsigned long aktzeit = millis();
if (ausEIN)
{
if (aktzeit - vergzeit >= EINZEIT)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (led, ausEIN);
}
} else {
if (aktzeit - vergzeit >= AUSZEIT)
{
vergzeit = aktzeit;
ausEIN = !ausEIN;
digitalWrite (led, ausEIN);
}
}
}
};
const byte FARBEN = 2;
Blink blink[FARBEN] =
{
//led, EINZEIT, AUSZEIT
{4, 1000, 5000}, // Gelb
{8, 5000, 1000}, // Gruen
};
void setup()
{
for (Blink &b : blink) b.init();
}
void loop()
{
for (Blink &b : blink) b.blinken();
}
benjixx:
Puhhh...
Fragen sind möglich
1 Like
combie
February 12, 2022, 10:11am
18
Richtig so....
Jetzt fehlt noch die Variante mit dem Multitaskingsystem
Die Datenflussorientierte.
Die mit switch/case, die mit goto, die mit Funktionspointern
Habe ich noch welche vergessen?
1 Like
jepp, "branchless coding"
combie
February 12, 2022, 11:40am
20
Du meinst das so in etwa:
#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"
// die neueste CombieLib.zip findest du mit der Forensuche
#include <CombieTypeMangling.h>
using namespace Combie::Millis;
#include <CombiePin.h>
using RoteLed = Combie::Pin::OutputPin<13>;
using BlaueLed = Combie::Pin::OutputPin<12>;
#include <CombieTimer.h>
Combie::Timer::PpmGenerator rotTimer {3_Sekunden, 1_Sekunde};
Combie::Timer::PpmGenerator blauTimer {1_Sekunde, 3_Sekunden};
void setup()
{
Serial.begin(9600);
cout << F("Start: ") << F(__FILE__) << endl;
RoteLed{} .init();
BlaueLed{} .init();
}
void loop()
{
RoteLed{} = rotTimer;
BlaueLed{} = blauTimer;
}
Wobei ich das gerne als Datenflusssichtweise bezeichne. Denn der Datenfluss kennt eher keine Entscheidungen oder Schleifen.