Forum: Mikrocontroller und Digitale Elektronik Switch-Case Anweisung - Frage


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von M. G. (Firma: privat) (nipp0n)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

Ich benötige eure Hilfe, da ich mit dem Verhalten einer Switch-Case 
Anweisung nicht weiter komme. Besser gesagt, dass Verhalten nicht 
verstehe.

Im Anhang findet ihr die dazugehörige INO Datei.

Folgendes Problem:
Ich möchte mit Hilfe von Hall Effekt Sensoren einen Zustand auslesen und 
anhand des Zustandes bestimmte LEDs aktivieren. Dazu habe ich ein Array 
erstellt, welche die zu schaltenden LEDs enthält. Das auslesen geschieht 
über einen 74HC165. Das klappt auch wunderbar.
Bei der Switch Anweisung wird auf 0 oder 1 reagiert, welche vom Hall 
Effekt Sensor . Wenn ich nur Case 0 oder Case 1 nutze, werden die LEDs 
korrekt angezeigt. Sobald jedoch beide Case Anweisungen enthalten sind, 
werden die LEDS nicht mehr korrekt geschalten. Mit einer Ausnahme: Das 
letzte Feld im Array(B5) wird immer korrekt angezeigt. Bei allen anderen 
sind eine LED statt 4 an oder 2 statt 4.

Ich weiß nicht, wo der Fehler liegt.
Auch habe ich schon versucht, die Case 0 und Case 1 in separate Void zu 
packen. Das Ergebnis ist das selbe.

Gruß

von Falk B. (falk)


Lesenswert?

Die geschweiften Klammern in den einzelnen case-Zweigen sind falsch. 
Mach die weg. Außerdem stimmt deine Einrückung nicht, da sieht man 
schlecht durch, was in welchem Block verschachtelt ist.

von Klaus W. (mfgkw)


Lesenswert?

Für ein paar Dutzend Euro bekommt man mittlerweile Festplatten im 
TB-Bereich.
Da kann man ein paar Byte für Zeilenvorschübe spendieren, das macht 
niemanden arm und den Quelltext lesbarer.

In einem Konstrukt der Art:
1
switch(...)
2
{
3
   case...:
4
         for(...)
5
         {
6
             ...;
7
             break;
8
         } 
9
   ...
10
}
bezieht sich das break nicht auf das switch/case, sondern auf das for.
Es wird die Schleife verlassen, nicht das switch.

: Bearbeitet durch User
von PittyJ (Gast)


Lesenswert?

>Auch habe ich schon versucht, die Case 0 und Case 1 in separate Void zu
>packen. Das Ergebnis ist das selbe.

Das nennt man Funktionen, und void bedeutet da nur, dass die Funktion 
nichts zurück liefert.

Ein Grundlagenbuch über C Programmierung würde gut tun. Man/fra sollte 
erst die Werkzeuge beherrschen/befrauschen, und dann damit was tun.

von Klaus W. (mfgkw)


Lesenswert?

PittyJ schrieb:
> befrauschen

Sehr schön!

Obwohl ich gerade zu bedamsen neige.

von EAF (Gast)


Lesenswert?

PittyJ schrieb:
> Ein Grundlagenbuch über C Programmierung würde gut tun.
C++
Aber die sind sich in dem Punkt einig.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

die geschweiften Klammern stimmen schon. Sieht nur doof aus so 
zusammengeklatscht.

Das Problem wird wohl sein, dass
1
char Belegung[8];
statt
1
byte Belegung[8];
verwendet wird.

Globale Schleifenzähler sind nie sinnvoll, außer man weiß genau was man 
tut. default case (default: break;) sollte man auch nicht vergessen, 
wenn man nicht alles definiert.
1
for (byte i = 0; i < lang; i++)
2
{
3
  Serial.print("i: "); Serial.print(i);
4
  Serial.print("  Belegung[i]: "); Serial.println(Belegung[i]);
5
  switch (Belegung[i])
6
  {
7
    case 0:   OFF(); break;
8
    case 1:   ON();  break;
9
    default: Serial.println("default"); break;
10
  }
11
}

