Forum: Compiler & IDEs Problem mir GCC - löschen von LED


von Achim S. (achims)


Lesenswert?

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
void HT16K33_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
void HT16K33_DisplayClear(void)    // Display löschen alles mit 0 voll schreiben
2
  {
3
  for (uint8_t i=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

von nureingast (Gast)


Lesenswert?

void HT16K33_DisplayClear(uint8_t start)

for (uint8_t i=start; i<16; i+=2)

von Achim S. (achims)


Lesenswert?

Fehler erkannt, danke für deine Hilfe
achim

von nureingast (Gast)


Lesenswert?

Sehr schön.
Viel Erfolg .

von Achim S. (achims)


Lesenswert?

Sorry, habe noch ein Problem. Das Problem von oben geht ohne Probleme. 
Hab es so gemacht:
1
int bild1 [8] = {0x3c, 0x42, 0xa5, 0x81, 0xa5, 0x99, 0x42, 0x3c};  // Bild 1
damit wird das Bild1 festgelegt
1
void HT16K33_WriteBild1(uint8_t start)// schreibt bild1
2
  {
3
    int8_t nr = 0;            // array nr auf 0
4
    for (uint8_t i=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

von Markus F. (mfro)


Lesenswert?

oben initialiserst Du das Array mit 8 (int) Elementen, unten iterierst 
Du aber über 16. Klar, daß mindestens in der 2. Hälfte Quatsch 
drinsteht, oder?

von achim (Gast)


Lesenswert?

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

von achim (Gast)


Lesenswert?

Sorry, vergessen, AT1284p, 16M, alles in C, HT16K33 und I2C Bus

von Martin (Gast)


Lesenswert?

Gibt es keinen Debugger für den Atmel?

von Dieter F. (Gast)


Lesenswert?

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

von Markus F. (mfro)


Lesenswert?

achim schrieb:
> Hallo Markus


Vergiß' was ich geschrieben habe, das war Quatsch, sorry. Hatte noch 
keinen Kaffee...

von achim (Gast)


Lesenswert?

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

von Dieter F. (Gast)


Lesenswert?

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?

von Franz (Gast)


Lesenswert?

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...

von achim (Gast)


Lesenswert?

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

von reimay (Gast)


Lesenswert?

int bild1 [8]

wieso int ?

von Dieter F. (Gast)


Lesenswert?

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

von Achim S. (achims)


Lesenswert?

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:
1
void HT16K33_WriteBild1Lauf(uint8_t start)  // schreibt bild1
2
  { 
3
  for (uint8_t i=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

von Dieter F. (Gast)


Lesenswert?

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

von Achim S. (achims)



Lesenswert?

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

von Achim S. (achims)


Lesenswert?

Sorry, vergessen.
Auf der rechten Matrix sind die "Störungen" zu sehen. Das Bild habe ich 
mit diesem Stück Code gemacht.

von Dieter F. (Gast)


Lesenswert?

Hallo Achim,

ich sehe gerade erst, dass Du
1
void HT16K33_WriteBild1Lauf(uint8_t start)  // schreibt bild1

mit dem Parameter "start" aufrufst. Wo und wie machst Du das denn? 
Vermutlich innerhalb einer weiteren Schleife - oder?

Gruß
Dieter

von Achim S. (achims)


Lesenswert?

Nein, das kommt aus dem Hauptprg:
1
 HT16K33_WriteBild1Lauf(0);      // Angabe schreiben mit adresse

von Dieter F. (Gast)


Lesenswert?

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_t i=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

von Achim S. (achims)


Lesenswert?

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

von Dieter F. (Gast)


Lesenswert?

Hallo Achim,

Du kennst meine eMail-Adresse - sende mir bitte das komplette Programm 
per eMail ...

Gruß
Dieter

von Dieter F. (Gast)


Lesenswert?

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

von Achim S. (achims)


Lesenswert?

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?

von Dieter F. (Gast)


Lesenswert?

Achim Seeger schrieb:
> Es werden aber nut die Werte bis 8 angezeigt,

Nein, in Bild P4272400__640_x_480_.jpg wird 12 angezeigt (_XX___) ...

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
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.