LEDs werden falsch angesteuert

Ich hab in den letzten Jahren schon etliche Varianten gebaut, die eigentlich auch einwandfrei funktionieren mit folgendem Aufbau:

  • Arduino Mega über USB an Windows-PC angeschlossen
  • Am Arduino sind direkt ein paar 6V-LED angeschlossen, meist im Bereich der höchsten Pinnummern
  • Meine Software sendet regelmäßig über den virtuellen COM-Port einen Satz bytes an den Arduino, der diesen Datenstrom analysiert und entsprechend die LED an oder ausschaltet (code unten).

Jetzt hab ich seit einigen Monaten auf neu aufgebauten Systemen das Problem, dass mal irgendwann früher oder später im laufenden Betrieb die LEDs anfangen, falsch zu leuchten, also z.B. statt Pin 53 leuchtet Pin 50. Das bleibt dann auch im weiteren falsch, also wenn man ein neues Leuchtmelderbild übermittelt, dann ergibt sich auch weiterhin eine dann andere falsche LED-Ansteuerung, bis man die ganze Verbindung neu aufbaut (ob diese "LED-Verschiebung" einer Systematik unterliegt, konnte ich noch nicht rausbekommen). Nun bin ich mir auf "meiner Seite" keiner Änderung bei der Ansteuerung bewußt. Frage: Gab es möglicherweise auf Arduinio-Seite irgendwelche Änderungen, die man wissen müßte? Hat jemand Tipps, wie ich mich dem Problem nähern könnte oder auch, wie man den Datentransfer besser machen kann, falls es denn daran liegen sollte? Im Einsatz sind nicht de Originalen sondern von Eckstein oder sowas.
Carsten

Folgend ein Beispiel für 3 LED:

int valLDTVor;
int valLDTMitte;
int valLDTRueck;

//  Arduino Pin-Nummern festlegen

int pinLDTVor = 51;
int pinLDTMitte = 53;
int pinLDTRueck = 50;


void setup()
{

  pinMode(pinLDTVor, OUTPUT);
  pinMode(pinLDTMitte, OUTPUT);
  pinMode(pinLDTRueck, OUTPUT);


  Serial.begin(9600);   // Serielle Schnittstelle aktivieren
  while (!Serial) {
  ; // auf Verbindung warten (nur fuer Leonardo noetig)
  }
  Serial.print("A");    // Info an Software -> Daten schicken
}


void loop()
{
  if (Serial.available())
  {


    valLDTVor = Serial.parseInt();
    if (valLDTVor == 0)
    { digitalWrite(pinLDTVor, LOW); }
    else
    { digitalWrite(pinLDTVor, HIGH); }

    valLDTMitte = Serial.parseInt();
    if (valLDTMitte == 0)
    { digitalWrite(pinLDTMitte, LOW); }
    else
    { digitalWrite(pinLDTMitte, HIGH); }

    valLDTRueck = Serial.parseInt();
    if (valLDTRueck == 0)
    { digitalWrite(pinLDTRueck, LOW); }
    else
    { digitalWrite(pinLDTRueck, HIGH); }

  

  }
  Serial.print("A");    // Info an Software -> Daten schicken
  delay(10);
}

Wieso 6Volt Leds ?
Und wie hast du die angeschlossen ?

Hast du mal kontrolliert, ob die übertragenen Daten richtig ankommen ?
Da würde ich eher ein Problem sehen.

Hat jemand Tipps, wie ich mich dem Problem nähern könnte oder auch, wie man den Datentransfer besser machen kann, falls es denn daran liegen sollte?

Einen vernünftigen Parser bauen!
Und/oder sscanf() verwenden.

Wie soll man dir helfen, wenn du das Format der gesendeten Daten geheim hältst?
Das ist doch genau das Problem, oder?
Das Format und seine Auswertung!
Und deine Beschaltung ist auch irgendwie ein Rätsel...
z.B. Wie man 6V LED an einem 5V Arduino zum leuchten bekommt....

Jetzt hab ich seit einigen Monaten auf neu aufgebauten Systemen das Problem, dass mal irgendwann früher oder später im laufenden Betrieb die LEDs anfangen, falsch zu leuchten, also z.B. statt Pin 53 leuchtet Pin 50. Das bleibt dann auch im weiteren falsch, also wenn man ein neues Leuchtmelderbild übermittelt, dann ergibt sich auch weiterhin eine dann andere falsche LED-Ansteuerung, bis man die ganze Verbindung neu aufbaut (ob diese "LED-Verschiebung" einer Systematik unterliegt, konnte ich noch nicht rausbekommen).

Da Serial.parseInt(); immer die nächste Zahl nimmt kommt es bei Übertragungsfehlern der Seriellen schnittstelle zum fehlen eines Wertes und die Nachfolgenden Werte werden auf das vorhergehende LED bezogen.

2 Besserungsvorschläge.

  • Die Datenübertragung ändern sodaß ein oder mehrere Start-Zeichen, Ein Zeichen für das angesproschenen LED und dessen Wert. Anschließend eine Quersumme und ein oder mehrere StopZeichen.
    So kann der Arduino erkennen ob die Übertragung fehlerfrei erfolgt ist und welches LED angesprochen werden soll.
  • Verwende nicht die Pins 50-53, die sind beim Arduino MEGA der SPI-Port.

Grüße Uwe

Wieso 6Volt Leds ?

Sind das nicht LED mit eingebauten Vorwiderstand für 6V?
Sowas für Anfänger und superfaule.
Grüße Uwe

uwefed:
Sind das nicht LED mit eingebauten Vorwiderstand für 6V?
Sowas für Anfänger und superfaule.
Grüße Uwe

Ach so....na dann.

Wieso 6Volt Leds ? Und wie hast du die angeschlossen ?

Weil es die LED-Form nur als 6V-LED gibt, sie leuchten aber auch mit 5V schon sehr hell. Anschluss: Plus an Pin X, Minus an Ground.

Hast du mal kontrolliert, ob die übertragenen Daten richtig ankommen ?
Da würde ich eher ein Problem sehen.

Bisher nicht weiter, so einen ganz einfachen Weg gibt es da auch nicht oder? Ich müßte die Daten im Arduino protokollieren, zurücksenden und anzeigen lassen, oder?

Sind das nicht LED mit eingebauten Vorwiderstand für 6V? Sowas für Anfänger und superfaule.

Oder auch für den Einbau in Lampenfassungen, die einen entsprechenden Sockel haben....

Danke für die hilfreichen Kommentare! Über manche Tonlagen bin ich etwas verwundert muss ich zugeben. Ist aber auch mein erster Beitrag hier. Vielleicht ist es ja normal.

Carsten

Nick Gammon hat sich darüber Gedanken gemacht: How to process incoming serial data without blocking

uwefed:
Sowas für Anfänger und superfaule.

Also für mich, zum Testen schön einfach :grin:

Über manche Tonlagen bin ich etwas verwundert

Und ich bin etwas verwundert, wie man wein solches Problem publiziert und dann darauf beharrt das Datenformat geheim zu halten.

Damit ist das ganze untestbar.
Unmöglich, konkrete Vorschläge zu zeigen.

Dabei scheinst du dir doch eine Lösung zu wünschen, ....

Aber ok, ....
Ich bin raus hier...

Die Daten sollen kein Geheimnis sein, aber sie ergeben sich doch m.E. unmittelbar aus dem Code. Es sind (im Beispiel) drei Integerwerte, die an den Ardunio geschickt werden. Anschließend wartet meine Software auf ein "A". Dann schickt sie wieder 3 integers - funktionierte wie gesagt seit Jahren auf mehreren Geräten problemlos. Was genau wäre denn noch zu erklären?

Carsten

uwefed:
Sind das nicht LED mit eingebauten Vorwiderstand für 6V?
Sowas für Anfänger und superfaule.