Weil sowas hier s=x ist überflüssig und provoziert nur unnötig Fehler.
1
for (x=0;x<lang;x++) {
2
  s=x;
3
  switch (Belegung[s]) {
4
  ...

von Veit D. (devil-elec)


Lesenswert?

Klaus W. schrieb:

> In einem Konstrukt der Art:
>
1
> switch(...)
2
> {
3
>    case...:
4
>          for(...)
5
>          {
6
>              ...;
7
>              break;
8
>          }
9
>    ...
10
> }
11
>

Nur so ein falsches Konstrukt hat der TO nicht.

von Klaus W. (mfgkw)


Lesenswert?

gelöscht...
sorry, hatte mich vertan.

Nachtrag: solange der Quelltext so gestaltet ist, tu ich mir das eh 
nicht an.

: Bearbeitet durch User
von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Hier mal etwas aufgräumt.

Einheitliche, übersichtliche Einrückung.
Deine vielfachen for-Schleifen packt man sinnvollerweise in eine 
Funktion.
Lies mal was über lokale Variablen, die sollte man nutzen.
Globale Variablen sparsam nutzen

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Danke für die viele Hilfe.

Mit soviel Unterstützung habe ich nicht gerechnet.
@Falk Vielen Dank für die Umgestaltung,

Mein Problem mit der Case Anweisung besteht weiterhin.
Sobald 2 Case Anweisungen vorhanden sind, funktioniert die Anzeige nicht 
mehr korrekt. die LEDs bei B5 leuchten korrekt und die anderen LEDs 
leuchten nicht korrekt, da leuchtet immer nur eine LED, anstatt die 4 
angegebenen. Das finde halt das komische.

So funktioniert es nicht, wie ich mir das vorgestellt habe.
1
switch (Belegung[s]) {
2
          case 0: OFF(); break; 
3
          case 1: ON(); break;
4
          default: break;
Wenn ich Case 0 auskommentiere, werden die LEDs genau so angezeigt, wie 
es im Array LED_Ausgabe angegeben ist.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

a) byte statt char Array
b) du musst weiter aufräumen
c) lasse dir Debugwerte ausgeben, du musst prüfen ob der gewünschte case 
überhaupt angesprungen werden kann und nicht nur angesprungen werden 
soll und warum er nicht angesprungen werden kann bzw. wird.

bspw. Beitrag "Re: Switch-Case Anweisung - Frage"

Was wird ausgegeben?

von PittyJ (Gast)


Lesenswert?

Ein printf() der Variablen z.B. :
s
Belegung[s]

ist nicht möglich? Man könnte damit einfach mal überprüfen, ob die 
Variablen stimmen, oder ob es dort schon einen Fehler gibt.
Auch an anderen Stellen kann man sich beim Debuggen mal etwas anzeigen 
lassen.

von Falk B. (falk)


Lesenswert?

M. G. schrieb:
> Sobald 2 Case Anweisungen vorhanden sind, funktioniert die Anzeige nicht
> mehr korrekt. die LEDs bei B5 leuchten korrekt und die anderen LEDs
> leuchten nicht korrekt, da leuchtet immer nur eine LED, anstatt die 4
> angegebenen. Das finde halt das komische.

Naja, deine Logik im Quelltext fand ich auch komisch, hab mich aber 
nicht weiter drum gekümmert. Du machst da irgendwie viel doppelt und 
dreifach.
Eher so.
1
void loop() {
2
  if(shift.update()) { // read in all values. returns true if any button has changed
3
    displayValues();
4
    // Clearing();
5
    for (b=0; b<8; b++) {
6
      Serial.print(Belegung[b],BIN);
7
    }
8
    Serial.println();
9
    Serial.print(lang,DEC);
10
    Serial.println();
11
    for (x=0; x<lang; x++) {
12
      switch (Belegung[x]) {
13
        case 0:
14
          Serial.print("Aus |");
15
          LED_set(x, 0,0,0);
16
          break;
17
        case 1:
18
          Serial.print("An |");
19
          LED_set(x, 0,20,0);
20
          break;
21
      }          
22
    }
23
    Pixels.show();
24
    Serial.println();
25
  }
26
}

Du musst für nacheinander ausgeführte Schleifen auch nicht immer eine 
"frische" Variable nutzen, da kann man immer di gleich nehmen, 
traditionell i (wie Index). Nur bei verschachtelten Schleifen braucht 
man mehrere Variablen, typisch i, j, k.

von Markus (Gast)


Lesenswert?

>Einheitliche, übersichtliche Einrückung.

Kleienr Tipp: In der Arduino IDE die Tastenkombination "STRG-T" drücken 
formatiert den Code automatisch.

von M. G. (Firma: privat) (nipp0n)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

Ich habe schon alles mögliche mir über Serial.println ausgeben lassen. 
Die Ausgabe von Belegung[s] zeigt genau den Status der Hall Effekt 
Sensoren.

Was mir dabei immer noch aufstößt ist, das sobald ich abprüfe, ob der 
Sensor ein LOW / 0 hat, ist die Anzeige der WS2812B nicht mehr korrekt. 
Vielleicht ist es an Hand der angehangenen Bilder verständlicher.
Beim ersten Bild ist die Switch Anweisung mit Case 0 und Case 1 
versehen.
beim zweiten Bild nur mit Case 1.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

M. G. schrieb:
> Vielleicht ist es an Hand der angehangenen Bilder verständlicher.

