Ich hoffe ich bin hier richtig- Hallo Leute.
Als Vollblutlaie habe ich mich mal an die Programmierung gewagt.
Mein Projekt: Ein Lichtschlauch (ws2812b), zwei Schalter.
Was es tun soll: Ein Schalter schaltet einen Kanal für Tag, einer für Nacht; diese ziehen beim Arduino zwei Kanäle auf High oder Low.
Auf dem Arduino habe ich ein Programm geschrieben, der das Licht am Lichtschlauch wie eine Gardine öffnet und schließt. Am Tag heller als Nachts. (An Zeit-Funktionen über den Arduino bin ich bereits mehrfach gescheitert, also übernimmt die Zeit der Shelly)
Zwei Kanäle werden mit einem definitiven Widerstand belegt, um ein klares High und Low zu erzeugen.
So weit, so gut, die Programmierung läuft, wie sie soll:
-drücke ich den Tag-Schalter, wird das Programm für den Tag abgespielt
-drücke ich den Nacht-Schalter, wird das Programm für die Nacht abgespielt.
-drückt man beide Schalter, wird das Programm für buntes Licht (Pink) abgespielt
ABER immer öfter tritt das Problem auf, dass der Arduino die LOW bzw High-Signale falsch interpretiert und den Lichtschlauch falsch einschaltet (hell statt dunkel, dunkel statt hell, pink). Mal mitten im Programmablauf, mal gänzlich ohne Schalterdruck.
Was ich probiert habe: Beide Kanäle auf High, beide auf LOW, beide gemischt- immer das selbe Ergebnis. Die beiden 10kOhm-Widerstande sind OK.
Habe ich einen Fehler im System? Die "Schalter" sind übrigens potenzialfreie Relaiskontakte.
..... solltest du dir erst mal die Hinweise zum Posten von
Quelltexten durchlesen und zu Herzen nehmen. Für alle die
das Kleingedruckte nicht entziffern können, hier nochmal:
1
Wichtige Regeln - erst lesen, dann posten!
2
............
3
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Weiterer Hinweis: "Längerer Sourcecode" ist es wenn eine
Bildschirmseite nicht ausreicht den Code vollständig
darzustellen.
Zwei Kanäle werden mit einem definitiven Widerstand belegt, um ein
klares High und Low zu erzeugen.
So weit, so gut,
So weit, so gut, wir lieben Schaltpläne in Prosa. Richtig
verständlich wird aber ein Schaltplan erst dann wenn er
vollständig gezeichnet ist und hier veröffentlicht wird.
Hier könnt ihr Projekte, Schaltungen oder Codeschnipsel vorstellen. Projekte bitte nur mit Code oder Schaltplan posten (falls ihr nur Fotos vorstellen möchtet, bitte in "Zeigt her eure Kunstwerke"). Bitte hier keine Fragen posten.
Ach nochwas: bitte den GANZEN Code posten und nicht nur einen
Ausschnitt. Und dann erhebt sich die Frage: hast du deine
Schalter-Eingänge entprellt?
Hmm bei mir sehe ich den gesamten Code. Der Tipp mit dem Entprellen- das werde ich mal weiterverfolgen. Soweit ich weis muss dazu ein weiterer Widerstand und ein Kondensator parallel zum Schalter installiert werden- richtig?
Bei 10kΩ fließen nur 0,5mA. Die meisten Schaltkontakte brauchen mehr Strom, um langfristig zuverlässig zu funktionieren.
Dazu kommt, dass so hochohmig abgeschlossene Eingänge für Radiowellen empfänglich sind. Gehe ruhig auf 2,2kΩ runter - auch wenn das im Moment wahrscheinlich nicht die Problemursache ist.
Wenn eine Taste gedrückt wird, soll etwas aktiviert werden.
Wenn beide Tasten gedrückt werden, soll es aus gehen.
Du wirst aber wohl kaum beide Tasten exakt im gleichen Moment loslassen können, ergo geht das Gerät nach dem Ausschalten direkt wieder an.
Anbei das Schaltbild und der Programmcode als .txt
Aus der Arduino Nano Beschreibung:
How to power up the Arduino Nano?
There are a couple of ways in which you can power the Nano board. The first and easy way is using the mini-B type USB Connector. The next way is to provide a regulated 5V supply through the 5V pin (Pin number 27).
Finally, the Nano has an onboard regulator at the bottom (along with the USB – to – Serial Converter). To use, you can provide an unregulated supply in the range of 6V to 20V to VIN pin of the Nano (Pin number 30).
Du hast die 5V mit VIN statt dem 5V Pin verbunden. Damit sieht der ATMega328P nach dem Spannungsregler weniger als 5V, und wenn die 5V nicht stabil anstehen, was ich mir bei 66 WS2812B gut vorstellen kann, dann schlägt eventuell der Brown-out Detektor zu und löst einen Reset aus.
Also 5V PowerSupply und Spannungsabfall auf GND und 5V Leitung nachmessen.
Ach nochwas: bitte den GANZEN Code posten und nicht nur einen
Ausschnitt. Und dann erhebt sich die Frage: hast du deine
Schalter-Eingänge entprellt?
Hmm bei mir sehe ich den gesamten Code. Der Tipp mit dem Entprellen- das
werde ich mal weiterverfolgen. Soweit ich weis muss dazu ein weiterer
Widerstand und ein Kondensator parallel zum Schalter installiert werden-
richtig?
Deine Taster kann man so benutzen, ist aber unüblich. Üblich sind Schalter gegen GND und interne oder externe Pull-Up Widerstände. Das ist aber nicht das zentrale Problem.
Wenn man Taster abfragt, sollte man die meistens entprellen, entweder in Hard- oder Software. Außerdem sollte man für die meisten Aktionen die Flanke erkennen, damit eine dauerhaft (länger) gedrückte Taste die Aktion nur einmalig auslöst. Deine Abfrage der Taster in hyperschallschnell, das is nicht nur Unsinn, sondern auch kontraproduktiv.
Ein Schreibzugriff auf digitale Eingänge is Unfug im setup().
Und dein Programm musst du werder umkopiere noch in.txt umbenennen. Man kann einfach die .ino Datei anfügen.
Siehe Anhang. Es wird die Flanke der Signale ausgewertet. Damit wird nur einmalig die Tag- oder Nachtsequenz ausgeführt. Ebenso wird der andere, inaktive Eingang ignoriert, solange der andere aktiv bleibt. D.h. nach einer erkannten Flanken müssen beide Eingänge erstmal auf inaktiv gehen und damit die Ausschaltsequenz auslösen, damit eine neue Einschaltsequenz möglich ist. Wenn beide Eingänge aktiv sind, wird des "bunt", was hier aber nur pink bedeutet. Naja.
Der Tipp mit dem Entprellen- das
werde ich mal weiterverfolgen. Soweit ich weis muss dazu ein weiterer
Widerstand und ein Kondensator parallel zum Schalter installiert werden-
richtig?
Nein, Entprellen macht man per Software. Dein Ablauf ist nicht zeitkritisch, das würde ich mit "delay(25)" machen. Also bei erkannter Taste 25ms warten, nochmal abfragen und den Wert nur übernehmen, wenn beide identisch sind. Damit werden kurze Störimpulse ausgeblendet, die man bei Dir als Ursache annehmen darf.
Deine beiden
digitalWrite(SENSORPIN1, LOW);
digitalWrite(SENSORPIN2, LOW);
sind nicht ursächlich, aber sinnfrei - es sind Eingänge.
Wie Stefan Monk schrieb, würde ich die 10kOhm an den Tastern deutlich niederohmiger machen, der Strom für die kurze Betätigung tut nicht weh. 1kOhm oder auch 500Ohm, das erhöht die Störsicherheit.
Auch der Hinweis von Loco passt,
Du hast die 5V mit VIN statt dem 5V Pin verbunden.
Vor allem die 5V am Pin 5V einspeisen! NICHT an VIN, dort müssen 6,5-12V
anliegen!
Ja, erst ab kurz über 6V kann der xx1117-5 die Spannung sauber halten. 12V verträgt er garantiert, aber als ängstlicher Mensch vermeide ich gerne die Verlustleistung.
Wie Stefan Monk schrieb, würde ich die 10kOhm an den Tastern deutlich
niederohmiger machen, der Strom für die kurze Betätigung tut nicht weh.
1kOhm oder auch 500Ohm, das erhöht die Störsicherheit.
Nicht so viel wie die Meisten glauben. Der Störabstand wird deutlich mehr duch einen anschließenden RC-Tiefpass erhöht. Da sind auch 10k Pull Up kein Problem.
ABER immer öfter tritt das Problem auf, dass der Arduino die LOW bzw
High-Signale falsch interpretiert und den Lichtschlauch falsch
einschaltet
Dein Problem ist, dass der µC viel schneller ist, als du dir vorstellen kannst.
Denn stell dir mal vor, wie schnell der µC die loop() durchlaufen kann. Nehmen wir hier mal gemächliche 20ms an (aber als Tipp: dein Programm sollte sogar noch funktionieren, wenn die Durchlaufzeit 0 ist).
Und dann stellst du dir vor, wie schnell du die Tasten "gleichzeitig" drücken und später dann "gleichzeitig" loslassen kannst. Und was die Zustände sind, die durchlaufen werden, weil du die beiden Taster eben garantiert nicht jedesmal innerhalb von 20ms "gleichzeitig" drücken und loslassen kannst.
Und weil da eben Zeit vergeht, bis beide Tasten sicher gedrückt sind, musst du vor dem Start der jeweiligen "Programme" mindestens diese Zeit abwarten.
Wo findest du das ?
Ich sehe in allen loop-Verzweigungen ausreichend lang dauernde
Operationen um nicht auf das Prellen von Kontakten reinzufallen.
Ja, aber beim "gleichzeitigen" Drücken von 2 Tasten kommt garantiert immer 1 Taste zuerst. Und wenn dann grade die Mainloop durchläuft. Aber dank der klarifizierten Schalter ist das hier nicht das Problem...
Deine beiden
digitalWrite(SENSORPIN1, LOW);
digitalWrite(SENSORPIN2, LOW);
sind nicht ursächlich, aber sinnfrei - es sind Eingänge.
In 1000 anderen Tutorials wird gesagt, man muss LOW und HIGH-Eingänge
definieren
LOW- und HIGH-Eingänge gibt es nicht, es gibt nur Eingänge. Die Tutorials meinen auch nicht "definieren", sondern "für einen definierten Spannungspegel sorgen".
Das geht nur mittels einer externen Beschaltung. Per Programm wirksam auf Pins schreiben kann man logischerweise nur, wenn es Ausgänge sind.
Und dann stellst du dir vor, wie schnell du die Tasten "gleichzeitig"
drücken und später dann "gleichzeitig" loslassen kannst. Und was die
Zustände sind, die durchlaufen werden, weil du die beiden Taster eben
garantiert nicht jedesmal innerhalb von 20ms "gleichzeitig" drücken und
loslassen kannst.
In 1000 anderen Tutorials wird gesagt, man muss LOW und HIGH-Eingänge
definieren, aber ich probiere auch mal deinen Tipp.
Kannst du mal auf ein Beispiel verweisen? Ich vermute ein
Missverständnis, dass ich aufklären möchte.
Das ist eine sinnfreie Nebenbaustelle, die nicht hilft.
Deine Formulierung "Radiowellen" ist eher laienhaft, aber vermutlich sein Problem. Da strahlt irgendwas ein und bringt das Programm in eine andere Betriebsart.
Aus dem Grunde wurde Entprellung angesprochen. Ich habe kein Problem, wenn ich die Taste nach einer Weile erneut abfrage und nur für gültig erkläre, wenn beide identisch sind.
pinMode(SENSORPIN1, INPUT);
digitalWrite(SENSORPIN1, 1); //Pullup aktivieren
Macht selten Sinn, aber kann man tun.
Es hat Wirkung.
Wirklich? Hast du in den Quelltext geschaut? (Ich nicht)
Die Arduino-Funktionen sind nicht das Gleiche wie der direkte Zugriff auf die Register, so daß ich vermuten würde, daß ein Schreibzugriff auf ein IO-Pin, welches vorher als Eingang definiert wurden, rein gar nichts bewirkt. Denn der Pull-Up wird mit der pinMode() Funktion eingeschaltet.
Alles andere wäre Murks.
Schade!
Wirklich schade!
Noch nicht mal in die Doku geschaut!
Ok, mein Fehler. Trotzdem ist es Unfug, dieses Spezialverhalten des AVRs in diese Funktionen reinzufummeln. Denn bei andern CPUs, die auch "Arduino" sind, funktioniert es so nicht, es sei denn man frickelt das rückwirkend dort rein.
Deine Formulierung "Radiowellen" ist eher laienhaft
Ich habe den Begriff vor 30 Jahren in der Ausbildung zum Kommunkationserlektroniker so gelernt, wie in Wikipedia beschrieben:
"Radiowellen, auch Funkwellen, oder Hertzsche Wellen sind in ... der Internationalen Fernmeldeunion (ITU) als „elektromagnetische Wellen definiert, deren Frequenzen vereinbarungsgemäß unterhalb 3000 GHz liegen, und die sich ohne künstliche Führung im freien Raum ausbreiten.“"
Die Arduino-Funktionen sind nicht das Gleiche wie der direkte Zugriff
auf die Register, so daß ich vermuten würde, daß ein Schreibzugriff auf
ein IO-Pin, welches vorher als Eingang definiert wurden, rein gar nichts
bewirkt.
Möp! Schau mal in den Quelltext:
1
voiddigitalWrite(uint8_tpin,uint8_tval)
2
{
3
uint8_ttimer=digitalPinToTimer(pin);
4
uint8_tbit=digitalPinToBitMask(pin);
5
uint8_tport=digitalPinToPort(pin);
6
volatileuint8_t*out;
7
8
if(port==NOT_A_PIN)return;
9
10
// If the pin that support PWM output, we need to turn it off
11
// before doing a digital write.
12
if(timer!=NOT_ON_TIMER)turnOffPWM(timer);
13
14
out=portOutputRegister(port);
15
16
uint8_toldSREG=SREG;
17
cli();
18
19
if(val==LOW){
20
*out&=~bit;
21
}else{
22
*out|=bit;
23
}
24
25
SREG=oldSREG;
26
}
Denn der Pull-Up wird mit der pinMode() Funktion eingeschaltet.
auch
Alles andere wäre Murks.
Arduino ist nur sehr knapp dokumentiert, deswegen kommt es Anfängern einfach vor. Es bietet dadurch aber auch reichlich Gelegenheiten für Probleme, insbesondere was die Kompatibilität zwischen Bibliotheken und µC Modellen angeht, sowie negative Überraschungen nach Updates.
Wobei dieser konkreten Fall (nur auf der englischen Seite) doch dokumentiert ist:
Was dort nicht steht: Das gilt nur für die alten AVR Mikrocontroller.
Meiner Meinung nach sollte digitalWrite() keine Auswirkung auf Eingänge habe. Da dort eh schon gefühlt 100 Takte verplempert werden, könnte man das problemlos mit unterbringen. Das Framework soll schließlich die Hardware abstrahieren.
Die Arduino-Funktionen sind nicht das Gleiche wie der direkte Zugriff
auf die Register, so daß ich vermuten würde, daß ein Schreibzugriff auf
ein IO-Pin, welches vorher als Eingang definiert wurden, rein gar nichts
bewirkt.
Möp! Schau mal in den Quelltext:
OK, hab ich nicht getan und falscg geraten 8-0
Meiner Meinung nach sollte digitalWrite() keine Auswirkung auf Eingänge
habe.
Meine Rede!
Da dort eh schon gefühlt 100 Takte verplempert werden, könnte man
das problemlos mit unterbringen. Das Framework soll schließlich die
Hardware abstrahieren.
Der Code liegt öffentlich aus.
Von jedem zu verändern.
Nein. Das Arduino Framework ist kein Community Projekt, wo jeder mitmachen kann.
Ich könnte höchstens meine eigene Kopie davon ändern. Das brauche ich aber nicht, weil ich Arduino nur für den ESP8266 verwende, wo digitalWrite() schon jetzt nicht die Pull-Ups verändert.
Nein. Das Arduino Framework ist kein Community Projekt, wo jeder
mitmachen kann.
Ich könnte höchstens meine eigene Kopie davon ändern.
Du irrst.
Der Arduino Core liegt auf Github.
Da kannst du deine Kopie anlegen und anschließend einen Pullrequest durchführen.
Hier die liste der offenen: https://github.com/arduino/ArduinoCore-avr/pulls
Die Frage ist, ob der genehmigt/übernommen wird.
Den Registern kann man aber nicht ansehen, ob ein pinMode(x,INPUT)
stattgefunden hat, was für euer Vorhaben unabdingbar ist.
Doch sicher. Das DDR Register zeigt an, welche Pins als Ausgang konfiguriert sind. Ich würde das PORT Register nur dann beschrieben, wenn das entsprechende Bit im DDR Register auf HIGH steht.
Doch sicher. Das DDR Register zeigt an, welche Pins als Ausgang
konfiguriert sind. Ich würde das PORT Register nur dann beschrieben,
wenn das entsprechende Bit im DDR Register auf HIGH steht.
Das geht nicht.
Damit handelst du dir ein Problem ein!
Das geht nicht durch! Keine Übernahme deiner Änderung.
Es ist etablierte Praxis folgendes zu tun:
digitalWrite(pin,HIGH);
pinMode(pin,OUTPUT);
Denn so hat man zwischen INPUT und HIGHoutput keinen Takt Low Phase.
Ein Umdrehen:
pinMode(pin,OUTPUT);
digitalWrite(pin,HIGH);
Hat einen Low Impuls zur Folge, in vielen Fällen will man das nicht.
Per Programm wirksam auf Pins schreiben kann man logischerweise nur,
wenn es Ausgänge sind.
Falsch.
Siehe verlinkte Tabelle. (Im Thread-Titel steht übrigens "Arduino Nano", also ist es definitiv ein Atmega328x.)
Man kann in die Register schreiben, ja. Unter "auf einen Pin schreiben" verstehe ich aber, dass man ihn beliebig auf HIGH oder LOW setzen kann. Das kann man aber ohne Berücksichtigung der externen Beschaltung nicht - sonst wäre es ja ein Ausgang. Man kann lediglich den internen Pullup aktivieren oder deaktivieren. Welcher Pegel sich dann am Pin einstellt, hängt von der Beschaltung ab.
pinMode(SENSORPIN1, INPUT);
pinMode(SENSORPIN1, INPUT);
digitalWrite(SENSORPIN1, 1); //Pullup aktivieren
Macht selten Sinn, aber kann man tun.
Es hat Wirkung.
Und wie schreibst du LOW auf den Pin? ;-)
Ich habe noch nie einer dieser Arduino-IO-Funktionen benutzt, die verstecken zu viel und verwirren teilweise ("DigitalWrite(PINxyz, LOW)" tut was??). Ich schreibe immer gemäß Datenblatt in die Register, da weiß ich, was passiert.
Du hast es geschafft ein "dokumentiertes Feature" als "Haar in der
Suppe" zu identifizieren.
Charakteristisch für Herrn Frings ist dass er möglichst das
letzte Wort haben muss - wenn irgendwie möglich. Also das letzte
Quentchen (Quäntchen) Wahrheit aus der Schief- oder Falschlage
seiner Aussagen herauszuholen.
Ich mach auch mal mit:
Wenn extern 10K als Pull-Down angeschlossen sind und die internen Pull-Ups aktiviert werden, hängt der Eingang elektrisch irgendwo bei einem Volt oder so (die externen 10K und die internen 60-80k(?) als Spannungsteiler) nicht ganz „in der Luft“, aber schonmal deutlich überm GND-Potenzial.
Daher - also so kenne ich das - schaltet man im allegemeinen auch gerne mit den Tastern oder Schaltern gegen GND und verwendet externe Pull-Up Widerstände, wenn die internen einen wegen „Radiowellen“ zu hochohmig erscheinen. Dann macht es auch keinen Unterschied, ob man die internen (versehentlich) aktiviert oder nicht.
Somit ergibt es schon Sinn, die internen Pull-ups zu deaktivieren.
Darüber hinaus die statemaschine etwas zu erweitern, um Tastendrücke und deren Flanken zu erkennen, wurde ja schon Hinweislich erörtert.
Hab mir jetzt den Stand der Umsetzung noch nicht angeschaut.
Aber Taste einlesen, wert merken und bei nächsten durchlauf vergleichen, ist üblich. Beide Zustände lassen sich dann verUnden oder verOdern.
Dass man (im einfachsten Fall hier) 50ms wartet und die gleiche Taste nochmals abfragt wurde auch schon als praktikabler Ansatz genannt.
Man /könnte/ auch PeDas „vertikalzähler“ als entprellroutine mit einbauen. Muss man aber nicht. 50ms oder sogar 100ms warten und erneut auf H(in diesem Fall hier) prüfen, reicht locker aus, einen ordentlichen Tastendruck zu erkennen, den man dann weglegt und beim nächsten Durchlauf der Loop() mit der Historie vergleicht.
Man muss das nicht auf Registerebene machen. Darf ab und an schon mal n Arduino sein.
(Wobei ich lieber VS-Code mit PlatformIO verwende)
Ich tät trotzdem gegen GND schalten und nicht gegen V_in oder gegen VCC.
Wenn extern 10K als Pull-Down angeschlossen sind und die internen
Pull-Ups aktiviert werden, hängt der Eingang elektrisch irgendwo bei
einem Volt oder so (die externen 10K und die internen 60-80k(?) als
Spannungsteiler) nicht ganz „in der Luft“, aber schonmal deutlich überm
GND-Potenzial.
Das wäre in der Tat eine Falle, die die Störsicherheit erheblich reduziert.
So gesehen gut, dass Stefan die Beschreibung ausgegraben hat und mit dem "digitalWrite(SENSORPIN2, LOW);" der Zustand sicher gesetzt wird.
Darf ab und an schon mal n Arduino sein.
Ich habe mit Arduino einige Geräte aufgebaut, die vorzeigbar sind. Da steht nicht draußen drauf, mit welcher Umgebung die realisiert wurden.
Du bist verwirrt!
Drücke dich bitte klar aus, dann kann dir evtl. geholfen werden.
Ich hatte das bereits erklärt. Kleiner Tipp: Es gibt rhetorische Fragen, die die meisten Leser durch den Kontext verstehen. Manche lesen aber jeden Satz(teil) einzeln und verabsolutieren ihn - denen kann man erfahrungsgemäß nicht helfen.
("DigitalWrite(PINxyz, LOW)" tut was??)
Der Code liegt öffentlich aus.
Die Doku eben so.
Wenn da noch Verwirrung bestehen bleibt, na, ich weiß nicht ....
Zu rhetorischen Fragen siehe oben. Der zitierte Schnipsel lässt jeden Leser, der die Arduino-Eigenheiten nicht kennt, annehmen, dass man damit den Pin auf LOW setzt. Das ist aber nicht der Fall, das habe ich kritisiert.
(Vor Jahrzehnten in meinem ersten Job sollte ich einen Drucker ansteuern. Da gab es eine Doku zu dem Drucker, in der waren je ein Status- und ein Befehlsregister beschrieben. Nun hätte jeder vernünftige Leser gedacht, im Statusregister könne man den Status des Druckers auslesen (Busy, offline, Papier alle, ...) und über das Befehlsregister könne man dem Drucker Befehle erteilen (Schalte den Modus XY ein, drucke den Inhalt deines Puffers, ...). Eine absolut übliche Sache bei allen damaligen simplen Peripherie-Geräten unterhalb der Mainframe-Ebene.
Tatsächlich war es aber genau umgekehrt: Man las den Druckerstaus aus dem Befehlsregister und schrieb Druckbefehle in das Statusregister.
Auf meine Bemerkung hin, das sei unlogisch, deswegen sei die Dokumentation schwer verständlich, bekam der zuständige Senior-Programmierer, der die Schnittstelle definiert und dokumentiert hatte, sofort Schnappatmung und ein wutrotes Gesicht. Seine Replik: Man könne "Status" und "Befehl" natürlich beliebig definieren. Über das nur lesbare(!) Befehlsregister könne der Drucker der Software im Rechner befehlen, bestimmte Dinge zu tun, z. B. bei Papiermangel eine Meldung auszugeben.
Nun ja. Der anwesende Chef hat nicht widersprochen, mir aber nachher privat gesagt, ich hätte natürlich Recht. Dieser Senior-Programmierer sei sprachlich/kommunikativ auch sonst etwas schwierig, das wisse man. Aber man wolle/dürfe ihn nicht verärgern, weil man ihn noch brauche. Der habe das wichtige Systemprogramm XY geschrieben, von dem die Firma abhinge.)
Mein Vorschlag:
Wenn dir an Arduino was nicht gefällt, dann ändere es, oder beantrage
wenigstens die Änderung.
Die alte Leier mit dem "Machs doch besser" im Hintergrund. Ich sag dir mal was: Wenn der Trompeter der Schützenfest-Kapelle nicht immer die richtigen Töne trifft, dann muss ich weder Noten kennen noch trompeten können, um das beurteilen zu dürfen. Punkt.
Auf meine Bemerkung hin, das sei unlogisch, deswegen sei die
Dokumentation schwer verständlich, bekam der zuständige
Senior-Programmierer, der die Schnittstelle definiert und dokumentiert
hatte, sofort Schnappatmung und ein wutrotes Gesicht.
Hehehe. Ein kleiner, leicht autistischer Choleriker. Solche Kollegen wünscht man sich . . .
Seine Replik: Man
könne "Status" und "Befehl" natürlich beliebig definieren.
Klar, Rot und Blau natürlich auch! Kirschen sind blau, Bananen rot!
Über das nur
lesbare(!) Befehlsregister könne der Drucker der Software im Rechner
befehlen, bestimmte Dinge zu tun, z. B. bei Papiermangel eine Meldung
auszugeben.
Da gab es wohl noch nicht die Konzepte Client/Server und der Drucker war der Chef, denn der macht immer Druck ;-)
Zu rhetorischen Fragen siehe oben. Der zitierte Schnipsel lässt jeden
Leser, der die Arduino-Eigenheiten nicht kennt, annehmen,...
Yep. SCNR
Bevor man sich an schwierigere Programme ranwagt, wäre es vielleicht besser, erst einmal das Kärrnerhandwerk der ASM-Programmierung anhand von "LED an"- "LED aus" zu erlernen.
C ist schon ne Nummer zu groß, zu abstrakt und nicht direkt genug an der "Maschine" dran. Das "C" kommt erst später bei etwas mehr Erfahrung, wenn etwas umfangreichere Programme sonst drohen, syntaxmäßig ins "Spaghettihafte" auszuufern.
Und die Arduino-Freaks fallen auf die angeblich kinderleicht anzuwendenden "Sketche" herein. Ohne auch nur im Geringsten zu wissen, was da eigentlich so passiert. Das fängt schon beim Anschluss der Betriebsspannung an. Siehe oben. Wenn das schon schiefgeht, wundert mich garnichts mehr.
Einfach Copy & Paste
Passt schon.
Sorry SCNR
Nur sieht man bei gefühlt 90% aller im Internet gefundenen "Sketche"
nichts von C++ und OOP.
Warum nur?
"Arduino programming language can be divided in three main parts: functions, values (variables and constants), and structure."
https://www.arduino.cc/reference/en/
Von OOP ist dort nicht viel zu sehen.
Am seltsamsten finde ich aber, dass die immer noch so tun, als hätten sie eine eigene "programming language" erfunden. Ich halte es für keine gute Idee, die Anfänger direkt am ersten Tag zu verarschen.
Und ich dachte Herr Frings weiss was Objekte und Instanzen sind.
Nope!
Ihm ist mal wieder auf dem Arduino Basher Trip.
Damit ihm seine Selbstverarsche aufrecht halten kann, muss ihm einen großen Teil seines Gehirns deaktivieren.
Wahrscheinlich einfach deshalb, weil OOP nur auf Betriebssystemen richtig funktioniert, da man sonst einfach zu viel selber machen muss und ein OS dann einfach zu schwer wird für so eine Arduino-Mühle.
Wer soll da wozu ein komplexes SW-System entwerfen und dann auf einem Spielzeug laufen lassen?
der Nächste der über OOP redet aber von OOP keine Ahnung hat. Hört das denn nie auf? OOP ist genauso MCU unabhängig wie es OS unabhängig ist. Aber dafür muss man eben wissen was OOP ist und was man damit alles machen kann.
Wer OOP nicht nutzen möchte okay, aber darüber immer wieder Blödsinn quatschen macht auch keinen Sinn.
Denn zwischen (OOP) Programm Code und der MCU sitzt immer noch die Toolchain.
(mir hätte klar sein
müssen das du ihn nicht verstehst).
Alles klar, du siehst kein C++, obwohl doch alle Sketche durch einen C++ Compiler genudelt werden.
Nachweislich!
Und dann meinst du, dass ich das nicht verstehe...
Alles klar.
Keine Fragen mehr...
Alles klar!
Andererseits hast du allerdings wahr:
Denn so blöd/borniert bin ich nicht, dass ich solche absurden Phantasien verstehen könnte.
Merke:
Wenn du da kein C++ siehst, dann ist das nicht die Realität, sondern deine Projektion.
Und ich dachte Herr Frings weiss was Objekte und Instanzen sind.
Weiss ich auch, aber die Dokumentation verbirgt das weitgehend.
Sie vermeidet die etablierten Fachbegriffe der OOP konsequent und sämtliche Beispiele nutzen nur die wenigen vordefinierten Klassen des Frameworks. Nirgendwo in der Doku der "Arduino programming language" wird erwähnt, dass man eigene Klassen schreiben kann.
Auf diese Doku bezog ich mich mit der Aussage "Von OOP ist dort nicht viel zu sehen". Diese meine Meinung darf jeder für sich so verdrehen, wie er will und dann damit glücklich werden :-)
Nirgendwo in der Doku der "Arduino programmin language" wird
erwähnt, dass man eigene Klassen schreiben kann.
Warum sollte man das erwähnen? Jeder einigermassen "erwachsene"
Programmierer, der schon Klassen geschrieben hat, weiss das.
Das ist natürlich selbstredend. Man kann immer eine Klasse
schreiben und diese verwenden sobald man einen C++ Compiler
zur Verfügung hat. Weder ist dazu die Arduino IDE erforderlich
noch verhindert sie das. Klassenprogrammierung ist unabhängig
von irgendeiner IDE.
Weil das als die "Arduino Programming language" verkauft wird. Nirgendwo ein Sterbenswörtchen davon, dass es sich um vollwertiges C++ handelt.
Jeder einigermassen "erwachsene" Programmierer, der schon
Klassen geschrieben hat, weiss das.
Arduino ist aber für den Einstieg gemacht. Es wird in Berufsschulen verwendet, um die Basics der Softwareentwicklung zu vermitteln. Da sollte man zumindest mal erwähnen, dass nach dem Einstieg das richtige C++ auf einen wartet.
Wenn du da kein C++ siehst, dann ist das nicht die Realität, sondern
deine Projektion.
Wenn etwas aussieht wie Hase, riecht wie Hase und das selbe frisst wie ein Hase, dann wird es wohl ein Hase sein. Wenn auch alle "Nasenbär" dazu sagen.
OOP ist genauso MCU unabhängig wie es OS unabhängig ist.
Und sogar sprachunabhängig. Wie z.B. Java, Python, C#, Ruby, PHP auch objektorieentiert sind. Warum sollte also etwas, was mit Nachnamen INO heißt, sich automatisch wie C++ verhalten.
Und ja natürlich: man kann es ausprobieren und findet es dann heraus, dass der Nasenbär eigentlich ein Hase ist.
Aber auch die eigenartige Benamung und die Tatsache, dass es um objektorientoiertes C++ geht, hilft dem TO in seinem Problem nicht weiter.
Nirgendwo in der Doku der "Arduino programmin language" wird
erwähnt, dass man eigene Klassen schreiben kann.
Warum sollte man das erwähnen?
Warum nicht, wenn man sich dazu versteigt, den Sourcecode nicht wie der
Rest der Welt *.cpp und "Programm" zu nennen, sondern *.ino und
"Sketch".
Das ist jetzt irgendwie Kindergarten hoch 10. Wie alt bist du?
Wissen die Leute überhaupt wovon sie aktuell reden? Ich denke nämlich nicht.
https://www.arduino.cc/reference/en/
Das ist einfach nur die Referenz (steht auch groß darüber) für die vorhandenen Funktionen bzw. Methoden. Mehr ist das nicht. Das ist kein Versteckspiel. Jeder will eine Doku. Dort ist sie. Jeder der eine Lib einbindet und eine Instanz erstellt ist zack in OOP drin. Ich weiß nicht was daran versteckt ist.
Die .ino Dateien dienen ja noch für mehr. Es können mehrere Tabs/Reiter in der IDE zusammengeführt werden usw. und dann übersetzt. Es ist eine andere Art der Programmierung möglich. Ob euch das gefällt oder nicht ist dabei egal. Die Möglichkeit gibt es. Bringt eine Untergliederung auf andere Art und Weise. Man muss sie nicht nutzen. Man kann sie nutzen. Nur weil das nicht der Standard Gewohnheit entspricht muss das nicht automatisch schlecht sein. Außerdem ist es menschlich das einem das Lieb und Teuer ist was man gewohnt ist. Deswegen muss das andere nicht schlecht sein.
Und wer Arduino nicht nutzt, sich aber darüber künstlich aufregt, bei dem weiß ich dann auch nicht weiter. Ganz ehrlich.
Rege ich mich künstlich über Assembler Programmierung auf?
Rege ich mich künstlich über VHDL Programmierung auf?
Nur weil ich mich darin nicht auskenne.
Mach ich das? Nein, mach ich nicht.
OOP ist genauso MCU unabhängig wie es OS unabhängig ist.
Und sogar sprachunabhängig. Wie z.B. Java, Python, C#, Ruby, PHP auch
objektorieentiert sind. Warum sollte also etwas, was mit Nachnamen INO
heißt, sich automatisch wie C++ verhalten.
Und ja natürlich: man kann es ausprobieren und findet es dann heraus,
dass der Nasenbär eigentlich ein Hase ist.
Aber auch die eigenartige Benamung und die Tatsache, dass es um
objektorientoiertes C++ geht, hilft dem TO in seinem Problem nicht
weiter.
Ich habe das Gefühl auch du regst dich wie Monk nur künstlich auf. Kann das sein? Nur weil das gesamte Programm Sketch heißt und die Dateiendung .ino soll das nun automatisch alles schlecht sein? Obwohl man ganz normales Standard C/C++ programmiert. Man kann auch setup/loop weglassen und mit main loslegen unter Verzicht der Annehmlichkeiten.
Zudem habt ihr noch nicht verstanden das man mit Arduino ganz schnell irgendwas testen kann, ohne jedes mal beim Urschleim anfangen zu müssen. Ein paar Zeilen eigener Code und es kann losgehen, wo andere noch am debuggen sind.
Wie gesagt, wenn ihr das nicht nutzt, warum regt ihr euch auf?
Eigentlich regt man sich doch auf wenn man irgendwas benutzt und es funktioniert irgendwas nicht. Im Forum ist das komischerweise immer umgekehrt wie in der echten Welt.
So, genug geschrieben. Denkt was ihr wollt. Es ändert sich ja doch nichts.
Ich hätte jetzt die Arduino-Klassen Print und vor allem Printable
herangezogen. Das Konzept ist schon sehr schön.
Naja...
Stream implementiert Print
Serial erbt von bzw. implementiert Stream,
Wire implementiert ebenfalls Print
Print ist also fett in meiner kurzen Liste enthalten, wenn auch verdeckt.
Print ist als abstrakte Klasse nicht direkt nutzbar, nur über Vererbung.
Somit: Print sieht man in den übliche Sketchen eher nicht.
Allerdings Serial durchaus.
Print er in den Libs.
Wie auch immer, jeder Arduino Krieger hat dauernd mit den OOP und sonstigen C++ Features zu tun.
Aber hier sehen manche nur Hasen.
Wie auch immer, jeder Arduino Krieger hat dauernd mit den OOP und
sonstigen C++ Features zu tun.
Aber hier sehen manche nur Hasen.
Ich finde diese Diskussion nur noch dämlich.
Das Ziel von Arduino ist, den Anwender nicht mit Details zu behelligen. Es ist doch scheißegal, dass A* nirgendwo auf C++ hinweist, obwohl es GCC unter dem Deckel hat, es funktioniert einfach.
Ob irgendwelche Dinge, die A* nicht an Bord hat, nun Library oder Klasse heißen, ist mir ebenso Wurst, wenn es spielt. Ich habe mit A* Dinge gemacht, die deutlich mehr als LED-blinken machen und muß dafür nicht im Detail wissen, was unter der Haube passiert.
Wie auch immer, jeder Arduino Krieger hat dauernd mit den OOP und
sonstigen C++ Features zu tun.
Es ist wohl eher so das jeder Arduino Krieger dauernd OOP- und
sonstige C++ Features nutzt, ohne sich weder darüber klar zu sein noch wissen muss worum es sich dabei handelt.
Und wer Arduino nicht nutzt, sich aber darüber künstlich aufregt
du regst dich wie Monk nur künstlich auf
Eigentlich regt man sich doch auf wenn man irgendwas benutzt
Ich nutze Arduino.
Und ich rege mich nicht nicht auf. Mein Puls ist ganz unten. Ich übe lediglich Kritik and der Dokumentation von Arduino.
Nur weil das gesamte Programm Sketch heißt und die Dateiendung .ino
soll das nun automatisch alles schlecht sein? ...
Das ist jetzt irgendwie Kindergarten hoch 10.
Es ist aber eben auch Kindergarten hoch 100, wenn man nicht sagen darf, dass etwas eigenartig ist (= eine eigene Art hat), ohne dass einem dann gleich unterstellt wird, man habe gesagt, dass "alles schlecht" wäre.
Wie alt bist du?
Alt genug um das Arduino-Environment mit einigen anderen Entwicklungsumgebungen vergleichen zu können.
Und wer Arduino nicht nutzt, sich aber darüber künstlich aufregt, bei
dem weiß ich dann auch nicht weiter. Ganz ehrlich.
Ganz ehrlich: ich selber verwende die Arduino auch. Im Schrank liegt eine Kiste mit 20-30 solcher Boards. Trotzdem finde ich auch einige Dinge daran schlecht. Schlecht ist es, dass da unbedingt von Anfang an eine "Insellösung" mit einer eigenen Arduino-Welt erzeugt werden musste (ich hätte z.B. einfach die erste vermurkste Charge Leiterplatten rausgeschmissen, die Pfostenleisten ins richtige Raster gesetzt und nicht einen saublöden Fehler zum "Standard" erklärt).
Wie gesagt, wenn ihr das nicht nutzt, warum regt ihr euch auf?
Eigentlich regt man sich doch auf wenn man irgendwas benutzt und es
funktioniert irgendwas nicht.
Wirklich schlecht ist vor allem, dass nicht von Anfang an ein brauchbarer Debugger in den Designanforderungen gestanden hat. Genau das hat mich davon abgehalten, das Arduino-Environment tatsächlich produktiv für "richtige" Projekte einzusetzen. So dürfen letztlich dann eben die Praktikanten und Bacheloranden mit dem Ding herumspielen oder es werden lediglich irgendwelche Funktionsmodelle damit gebastelt.
BTW: versuche mal in der aktuellen Arduino IDE-Version 2.3.2 den Proxy-Port 80 zu setzen. Du wirst sehen: es geht nicht. Auch nicht direkt über die arduino-cli.yaml. Die Ports 79 und 81 können problemlos eingestellt werden, kommen aber natürlich nicht durch den Proxy, auf dem nur der Port 80 offen ist. Auch das finde ich schlecht, sehr schlecht sogar. So bleibt eben nur die Verwendung der alten Version 1.8.19 übrig. Da geht das problemlos.
ABER immer öfter tritt das Problem auf, dass der Arduino die LOW bzw
High-Signale falsch interpretiert
Nun ja, ich mach das immer mit wachsender Begeisterung und spielerisch so zwischen Mittagspause und Einschlafphase.
(Wozu gibt es eigentlich Atmel Studio. Fremdwort für Arduino-Fans.)
Mit Käsekästchen fällt Nachhilfeunterricht leichter.
Ahh. Eine Osram Lampenfabrik plötzlich aufgegangen. Oder?
Schade, dass sich bisher scheinbar noch niemand drum gekümmert hat.
Ja, das finde ich auch. Aber wenn ich in den Issues dort nach "Proxy" suche, dann betrifft so ein Problem (erstaunlicherweise) nur relativ wenige User. Ich hätte gedacht, dass einige User in Firmen hinter Proxys sitzen...
Nun ja, ich mach das immer mit wachsender Begeisterung und spielerisch
so zwischen Mittagspause und Einschlafphase.
(Wozu gibt es eigentlich Atmel Studio. Fremdwort für Arduino-Fans.)
Mit Käsekästchen fällt Nachhilfeunterricht leichter.
Ahh. Eine Osram Lampenfabrik plötzlich aufgegangen. Oder?
Was möchtest du damit sagen?
Dein lustiger ASM Code lässt sich übrigens problemlos nach C++ portieren und das Kompilat ist identisch mit deiner Variante.
(ich hätte z.B. einfach die erste vermurkste Charge Leiterplatten
rausgeschmissen, die Pfostenleisten ins richtige Raster gesetzt und
nicht einen saublöden Fehler zum "Standard" erklärt).
Das bezieht sich auf den Uno. Ich habe mir damals zwei Chinesen-Uno zum Spielen gekauft. Für tatsächliche Anwendungen verwende ich A*-Nano, der passt ins Raster und belegt keine unnötige Fläche.
Wenn ich Strom sparen will, dann eben ProMini.
Wenn man über modernere µCs spricht, kommen alle Boards im 2,54er-Raster, der UNO ist nur noch für Shield-Kiddies.
Das Steck Layout ist eine "Sicherung" gegen versehentliches falsch rum drauf stecken. Solche, oder ähnliche, Steckercodierungen sind in der Industrie und im KFZ Bereich allgegenwärtig-
Natürlich forcieren die Arduino Basher eine andere "Theorie", die "zu dumm zum zum" Theorie.
Auch wissen die Arduino Basher meist nicht wo der Begriff Sketch der Arduino Welt her stammt. Oder auch das setup() und loop().
Das Steck Layout ist eine "Sicherung" gegen versehentliches falsch rum
drauf stecken.
Das bekommt man auch anders hin.
Natürlich forcieren die Arduino Basher eine andere "Theorie", die "zu
dumm zum zum" Theorie.
Du hast ein recht primitives Bild der Umgebung - Kritik und Bashing sind unterschiedliche Dinge.
Auch wissen die Arduino Basher meist nicht wo der Begriff Sketch der
Arduino Welt her stammt. Oder auch das setup() und loop().
Und nochmal von Dir ein unqualifiziertes "Basher".
Falls es Dir entgangen sein sollte: Ich verwende Arduino, sowohl die Hardware als auch deren IDE. Lothar M., der (zu recht) das Layout beanstandet hat, ist aktiv dabei. Wenn wir A* richtig scheiße finden würden, hätten wir etwas anderes!
Also höre mit Deinen Unterstellungen auf und akzeptiere, dass es Kritikpunkte gibt.
Zu Sketch, setup() und loop() hätte ich gerne Deine Erklärung, tatsächlich weiß ich nicht, welcher Abstammung diese Begriffe sind.
Man könnte aber auch sagen, dass das egal ist, solange man sie zu benutzen weiß.
KA!
Wie nennst du Leute, welche sich (gerne auch immer wieder) über Dinge Aufregen, diese anprangern, ohne dass irgendwer, z.B. Nobody, irgendwas dagegen unternehmen kann?
Klar kann es sein, dass einem Kind die Füße falsch gewachsen sind...
Aber muss man es wirklich dafür ein Jahrzehnt, oder zwei davon, mobben?
Leitsatz:
Gott gebe mir Gelassenheit, hinzunehmen, was nicht zu ändern ist.
Mut zu ändern, was ich ändern kann.
Und die nötige Weisheit, zwischen beidem zu unterscheiden.
Ganz im Gegenteil: ich habe nicht mit einer unzusammenhängenden Gegenfrage gekontert, sondern nur den von dir gespielten Ball in die selbe Richtung verlängert. Denn du sagst: das Pinout vom Arduino ist so wie es ist, wer das nicht gut findet, der soll irgendwas anderes nehmen. Und ich sage das auch vom Debugging und der IDE.
Wer jetzt noch nach gefühlten 20 Jahren weiter darauf in der
Öffentlichkeit rum hackt, hat ein mentales Problem.
Evtl. eine neurotische Fehlanpassung.
Wer da nach echten 19 Jahren noch sensibel drauf reagiert, der aber auch.
Klar kann es sein, dass einem Kind die Füße falsch gewachsen sind...
Die sind nicht zufällig falsch gewachsen, sondern sie wurden wie gesagt aus Versehen fehlerhaft platziert. Zitat von https://de.wikipedia.org/wiki/Arduino_(Plattform): "Die erste Auflage des Boards betrug 200 Stück, davon gingen 50 an eine Schule." Und dass diese offensichliche Fehlstellung der Füße nicht schon spätestens beim 201. Board korrigiert wurde, dafür können "die vielen Shields am Markt" sicher nicht als Grund vorgehalten werden, denn die gab es da noch gar nicht.
Und solche Nachlässigkeiten sind für mich irgendwie der Grundtenor des gesamten Arduino-Environments.
Deshalb bleibt mir nur das Erste übrig: ich finde mich damit ab und verwende die alte IDE.
Und in diesem Sinne sei es wie es will, ich setze den Arduino weiterhin dort ein, wo der Entwickler ganz offensichtlich auch seinen Platz gesehen hat: bei irgendwelchen Basteleien und Funktionsmodellen, aber sicher nicht in einem produktiven Umfeld in einer Serie.
Deshalb bleibt mir nur das Erste übrig: ich finde mich damit ab und
verwende die alte IDE.
Oder man schaut mal über den Tellerrand und schaut sich z.B. mal PlatformIO (Visual Studio Code) an. Die Programme (Sketches) können 1:1 weiter verwendet werden. Beim Programmieren muss man sich also nicht umgewöhnen.
Damit er seinen Thread leicht wiederfindet, halten wir den aktiv oben in der Liste. Und so lange wir das tun, tun wir schon keinen anderen Blödsinn... ;-)
Habe ich das behauptet?
Soweit ich weiß, nicht...
Wie auch immer, Mobbing und/oder dauerhaftes Nörgeln lässt sich nicht damit rechtfertigen. Vielleicht kannst du das. Ich nicht.
Es ging doch um die Veranschaulichung mit den Kästchen im Debugger im ATMEL Studio.
Wenn man nicht weiß, was überhaupt passiert, hilft das vielleicht, erst einmal zu simulieren. Beitrag "MSF60 Dekoder AVR Teil_2"
Step by step mit F10
Dabei gilt die Einschränkung, dass Timings und Zeitschleifen zwangsläufig nicht stimmen können(ISRs). Und auf externe Abfragen kann natürlich nicht reagiert werden.
Aber Portzuweisungen etc., was im Thread ja das Kernproblem zu sein scheint, lassen sich gut darstellen.
Na dann hast du ja gleich drei Gründe genannt, die mich als "Basher"
ausschließen.
Nein!
Unterscheide zwischen "Basher" und "Vollblut Basher".
Du und Lothar seid einfach nur Basher.
Euch beiden traue ich zu die Doku zu lesen und in den Code zu schauen.
Ob ihr das auch wirklich tut?
Naja, das ist nicht immer zu erkennen.
Nachdem ich dir über die letzten Jahre einige Dutzend mal den Kopf gewaschen habe, bist du ein Basher mit Erfahrung.
Klarer: Es kommen mittlerweile weniger Falschinformationen von dir.
Ein Schritt in die richtige Richtung, würde ich mal sagen.
Ich hab die Diskussion jetzt nicht durchgelesen, dafür reicht meine Lebenszeit nicht aus.
Also Eingang auf 5V gelegt und den erwähnten Eintrag entfernt.
Geändert hat sich aber nichts.
Nun die Frage zu dem Code
Falk B. schrieb im Beitrag #7724794:
#define INPUT1 (1<<0) // Bitmuster für Codeauswertung
#define INPUT2 (1<<1) // Bitmuster für Codeauswertung
#define INPUT12 (INPUT1 | INPUT2) // Bitmuster für Codeauswertung, beide >Eingänge
Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL_PIN, NEO_GRBW + NEO_KHZ800);
int code, flanke;
int code_old;
bool led_active = false;
Ich nutze nur Code, den ich verstehe, daher meine Frage:
-Was genau macht das Bitmuster für die Codeauswertung?
-Was bedeutet der senkrechte Strich
-was bedeutet code, flanke
-was bedeutet code_old
das bool bedeutet vermutlich, dass standardmäßig die LED aus sind.
Der Code funktioniert leider nicht richtig:
-hell geht an, schaltet dann aber sofort auf bunt
-beim Ausschalten bleibt der rote Kometenschweif stehen (quasi ein Nachtlicht ;))
-dunkel wird gänzlich ignoriert
Das habe ich doch richtig eingefügt oder?
void loop() {
code = 0;
Learning by doing, daher sollte man wissen, was man da eigentlich macht, anstatt blind Codeschnipsel zu kopieren.
Nur so kann man auch Fehler suchen und finden.
Ja.
Man muss eine systematische Fehlersuche durchführen.
Ich hab "bunt" aus dem Programm geschmissen, zumindest läuft das Programm jetzt. Der Fehler tritt ja leider erst später auf und dann immer öfter, ich werde das beobachten.
Manche Dinge verstehe ich nicht!
int i=-7; // ok, kann man tun
Aber dieses hier pixels.setPixelColor(i,
Auch pixels.setPixelColor(i+8, sieht komisch aus.
Das verstehe ich dann beides nicht mehr....
setPixelColor erwartet an der Stelle ein uint16_t von 0 bis NUMPIXELS
Also 0 bis 65, bekommt aber -7 bis 73
Selbst wenn solche Irrwitzigkeiten in der Lib geprüft werden sollten, haben wir hier einen offensichtlichen Unterlauf und einen Überlauf, der mir doch sehr verdächtig aussieht.
Ein Verstoß gegen die Regel:
Programmiere immer gegen das Interface einer Methode
und nie gegen die Implementierung.
earning by doing, daher sollte man wissen, was man da eigentlich macht,
anstatt blind Codeschnipsel zu kopieren.
Ich machs lieber von Grund auf anders. Erstmal in ASM.
Und zwar Portabfragen(ein/aus) separat. Und
Bildmuster in Arrays.
Die beiden Dinge überkreuzen sich in dem Programm oben.
Als Beispiel code im Anhang.
Die Entprellroutine gibt es auch in ASM, fehlt hier der Einfachheit halber.
Manche Dinge verstehe ich nicht!
int i=-7; // ok, kann man tun
Aber dieses hier pixels.setPixelColor(i,
Auch pixels.setPixelColor(i+8, sieht komisch aus.
Das verstehe ich dann beides nicht mehr....
setPixelColor() ist eine Methode zum Setzen der Farbe eines Pixels. Dabei wird nicht der Pixel in Hardware beschrieben, sondern der interne Puffer(RAM).
pixels.Color() ist eine Methode, um aus RGBW Einzelwerten einen zusammengesetzten Wert zu erzeugen, den die Methode setPixelColor() haben will.
Erst die Methode show() schreibt die internen Daten auf die realen Pixel in Hardware.
Selbst wenn solche Irrwitzigkeiten in der Lib geprüft werden sollten,
haben wir hier einen offensichtlichen Unterlauf und einen Überlauf, der
mir doch sehr verdächtig aussieht.
Ist er auch, deswegen hab ich das auch geändert. Aber der OP will halt einen Anlaufeffekt haben. Praktisch funktioniert es, denn die Methode prüft den Parameter und reagiert entsprechend.
Ein Verstoß gegen die Regel:
Programmiere immer gegen das Interface einer Methode
und nie gegen die Implementierung.
Ja, aber ebenso sollte/muss jede Methode ihre Eingangsparameter auf einen gültigen Wertebereich prüfen.
Ich hab "bunt" aus dem Programm geschmissen, zumindest läuft das
Programm jetzt. Der Fehler tritt ja leider erst später auf und dann
immer öfter, ich werde das beobachten.
Du sollst MESSEN! Außerdem war in meiner 1. Version noch ein Fehler drin.
setPixelColor() ist eine Methode zum Setzen der Farbe eines Pixels.
Dabei wird nicht der Pixel in Hardware beschrieben, sondern der interne
Puffer(RAM).
Ja, aber ebenso sollte/muss jede Methode ihre Eingangsparameter auf
einen gültigen Wertebereich prüfen.
Ich halte es es für etwas schlampig, Methoden mit kaputten Werten aufzurufen.
Und schon gar nicht, sollte sich das zu einer Grundeinstellung entwickeln.
Es bieten sich einfach zu viele Wege, in C++ in ein UB zu stolpern.
Pointer/Array Unter- Überläufe stehen da ganz weit oben, auf der Liste.
Die Sorgfalt eines Lib Programmierers kann kein Freibrief für eigene Schlampigkeiten sein.
setPixelColor() ist eine Methode zum Setzen der Farbe eines Pixels.
Dabei wird nicht der Pixel in Hardware beschrieben, sondern der interne
Puffer(RAM).
Das musst du mir nicht erklären!
Ja warum schreibst du dann sowas?
Auch pixels.setPixelColor(i+8, sieht komisch aus.
Das verstehe ich dann beides nicht mehr...."
Vielleicht mal versuchen, weniger lässig zu sein und dafür klar kommunizieren.
Falk B. schrieb:
Ja, aber ebenso sollte/muss jede Methode ihre Eingangsparameter auf
einen gültigen Wertebereich prüfen.
Ich halte es es für etwas schlampig, Methoden mit kaputten Werten
aufzurufen.
Und schon gar nicht, sollte sich das zu einer Grundeinstellung
entwickeln.
Stimmt, aber der OP ist Lichtjahre davon entfernt, ein Entwickler zu sein.
Er ist der Hobbybastler der Hobbybastler.
An solchen UB Fällen verzweifelt ein Anfänger aber noch mehr. Wir hatten hier schon mehr als einmal Fälle wo der Compiler Code der nicht durchlaufen werden muss wegoptimiert. Dazu die Einstellung von Arduino wo man den User lieber nicht mit zu vielen Meldungen (Warnungen) belästigt.
An solchen UB Fällen verzweifelt ein Anfänger aber noch mehr. Wir hatten
hier schon mehr als einmal Fälle wo der Compiler Code der nicht
durchlaufen werden muss wegoptimiert.
Was ist daran undefiniertes Verhalten?
Dazu die Einstellung von Arduino
wo man den User lieber nicht mit zu vielen Meldungen belästigt.
Ist halt so. Man kann die Meldungen des Compiler ja aktivieren, auch als Noob. Ist ein Häkchen in den Einstellungen.
Die meisten Libs von Arduino sind schon relativ defensiv und idiotensicher programmiert, damit eben solche Parameterfehler von Anfängern abgefangen werden.
Es bieten sich einfach zu viele Wege, in C++ in ein UB zu stolpern.
Pointer/Array
Yes sir.
Deutete ich oben schon an.
Aber was die einen als Unsinn titulieren, wird anderen schnell deutlich, wie man am effektivsten zum Ziele kommt.
Ob ASM oder C++ spielt doch keine Rolle.
Nochmals: Die Schalter haben mit der Lauflichtfunktion zunächst garnichts zu tun.
Die ursprüngliche Frage bezog sich auf die "Schalter".
Und wieso die einmal funktionieren, dann wieder nicht.
Falk B. schrieb im Beitrag #7731607:
Aber der OP will halt
einen Anlaufeffekt haben.
Das kann man mit Array machen. Und die Timerwerte als solche ebenfalls
in ein Array schreiben.
Zur Sichrheit noch einen Watchdog aktivieren. Falls es zu:
Da kann man mit Array machen. Und die Timerwerte als solche ebenfalls
in ein Array schreiben.
Zur Sichrheit noch einen Watchdog aktivieren. Falls es zu:
Wenn man den ganzen anderen Kram/Beiwerk mal weglässt kommt man im Kern auf sowas:
unsigned i = -7;
Was auf den ersten Blick schon arg unlogisch erscheint.
Das geht dennoch durch, wohl ein Relikt aus der C Zeit.
C++ bietet da schon einiges mehr, um solche "Versehen" wenigstens zu bemerken:
unsigned i {-7};
Wird angemeckert:
warning: narrowing conversion of '-7' from 'int' to 'unsigned int' [-Wnarrowing]
Dein Assembler hat keine Chance überhaupt irgendeine Schlampigkeit solcher Art zu bemerken.
Natürlich liefert "unsigned i = -7;" auch unterschiedliche Werte in i, in Abhängigkeit davon wieviel Bit ein unsigned hat.
Könnte ein Problem mit der Portierung geben. Aber mit Portierungen haben ASM Leute ja sowieso nix am Hut, ganz im Gegensatu zu den Arduino Leuten.
So, jetzt hab ich es mal real aufgebaut und getestet, DOH! Da war noch ein kleiner Fehler drin, darum wurde es sofort pink. Siehe Anhang, jetzt funktioniert alles korrekt!
Ahhhhhhh, in meiner letzten VErsion sind noch Testeinstellungen drin! Oder anders formuliert, bau deine Schaltung auf Pull-Up Widerstände um, wie es der Rest der Welt macht. Dann funktioniert die Software ohne Änderungen.
Dein Assembler hat keine Chance überhaupt irgendeine Schlampigkeit
solcher Art zu bemerken.
Weil ich dabei auch keinen C oder sonstwas Compiler brauche, der mir Mist macht.
Der "Assembler" macht nur 0 erros 0 warnings.
Ob das Programm etwas Sinnvolles macht oder nicht ist dem egal.
Hauptsache die Syntax stimmt.
Und wenn Dein schlauer C++-Compiler dem Mist nicht merkt, taugt der genausowenig.
"Assembler" ist nicht die ASM Programmiersprache hier, sondern das Programm, dass "assembliert", also aus Mnemonik dann umsetzt.
Warum man bei C und Derivaten nicht auch "Assembler" sagt, sondern "Compiler" ist nicht so ganz klar.
So könnte man bei ASM den "Assembler" durchaus auch "Compiler" nennen.
Afaik wurde früher der Unterschied so erklärt, dass ein Assembler übersetzt und zwar Schritt für Schritt, wobei ein Compiler alles in einem Rutsch übersetzt. Stimmt wohl nicht mehr ganz definitionsmäßig.
Da steht:
"Ein Compiler ist ein Programm, das den in einer höheren Programmiersprache geschriebenen Quellcode in die maschinenlesbare, binäre Sprache übersetzt."
Das ist ein wesentlicher Unterschied zu einem Assembler, der mehr oder weniger nur ein 1:1-Übersetzer ist.