Überprüfen von Code Danke

Hallo kann mir jemand damit helfen diesen code zu überprüfen und zu korrigieren bitte. Ich habe 4 LED und einen bestimmten Ablauf einer Sequenz z.B (ROT, ROT,BLAU, ROT, GRÜN, BLAU,GELB) etc. diese jeweils sollen für eine bestimmte zeit an/aus gehen 200ms 1200ms usw.!

int LEDPins[] = {2,3,4,5};

unsigned long letzterWechsel;

int zeitProLed LEDPins [2] = 200;
int zeitProLed LEDPins [3] = 1200;
int zeitProLed LEDPins [4] = 3200;
int zeitProLed LEDPins [5] = 500;

int LEDWert LEDPins[2] = A;
int LEDWert LEDPins[3] = B;
int LEDWert LEDPins[4] = C;
int LEDWert LEDPins[5] = D;

unsigned long LEDWert;


int aktuelleLED = 5;

void setup () {
	for(int i=0; i < 6;i++) {

	pinMode(LEDPins[i], OUTPUT);
	digitalWrite(LEDPins[i], HIGH);

	(AABABCDBBCABDBCBABDCABDBCABDCBABCABCDBACBADBCBBCBBCBBDBCBABDBBCDBABDCABBCBBDBACBBDCBABDABBCA);

	LEDWert = sequenz;

}

void loop() {
	unsigned long aktuelleZeit = millis();

	if(aktuelleZeit - letzterWechsel > zeitProLED) {
	digitalWrite(LEDPins[aktuelleLED],LOW);

	aktuelleLED = (aktuelleLED + 1) % 6;

	digitalWrite(LEDPins[aktuelleLED],HIGH);

	letzterWechsel = aktuelleZeit;

	}
}

Habs überprüft ;D . Der Code geht nicht.

Korrektur mE nicht möglich, da Neuschreiben einfacher.

Wo hast du den Sketch herkopiert? Die herangehensweise mag zwar nicht grundlegend verkehrt sein, sowas ist aber falsch

(AABABCDBBCABDBCBABDCABDBCABDCBABCABCDBACBADBCBBCBBCBBDBCBABDBBCDBABDCABBCBBDBACBBDCBABDABBCA);

und ich hab auch keine Ahnung wie du da drauf gekommen bist, dass sowas funktioniert.

Das mit dem LEDPins Array ist auch mehr als seltsam.

Longbardo:
Hallo kann mir jemand damit helfen diesen code zu überprüfen und zu korrigieren bitte. Ich habe 4 LED und einen bestimmten Ablauf einer Sequenz z.B (ROT, ROT,BLAU, ROT, GRÜN, BLAU,GELB) etc. diese jeweils sollen für eine bestimmte zeit an/aus gehen 200ms 1200ms usw.!

Den Code kann man so nicht verwenden.

Von dem, was ich aus Deiner Beschreibung herausgelesen habe, könntest Du vielleicht so einen Ablauf meinen:

// Struktur für eine LED
struct led_t { byte pin; int zeit; char wert; };

// Array für alle LEDs
led_t leds[]={
  { 2, 200, 'A' }, 
  { 3, 1200, 'B' }, 
  { 4, 3200, 'C' }, 
  { 5, 500, 'D' }, 
};

char playList[]="AABABCDBBCABDBCBABDCABDBCABDCBABCABCDBACBADBCBBCBBCBBDBCBABDBBCDBABDCABBCBBDBACBBDCBABDABBCA";
int playIndex=0;
int ledIndex=0;

#define NUMLEDS (sizeof(leds)/sizeof(leds[0]))

void setup () {
  Serial.begin(9600);
  Serial.println("Start");
  for(int i=0; i<NUMLEDS; i++) 
  {
    pinMode(leds[i].pin, OUTPUT);
  }
  Serial.print(leds[ledIndex].wert);
  digitalWrite(leds[ledIndex].pin,HIGH);
}



unsigned long letzterWechsel;
void loop() {
  if(millis()-letzterWechsel >= leds[ledIndex].zeit) 
  {
    letzterWechsel+= leds[ledIndex].zeit;
    digitalWrite(leds[ledIndex].pin,LOW);
    playIndex++;
    if (playIndex>=strlen(playList))
    {
      playIndex=0;      // Am Ende Überlauf auf null
      Serial.println(); // Neue Zeile auf Serial beginnen
    }
    if (playList[playIndex]=='A') ledIndex=0;
    else if (playList[playIndex]=='B') ledIndex=1;
    else if (playList[playIndex]=='C') ledIndex=2;
    else if (playList[playIndex]=='D') ledIndex=3;
    digitalWrite(leds[ledIndex].pin,HIGH);
    Serial.print(leds[ledIndex].wert);
  }
}

Ich habe zusätzlich ein serielles Debugging mit eingebaut, so dass Du auf dem Seriellen Monitor mitverfolgen kannst, welche LED-Buchstaben-Zeitkombination gerade abgespielt wird.

Tja, wie immer der berühmten jurs.
Dafür gibt's von mir ein Karma :smiley:

jurs der code funktioniert perfekt aber das wiederholt sich immer wieder das will ich aber nicht, sobald die die Sequenz durch ist soll eine 5 LED angehen die soll den Start und den Ende anzeigen.

Was meinst du, was

    if (playIndex>=strlen(playList))
    {
      playIndex=0;      // Am Ende Überlauf auf null

macht?

Ist übrigens ungewöhnlich, dass ein µController absichtlich nichts mehr macht bis zum nächsten Reset.

Longbardo:
jurs der code funktioniert perfekt aber das wiederholt sich immer wieder das will ich aber nicht, sobald die die Sequenz durch ist soll eine 5 LED angehen die soll den Start und den Ende anzeigen.

Findest Du die Stelle im Code nicht, wo die Liste einmal komplett abgespielt ist?
Der Code enthält doch Kommentare, sind die so unverständlich?

Wenn die Liste einmal komplett durch ist, könnte man natürlich in eine Endlosschleife mit while(1) übergehen:

    if (playIndex>=strlen(playList))
    {
      playIndex=0;      // Am Ende Überlauf auf null
      Serial.println(); // Neue Zeile auf Serial beginnen
      while(1);  // Ende mit Endlosschliefe
    }

Dann kannst Du über den Reset-Knopf auf dem Arduino-Board neu starten.

Genau so gut könnte man statt der Endlosschleife aber auch eine Schleife einbauen, um einen angeschlossenen Taster auszulesen, und ohne Neustart dann fortsetzen, wenn der Taster gedrückt wird.

michael_x:
Ist übrigens ungewöhnlich, dass ein µController absichtlich nichts mehr macht bis zum nächsten Reset.

Das wird öfters bei diesen TV B-Gone Fernbedienungen gemacht. Da ist der Taster der Reset Knopf. Dann läuft das Programm einmal durch und der Controller geht in den Sleep Modus.

Ein Bootloader würde dabei natürlich stören.

Noch eine letzte Frage wie gebe ich "delay(1000); // Pause zwischen den LEDSequenz" an wenn ich die im loop eingebe funktionieren Vorgabe der Array nicht mehr (Ich möchte die pausen zwischen den LED high to low bestimmen das die LED nicht sofort überspringt sondern einen kurzen Augenblick wartet)

Bitte mal die Basics durcharbeiten. Eine Möglichkeit wäre es, einen "toten" Pin anzusprechen.

Ich komm nicht dahinter wo bez. wie muss ich das "delay(1000); // Pause zwischen den LEDSequenz (char = werten)" einfügen. Ich will das nachdem eine LED aufleuchtet z.b eine sec. pause macht bis die nächst dran kommt!

Dann verstehe mal wie das Programm funktioniert. Zumindest in Ansätzen.

if(millis()-letzterWechsel >= leds[ledIndex].zeit)
{ 
    ....
}

EDIT:
War erst falsch. Hatte erst gedacht einmal am Ende warten.

Am Anfang des Blocks bist du vor dem Zustandsübergang. Am Ende des Blocks wurden die LEDs in den neuen Zustand geschaltet.

Da siehst du auch wo die aktuelle LED ausgeschaltet wird:

digitalWrite(leds[ledIndex].pin,LOW);

Vielleicht willst du danach warten bevor die nächste LED eingeschaltet wird.

Wobei das mit delay() allerdings sowieso in den meisten Fällen nicht klappen wird, weil du die Zeitzählung durcheinander bringst so wie es im Moment ist. Da müsste man ändern wie das mit millis() berechnet wird, oder besser gleich auf das Delay verzichten und das auch mit millis() machen

Mit einem Delay könnte man es so machen:

void loop() 
{
  if(millis()-letzterWechsel >= leds[ledIndex].zeit)
  {
    digitalWrite(leds[ledIndex].pin, LOW);
    delay(1000);
    letzterWechsel = millis();

    playIndex++;
    if (playIndex>=strlen(playList))
    {
      playIndex=0;      // Am Ende Überlauf auf null
      Serial.println(); // Neue Zeile auf Serial beginnen
    }
    if (playList[playIndex]=='A') ledIndex=0;
    else if (playList[playIndex]=='B') ledIndex=1;
    else if (playList[playIndex]=='C') ledIndex=2;
    else if (playList[playIndex]=='D') ledIndex=3;
    digitalWrite(leds[ledIndex].pin,HIGH);
    Serial.print(leds[ledIndex].wert);
  }
}

Das schaltet die aktuelle LED aus und wartet dann eine Sekunde bis die nächste gesetzt wird. Wichtig ist dass letzterWechsel nach dem delay() gesetzt wird

Aber wie gesagt, solltest du lernen komplett auf delay() zu verzichten

Longbardo:
Noch eine letzte Frage wie gebe ich "delay(1000); // Pause zwischen den LEDSequenz" an wenn ich die im loop eingebe funktionieren Vorgabe der Array nicht mehr (Ich möchte die pausen zwischen den LED high to low bestimmen das die LED nicht sofort überspringt sondern einen kurzen Augenblick wartet)

Warum gibt es inzwischen von Dir DREI Threads zum SELBEN THEMA?

Einmal hast Du mein komplett mit deutschen Variablennamen und deutschen Kommentaren geschriebenes Programm sogar in den internationalen Teil des Forums gepostet, wo vermutlich nur die wenigsten Forenteilnehmer Deutsch verstehen.

Grundsätzlich besteht ein Programm aus zwei Bestandteilen, und zwar:
1.) Datenstrukturen, die die physikalische Welt in Deinem Programm auf den RAM-Speicher abbilden
2.) Algorithmen zur Anwendung auf die Datenstrukturen, die die Ablauflogik bilden

