# LED Steckboard - Rahmen aufleuchten lassen



## melanie17 (5. Nov 2021)

Hallo,
ich hoffe Ihr könnt mir helfen!

Bin schon seit einiger Zeit am Recherchieren und ausprobieren..
Ich versuche mittels Java auf einem LED Steckboard (mit 256 LEDs also 16 Zeilen und 16 Spalten), die LEDs die sich am Rande des Steckboards befinden anzuschalten, damit ein Rahmen leuchtet.
Kann man definieren, dass die erste und letzte Spalte sowie die erste und letzte Zeile aufleuchtet? Oder wie kann ich das machen?

Zuvor habe ich versucht, eine beliebige Dezimalzahl in eine Binärzahl umzuwandeln und anschliessend so viele LEDs dem Steckboard hinzuzufügen, wie die Zahl "Zeichen" hat bzw. lang ist. Dabei habe ich es so programmiert, das diejenigen LEDs eingeschalten werden, die eine 1 haben.
Der Code sah wie folgt aus:

[CODE lang="java" title="Binärzahl"]private static void showBinary(){
        LedService service = new LedService();
        Scanner scanner = new Scanner(System.in);
        System.out.println("Geben Sie eine positive Dezimalzahl ein:");

        int zahl = scanner.nextInt();
        int anzahlStellen = 0;
        int zahlZwei = zahl;


        while (zahlZwei != 0){
            zahlZwei = zahlZwei / 2;
            anzahlStellen++;
        }

        int zahlen[] = new int [anzahlStellen];


        for (int i = 0; i < anzahlStellen; i++){
                        zahlen_ = zahl % 2;  im Array
                        zahl = zahl / 2;
        }

                for(int i = anzahlStellen - 1; i >= 0; i--){
                    System.out.print(zahlen);
                }
                System.out.println("\n" + anzahlStellen);
                    for (int i = 0; i < anzahlStellen; i++) {
                    if (zahlen == 1) {
                        service.turnLedOn(i);
                    }

                }
    }[/CODE]

Doch um einen Rahmen aufleuchten zu lassen bin ich ein wenig planlos! Wenn ich jedes einzelne LED einzeln anschalten muss, habe ich ja einen ewig langen Code... Könnt Ihr mir helfen? Wie würdet Ihr ansetzen?

Vielen Dank für die Hilfe.

Grüsse
Melanie_


----------



## mihe7 (6. Nov 2021)

melanie17 hat gesagt.:


> Wie würdet Ihr ansetzen?


Es sind ja nicht irgendwelche LEDs, also würden sich doch Schleifen anbieten, oder?


----------



## melanie17 (6. Nov 2021)

mihe7 hat gesagt.:


> Es sind ja nicht irgendwelche LEDs, also würden sich doch Schleifen anbieten, oder?


Danke für die schnelle Antwort.

Das habe ich zuerst auch gedacht, habe es aber zuerst mit If versucht.. 
Könnte es demfall mit der Do-While-Schleife funktionieren? Oder welche Schleifen-Art würdest du verwenden?


----------



## Jw456 (6. Nov 2021)

Wie werden den die 256 LED angesprochen angesteuert?
Scheinbar schaltest du sie mit diesen Befehl
service.turnLedOn(i);
Ist das so?
Somit werden wohl die LED in Reihe serial angesprochen.
1 ist dann wohl die oben links.
17 die erste in der zweiten Zeile usw.

Für einen Ramen würde das heißen.
LED 1 bis 16 on
LED  240 bis 256 on

Dann eine Schleife die bis 14 zählt
Immer die erste und letzte einer Zeile einschaltet.
17  + 16 +1 +16+1........


----------



## mihe7 (6. Nov 2021)

melanie17 hat gesagt.:


> Könnte es demfall mit der Do-While-Schleife funktionieren? Oder welche Schleifen-Art würdest du verwenden?


Für die Funktion spielt es gar keine Rolle, welche Art von Schleife. Wenn Du zählst, bietet sich eine Zählschleife (for) an. Man kann aber auch mit einem while arbeiten. In den folgenden Beispielen würde ich die for-Schleife bevorzugen:


```
int start = 10;
int breite = 10;
for (int i = 0; i < breite; i++) {
    int led = start + i;
    System.out.printf("service.turnLedOn(%d)%n", led);
}
```