Nö. Wie soll denn deine Anzeige korrekt aussehen? Es ist keine normale 
Balkenanzeige. Die Nummern in deinem Array überlappen sich teilweise. 
Hast du erst einmal geprüft, ob du ALLE LEDs EINZELN mit ihrer korrekten 
Nummer ein- und ausschalten kannst?

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Hallo Falk

Ja die Überlappung der LEDs ist korrekt. Wenn z.b. Schalter A3 ein HIGH 
hat, sollten laut Array die LEDs 0,1,6,7 leuchten. bei A4 Sollen es 
1,2,7,8 sein. Was sie auch machen, Wenn ich das Case 0 rausnehme. 
Sobald ich die Case 0 auswerte, geht bei A3 nur die LED0 an, jedoch bei 
B5 gehen alle 4 angegebenen LED an. Das sieht man im ersten Bild.

Ja das einschalten der einzelnen LED funktioniert korrekt, auch wenn ich 
die einzelnen LED so wie angegeben schalte, reagieren sie richtig.

Ich habe auch versucht, das ganze mal per Eingabe über die serielle 
Schnittstelle zu machen, das ist der gleiche Effekt.

von Klaus W. (mfgkw)


Lesenswert?

Und dein Programm ist jetzt das von Falk B., oder noch das 
ursprüngliche?

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

@ Klaus

Ich auch das von Falk getestet. Es zeigt den selben Effekt.

Langsam glaube ich, das der Weg den ich gewählt habe der falsche ist, 
denn selbst mit den überabeiteten Code habe ich das gleiche Ergebnis.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

zeige doch einmal den aktuellen kompletten Code. Damit wir alle den 
gleichen Stand haben.

von M. G. (Firma: privat) (nipp0n)


Angehängte Dateien:

Lesenswert?

So das wir jetzt mal auf den aktuellen Stand kommen.
Hier wie gewünscht, die aktuellste Version, mit Falk B. seiner Loop.

von Johannes S. (Gast)


Lesenswert?

es müssten doch immer mehr LED einschalten weil zwischen den Stati die 
Pixel gar nicht gelöscht werden, ist doch wie beim Display wenn ich 
Zeichen ausgebe aber das vorhergende nicht lösche.
Da müsste es ein Pixel.Clear() oder sowas geben was vor der neuen 
Ausgabe erstmal alles löscht.

von 900ss (900ss)


Lesenswert?

Klaus W. schrieb:
> PittyJ schrieb:
>> befrauschen
>
> Sehr schön!
>
> Obwohl ich gerade zu bedamsen neige.

LOL, beide sehr schön :)

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Johannes S. schrieb:
> Da müsste es ein Pixel.Clear() oder sowas geben was vor der neuen
> Ausgabe erstmal alles löscht.

Ja, auch diese Variante funktioniert nicht. Ich setze wenn dem Feld 
Belegung z.b. 1000001 dann enpricht die 1 an und die 0 aus. Das mache 
ich ja mit Case 0 und 1.

900ss D. schrieb:
> Klaus W. schrieb:
>> PittyJ schrieb:
>>> befrauschen
>>
>> Sehr schön!
>>
>> Obwohl ich gerade zu bedamsen neige.
>
> LOL, beide sehr schön :)

Leider sind nicht alle Menschen als Genie auf die Welt gekommen. Kein 
Mensch ist perfekt und ich möchte mich für deinen sehr hoch 
intellektuellen Beitrag bedanken. Ohne diesen würde ich nicht mehr klar 
kommen und hätte die Lösung für mein Problem nie gefunden. IRONIE aus

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

M. G. schrieb:
> Folgendes Problem:
> Ich möchte mit Hilfe von Hall Effekt Sensoren einen Zustand auslesen und
> anhand des Zustandes bestimmte LEDs aktivieren. Dazu habe ich ein Array
> erstellt, welche die zu schaltenden LEDs enthält. Das auslesen geschieht
> über einen 74HC165. Das klappt auch wunderbar.
> Bei der Switch Anweisung wird auf 0 oder 1 reagiert, welche vom Hall
> Effekt Sensor .

Äh, was bitte?
Also ob du nun Hall-Sensoren oder etwas anders ausweren willst, dürfte 
für eine 'switch'-Anweisung keine Rolle spielen. Und wenn du nur auf 0 
oder 1 reagieren willst, dann ist eine 'switch'-Anweisung eher weniger 
geeignet. Schließlich dient diese Anweisung in erster Linie zum 
Unterscheiden von mehr als nur 2 Fällen:
1
switch (zahl)
2
{ case 1: Tue_erstes(); break;
3
  case 2: Tue_zweites(); break;
4
  case 3: Tue_drittes(); break;
5
  ... usw.
6
}