Wenn Deine LEDs nun plötzlich außer einer Einschaltphase auch noch eine Ausschaltphase aufweisen sollen, bevor die nächste LED dran ist, muss sich das auch in der Datenstruktur wiederspiegeln. Du kannst entweder in der Datenstruktur die Ausschaltphase als eigene Schaltzeit festlegen:

/ Struktur für eine LED
struct led_t { byte pin; int EINzeit; int AUSzeit; };

// Array für alle LEDs
led_t leds[]={
  { 2, 200, 1000 }, // pin-2, 200ms EIN, 1000ms AUS
  { 3, 1200, 1000 }, 
  { 4, 3200, 1000 }, 
  { 5, 500, 1000 }, 
};

Oder Du definierst eine GESAMTzeit, in der die LED insgesamt dran ist, und schlägst die Ausschaltzeit auf die Einschaltzeit drauf, um die Gesamtzeit zu erhalten:

/ Struktur für eine LED
struct led_t { byte pin; int EINzeit; int GESAMTzeit; };

// Array für alle LEDs
led_t leds[]={
  { 2, 200, 1200 }, // pin-2, 200ms EIN, 1200ms GESAMT
  { 3, 1200, 2200 }, 
  { 4, 3200, 4200 }, 
  { 5, 500, 1500 }, 
};

