ich habe ein kleines Problem ( so einen ähnlichen Fall hatte ich schonmal, kann aber mit dem alten Code irgendwie nichts anfangen, komme da nicht weiter).
An einen Nano wird an Pin 10 eine externe Lichtschranke angeschlossen. Wenn jemand vor der Lichtschranke steht fällt das Signal an Pin 10 auf LOW ab, ansonsten HIGH. Das funktioniert schon einmal.
Nun möchte ich dass, sobald das Input Signal an Pin 10 auf LOW abfällt, ein OUTPUT an Pin 2 ebenfalls auf LOW abfällt, aber nur für ca. 500 millisekunden. Danach soll Pin 2 wieder auf HIGH gesetzt werden.
Erst wenn das Eingangssignal an Pin 10 wieder auf HIGH wechselt darf der Prozess wieder von vorne beginnen.
Im Prinzip so > Jemand steht vor die Lichtschranke > jetzt wird nur ein kurzes Signal ausgegeben, also nicht so lange wie tatsächlich jemand vor der Lichtschranke steht.
Das Signal soll erst erneut ausgegeben werden,wenn die Person den Bereich der Lichtschranke wieder verlassen hat, und dann wieder betritt.
Ich habe mal angefangen, komme aber nicht wirklich weiter.
int hupePin = 2;
int lichtschrankePin = 10;
int bewegungsstatus = 0;
bool merker = false;
unsigned long startTime; // Merker Wann hat hupen angefangen
unsigned long hupeTime = 100; // Zeit in ms!
void setup()
{
pinMode (hupePin, OUTPUT);
pinMode (lichtschrankePin, INPUT);
}
void loop()
{
.....????
Vielleicht kann mir wieder jemand auf die Sprünge helfen dieses Problem zu lösen,
ich würde mich sehr darüber freuen!
Ich würde gerne etwas ganz bestimmtes herausfinden.
Ich möchte herausfinden ob ich mit meiner Vermutung falsch oder richtig liege.
Meine Vermutung: Wenn im Programm zwei Dinge gemacht werden:
konsequent möglichst spezifische und selbsterklärende Namen wählen
zusätzlich viele Kommentare hinzufügen
Diese Kombination aus 1.) und 2.) führt möglicherweise zu mehr Verwirrung als zu Erklärung. Und das ist das was ich herausfinden will.
Welche Art der Programmierung ist für dich als Einsteiger leichter verständlich
Ich bin jetzt explizit auf eine vergleichende Bewertung aus.
Ein Stil kurze Variablennamen relativ wenig Kommentare im Vergleich zu
lange selbsterklärende Namen und zusätzliche Konstanten plus oben drauf viele Kommentare.
Das ist für mich eine wirklich offene Frage an user @zappzerapp4
Ich möchte daraus erfahren welcher Stil leichter verständlich ist.
hier meine Code-Version
const byte hupePin = 2;
const byte lichtschrankePin = 10;
byte LS_State;
byte LS_lastState;
bool LS_flanke_HIGH_LOW = false;
unsigned long startHupe; // Variable für ZeitStempel Wann hat hupen angefangen
unsigned long hupeEinschaltZeit = 500; // Zeit in ms!
#define LS_unterbrochen LOW
#define Einschalten HIGH
#define Ausschalten LOW
void setup() {
pinMode (hupePin, OUTPUT);
pinMode (lichtschrankePin, INPUT);
}
void loop() {
LS_State = digitalRead(lichtschrankePin);// IO-pin status einlesen und speichern
if (LS_lastState != LS_State) { // prüfe ob sich IO-pin status geändert hat
// WENN sich IO-pin-Status geändert hat
if (LS_State == LS_unterbrochen) { // prüfe ob NEUER Zustand Lichtschranke unterbrochen ist
// WENN Lichtschranke unterbrochen ist
LS_flanke_HIGH_LOW = true; // setze Flankenmerker
}
LS_lastState = LS_State; // nach dem Vergleich if (LS_lastState != LS_State) LS_lastState aktualisieren
}
if (LS_flanke_HIGH_LOW) { // prüfe ob es eine HIGH_LOW-FLANKE ist
// WENN es eine HIGH-LOW-Flanke ist
LS_flanke_HIGH_LOW = false; // flankenmerker zurücksetzen
startHupe = millis(); // aktuellen Zeitstempel speichern
digitalWrite(hupePin, Einschalten);
}
if (millis() - startHupe >= hupeEinschaltZeit) { // prüfe ob Hupe-Einschaltzeit vorbei ist
// WENN Hupe-Einschaltzeit vorbei ist
digitalWrite(hupePin, Ausschalten);
}
}
Und hier die WOKWI Simulation dazu
Schon klar dass das für jeden user wieder anders ist.
Es geht darum - im Laufe der Zeit viele Einsteiger das zu Fragen um herauszufinden gibt es eine Tendenz.
vgs
Das ist mir völlig klar! Deswegen gibt es ja so wenig Programme die das im Ausführlich-Stil machen. Die für mich entscheidende Frage ist aber nicht wie gut gefällt der Code einem Experten sondern die entscheidende Frage für mich ist:
Wie leicht verständlich ist ein Programm das explizit für Einsteiger zum Lernen geschrieben ist.
"Beispiele" zum Code lesen lernen der nullkomma-garnicht kommentiert ist gibt es schon ganz viele.
Und wenn jetzt das Argument kommt damit "versaut" man Einsteigern "clean-coding"
dann antworte ich dazu:
"Ihr Super-Experten macht erst mal das dämliche delay() aus den ganzen Beispielen raus!
Das versaut richtig!
Wenn schon "Anspruch von Anfang an" dann in der Form, dass als erstes nicht-blockierendes timing und state-machine erklärt wird. Und zwar in einem für Einsteiger möglichst leicht verständlichen Tutorial. Nicht durch schnelles reinklatschen von "clean-code"
vgs
Aha und was ist mit kurzen Variablennamen und vielen Kommentaren? Das erscheint mir logischer. Wenn jemand nur einzelne Buchstaben verwendet, wie das mal vor 40 Jahren "Basic Style" war, dann dürften Kommentare eher hilfreich sein als bei selbsterklärenden Namen.
Es kann nicht der Sinn von Kommentaren sein, den Quellcode noch einmal mit anderen Worten aufzuschreiben.
Das ist eine der Fragen die ich gerne von den Einsteigern selbst beantwortet haben möchte. Ich selbst vermute dass das eine Fehleinschätzung ist. Und um zu klären ob diese Einschätzung zutrifft oder eine Fehleinschätzung ist Frage ich explizit diejenigen die es wirklich berifft: Die Einsteiger
vgs
Und dann macht der selbsterklärende Name Sinn und an der Stelle braucht man dann tatsächlich keinen weiteren Kommentar.
Mal eine andere Frage:
Verwirrt es die werten Experten wenn viele Kommentare drinstehen die den Code mit anderen Worten noch einmal wiedergeben?
Wenn ja, dann ist das mit dem Expertensein wohl noch nicht so richtig gelungen.
vgs
Katze - Maus - Bauer
Bei dem Dreieck ist nicht jedem gleich klar, wer gut und böse ist.
bzw. vom Standpunkt abhängig.
Nein, man fragt nicht den Anfänger, wenn man fortgeschrittene Techniken implementieren möchte.
Wie man auch nicht den Bock zum Gärtner macht.
Aber ok, ich halte mich ab jetzt hier raus!
Doppelte Information ist arg "irritierend"!
Wenn ich mich als Experte betrachte: JA! Mich stört das massiv!
Der LichtschrankePin geht LOW wenn eingetreten wird.
Nur wenn KEIN merker gesetzt ist, geht die Hupe AN
Kommt jetzt der Wechsel von LOW nach HIGH beim verlassen, wird zwar der merker gelöscht, aber es wird kein neues Timing ausgelöst.
Im Original waren 100ms Hupe als Anforderung.
Wenn man nun innerhalb der 100ms vermeiden möchte, das der Timer durch erneutes eintreten ausgelöst wird, müsste mit verlassen das Signal beendet werden.
if (millis() - startTime > hupeTime || !merker)
digitalWrite(hupePin, LOW);
Ob redundante Wiederholung dessen, was der Code bereits aussagt, sinnvoll ist oder nicht, ist m.E.
a) von der Qualität des Codes selbst,
b) dem Nutzwert des Kommentars
c) dessen Zweck und damit auch der Zielgruppe
abhängig.
Kommentare, die nur wiederholen, was im Quelltext nachzulesen ist, sind im besten Fall nur für absolute Anfänger hilfreich, in der Regel aber eher "Zeichenverschwendung" beim Erstellen und Lesen...
Umständlich bzw. schwer nachvollziehbar geschriebener Code wird durch Kommentare nicht besser.
Kommentare sollten das ergänzen, was dem Code nicht oder ggf. nur indirekt entnehmbar ist; im optimalen Fall braucht es diese höchstens zur Schnittstellenbeschreibung oder um Grenzen oder Beschränkungen zu beschreiben.
Anders kann dies bei einführenden Beispielen für Anfänger aussehen. Aber auch dort ist der fehlende Kenntnisse ergänzende Charakter von Bedeutung.
Bin noch nicht überzeugt... Wenn die Lichtschranke "zappelt", wird mit Deinem Code ( wenn ich das im Trockendurchgang richtig interpretiere, kann mich natürlich irren) die startTime neu gesetzt ... Oder täusche ich mich?
Also ich spreche von mehrfachem Wechseln. Bei 100 ms ist das sicher weniger wahrscheinlich, bei den 1100 ms könnte es passieren.
Danke, allerdings ist das herausfordernder, als es zu formulieren ... Es braucht Disziplin, Übung und eine Auseinandersetzung mit der Zielgruppe, für die man kommentiert.
Übersichtlich und nachvollziehbar geschriebener Code ist das A&O.
Vorteilhaft sind i.d.R.
kürzere Funktionen, aus denen das Programm in setup() und loop() zusammen gesetzt wird
das Vermeiden von mehrfach kopierten Funktionen
die Verwendung von globalen Variablen auf das Notwendige beschränken
Damit kann man den Code besser nachvollziehen und in den meisten Fällen einzeln mit definierten Werten (z.B. in setup()) testen, bevor man sie im Verbund in loop() einsetzt.
Das ist sicher ein interessantes Thema ... Aber wir kapern hier gerade den Thread ... ;-(