Also, denke nochmal über die gewünschte Funktionalität deines Programms 
nach. Wenn man das ohne sich zu verheddern formulieren kann, dann ist es 
auch leicht zu programmieren. Sonst hat man etwas falsch gedacht.

W.S.

von Klaus W. (mfgkw)


Lesenswert?

Dann kommt dir die Frage vielleicht auch zu unintellektuell vor, aber 
trotzdem:
Was bezweckst du mit dieser Schleife?
1
    for (b = 0; b < 8; b++) {
2
3
    }
Da könnte man auch gleich b=8 schreiben?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

eigentlich solltest du weiter aufräumen.
1
#include <ShiftIn.h>
2
#include <Adafruit_NeoPixel.h>
3
const uint8_t PIN = 6;
4
const uint8_t NUMPIXELS = 18;
5
Adafruit_NeoPixel Pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
6
// Belegung Feld - LED
7
int LED_Ausgabe[8][4] = 
8
{
9
  {0, 1, 6, 7}, //A3
10
  {1, 2, 7, 8}, //A4
11
  {2, 3, 8, 9}, //A5
12
  {4, 5, 12, 13}, //B1
13
  {5, 6, 13, 14}, //B2
14
  {6, 7, 14, 15}, //B3
15
  {7, 8, 15, 16}, //B4
16
  {8, 9, 16, 17} //B5;
17
};
18
19
// Init ShiftIn instance with a single chip
20
ShiftIn<1> shift;
21
const uint8_t numberOfButtons = shift.getDataWidth();
22
23
char Belegung[8];
24
25
void setup()
26
{
27
  Serial.begin(9600);
28
  Pixels.begin();
29
  Pixels.show();
30
  // declare pins: pLoadPin, clockEnablePin, dataPin, clockPin
31
  shift.begin(8, 9, 11, 12);
32
  Serial.print("Anzahl der Eingänge:");
33
  Serial.print(numberOfButtons); // drucke Länge der Belegung
34
  Serial.println();
35
}
36
37
void displayValues()
38
{
39
  // print out all 8 buttons
40
  Serial.print("Schalterstatus:");
41
  for (uint8_t i = 0; i < numberOfButtons; i++)
42
  {
43
    Serial.print( shift.state(i) );     // get state of button i
44
    Belegung[i] = shift.state(i);
45
  }
46
  Serial.println();
47
}
48
49
50
void loop() {
51
  if (shift.update()) 
52
  {
53
    displayValues();
54
       
55
    for (uint8_t i = 0; i < numberOfButtons; i++)
56
    {
57
      Serial.print("i: "); Serial.print(i);
58
      Serial.print("  Belegung[i]: "); Serial.println(Belegung[i]);
59
      switch (Belegung[i])
60
      {
61
        case 0:
62
          Serial.println("case 0"); 
63
          LED_set(i, 0, 0, 0);
64
          delay(50);
65
          break;
66
        case 1:
67
          Serial.println("case 1"); 
68
          LED_set(i, 0, 20, 0);
69
          delay(50);
70
          break;
71
      }
72
    }
73
    Pixels.show();
74
    Serial.println();
75
  }
76
}
77
78
void LED_set(uint8_t i, uint8_t r, uint8_t g, uint8_t b)
79
{
80
  for (uint8_t z = 0; z < 4; z++)
81
  {
82
    Pixels.setPixelColor(LED_Ausgabe[i][z], r, g, b);
83
  }
84
}

Was wird hier:
1
Serial.print("  Belegung[i]: "); Serial.println(Belegung[i]);
ausgegeben? Bei meinen reduzierten Test bekomme ich immer 0. Das heißt 
er springt immer nur ins case 0. Ändere ich
1
char Belegung[8];
 auf
1
byte Belegung[8];
 funktioniert es.

von M. G. (Firma: privat) (nipp0n)


Angehängte Dateien:

Lesenswert?

Hallo Klaus.

die 8 bezieht sich aktuell auf ein Schieberegister 74HC165. Im späteren 
Verlauf werden es 4 sein. Mit insgesamt 27 Hall Sensoren, welche mir die 
Belegung eines Feldes zeigen und je nach Belegung 4 LEDS schalten. Dabei 
überlappen sich auch LEDS. Anhand des angehangenen PNG ist die Anordnung 
der LEDs ersichtlich und welche immer zusammen gehören.

von Peter D. (peda)


Lesenswert?

Gibt es eine Beschreibung, was shift.getDataWidth(); genau macht?
Als Abbruchbedingung in der Schleife ein Funktionsaufruf, kommt mir doch 
sehr merkwürdig vor.

von Klaus W. (mfgkw)


Lesenswert?

M. G. schrieb:
> die 8 bezieht sich aktuell auf ein Schieberegister 74HC165