Und wenn Du Dir eine Datenstruktur für Dein neues Programm ausgesucht und definiert hast, schreibst Du für diese Datenstruktur Deinen neuen Algorithmus, nach dem die LEDs zeitweise EIN und zeitweise AUS geschaltet werden, immer wenn diese LED an der Reihe ist, statt nur für eine bestimmte Zeit EIN wie vorher.

Generell gibt es aber immer ganz viele verschiedene Möglichkeiten, etwas zu programmieren.
Man sollte nur möglichst von Anfang an wissen, was eigentlich programmiert werden soll, weil danach die grundlegenden Datenstrukturen im Programm festgelegt werden müssen.

Falls es Dir aufgefallen ist, dass ich die Angabe "char wert;" in der Datenstruktur weggelassen habe: Die Information ist redundant ("doppelt gemoppelt") und kann daher weggelassen werden. Denn der einer LED zugeordnete Buchstabe ergibt sich ja quasi direkt bereits aus der Position der LED im Array, mit der Beziehung ('A'+ledIndex==leds[ledIndex].wert). Also braucht der Wert nicht extra in der Datenstruktur durch das Programm geschleppt werden.

Ist das eine Übungsaufgabe und Du hast einen festen Abgabetermin?
Und wir sollen hier Deine Übungsaufgabe vollständig für Dich lösen, ohne dass Du irgendwas dabei machst (außer die LEDs über Vorwiderstände mit dem Arduino verbinden)?