```
int start = 10;
int ende = 20;
int led = start;
while (led < ende) {
    System.out.printf("service.turnLedOn(%d)%n", led);
    led++;
}
```


```
int start = 10;
int ende = 20;
for (int led = start; led < ende; led++) {
    System.out.printf("service.turnLedOn(%d)%n", led);
}
```


----------



## melanie17 (6. Nov 2021)

Ich habe nun versucht die Aufgabe in verschachtelte Schleifen zu packen. Dabei sollten in der äusseren Schleife über die Zeilen (rows) iteriert werden, während die innere Schleife über die Spalten (columns) iteriert werden sollten.
Habe es zuerst nach der Antwort von @mihe7 versucht, jedoch sieht der Code nicht so toll aus, wenn ich dies so mache:

```
for(int led = start; led < ende; led++) {
            service.turnLedOn(led);
        }
        for(int led = start2; led < ende2; led++) {
            service.turnLedOn(led);
        }
        for(int led = start; led < start2; led +=16) {
            service.turnLedOn(led);
        }
        for(int led = ende; led < ende2; led +=16) {
            service.turnLedOn(led);
        }
```
Meine Lösung sieht wie folgt aus:

```
LedService service = new LedService();
    service.addLeds(LedService.MAX_NUMBER_OF_LEDS);
    int start = 0;
    int ende = 15;
    
    service.stopExecutionFor(2000);       

    for(int rows = 0; rows < LedService.MAX_ROWS; rows++) {
        int x = rows*16;
        if(rows == 0) {
            for(int i = 0; i < 16; i++) {
                service.turnLedOn(i);
            }
        }else if(rows == 15) {
            for(int i = 240; i < 256; i++) {
                System.out.println("row 15");
                service.turnLedOn(i);
            }
        }else {
            for(int i = 0; i < 16; i++) {
                if(i == start+x || i == ende+x) {
                service.turnLedOn(i);
            }
    }
}
    service.stopExecutionFor(5000);
    
    for(int led = 0; led < LedService.MAX_NUMBER_OF_LEDS; led++) {
        service.turnLedOff(led);
        }
    
    service.stopExecutionFor(2000);       
    
    service.reset();
    }
}
```
Hoffe Ihr könnt mir ein Feedback geben, ob die Lösung so stimmt oder wo der Fehler liegt. Denn bei der Ausgabe auf dem Steckboard erscheinen nur die Rahmen oben, unten und rechts.


----------



## mihe7 (6. Nov 2021)

melanie17 hat gesagt.:


> Habe es zuerst nach der Antwort von @mihe7 versucht, jedoch sieht der Code nicht so toll aus, wenn ich dies so mache:


Ja, das war auch nicht als Lösung gedacht, sondern sollte nur verschiedene Möglichkeiten der Schleifen zeigen.

Wenn ich es richtig sehe, dann hast Du LEDs in einer 16x16-Matrix, die von links oben nach rechts unten durchnummeriert sind.

D. h. je Richtung gibt es 16 LEDs, die Du am Rand einschalten möchtest. Wenn man eine LED auch doppelt anschalten darf (wovon ich mal ausgehe), reicht also:

```
for (int i = 0; i < 16; i++) {
    service.turnLedOn(i); // (i+1)-te LED der ersten Reihe
    service.turnLedOn(240 + i); // (i+1)-te LED der letzten Reihe
    service.turnLedOn(i * 16);  // erste Spalte der (i+1)-ten Reihe
    service.turnLedOn(i * 16 + 15); // letzte Spalte der (i+1)-ten Reihe
}
```


----------



## melanie17 (6. Nov 2021)

Ich habe nun versucht die Aufgabe in verschachtelte Schleifen zu packen. Dabei sollten in der äusseren Schleife über die Zeilen (rows) iteriert werden, während die innere Schleife über die Spalten (columns) iteriert werden sollten.
Habe es zuerst nach der Antwort von @mihe7 versucht, jedoch sieht der Code nicht so toll aus, wenn ich dies so mache:

```
for(int led = start; led < ende; led++) {
            service.turnLedOn(led);
        }
        for(int led = start2; led < ende2; led++) {
            service.turnLedOn(led);
        }
        for(int led = start; led < start2; led +=16) {
            service.turnLedOn(led);
        }
        for(int led = ende; led < ende2; led +=16) {
            service.turnLedOn(led);
        }
```
Meine Lösung sieht wie folgt aus:

```
LedService service = new LedService();
    service.addLeds(LedService.MAX_NUMBER_OF_LEDS);
    int start = 0;
    int ende = 15;
    
    service.stopExecutionFor(2000);       

    for(int rows = 0; rows < LedService.MAX_ROWS; rows++) {
        int x = rows*16;
        if(rows == 0) {
            for(int i = 0; i < 16; i++) {
                service.turnLedOn(i);
            }
        }else if(rows == 15) {
            for(int i = 240; i < 256; i++) {
                System.out.println("row 15");
                service.turnLedOn(i);
            }
        }else {
            for(int i = 0; i < 16; i++) {
                if(i == start+x || i == ende+x) {
                service.turnLedOn(i);
            }
    }
}
    service.stopExecutionFor(5000);
    
    for(int led = 0; led < LedService.MAX_NUMBER_OF_LEDS; led++) {
        service.turnLedOff(led);
        }
    
    service.stopExecutionFor(2000);       
    
    service.reset();
    }
}
```
Hoffe Ihr könnt mir ein Feedback geben, ob die Lösung so stimmt oder wo der Fehler liegt. Denn bei der Ausgabe auf dem Steckboard erscheinen nur die Rahmen oben, unten und rechts.


----------



## mihe7 (6. Nov 2021)

Wird das bei mir nur falsch angezeigt (das Forum spinnt bei mir momentan), oder ist Dein Kommentar #8 der gleiche wie Kommentar #6? Hast Du Kommentar #7 gesehen?


----------



## melanie17 (6. Nov 2021)

mihe7 hat gesagt.:


> Ja, das war auch nicht als Lösung gedacht, sondern sollte nur verschiedene Möglichkeiten der Schleifen zeigen.
> 
> Wenn ich es richtig sehe, dann hast Du LEDs in einer 16x16-Matrix, die von links oben nach rechts unten durchnummeriert sind.
> 
> ...


okay, danke! Hat super geklappt!


mihe7 hat gesagt.:


> Wird das bei mir nur falsch angezeigt (das Forum spinnt bei mir momentan), oder ist Dein Kommentar #8 der gleiche wie Kommentar #6? Hast Du Kommentar #7 gesehen?


Nein bei mir spinnt das Forum eben auch, es hat meine Antwort einfach mehrmals gepostet.. Habe deine Antwort gesehen, danke viel Mal


----------



## mihe7 (6. Nov 2021)

melanie17 hat gesagt.:


> Nein bei mir spinnt das Forum eben auch, es hat meine Antwort einfach mehrmals gepostet..


Ah, gut zu wissen.

Wichtig dabei ist nicht Code, sondern das Konzept dahinter. Das taucht nämlich immer wieder mal in gleicher oder ähnlicher Form auf.

Die Idee ist, dass man eine zweidimensionale m x n-Matrix wie folgt durchnumerieren kann:

```
0n     0n+1     0n+2   ...   0n+n-1
  1n     1n+1     1n+2   ...   1n+n-1
  2n     2n+1     2n+2   ...   2n+n-1
  ...    ...      ...    ...    ...
(m-1)n (m-1)n+1 (m-1)n+2 ... (m-1)n+n-1
```
D. h. der Index berechnet sich einfach aus zeilenIndex*n + spaltenIndex, wobei n die Anzahl der Spalten ist.

Beispiel anhand einer 3x4-Matrix:

```
0  1  2  3
  4  5  6  7
  8  9 10 11
```

Hier ist n=4, m=3. Anzahl der Elemente ist m*n und das Element bei (x,y) hat den Index y*n+x. Beispiel (2,2) = 2*4+2 = 10, (0,2) = 0*4+2 = 2, (1,2) = 1*4+2 = 6.


Umgekehrt kann man auch die Koordinate anhand des Index berechnen: die ganzzahlige Division durch die Spaltenanzahl n liefert den Zeilenindex, der ganzzahlige Rest den Spaltenindex:


```
y = i / n
x = i % n
```

Auf diese Weise kann man ein rechteckiges, zweidimensionales Array mit einer einzigen Schleife durchlaufen:


```
int m = 3;
int n = 4;
int[][] arr = new int[m][n];
...
for (int i = 0; i < m*n; i++) {
    int y = i / n;
    int x = i % n;
    System.out.println(arr[y][x]);
}
```

Alles klar?


----------