Ich hatte mich nicht über die 8 gewundert, sondern darüber daß die 
Schleife leer ist und nichts macht.

von Veit D. (devil-elec)


Lesenswert?

Peter D. schrieb:
> Gibt es eine Beschreibung, was shift.getDataWidth(); genau macht?

https://github.com/InfectedBytes/ArduinoShiftIn

Beitrag #6826678 wurde vom Autor gelöscht.
von M. G. (Firma: privat) (nipp0n)


Lesenswert?

@ Veit

Danke für deine Bemühungen. Deine Änderungen am Quellcode, haben mir 
etwas mehr Übersicht gebracht. Jedoch keine Änderung am Ergebnis.

wenn Button 1 und 8 High sind sollten laut der LED Matrix die LEDs 
0,1,6,7 sowie LED 8,9,16,17 leuchten. Und das machen sie nicht. Es 
leuchten LED 8,9,16,17 und LED 0. Sobald ich jedoch das Case 0 
auskommentiere, leuchten die LEDs korrekt. Und dieses Phänomen kann ich 
nicht mehr nachvollziehen.  Das passierte auch schon bei meiner ersten 
Version.

Selbst wenn ich das ganze als IF Anweisung formuliere, wie Falk B. es 
vorgeschlagen hat, passiert genau das gleiche.

shift.getDataWidth(); gibt die Länge des der Bits des Schieberegisters 
zurück. 1 Register = 8 und so weiter.

Die leere Schleife hatte ich vergessen zu löschen, damit habe ich mir 
den Inhalt vom Shiftregister ausgeben lassen, um zu sehen, was da genau 
rauskommt.

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

M. G. schrieb:
> wenn Button 1 und 8 High sind sollten laut der LED Matrix die LEDs
> 0,1,6,7 sowie LED 8,9,16,17 leuchten. Und das machen sie nicht. Es
> leuchten LED 8,9,16,17 und LED 0. Sobald ich jedoch das Case 0
> auskommentiere, leuchten die LEDs korrekt.

so ist es doch auch programmiert? Im ersten Schritt werden 0,1,6,7 
eingeschaltet, dann durch die 0en 1,6,7 wieder aus und im letzten 
Schritt 8,9,16,17 wieder ein. Bleibt das über was du siehst.

von Peter D. (peda)


Lesenswert?

M. G. schrieb:
> wenn Button 1 und 8 High sind sollten laut der LED Matrix die LEDs
> 0,1,6,7 sowie LED 8,9,16,17 leuchten. Und das machen sie nicht. Es
> leuchten LED 8,9,16,17 und LED 0.

Na das ist endlich mal ne Fehlerbeschreibung, mit der man was anfangen 
kann.
Die Erklärung ist ganz einfach, Du löscht die gleichen LEDs wieder bei 
den anderen Tasten, nur LED 0 taucht nicht nochmal auf.
Abhilfe ist auch ganz einfach, lösche in der Loop zuerst alle LEDs und 
bei ner Taste setze dann die gewünschten. Das ergibt dann eine 
Oder-Verknüpfung.

von Falk B. (falk)


Lesenswert?

M. G. schrieb:
> So das wir jetzt mal auf den aktuellen Stand kommen.
> Hier wie gewünscht, die aktuellste Version, mit Falk B. seiner Loop.

Ist dir klar, daß einige LEDs andere LEDs überschreiben und damit wieder 
ausschalten?
Mach mal einen Test, wo du Muster ausgibst, die immer nur 1 LED 
anschalten. Also 00000001, 00000010 etc.

von Johannes S. (Gast)


Lesenswert?

also
1
    Pixels.clear();
2
    for (uint8_t i = 0; i < numberOfButtons; i++)
3
    {
4
        if (Belegung[i]) {
5
                LED_set(i, 0, 20, 0);
6
        }
7
        Pixels.show();
8
    }

und Belegung[] ist denglisch und überflüssig, ersetzen durch 
shift.state(i).

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Hallo Johannes.

Das Feld Belegung sieht in dem Beispiel so aus: 10000001

Das heißt, dach meiner Denkweise: Wenn Belegung[0] eine 1 ist, dann 
schalte LED 0,1,6,7 an  Belegung[1] eine 1 ist, Schalte LED 1,2,7,8 an.
Bei LED 8,9,16,17 funktioniert es ja. nur bei den anderen nicht. Wenn 
Belegung[7] eine 0 ist, gehen die 4 dazugehörigen LEDS aus. bei 1 gehen 
die 4 auch an. Eine Änderung des LED zustandes sollte nur stattfinden, 
wenn sich der Zustand eines Schalters ändert. Habe ich irgendwo da einen 
Denkfehler in der Routine, das der LED 1,6,7 wieder ausmacht?

von Johannes S. (Gast)


Lesenswert?

ja, es werden immer alle Zeilen in LED_Ausgabe[] durchgenudelt, das 
Ergebnis ist das was durch Led Aus oder An übrig bleibt.

von Falk B. (falk)


Lesenswert?

M. G. schrieb:
> Hallo Johannes.
>
> Das Feld Belegung sieht in dem Beispiel so aus: 10000001
>
> Das heißt, dach meiner Denkweise: Wenn Belegung[0] eine 1 ist, dann
> schalte LED 0,1,6,7 an  Belegung[1] eine 1 ist, Schalte LED 1,2,7,8 an.

Ja, aber die gleichen LEDs schaltest du AUS, wenn es jeweils 0 ist!

> Bei LED 8,9,16,17 funktioniert es ja. nur bei den anderen nicht. Wenn
> Belegung[7] eine 0 ist, gehen die 4 dazugehörigen LEDS aus. bei 1 gehen
> die 4 auch an. Eine Änderung des LED zustandes sollte nur stattfinden,
> wenn sich der Zustand eines Schalters ändert. Habe ich irgendwo da einen
> Denkfehler in der Routine, das der LED 1,6,7 wieder ausmacht?

JA! Ua. mit deinen überlappenden LED-Gruppen! Wenn die alle keinerlei 
Überlappung haben, ist es egal. Hier aber nicht!

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Danke Johannes.
Deine Erläuterungen verstehe ich. Bloß kommt er doch nur einmal an LED 
0,1,6,7 vorbei. Belegung[x] sagt doch nur aus, an welche Stelle er in 
dem Feld Belegung schauen soll. Das Feld beinhaltet 8 Zeichen, entweder 
0 oder 1.
Wann schaltet die Routine denn die LEDS 1,6,7 wieder aus.

Ich habe es jetzt händisch mal nachgestellt. Wenn ich X fest vergebe, 
funktioniert es. Ich weiß nur noch nicht warum es in der Schleife nicht 
funktioniert.

von Falk B. (falk)


Lesenswert?

M. G. schrieb:
> Wann schaltet die Routine denn die LEDS 1,6,7 wieder aus.

Schon mal in deinen Quelltext geschaut?
1
      switch (Belegung[i])
2
      {
3
        case 0:
4
          Serial.println("case 0"); 
5
          LED_set(i, 0, 0, 0);      // AUSSCHALTEN
6
          delay(50);
7
          break;
8
        case 1:
9
          Serial.println("case 1"); 
10
          LED_set(i, 0, 20, 0);    // EINSCHALTEN
11
          delay(50);
12
          break;
13
      }

von Johannes S. (Gast)


Lesenswert?

ein Königreich für einen Debugger...
du hast eine Schleife die 8x durchlaufen wird, jedesmal wird 
LED_set(i,...) aufgerufen, mal zum LED einschalten, dann wieder zum 
ausschalten. LED_set schaltet immer 4 LED ein oder aus.

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Falk B. schrieb:
> M. G. schrieb:
>> So das wir jetzt mal auf den aktuellen Stand kommen.
>> Hier wie gewünscht, die aktuellste Version, mit Falk B. seiner Loop.
>
> Ist dir klar, daß einige LEDs andere LEDs überschreiben und damit wieder
> ausschalten?
> Mach mal einen Test, wo du Muster ausgibst, die immer nur 1 LED
> anschalten. Also 00000001, 00000010 etc.

Ich habe mit eine Testroutine geschrieben, wo fortlaufend die LEDS 
angeschalten werden. Es wird trotz Doppelbelegung keine mit Aus 
überschrieben.

Auch dein Vorschlag mit dem Muster habe ich probiert. funktioniert genau 
wie es soll.

Auch habe ich Belegung durch Shift.state(i) ersetzt. Brachte keine 
Änderung.

Meiner Auffassung nach hängt es irgendwo an der For-Schleife. Händlich 
setzen funktioniert ja.

von 900ss (900ss)


Lesenswert?

M. G. schrieb:
> Leider sind nicht alle Menschen als Genie auf die Welt gekommen.

Ich auch nicht :)

Das war überhaupt nicht auf dich bezogen und auch nicht auf deine Frage. 
Ich fand einfach diese beiden für mich neuen Varianten der 
Genderisierung zu entsprechen, äußert gelungen.

Dass dir das nicht hilft, klar. Dass du nicht auch darüber lachen 
kannst.... schade.

: Bearbeitet durch User
von 900ss (900ss)


Lesenswert?

M. G. schrieb:
> Meiner Auffassung nach hängt es irgendwo an der For-Schleife. Händlich
> setzen funktioniert ja.

Vielleicht kannst du dein Programm auf dem PC debuggen? Statt LED 
schalten gibt's du mit printf die Portzustände aus.
GCC + Debugger gibt's kostenlos.

Dann erkennst im Schrittbetrieb direkt wo es klemmt.

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

@

Falk B. schrieb:
> Schon mal in deinen Quelltext geschaut?

Wenn shift.state(i) eine Null hat. Leider ist es so das shift.state(0) 
eine 1 hat und keine null. Auch wenn shift.state(3) eine 1 hat, sind nur 
2 statt 4 Leds an. Und nur bei 7 sind alle 4 an und ich raff nicht 
warum.

Das shift.state wird auch richtig erkannt, ob 0 oder 1.

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

der Wald und die Bäume?
1
1:  {0, 1, 6, 7}, //A3
2
0:  {1, 2, 7, 8}, //A4
3
0:  {2, 3, 8, 9}, //A5
4
0:  {4, 5, 12, 13}, //B1
5
0:  {5, 6, 13, 14}, //B2
6
0:  {6, 7, 14, 15}, //B3
7
0:  {7, 8, 15, 16}, //B4
8
1:  {8, 9, 16, 17} //B5;

das wird ausgeführt bei deinem Schaltermuster 1000.0001
Da wo ne 1: vorsteht werden die LED eingeschaltet,
da wo ne 0: vorsteht werden die LED ausgescahltet.
Was bleibt dann über wenn alle 8 Zeilen abgearbeitet wurden?

Edit:
Johannes S. schrieb:
> Pixels.show();

diese Zeile in meinem Code gehört natürlich hinter die for-Schleife!

von Veit D. (devil-elec)


Lesenswert?

M. G. schrieb:
> @ Veit
> Danke für deine Bemühungen. Deine Änderungen am Quellcode, haben mir
> etwas mehr Übersicht gebracht. Jedoch keine Änderung am Ergebnis.

Ist mir schon klar, hatte erstmal nur weiter aufgeräumt. Tja und dann 
wollte ich die Debugausgaben von dir sehen. Aber das hat sich ja nun 
erledigt.

von M. G. (Firma: privat) (nipp0n)


Lesenswert?

Was das Debuggen betrifft. Das ist für mich noch wie böhmische Dörfer.
Ich habe mir MinGW heruntergeladen und installiert und dann stand ich 
da.
Auch was Google mir angeboten hat, war nicht sehr Hilfreich. Hat jemand 
von euch vielleicht nen Link mit einer verständlichen Erklärung wie man 
den Debugger benutzt.

Ich habe dann Visual Code Studio installiert. Da muss ich erstmal nach 
den Einstellungen schauen, weil die Shiftin Libary wird immer 
angemeckert und der Debugmodus funzt dann scheinbar auch nicht, weil er 
immer die "angegebene Aufgabe nicht findet"

Damit werde ich mich aber erst morgen befassen.

Danke an alle die mich bisher unterstützt haben.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

lasse dich nicht auf Nebenkriegsschauplätze ablenken. Du bist so schon 
überfordert. Mit Debugausgaben sind hier die Seriellen Ausgaben gemeint. 
Die vielen Serial.println(...); Das sinnvoll an verschiedenen Stellen, 
außer in Interrupt Routinen, und man kann wunderbar mit einfachsten 
Mitteln debuggen. Debuggen heißt nur Fehlersuche.

von 900ss (900ss)


Lesenswert?

Veit D. schrieb:
> Debuggen heißt nur Fehlersuche

Allerdings. Wenn man das  auch mit einem Debugger beherrscht, ist dieser 
durchaus ein hilfreiches Werkzeug. Man kann eben z.B. Einzelschritte 
ausführen und genau sehen was passiert.
Aber es stimmt, es nichts was man mal eben aus dem Ärmel schüttelt. Auch 
damit muss man sich beschäftigen. MinGW ist schon richtig. Da ist alles 
drin, was man braucht.
Und für Sachen die Echtzeit erfordern, ist es auch nur bedingt 
einsetzbar.

M. G. schrieb:
> Was das Debuggen betrifft

Wenn es dir egal ist, mit dem Debugger umgehen zu können, dann ist es 
vielleicht tatsächlich etwas viel. Dann solltest du es mit den seriellen 
Ausgaben weiter versuchen.
Wenn du aber interessiert bist ein wertvolles Hilfsmittel zu 
beherrschen, dann versuche es.
Aber Du kannst damit das Programm für den Arduino so wie es jetzt ist 
nicht debuggen. Das ist ja für den Mikrocontroller geschrieben. Du musst 
die Funktionen, die dir Probleme bereiten einzeln von einer main() 
Funktion aufrufen und testen.

: Bearbeitet durch User
von M. G. (Firma: privat) (nipp0n)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen.

