Hallo
sorry, komme nicht klar mit dem löschen von LED
Problem:
Habe 2 Matrix LEDs mit 8x8 LEds, werden von einem I2C IC angesteuert.
1. LED Matrix verwendet die Zeilen 00,02,04,06,08,0A,0C.0E
2. LED Matrix verwendet die Zeilen 01,03,05,07,09,0B,0D,0F
Ansteuern kann ich z.B. so:
1
voidHT16K33_Write(void)// LED anzeigen
2
{
3
i2c_start(HT16K33_modul1_addr<<1);
4
i2c_write(0x02);
5
{
6
i2c_write(0x0f);
7
}
8
i2c_stop();
9
}
Damit gebe ich die Zeile an und welche LED leuchten sollen.
Problem: Möchte eine Matrix komplett löschen.
Dazu kann ich die LED Angaben oder alle Zeile einer LED Matrix mit 0
überschreiben. z.B. so:
1
voidHT16K33_DisplayClear(void)// Display löschen alles mit 0 voll schreiben
2
{
3
for(uint8_ti=0;i<16;i++)
4
{
5
i2c_start(HT16K33_modul1_addr<<1);
6
i2c_write(i);// angabe Zeile
7
i2c_write(0x00);// Angabe LED
8
9
i=i+1;
10
}
11
}
Der Aufruf erfolgt damit
1
HT16K33_DisplayClear();
Was nicht klappt dabei. Ich darf nur jede zweite Zeile überschreiben.
Dazu habe ich eine for genommen, starte es bei 0, zähle hoch, lösche die
Zeile und erhöhe i noch mal um 1 damit beim nächsten Lauf um 2 Zeilen
erhöht wird.
Ich möchte auch auswählen, welche LEd Matrix löschen möchte.
Dazu könnte ich beim Aufruf die erste Zeile mit übergeben z.B so
1
HT16K33_DisplayClear(0x00)
2
oder
3
HT16K33_DisplayClear(0x01)
Das klappt garnicht.
Hat jemand eine Idee dazu?
achim
for(uint8_ti=start;i<16;i+=2)// Auswahl der Zeile jede 2.
5
{
6
i2c_start(modul1_addr<<1);// schreibt modul 1
7
i2c_write(i);// angabe Zeile
8
i2c_write(bild1[nr]);// anzeige array
9
nr=nr+1;// array nr um 1 erhöht
10
}
Damit wird das Bild aif der Matrix dargestellt. Die einzelnen Daten des
Arrays werden mit der {nr} aufgerufen.
Möchte das Bild zusätzlich von oben bzw unten einschieben. Dabei sollen
die einzelnen Zeilen über die Matrix "geschoben" werden. Das mit den nr
geht scheinbar nicht.
Hat jemand eine Idee dazu?
achim
Hallo Markus
das ganze besteht aus 2 LED Matrix mit 8x8. Die linke Matrix hat die
Zeilenaderessen 00,02,04 .. (alle geraden)
Die rechte Matrix hat die Zeilenadressen 01,03,05 ... (alle ungeraden)
Achim Seeger schrieb:> for (uint8_t i=start; i<16; i+=2) // Auswahl der Zeile jede 2.
Mit dieser Zeile nehme ich nur jede zweite Zeile in Anhängigkeit der
Startzeile (0 oder 1). Dadurch erscheint jeweils auf linken oder rechten
Matrix das gewünschte. Die jeweils andere Matrix bleibt sauber.
Anders beim "einschieben" des Bildes. Mit "einschieben" meine ich, das
das Bild von oben nach unten geschoben wird. Die dargestellten Zeilen
wandern langsam nach unten. Das klappt nicht und habe keinen Ansatz wie
das geht.
achim
Hallo Achim,
male Dir mal 8 Quadrate, jeweils 8 * 8 Kästchen beinhaltend, auf
Rechenpapier (Kästchenpapier), untereinader - mit jeweils etwas Abstand
zueinander.
Dann füllst Du Bild für Bild (Quadrat für Qaudrat) aus, wie dein
"Einschieben von oben" genau für jedes Bild der Einschiebe-Folge
aussehen soll.
Anschliessend sollte Dir klar sein, wie Du vorgehen musst.
Gruß
Dieter
Hallo Dieter
das habe ich schon gemacht. Beim ersten Versuch wandert auch was nach
unten. Die neuen Zeilen werden oben eingeschoben und wandert nach unten.
Solange bis das Bild voll ist bzw das gewünschte dargestellt wird.
Leider sind viele "Ausreisser" dabei und stellen auch was auf der
zweiten Matrix dar, die sauber bleiben sollte. Leider noch unklar warum.
Könnte an der Zeilenzahl (gerade/ungrade) liegen und dem beschreiben
dieser Zeilen. Auch die Art, wie ich es mache könnte zu vielen Fehlern
führen. Kann dir heute abend erst den Code zeigen. Vielleicht finde ich
noch eine andere Lösung
achim
achim schrieb:> Leider sind viele "Ausreisser" dabei und stellen auch was auf der> zweiten Matrix dar, die sauber bleiben sollte.
Wie sollen denn "Aussreiser" in die von Dir per Hand gemalten Bilder
kommen? Das verstehe ich nicht ... kannst Du mir das bitte erklären?
Ohne jetzt deinen Code genauer angeschaut zu haben:
Trenne mal deine Led-Matrix-Objekte sauber voneinander.
Wenn du 2 8*8 Matrizen hast dann stelle dies auch im Code so dar, und
versuche nicht eine "virtuelle" 16*8 Matrix draus zu machen.
Du merkst ja, an jeder Stelle Code an der du auf die Matrix zeichnen
willst musst du diese - etwas spezielle - Form der Datenorganisation
berücksichtigen.
Erstelle dir stattdessen für jede Matrix ein Objekt (darfst auch
Variable dazu sagen) und übergeb deiner Zeichen-Funktion einen Zeiger
drauf.
Dann ist es der Funktion auch egal wenn du in 2 Jahren mal eine 3. und
4. Matrix hinzufügst...
Hallo Dieter
das mit den Ausreissern kommt wahrscheinlich von den Zeilenadressen her.
Die erste Zeile liegt auf der erstem Matrix. Die zweite Teile ist auf
der zweiten Matrix. Jede Zeile sind 8 LED. Setze heute abend meinen
ersten Versuch rein. Ist nur eine erster Versuch. Das mit den zählen
scheint nicht zu klappen.
Habe zwei Bilder (LED) gemacht, die ich separat lade. Habe keinen
"virtuelle" Matrix gemacht. Das mit den Bildern klappt ohne Probleme,
allerdings ohne Bewegung.
achim
achim schrieb:> das mit den Ausreissern kommt wahrscheinlich von den Zeilenadressen her.
Hallo Achim,
wir schreiben aneinander vorbei.
Ich habe Dir vorgeschlagen, Dein Vorhaben erstmal AUF PAPIER
aufzuzeichnen.
Dann sollte Dir auch einfallen, wie Du das im Programm umsetzen kannst.
Gruß
Dieter
Hallo Dieter
glaube nicht, das wir an einander vorbeischreiben. Habe es zu Anfang
gemacht. Ein Blatt Papier, 8x8 Kästen drauf und habe die Zeilen
eingetragen und das Bild drüber laufen lassen, dann vergleichen mit dem
Programm und erster Versuch gestartet und das sieht so aus:
for(uint8_ti=start;i<16;i+=2)// Auswahl der Zeile jede 2.
4
{
5
i2c_start(HT16K33_modul1_addr<<1);// schreibt modul 1
6
7
i2c_write(i);// angabe Zeile
8
i2c_write(0x00);// anzeige array
9
i2c_write(i);
10
i2c_write(bild1[0]);// anzeige array
11
i2c_write(i);
12
i2c_write(bild1[1]);// anzeige array
13
i2c_write(i);
14
i2c_write(bild1[2]);// anzeige array
15
i2c_write(i);
16
i2c_write(bild1[3]);// anzeige array
17
i2c_write(i);
18
i2c_write(bild1[4]);// anzeige array
19
i2c_write(i);
20
i2c_write(bild1[5]);// anzeige array
21
i2c_write(i);
22
i2c_write(bild1[6]);// anzeige array
23
i2c_write(i);
24
i2c_write(bild1[7]);// anzeige array
25
_delay_ms(200);
26
}
27
}
Damit wird das Bild von oben her Zeile für Zeile eingeschoben und
wandert langsam nach unten. Wenn es vollständig ist bleibt es kurz
stehen. Leider wird auf der zweiten Matrix auch LED angesteuert. Da das
Bild vollständig und korrekt angezeigt wird, weiss ich nicht wieso.
achim
Achim Seeger schrieb:> Damit wird das Bild von oben her Zeile für Zeile eingeschoben und> wandert langsam nach unten.
Hallo Achim,
das glaube ich nicht. Mit dem Code werden in jeder Zeile - von oben
beginnend - einmal alle Zeilen-Codes unmittelbar nacheinander
ausgegeben. Zum Schluss steht in jeder Zeile 0x3C (lt. Deinem Beispiel).
Korrekt ist da erstmal nichts.
Wenn Du die 8 Quadrate mit jeweils 8*8 Kästchen gemalt hättest (und
jeden Schritt der Ausgabe in ein Quadrat) wäre Dir aufgefallen, dass Du
sozusagen 8 Bilder (mit 1 - 8 Zeilen) nacheinander auf die Matrix geben
musst. Mit dem gezeigten Code geht das ganz sicher nicht.
Gruß
Dieter
Hallo Dieter
habe dazu 8 Bilder gemalt mit dem Lauf nach unten, dann konnte ich sehen
in welchwer Zeile welches Teil des Bildes stehen muss. Habe dann an jede
zweite Zeile das Bild angehängt. Und dann kamen dieise Bilder dabei
raus. Habe schnelle in paar Fotos gemacht, sind nicht künstlerisch
Wertvoll, das wichtigeste ist zu erkennen.
achim
Hallo Achim,
dann bleibe ich bei meiner Aussage.
Du lässt eine Schleife über die Zeilen von (Start) 0 bis 16 mit
Schrittweite 2 laufen.
1
for(uint8_ti=start;i<16;i+=2)// Auswahl der Zeile jede 2.
Innerhalb der Schleife (über die 8 Zeilen) löscht Du die jeweilige Zeile
zunächst (das kannst Du Dir in diesem Fall sparen, da Du jede Zeile
sowieso 8 mal überschreibst).
1
i2c_write(i);// angabe Zeile
2
i2c_write(0x00);// anzeige array
und schreibst dann alle Werte aus Deiner Tabelle nacheinander in die
aktuelle Zeile und überschreibst damit den jeweils vorigen Wert. Nur der
letzte Wert der Tabelle bleibst in der Zeile stehen. Und zwar in JEDER
Zeile der gleiche Wert.
1
i2c_write(i);
2
i2c_write(bild1[0]);// anzeige array
3
...
4
i2c_write(i);
5
i2c_write(bild1[7]);// anzeige array
Am Ende der Schleife wartest Du jeweils 200 ms bis zur Ausgabe der
nächsten Zeile.
1
_delay_ms(200);
Am Ende steht in jeder Zeile der letzte Wert aus Deiner Tabelle. Die
Bilder haben damit nichts zu tun.
Gruß
Dieter
Wenn ich das richtig verstehe, ist das eine Erklärung zu dem Programm.
Ausführlicher als ich es könnte. Es wird aber etwas verschoben und
erscheint auf der rechten Matrix, wo eigentlich nichts sein sollte. Wenn
ich Teile des Programmes auskommentiere und langsamer laufen lasse, sind
es die Zahlen 0 (1) bis 8 in binär
achim
Achim Seeger schrieb:> i2c_start(HT16K33_modul1_addr<<1); // schreibt modul 1>> i2c_write(i); // angabe Zeile> i2c_write(0x00); // anzeige array> i2c_write(i);> i2c_write(bild1[0]); // anzeige array
Hallo Achim,
jetzt verstehe ich es langsam - habe mal ins Datenblatt geschaut. Deine
i2c_start-Funktion initialisiert das Modul.
Der nächste Wert "i2c_write(i);" definiert die Zeile, ab welcher
geschrieben wird. Ab da folgen bis zum nächsten "i2c_start" nur noch
Daten-Bytes.
D.h., das was Du weiter als Zeilennummer per "i2c_write(i);" übergibst
wird als Daten-Byte für die jeweils nächste Zeile (auf der 2.
LED-Matrix) übernommen etc.
Daher kommen die "Störungen". Du hast einen kontinuierlichen
Datenübergabe-Modus gewählt und das macht das Modul daraus.
In Deiner ursprünglichen Programm-Version hast Du nach jeder Zeile neu
initialisiert und die nächste Zeilennummer angegeben.
So gesehen reiner Zufall, dass Dein Code das gewünschte Bild erzeugt :-)
Gruß
Dieter
Auf dem Papier sah das so einfach aus
Dieter Frohnapfel schrieb:> D.h., das was Du weiter als Zeilennummer per "i2c_write(i);" übergibst> wird als Daten-Byte für die jeweils nächste Zeile (auf der 2.> LED-Matrix) übernommen etc.
Es werden aber nut die Werte bis 8 angezeigt, nehme aber die Nummern von
0 bis 16 - jede zweite
Dieter Frohnapfel schrieb:> In Deiner ursprünglichen Programm-Version hast Du nach jeder Zeile neu> initialisiert und die nächste Zeilennummer angegeben.
Stimmt, habe die Nr erhöht.
Mit i wird doch jede zweite Zeile angegeben. ???
Scheint Zufall zu sein. Ist ja mein erster Versuch dabei. Wie geht man
bei so was ran?
Hmm, das Problem haben damals per Email gelöst. Hier das Ergebnis.
Achtung, hier wird die 7 Bit I2C Adresse verwendet!
HT16K33_i2c_adr = 0x70; // 0x70-0x77
Die Bitmusterverdrehung mit dem flip[] Array ist nötig wegen der
Verdrahtung von Achims Board.
https://www.mikrocontroller.net/articles/Modulares_Board#Der_HT_16_K_33