LED Steckboard - Rahmen aufleuchten lassen

melanie17

Mitglied
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
 
Zuletzt bearbeitet:

Jw456

Top Contributor
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

Top Contributor
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:

Java:
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);
}

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

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

melanie17

Mitglied
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:
Java:
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:
Java:
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

Top Contributor
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:
Java:
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

Mitglied
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:
Java:
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:
Java:
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

Top Contributor
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

Mitglied
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:
Java:
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
}
okay, danke! Hat super geklappt!
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

Top Contributor
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:
Code:
  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:
Code:
  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:

Java:
y = i / n
x = i % n

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

Java:
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?
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben