LED über Taster ein-nach 3s wieder aus

Hallo,

ihr verlangt jetzt nicht von mir das ich 2 Sketche pflege für mich und fürs Forum?
Pflegt ihr im Gegenzug 2 Varianten für mich und für euch?
Merkt ihr was? :wink:

Ich muss mich mit Eurem Codestyle arrangieren und ihr mit meinem. Leerzeilen und Leerzeichen lockern das Lesebild auf. Wer das nicht möchte kann das für sich gern alles zusammenklatschen. Wenn ich etwas gut finde übernehme ich das, wenn nicht dann nicht. :wink:

Keine Sorge, es verlangt keiner etwas von Dir. Wir sagen nur unsere Meinung, genau wie Du.

Gruß Tommy

Hallo,

da bin beruhigt. :slight_smile:

Habe in der Zwischenzeit mit Template probiert. Aber das bringt Null Punkte. Kann es sein das Template bei diesen Funktionen generell nichts bringt, weil nichts so richtig konstant ist? Ich meine die Werte der Variablen ändern sich ständig zur Laufzeit. Oder muss man das anders machen?

/*
  Doc_Arduino - german Arduino Forum
  IDE 1.8.12
  avr-gcc 9.2.0
  Arduino Mega2560
  12.03.2020
  License: GNU GPLv3
*/

struct Daten
{
  byte const pinTaster = 2;
  byte const pinLed = 28;
  unsigned long const offDelay = 3000;
  unsigned long timeStamp = 0;
} led;

void setup(void)
{
  pinMode(led.pinTaster, INPUT_PULLUP);
  pinMode(led.pinLed, OUTPUT);
}

void loop(void)
{
  bool state = updateTaster<byte>(led.pinTaster);
  bool onoff = combinedLogic<bool, unsigned long> (state, led.offDelay, led.timeStamp);
  digitalWrite(led.pinLed, onoff);
}

// ****** Funktionen ******
template<typename T>
bool updateTaster(const T pin)
{
  static unsigned long lastMillis {0};
  unsigned long ms {millis() };
  static bool read {true};

  if (ms - lastMillis >= 20)
  {
    lastMillis = ms;
    read = digitalRead(pin);
  }

  return read;
}

template <typename S, typename T>
bool combinedLogic (const S state, const T offDelay, T &timeStampOn)
{
  static bool oldState {true};
  unsigned long ms {millis() };
  static bool result {false};

  if (!state && (oldState == HIGH) )
  {
    timeStampOn = ms;       // aktualisiert 'timeStampOn' nur auf fallende Triggerflanke von 'state'
  }
  oldState = state;

  unsigned long const remainingTime = ms - timeStampOn;

  if (!state && (remainingTime < offDelay) )
  {
    result = true;    // wenn Taster gedrückt und Einschaltdauer noch nicht um, gib 'true' zurück
  }
  else if (state || (remainingTime >= offDelay) )
  {
    result = false;   // wenn Taster nicht gedrückt oder Einschaltdauer abgelaufen, gib 'false' zurück
  }

  return result;
}

Kann es sein das Template bei diesen Funktionen generell nichts bringt

... das kann ich nicht beurteilen - da fehlt mir noch gaaanz viel Wissen....

Nach Michael_x seinem Code habe ich meinen Ansatz eingepackt.
Aber jetzt hol ich den doch raus, weil ich mit menem wenigen Wissen schön zwischen Euch liege.

michael_x seiner compiliert mit 998 bytes / 13 bytes
Doc_arduino mit 1150 bytes / 26 bytes
Meiner mit 1082 / 14

Ich hab im Original noch die Möglichkeit eröffnet, ein debounce zu machen, darum unterscheidet sich das Attachment vom Code hier. ist aber selbst erklärend.

const int timing = 3000;
const int TasterPin = 5;

unsigned long lastmillis;
bool TasterStatus = LOW;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(TasterPin, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(TasterPin) == LOW && TasterStatus == LOW && digitalRead(LED_BUILTIN) == LOW )
  {
    TasterStatus = HIGH;
    digitalWrite(LED_BUILTIN, HIGH);
    lastmillis = millis();
  }

  if (digitalRead(TasterPin) == HIGH )
  {
    TasterStatus = LOW;
  }

  if ((digitalRead(LED_BUILTIN) == HIGH && millis() - lastmillis > timing) || TasterStatus == LOW)
  {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Forum_tast-led-time.ino (1.11 KB)

@Doc_Arduino
Habe mir das noch ein par mal durchgelesen und verwundert mit dem Kopf geschüttelt....
Eine Nacht drüber geschlafen, um alle akuten Emotionen da raus zu bekommen

combie, du suchst wieder nach Vergleichen die hier nicht passen nur damit du mir etwas unterstellen kannst.

Es ist nicht in meinem Interesse dir irgendwas zu unterstellen.
Aber das kann ich ja hier mal tun.....

Warum machst du sowas?

Ich breite hier meine Überzeugungen aus.
Und dabei ist es mir auch relativ egal, ob diese dir schmecken, oder in den Kram passen.
Aber mir "niedrige Beweggründe" zu unterstellen, ist irgendwie nicht nett.

Hier gehts um µC,

Deine Ansicht zu delay() yield() und Multitasking im allgemeinen, erinnert mich irgendwie an deine ehemaligen Ansichten über OOP.
Deine original Ansagen zu OOP kann ich nur sinngemäß wieder geben...

OOP braucht man auf µC nicht
macht das überhaupt Sinn
Das geht doch auch alles mit Funktionen
Natürlich stimmen diese Aussagen, wenn man sie gegen die Realität abgleicht.

Dennoch hast du dich auf das Abenteuer C++ OOP eingelassen, und einen Großteil der Vorteile dieser Betrachtungsweise erkannt.
Ich glaube, du möchtest die OOP nicht mehr missen, darauf verzichten.
In dem Punkt hast du es von einer (latenten) Ablehnung zu einer Akzeptanz gebracht.
Das geht so weit, dass du es selber freiwillig nutzt, obwohl es doch faktisch nicht unbedingt nötig ist. Bist hier mittlerweile sogar der Vorreiter, in Sachen moderner Kompiler, geworden.
Einen Teil der Schuld, für diese Änderung der Gesinnung schreibe ich mir zu, denn wir haben uns mittlerweile Monate darüber unterhalten

In Sachen delay() yield() und Multitasking im allgemeinen, stehen wir an einem ähnlichen Punkt.

Hier gehts um µC, wir haben kein Betriebssystem onboard.

Wenn es men so einfach wäre.....

Der ESP8266 nutzt das coroutinen Konzept. Dieses ist im Arduino ESP8266 Core fest eingebaut.
Man MUSS es nutzen, da gibts keine Alternative, denn sonst frisst dich der Wachhund.
Entweder direkt, über delay() oder yield(), oder indirekt, da zwischen den loop() aufrufen automatisch yield() oder eins seiner Brüder, aufgerufen wird.
Auf dem ESP8266 haben wir also 2 Coroutinen , einmal die Schleife mit den loop() Aufrufen und zweitens die Wlan Grund Funktionalität.
Natürlich darfst du das ausblenden, wird der Sache aber nicht gerecht.

Der ESP32 nutz FreeRTOS. Dieses ist im Arduino ESP32 Core fest eingebaut.
Loop und das andere Arduino Gedöns läuft auf Core1, das Wlan Gedöns auf Core0.
Jetzt kann man sich damit zufrieden geben und sich auf einen Core beschränken, FreeTOS ignorieren/ausblenden.
Aber damit beschränkt man sich selber. Das kann aus meiner Sicht nicht das, oder ein, Ziel sein.
Zudem verschenkt man 50% der Rechenleistung, und echte Parallelverarbeitung.
Am Anfang evtl. ok, aber später, sollte man sich dem dann doch schon öffnen, meine ich.

Selbst für den kleinsten Arduino gibt es yield() und delay().
Und ich sehe keinen Grund das auszublenden, oder gar dagegen zu kämpfen.

Zusammengefasst:
Auf diesen µC existieren "Multitasking Systeme". Ob du willst, oder nicht.
Man kann sie im Kopf ausblenden, aber die Realität sieht anders aus.

Mit den größeren original Arduinos kenne ich mich nicht so aus, aber die Regel lautet wohl:
Je fetter der µC, desto vollwertiger das Multitasking System, was darauf läuft.


Aus meiner Sicht kann man sehr wohl das OOP Konzept auf die kleinen µC anwenden.
Aus meiner Sicht kann man sehr wohl die allgemein üblichen Multitasking Konzepte auf die kleinen µC anwenden.

In beiden Fällen beschränkt die Kleinheit mancher µC den Leistungsumfang.
Aber das spricht doch nicht gegen die Konzepte im allgemeinen.

Hallo,

wir reden hier komplett aneinander vorbei. Warum eigentlich?
Klar gibt es beim ATmega und ESP yield. Das spreche ich doch nicht ab und habe ich auch nie abgesprochen.
Das benötigt er für sich selbst. Soweit ist wohl noch alles geklärt.
Ich sage nur folgendes. Das Vorhanden sein heißt nicht das man es selbst für sein Programm nutzen muss. Auf unseren Einkern ATmega ohne eigenes OS sehe ich nachwievor keinen Nutzen. Da programmiere ich lieber gleich von Anfang an ohne jede Blockade. Wenn ich in 5 Jahren anderer Meinung bin okay, aktuell sehe ich da keinen Horizont für. Ansonsten treffen wir irgendwann vielleicht damit wieder zusammen. Wer weiß da schon. :slight_smile:

Ihr dürft yield aber gern verwenden wenn ihr möchtet. Ich verbiete das nicht. Ich habe mich nur über den Sinn ausgelassen.

Ich habe mich nur über den Sinn ausgelassen.

Ja, "ausgelassen" stimmt schon....

nun mal Butter bei die Fische. Wozu hat man yield beim ESP eingeführt? Eben damit der noch dumme Neue seine loop mit delay zukloppen kann und WLAN etc. trotzdem funktioniert. Sonst denkt er sein ESP ist kaputt. Die Begründung taucht seltsamerweise nirgends hier auf. Würde man auf delay komplett verzichten bräuchte man die Krücke yield nicht. Ganz simpel.

ESP ist eine Baustelle .... die kleinen µC eine andere ....

Die Arduino Begründung zu den kleineren µC ist im Arduino Core verankert.
2012 wurde dazu geschrieben:

/**
 * Empty yield() hook.
 *
 * This function is intended to be used by library writers to build
 * libraries or sketches that supports cooperative threads.
 *
 * Its defined as a weak symbol and it can be redefined to implement a
 * real cooperative scheduler.
 */

Vergleiche bitte mit:

Eben damit der noch dumme Neue seine loop mit delay zukloppen kann
Da ist es doch unausweichlich klar, welcher Denkart ich mich da eher anschließen kann.
(zumindest mir)

Ich sage nur folgendes. Das Vorhanden sein heißt nicht das man es selbst für sein Programm nutzen muss. Auf unseren Einkern ATmega ohne eigenes OS sehe ich nachwievor keinen Nutzen. Da programmiere ich lieber gleich von Anfang an ohne jede Blockade. Wenn ich in 5 Jahren anderer Meinung bin okay, aktuell sehe ich da keinen Horizont für. Ansonsten treffen wir irgendwann vielleicht damit wieder zusammen. Wer weiß da schon. :slight_smile:

Wenn ich meine eigenen Interessen, da raus halte, kann ich nur sagen: Das wird schon!

Oder interessiert es dich, welchen Nutzen ich sehe?
Dann können wir gerne noch etwas weiter machen...

Hallo,

den Nutzen aus deiner Sicht kenne ich nun ja. Darüber quatschen wir ja schon Seitenweise.
Du möchtest die loop mit delay verstopfen und verschiebst Dinge die nicht blockieren dürfen in yield.
Über diesen Nutzen müssen wir nicht weiter reden. Darüber haben wir komplett verschiedene Ansichten.
Wenn du einen Nutzen erklären kannst wo kein delay, kein Blockierung drin vorkommt, dann höre ich dir gern weiter zu. Beschränke dich dabei erstmal bitte auf den ATmega. Das sollte die Erklärung deinerseits und die Verständlichkeit meinerseits einfacher machen. Ansonsten können wir die Unterhaltung aus meiner Sicht vertagen. Nimm es mir nicht übel.

den Nutzen aus deiner Sicht kenne ich nun ja. Darüber quatschen wir ja schon Seitenweise.
Du möchtest die loop mit delay verstopfen und verschiebst Dinge die nicht blockieren dürfen in yield.

Leider falsch.

Und solange mir du mit solchen irrationalen Fantasien entgegen stehst, macht eine weitere Unterhaltung wirklich wenig Sinn.
So kann man keinen Dialog führen.
Das wird ein Disput.
Drauf habe ich nun wirklich keine Lust.

Hallo,

tut mir leid. Aber genau das habe ich während unserer gesamten Unterhaltung hier immer so verstanden. Das man ohne Rücksicht delay verwenden kann, weil man ja noch yield hat was einem den Arsch rettet. Diese Aussage habe ich nie verstanden.
Vorschlag.
Da das hier eh festgefahren ist, vertagen wir es oder setzen es ganz aus. Sonst könnte es ausarten und das wollen wir beide nicht. Da bin ich mir sicher. Nichts für ungut. Alles cool.

Aber genau das habe ich während unserer gesamten Unterhaltung hier immer so verstanden. Das man ohne Rücksicht delay verwenden kann, weil man ja noch yield hat was einem den Arsch rettet. Diese Aussage habe ich nie verstanden.

Diese Aussage verstehe auch ich nicht.
Habe keine blasse Ahnung, wie du darauf kommst....

Was ich wohl schon mal so, oder sinngemäß, gesagt habe:

Es gibt noch ein Leben neben delay()

Wer delay verwendet, weil er die Auswirkungen nicht versteht, sollte sich lieber darüber Gedanken machen statt irgendwelche Hilfslösungen (yield, TaskScheduler, etc. ) - ebenso unverstanden - zu verwenden, finde ich.

Deswegen nichts von yield() zu erzählen, wird schonmal als "die Leute dumm halten" kritisiert.
Das kann ich allerdings ertragen.

Gab schon zu meiner Berufszeit beim Kurse abhalten ähnliche Diskussionen unter Kollegen, wo meine Meinung war, dass es meist gut ist, nicht zuviel zu erzählen und bei Grundlagen erstmal zu zeigen, wie einfach es ist.

... und weil Es bei den Grundlagen nun Mal nur um dieses eine Problem geht, schadet (hier) delay() nicht.
Auch muß man ja nicht konstant machen, was konstant ist - ist für das Beispiel völlig übertrieben ...

Wenn's aber schon nicht Mal in den mitgelieferten beispielen 'richtig' gemacht wird - weil's hier ja gar nicht um 'Das und Das' ankommt, sondern NUR um diese eine Funktionalität - wie soll Da ein Neuling Sinnvolles von "Ist egal, nur Mittel zum Zweck" unterscheiden können?

Überall liest Er
int pin=3;

WARUM soll Er nun das Gelernte nicht genau so anwenden? Selbst in den mitgelieferten Beispielen wird überall int genommen, funktioniert Das doch so - und wenn schon die Hersteller nicht richtig wissen, wie man mit dem Kram umgeht - wer sonst?

Aber auch Das wäre Don Quijote wohl dran gescheiter ... kommt hier halt nicht drauf an ...

MfG

postmaster-ino:
... und weil Es bei den Grundlagen nun Mal nur um dieses eine Problem geht, schadet (hier) delay() nicht.
Auch muß man ja nicht konstant machen, was konstant ist - ist für das Beispiel völlig übertrieben ...

Bei der Aufgabe in diesem Thread Beitrag #0 kann man kein delay verwenden. Man muss sich irgendwelchen Zeiten merken und vergleichen. Es gibt in diesem Thread kein Bsp. welches delay für die Ursprungsaufgabe verwendet.
Pinnummer mit const byte zu initialisieren sollte zu den Grundlagen gehören.
Man müßte alle Bsp. umschreiben. Ob das Arduino.cc gefällt weiß ich nicht.
int liest sich für "Künstler" leider einfacher.

int liest sich für "Künstler" leider einfacher.

byte statt int bringt leider an der Stelle nicht so richtig viel...

Einerseits liegts daran, dass z.B. digitalWrite() in einer C Datei liegt, und auch von einem C Kompiler verwurstet wird.
Und vor allen Dingen daran, dass Parameter an Funktionen als int übergeben werden.
Bei einem AVR Funktionsaufruf werden min. 2 Register für die Parameterübergabe genutzt. Gilt für C und C++.
Dort ist es also recht egal, ob int oder byte.

Bei anderen µC, z.B. den 32 und 64 Bit Rechnern, die tun sich richtig schwer mit 8 Bit Zugriffen.
Da ist es eher kontraproduktiv byte Verarbeitung zu erzwingen.
Stichworte: Alignment und Padding

Ich halte das const an der Stelle für viel effektiver.
Das ermöglicht dem Kompiler zu optimieren.
Ob const int oder const byte macht dagegen im generierten Code nur ganz selten einen Unterschied.

--

Deswegen nichts von yield() zu erzählen, wird schonmal als "die Leute dumm halten" kritisiert.

Ich fühle mich angesprochen und missverstanden.

Tipp:
Die wörtliche Übersetzung von yield ist Ertrag, oder Ausbeute.
Natürlich kann man den Begriff negativ bewerten, oder ausblenden, aber dennoch ist es eben der Ertrag, und die Ausbeute, welche uns am Leben erhält.
:smiling_imp: :smiling_imp: :smiling_imp:

Hallo,

ich erwähne das manchmal wenn es irgendwie zum Thema passt, weil manche Leute schon die Bits zählen. :slight_smile:
Aber ja, selbst beim Mega mit seinen 52 Pins wären das im dümmsten Fall 52 Byte Verschwendung. Bei 8kB RAM ist das auch egal. Wenn man daran denkt nimmt man byte, ansonsten eben int, Hauptsache konstant.

Zum Thema yield. Wenn du dich missverstanden fühlst, fühle ich mich auch missverstanden. :smiling_imp: :smiling_imp: :smiling_imp:
Irgendwie fühlen sich wohl alle missverstanden. :wink:

Wenn du dich missverstanden fühlst, fühle ich mich auch missverstanden.

Ja klar, fühle ich mich missverstanden!

Irgendwie fühlen sich wohl alle missverstanden.

Jooo....

Die Wahrheit triumphiert nie, ihre Gegner sterben nur aus.
Quelle: Max Planck