--- title: Matrix Erklärung --- Hallo zusammen, ich habe mal euer Programm umgehend getestet und habe ziemlich wahrscheinlich den Grund gefunden weshalb die erste led leuchtet. Den Grund habe ich gestern schonmal versucht Jonas zu erklären aber ich versuche es hier nochmal in schriftlicher form. Um es besser zu verstehen, habe ich euer Programm ein bisschen angepasst, um die Matrix virtuell testen zu können, ohne dass man eine Matrix benötigt. Letzendlich wird durch meine Änderungen die Matrix in der Konsole ausgegeben. Hier einmal mein angepasstes Programm und die resultierende Konsolenausgabe: matrix_test.c: ```c= #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <asm/types.h> void led_clear(int first, int second, int third); void led_set_pixels(int leds[64], int r, int g, int b); int main(void) { struct timespec delay; delay.tv_sec = 0; delay.tv_nsec = 50 * 1000 * 1000; int led[64]; int Jahr; int Mon; int Tag; int Std; int Min; int Sek; while (1) { led_clear(0, 0, 0); time_t aktuell; time( &aktuell); struct tm *Zeit; Zeit = localtime( &aktuell); Jahr = Zeit -> tm_year - 100; Mon = Zeit -> tm_mon + 1; Tag = Zeit -> tm_mday; Std = Zeit -> tm_hour; Min = Zeit -> tm_min; Sek = Zeit -> tm_sec; for (int i = 7; i > 0; i--) { led[i] = Jahr % 2; Jahr = Jahr / 2; } for (int i = 7; i > 0; i--) { led[i + 8] = Mon % 2; Mon = Mon / 2; } for (int i = 7; i > 0; i--) { led[i + 16] = Tag % 2; Tag = Tag / 2; } for (int i = 7; i > 0; i--) { led[i + 24] = 0; } for (int i = 7; i > 0; i--) { led[i + 32] = Std % 2; Std = Std / 2; } for (int i = 7; i > 0; i--) { led[i + 40] = Min % 2; Min = Min / 2; } for (int i = 7; i > 0; i--) { led[i + 48] = Sek % 2; Sek = Sek / 2; } for (int i = 7; i > 0; i--) { led[i + 56] = 0; } led_set_pixels(led, 0, 0, 128); nanosleep( & delay, NULL); } } void led_clear(int first, int second, int third){ printf("led_clear %d,%d,%d\n", first,second,third); } void led_set_pixels(int leds[64], int r, int g, int b){ printf("led_set_pixels, r: %d, g: %d, b: %d\n",r,g,b); for(int i = 0; i < 8; i++){ printf("%d: ",i+1); for(int j = 0; j < 8; j++){ printf("%d ", leds[i*8+j]); } printf("\n"); } } ``` matrix_test.out.txt: ```shell= led_clear 0,0,0 led_set_pixels, r: 0, g: 0, b: 128 1: 545724208 0 0 1 0 1 0 1 2: 0 0 0 0 1 0 1 1 3: 0 0 0 1 1 1 0 1 4: -20424960 0 0 0 0 0 0 0 5: 0 0 0 0 1 0 0 1 6: -20073880 0 0 1 0 1 0 0 7: 0 0 1 0 0 0 1 1 8: 0 0 0 0 0 0 0 0 ``` Wie ihr seht ist euer Programmcode unverändert und ich habe nur die Funktionen selbst geschrieben, welche von der Bibliothek für die Matrix hinzugefügt wurden. In der Ausgabe seht ihr, dass der Aufruf von led_clear noch super funktioniert, aber der Aufruf von led_set_pixels gibt ein paar Probleme. Wie ihr seht stehen komische Werte an 3 Stellen: (0,0), (0,3) und (0,5). Dort stehen sehr hohe oder sehr niedrige Werte. Durch euren Code könnten solche hohen Werte nicht entstehen. Um zu verstehen wieso diese Werte dort drin stehen, benötigt man ein bisschen Hintergrundwissen zu c (hierbei ist es egal ob c oder c++). Wenn man, wie ihr es in Zeile 18 tut, ein Array erstellt, reserviert c genug Platz im Arbeitsspeicher um die Werte zu Speichern. Was c dabei nicht tut ist diese Werte zu überschreiben, das bedeutet also, dass im Array jetzt die Werte an den unterschiedlichen stellen stehen, welche vorher an diesen Stellen im Arbeitsspeicher standen. Wenn ihr also manuell diese Werte nicht überschreibt, dann bleiben sie dort drin stehen, und ihr übergebt diese Werte mit in led_set_pixels was dafür sorgt, dass falsche Leds leuchten. Der letzendliche fehler findet man in euern For-Loops Zum Beispiel diese: ```c for (int i = 7; i > 0; i--) { led[i + 24] = 0; } ``` Ihr startet mit dem Wert `i=7`, dann prüft ihr ob i größer als 0 ist, anschließend wird der Wert an der stelle `i+24` auf 0 gesetzt. Wenn dass alles abgeschlossen ist, wird i um einen Wert veringert. Nun wird wieder getestet ob i größer null ist. Da i den Wert 6 hat stimmt das immer noch. Überspringen wir ein paar Schleifendurchläufe bis `i = 1` ist. Nun wird der Wert an der Stelle `24+1` im led array auf 0 gesetzt. Anschließend wird i um einen Wert veringert. Die anschließende Prüfung, ob i größer als null ist schlägt nun aber fehl und der Schleifenkörper wird nicht noch einmal ausgeführt. Und das ist exact der knackpunkt. Dadurch das der Schleifenkörper nie mit `i=0` durchlaufen wird, wird der Wert an der Stelle 24 im led array nie überschrieben und der vorherige Wert aus dem Speicher bleicht an Stelle 24 bestehen. Zum Glück lässt sich dieser Fehler leicht beheben, man muss einfach in jeder For-Schleife aus `i>0` `i>=0` machen. Nun wird der Schleifenkörper auch mit `i=0` durchlaufen, und alle Stellen im Array werden überschrieben. (P.S. es kann natürlich auch sein, dass vorher im Speicher eine Null an manchen stellen im Array steht, deswegen haben wir nur 3 unerklärliche stellen in unserem Array) Mit der Fehlerbehebung sieht das obige Programm nun wie folgt aus und hat folgende Konsolenausgabe: matrix_test_fixed.c ```c= #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <asm/types.h> void led_clear(int first, int second, int third); void led_set_pixels(int leds[64], int r, int g, int b); int main(void) { struct timespec delay; delay.tv_sec = 2; delay.tv_nsec = 50 * 1000 * 1000; int led[64]; int Jahr; int Mon; int Tag; int Std; int Min; int Sek; while (1) { led_clear(0, 0, 0); time_t aktuell; time( &aktuell); struct tm *Zeit; Zeit = localtime( &aktuell); Jahr = Zeit -> tm_year - 100; Mon = Zeit -> tm_mon + 1; Tag = Zeit -> tm_mday; Std = Zeit -> tm_hour; Min = Zeit -> tm_min; Sek = Zeit -> tm_sec; for (int i = 7; i >= 0; i--) { led[i] = Jahr % 2; Jahr = Jahr / 2; } for (int i = 7; i >= 0; i--) { led[i + 8] = Mon % 2; Mon = Mon / 2; } for (int i = 7; i >= 0; i--) { led[i + 16] = Tag % 2; Tag = Tag / 2; } for (int i = 7; i >= 0; i--) { led[i + 24] = 0; } for (int i = 7; i >= 0; i--) { led[i + 32] = Std % 2; Std = Std / 2; } for (int i = 7; i >= 0; i--) { led[i + 40] = Min % 2; Min = Min / 2; } for (int i = 7; i >= 0; i--) { led[i + 48] = Sek % 2; Sek = Sek / 2; } for (int i = 7; i >= 0; i--) { led[i + 56] = 0; } led_set_pixels(led, 0, 0, 128); nanosleep( &delay, NULL); } } void led_clear(int first, int second, int third){ printf("led_clear %d,%d,%d\n", first,second,third); } void led_set_pixels(int leds[64], int r, int g, int b){ printf("led_set_pixels, r: %d, g: %d, b: %d\n",r,g,b); for(int i = 0; i < 8; i++){ printf("%d: ",i+1); for(int j = 0; j < 8; j++){ printf("%d ", leds[i*8+j]); } printf("\n"); } } ``` matrix_test_fixed.out.txt: ```shell= led_clear 0,0,0 led_set_pixels, r: 0, g: 0, b: 128 1: 0 0 0 1 0 1 0 1 2: 0 0 0 0 1 0 1 1 3: 0 0 0 1 1 1 0 1 4: 0 0 0 0 0 0 0 0 5: 0 0 0 0 1 0 0 1 6: 0 0 0 1 1 0 0 1 7: 0 0 1 1 1 0 1 1 8: 0 0 0 0 0 0 0 0 ```