Oder versuchst Du es selbst, aus der neuen Datenstruktur und grob angelehnt an das von mir bereits gepostete Programm, oder auch mit blockierendem "delay()" wenn Dir das lieber ist, das neue Programm mit den zusätzlichen Ausschaltzeiten zu programmieren?

Hallo Leute bin weiter gekommen und habe jetzt LCD-Display angeschlossen, kann ich theoretische dieses Display als serieller Monitor benutzen. Also mir in der ersten Zeile Start/Ende der und Sequenz anzeigen lassen und wie viel “%” der Sequenz durchgelaufen wurden und in der zweiten Zeile die Sequenz an sich sichtbar machen wie im seriellen Monitor Anzeigen lassen?

#include <LiquidCrystal.h>
//lcd(RS, Enable, D4, D5, D6, D7);

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

char text1 = " LED Light";
char text2 = “”;

// Struktur für eine LED
struct led_t { byte pin; int zeit; char wert; };

// Array für alle LEDs
led_t leds={

{ 2, 500, ‘A’ }, // Red PIN 2
{ 3, 200, ‘B’ }, // Yellow PIN 3
{ 4, 100, ‘C’ }, // Green PIN 4
{ 5, 200, ‘D’ }, // Blue PIN 5
};

char playList=“ABCDDSBABCDBCABCAD”;
int playIndex=0;
int ledIndex=0;

#define NUMLEDS (sizeof(leds)/sizeof(leds[0]))

void setup() {
lcd.begin(16,2);
lcd.clear();
lcd.print(text1);
lcd.setCursor(0,1);
lcd.print(leds[ledIndex].wert);

Serial.begin(9600);
Serial.println(“Start”);
for(int i=0; i<NUMLEDS; i++)
{
pinMode(leds*.pin, OUTPUT);*

  • }*

  • Serial.print(leds[ledIndex].wert);*

  • digitalWrite(leds[ledIndex].pin,HIGH);*

  • // put your setup code here, to run once:*
    }
    unsigned long letzterWechsel;
    void loop() {

  • lcd.scrollDisplayLeft();*

  • delay(500);*

  • if(millis()-letzterWechsel >= leds[ledIndex].zeit)*

  • {*

  • digitalWrite(leds[ledIndex].pin, LOW);*

  • delay(50);*

  • letzterWechsel = millis();*

  • playIndex++;*

  • if (playIndex>=strlen(playList))*

  • {*

  • playIndex=0; // Am Ende Überlauf auf null*

  • Serial.println(); // Neue Zeile auf Serial beginnen*

  • while(1); // Ende mit Endlosschliefe*

  • }*

  • if (playList[playIndex]==‘A’) ledIndex=0;*

  • else if (playList[playIndex]==‘C’) ledIndex=1;*

  • else if (playList[playIndex]==‘G’) ledIndex=2;*

  • else if (playList[playIndex]==‘T’) ledIndex=3;*

  • digitalWrite(leds[ledIndex].pin,HIGH);*

  • Serial.print(leds[ledIndex].wert);*

  • }*
    }

Im Prinzip schon. Du kannst kein println verwenden, aber print. Musst jedesmal auf die richtige Zeile positionieren und was überschrieben ist, ist weg.

char text2 = “”;

Das ist ziemlich nutzlos, und wird auch nicht verwendet.

Was du machen kannst, ist

char text2[17]="                "; // Textpuffer für Zeile 2: 16 Zeichen + Endekennung

text2[5] = 'A';  // einzelne Zeichen ändern, hier in der 6. Spalte, als Demo

lcd.setCursor(0,1); lcd.print(text2); // komplette Zeile schreiben

Mit Code - Tags </> verschwindet kein [ i ] :wink:

Hallo Leute eine solche anzeige würde ich gerne hinbekommen wie in diesem youtube video! "Horizontal Analog Bar-graph with LCD Character, 16x2 (The Power of CGRAM) - YouTube" also wenn die Sequenz abläuft soll der Vorgang so angezeigt werden auf dem lcd display. Wie programmiere ich das ?

Buch kaufen, Basics lernen.
Die Ansteuerung ist recht simpel, wird aber soweit bekannt in keiner Libary verwendet. Du nutzt hierfür CostumChars, die im Display hinterlegt werden müssen.

Ok, verstanden ich bedanke mich für eure Hilfe. Dan werde ich mich mal ranmachen das zu lernen! :slight_smile: