Ich möchte von überall im Code die Funktion trigger() aufrufen können,
also z.B. trigger(LED1), trigger(LED2) und trigger(LED3)
und es soll dann die jeweilige LED für 500ms "gepulsed" werden.
Und gern ohne Library.
Nun könnte ich natürlich für jede LED 1-3 die trigger-Funktion und das if-Konstrukt in den Code setzen, aber ich weiß, dass es schöner geht
Mir fehlt nur gerade der Denkansatz.
Die trigger-Funktion mit byte Parameter-Übergabe?
Das if-Konstrukt dann mit enum class und switch case?
Kann mir jemand mit ein paar Pseudo-Codezeilen auf die Sprünge helfen?
eine Klasse schreiben,
beim Objekt anlegen den Pin übergeben.
Wenn notwendig die Member Funktion pulse aufrufen
im Loop einfach eine Member Funktion run() aufrufen damit das Objekt gegebenenfalls den pin wieder abschaltet.
das soll unter 42 Zeilen für 3 LEDs zu machen sein.
Nicht vergessen, dass das Rücksetzen der jeweiligen LED in loop() dann ebenfalls nicht mehr mit einer hart verdrahteten 13 funktionieren kann.
Tipp: Man kann - analog zum triggered Flag - auch Portpins aufheben.
Und es wäre auch möglich, sowas wie setTrigger() und resetTrigger() zu konstruieren - oder eine Klasse, die den LED-Pin und die Ablaufzeit hält und Methoden wie set() und run() kennt.
Ha...
Das wird doch wieder so ein Ding in Richtung "aber ich hätte da gerne noch..." ?
Denn Du wirst auf retrigger ja/nein eingehen, genauso wie eine unterschiedliche Blinkzeit, wie eben auch eine unterschiedliche Triggertime, sodas Du jede LED unabhängig betreibst. Von den Blinker vorzeitig beenden sprech ich dabei noch nicht mal.
Hallo,
was soll denn passieren wenn Du trigger(LED1) innerhalb von 500 ms erneut aufruftst ? Bleibt die LED dann an oder geht sie dennoch nach 500ms aus.
Ich finde es auch nicht besonders gut triger(lLED1) an unterschiedlichen Stellen aufzurufen. Sowas macht doch nur Probleme bei der Fehlersuche. Stell Dir mal vor die LED geht an, was sie aber eigentlich nicht sollte , und du suchst an der falschen Stelle. Dann verstehst du die Welt nicht mehr. Ich würde sowas an einer Stelle machen und die Bedingungen logisch verknüpfen.
Gut, wenn schon Codes kommen, gebe ich mal einen zur Diskussion.
Der beinhaltet 2 Varianten.
Man könnte die ggfls. sogar mischen.
Du kannst den Auslöser jederzeit aufrufen via
void chkBlinkStart(const int led)
Ich mache das einfach mit dem SerMon. Da kannst 0 bis 2 eingeben und der jeweilige Blinker blinkt. Kannst auch 012 eingeben, dann starten die fast zugleich....
Die Arrays kannste auch auflösen zu struct und dann ein arrayOfStruct bauen oder wie auch immer.
nur mal so als Idee, wenn du dir eh schon eine Struktur mit Member Functions machst, dann kannst gleich deinem Array der Struktur die Pins und Intervalle übergeben. Brauchst aus meiner Sicht nicht doppelt im Programm anführen (trotz constexpr, schaut das für mich eigenartig aus...).
Hallo,
ich hätte da eventuell noch eine generelle Anmerkung zu Thema. Der generelle Lösungsansatz hängt wie so oft von der Aufgabenstellung und dem Anwendungsfall ab.
Bei Maschinensteuerungen werden oft Meldeleuchten benutzt die mit Ihrem Leuchtstatus unterschiedliche Funktionen signalisieren. z.B
langsames blinken = Funktion ist vorgewählt
Leuchte ein_ Funktion in Betrieb
schnelles Blinken = Funktion ist gestört.
In der Regel stellt das Programm dann dazu die beiden unterschiedlichen Blinkfrequenzen zur Verfügung. Diese werden an einer zentralen Stelle gebildet und dem Programm über globale "Merker" zu Verfügung gestellt.
Die einzelnen Meldeleuchten werden dann an den betreffenden unterschiedlichen Stellen im Programm mittels logischen "oder" angesteuert. In Etwa so:
Betrieb
oder Vorwahl & Vorwahlblinker & nicht Störung
oder Störung & Störblinker & nicht Vorwahl
LED ein
zur Realisierung bietet sich in dem Fall eine Funktion an die z.B als Rückgabewert eine bool Variable zur Verfügung stellt und als Parameter die bool Variablen Betrieb, Vorwahl, VW-Blinker,ST-Blinker hat. z.B
Der Vorteil bei der Variante, alle gestörten oder vorgewählten leuchten blinken gleichzeitig und nicht wild durcheinander.
Für eine Aufgabestellung im Modellbau ist natürlich ehr gewünscht das verschiedene Leuchten zu unterschiedlichen Zeitpunkten ehr zufällig ein und ausgehen.
Mir ging es vorrangig um das Zusammenspiel der Funktionen, da ich ja eine brauche, die immer durchlaufen wird, um den Impuls zu generieren.
Und dann verschiedene LEDs damit zu steuern.
Ich habe mir dazu folgendes überlegt.
Vielleicht könnt ihr mir dazu noch eure Meinungen sagen?
Danke mal wieder
Global
enum class LED : byte {
NULL,
EINS,
ZWEI,
WARTEN
};
LED status {LED::WARTEN};
LED status_vorher {LED::WARTEN};
void loop() {
impuls();
}
void LED(byte trigger) {
if (trigger== 0) status = LED::NULL;
if (trigger== 1) status = LED::EINS;
if (trigger== 2) status = LED::ZWEI;
}
void impuls() {
if (status == status_vorher) return;
constexpr unsigned long IMPULS {500UL};
static bool ledLock {false};
static unsigned long impulsMillis {0};
switch (status) {
case LED::NULL :
if (!ledLock) {
impulsMillis = millis();
digitalWrite(pinLED0, HIGH);
ledLock = true;
}
if (millis() - impulsMillis < IMPULS) return;
digitalWrite(pinLED0, LOW);
break;
case LED::EINS :
if (!ledLock) {
impulsMillis = millis();
digitalWrite(pinLED1, HIGH);
ledLock = true;
}
if (millis() - impulsMillis < IMPULS) return;
digitalWrite(pinLED1, LOW);
break;
case LED::ZWEI :
if (!ledLock) {
impulsMillis = millis();
digitalWrite(pinLED2, HIGH);
ledLock = true;
}
if (millis() - impulsMillis < IMPULS) return;
digitalWrite(pinLED2, LOW);
break;
case LED::WARTEN :
break;
}
ledLock = false;
status_vorher = status;
}
So könnte ich in der Steuerfunktion mit
LED(1) ;
die LED 1 pulsen.
Wenn du es einigermaßen richtig machst, wird jede Funktion "immer durchlaufen", wenn du das willst.
Du möchtest einen zentralen Blink-Geber, damit alle Lämpchen deiner Anzeigetafel, die gerade blinken sollen, synchron blinken. (Oder war das @Rentner?)
Falls ja, und du damit in das objektorientierte Programmieren einsteigen willst, mach lieber aus jeder Led ein Element der Klasse LED, das dann einen der Zustände AN, AUS, BLINKEN hat.
z.B. sowas
enum LEDSTATE {AUS, AN, BLINKEN};
class LED {
const uint8_t pin;
LEDSTATE state = AUS;
static bool blinker;
static unsigned long timer;
static const uint16_t ON, OFF;
public:
static void ZentralBlinker() {
if (millis() - timer >= (ON+OFF)) timer += ON+OFF;
blinker = (millis() - timer <= ON);
}
LED(uint8_t p): pin(p) {}
void set(LEDSTATE s) {state = s;}
void init() {
pinMode(pin, OUTPUT);
state = AUS;
}
void show() {
switch (state) {
case AUS: digitalWrite(pin, LOW); break;
case AN: digitalWrite(pin, HIGH); break;
default: digitalWrite(pin, blinker); break;
}
}
};
LED l1 {LED_BUILTIN};
LED l2 {2};
// Der Zentrale Blinkgeber
bool LED::blinker;
unsigned long LED::timer;
// Zentrale Blink-Parameter
const uint16_t LED::ON {100};
const uint16_t LED::OFF {900};
void setup() {
l1.init();
l2.init();
l2.set(BLINKEN); // Beispielcode
}
void loop() {
// Beispielcode: Dies kann irgendwo beliebig gemacht werden
uint16_t zyklus = millis() & 0x3FFF; // 16384 ms Zyklus
if (zyklus < 3000) l1.set(AUS);
else if (zyklus < 8000) l1.set(BLINKEN);
else if (zyklus > 12000) l1.set(AN);
// zwischen 8000 und 12000 wird set nicht aufgerufen, l1 bleibt blinkend
// Dies soll immer ausgeführt werden
LED::ZentralBlinker();
l1.show();
l2.show();
}
Da habe ich einen zentralen Blinker als static Elemente der Klasse LED hinzugefügt.
Falls das verwirrt, kann der auch global ausserhalb der Klasse angelegt werden.
Hallo,
Ich bin mir da immer noch nicht sicher von was du redest, Geht es Dir um einen einzigen Impuls der ausgegeben wird .
Verlängerter Impuls ?
Die letzen Beispiele bezogen sich häufig auf Blinker.
Egal wenn Du mehrere davon benötigst die unabhängig voneinander laufen sollen dann benötigst du Speicher in dem die aktuellen Zustände gespeichert werden. Das kann man mit einer Struktur machen von der man z.B ein Array anlegt das ist dann C Style , oder man macht es mir einer Classe das ist dann C++