Und für Leute mit sehr wenig Platz auf der Platine :slight_smile:

Gruß

Gregor

Die Daten sollen kein Geheimnis sein, ...

Sind sie aber, denn ich sehe sie nicht.

Es ist ok, wenn du dich nicht dafür interessierst.
Aber mir machst du so jegliche Hilfe unmöglich, mit deiner Weigerung Testdaten zur Verfügung zu stellen.

Und nein, ich glaube dass es noch nie richtig funktioniert hat.
Und wenn, dann war das eher ein Zufall.

Jetzt ist die Glücksträhne allerdings um, wie mir scheint.
Ab jetzt wirst du dich um die harte Realität kümmern dürfen:

Was schief gehen kann, wird auch schief gehen. Irgendwann....

aber sie ergeben sich doch m.E. unmittelbar aus dem Code.

Wenn der Code in Ordnung wäre, dann vielleicht.
Ist er aber offensichtlich nicht.
Ich sehe da keinerlei Fehlerprüfung.
Nix.

Beispiel:
Serial.parseInt() liefert dir bei einem Timeout eine Null, oder besser : 0
Irgendwie dumm, da doch 0 bei dir ein gültiger Wert ist.
Du weißt(dein Programm weiß) also nie, ob die Null gültig, oder eine Timeout Meldung ist.

Also, solange die Testdaten geheim sind, bleibt mir nur der Tipp:
Ändere das.

Alternativ:
Verwende was fertiges, zuverlässiges.
Z.B. den CmdMessenger

Aber mir machst du so jegliche Hilfe unmöglich, mit deiner Weigerung Testdaten zur Verfügung zu stellen.

Ich "verweigere" nichts, ich wüßte im Moment aber einfach nicht, wie ich hierzu mit vertretbarem Aufwand eine Umgebung bereitstellen könnte, so dass jemand sowas nachstellen kann. Ich würde auch gar nicht erwarten, dass hier jemand groß Zeit investiert.

Und nein, ich glaube dass es noch nie richtig funktioniert hat. Und wenn, dann war das eher ein Zufall.

Das Problem ist schon so wie beschrieben und auch statistisch halbwegs belastbar.
Warum auch immer es sich bei den in den letzten Monaten zusammengebauten Geräten anders verhält: Sinn des Themas war, ein paar Anregungen zu bekommen, um nicht einen unsinnigen Weg einzuschlagen. Das Ganze ist für mich eher ein "Nebenkriegsschauplatz", in den ich eigentlich nicht mehr Zeit versenken möchte/kann als nötig ist. Ich hätte jetzt wohl auch eine Fehlerkorrektur oder Datenrückmeldung und Prüfung oder sowas eingebaut, aber durch die Hinweise und Links hier dürfte es etwas einfacher ins Ziel kommen. danke sehr.

Carsten

combie:
Sind sie aber, denn ich sehe sie nicht.

@ combie, hat er doch:

CarstenH:
... Es sind (im Beispiel) drei Integerwerte, die an den Ardunio geschickt werden. Anschließend wartet meine Software auf ein "A". Dann schickt sie wieder 3 integers - ...

Er sendet also nur 6 Byte an den Arduino und dann wieder 6 Byte wenn der Arduino ein "A" schickt.
Wenn nur 5 Byte ankommen ist das Durcheinander gemacht.

Grüße Uwe

uwefed:
Er sendet also nur 6 Byte an den Arduino und dann wieder 6 Byte wenn der Arduino ein "A" schickt.
Wenn nur 5 Byte ankommen ist das Durcheinander gemacht.

Wenn er parseInt() verwendet werden Strings geschickt. Und es sind mehr als 6 Bytes

Das Problem ist aber das gleiche. Vernünftig schickt man hier eine Zeile mit einem Linefeed abgeschlossen. Dann kann man einfach bis zum Zeilenende lesen. C Strings entlang Kommas zu trennen ist mit strtok() trivial