Ich habe mir heute nochmal einige Zeit in dieses Problem gesteckt und 
bin keinen Schritt weitergenommen. Das Verhalten der LEDs ist für mich 
nicht nachvollziehbar. Ich habe mir jeden Schritt einzeln ausgeben 
lassen, um zu schauen, wo der Fehler ist. Ich habe keinen gefunden.

Nach einigen Versuchen, einen anderen Weg zu gehen, welche genauso 
endeten wir die bisherigen Versuche, habe ich eine Lösung gefunden. Sie 
ist mit Sicherheit nicht die Beste. Ich habe das prüfen ob ein ein 
Schalter LOW ist, ganz weggelassen. Stattdessen prüfe ich ab, ob 
shift.state ein High hat. Wenn ja dann soll er die LEDS entsprechend 
schalten. Bevor er diese Schleife durchläuft, setzt ich die LEDs alle 
einmal auf Aus und schreibe, dann die Belegung neu.

Ein Riesen Dankschön an alle die mich unterstützt haben, eine Lösung. 
Mir die Augen geöffnet haben, das mein Programmierstil unsauber war.

Danke nochmal an alle.

Im Anhang ist jetzt meine Version, die ich mit eurer Hilfe 
zusammengebaut habe.

M.G.


P.S.: Ich lasse mich von diesem Problem nicht kleinkriegen. Ich finde 
mit Sicherheit die Lösung für das komische Verhalten.

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

na so hatte ich es ja gezeigt. Nur das Pixel.show() gehört hinter die 
for Schleife, es ist nicht nötig das 8 mal auszugeben.

von Egon D. (Gast)


Lesenswert?

M. G. schrieb:

> Ich finde mit Sicherheit die Lösung für das
> komische Verhalten.

Kein "komisches Verhalten", sondern das sprichwörtliche
"Brett vor dem Kopf" :)


Wenn eine bestimmte Belegung aktiv sein soll, dann sollen
ALLE LEDs leuchten, die zu dieser Belegung gehören.

Die aussagenlogische Negation von "alle" ist aber NICHT
"keine", sondern "nicht alle"!!!

Wenn also eine bestimmte Belegung nicht aktiv sein soll,
dann bedeutet das nicht , dass keine ihrer LEDs leuchten
soll -- es bedeutet nur, dass nicht alle ihrer LEDs
leuchten sollen.

Du darfst daher inaktive Belegungen nicht löschen, nachdem
bereits aktive Belegungen gesetzt wurden -- denn dann kann
genau das passieren, was Du beobachtet hast: Es werden LEDs
gelöscht, die leuchten müssten, weil sie zu mehr als einer
Belegung gehören.

von Peter D. (peda)


Lesenswert?

M. G. schrieb:
> Ich habe das prüfen ob ein ein
> Schalter LOW ist, ganz weggelassen. Stattdessen prüfe ich ab, ob
> shift.state ein High hat. Wenn ja dann soll er die LEDS entsprechend
> schalten. Bevor er diese Schleife durchläuft, setzt ich die LEDs alle
> einmal auf Aus und schreibe, dann die Belegung neu.

So hatte ich das hier doch schon geschrieben:

Beitrag "Re: Switch-Case Anweisung - Frage"

"Abhilfe ist auch ganz einfach, lösche in der Loop zuerst alle LEDs und
bei ner Taste setze dann die gewünschten. Das ergibt dann eine
Oder-Verknüpfung."

von Falk B. (falk)


Lesenswert?

Peter D. schrieb:
> So hatte ich das hier doch schon geschrieben:

Das Problem saß und sitzt VOR der Tastatur . . . ;-)

von Peter D. (peda)


Lesenswert?

Johannes S. schrieb:
> Nur das Pixel.show() gehört hinter die
> for Schleife, es ist nicht nötig das 8 mal auszugeben.

Man kann es zum Debuggen in die alte Schleife setzen mit 1s Delay 
dahinter. Dann sieht man, wann welche LEDs wieder gelöscht werden.

von Rainer V. (a_zip)


Lesenswert?

Falk B. schrieb:
> Das Problem saß und sitzt VOR der Tastatur . . . ;-)

Aber Hallo!!! Anfänger hin oder her, das ist "krankes" Denken.
Ein Ehepaar ist zusammen 49 Jahre alt. Er ist heute doppelt so alt, wie 
sie war, als er so alt war, wie sie heute ist. Wie alt sind beide?
Habe das immer mal wieder meinen Nachhilfeschülern aufgegeben. Mit 
durchaus erstaunlichen Ergebnissen!
Gruß Rainer

von Falk B. (falk)


Lesenswert?

Rainer V. schrieb:
> Aber Hallo!!! Anfänger hin oder her, das ist "krankes" Denken.

Nö, da fehlt es schlicht an einfacher Logik.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.