Attiny85+ HT16K33 8x8 LED-Matrix Array Problem

Hallo Leute,

ich habe ein Problem und komme absolut nicht weiter.
Ich experimentiere gerade mit einem Attiny85 auf 1Mhz und einer 8x8 LED Matrix mit HT16K33 Treiber
Für die I2C Kommunikation benutze ich die TinyWireM Bibliothek. Das scheint bis jetzt auch alles zu funktionierten. Da ich demnächst noch was mit OLEDs vorhabe und ich was lernen möchte, benutze ich keine Bibliothek für den HT16K33. Punkte und Bildchen kann ich so anzeigen lassen wie ich möchte. Mit der Ansteuerung der Matrix komme ich soweit klar.

Jetzt hab ich mich daran gemacht ein Snake-Spiel zu programmieren. Für den Anfang wollte ich erstmal nur eine 3 Punkte lange Schlange haben, die ich über das Feld bewegen kann.

Die Idee war, ein Array zu erzeugen, welches das Spielfeld darstellt. Bei einer 0 leuchtet nichts, alles was größer ist gehört zur Schlange. Die größte Zahl (hier 3) ist der Kopf. Bei jedem Durchlauf wird auf der neuen Koordinate des Schlangenkopfes eine 3 eingefügt, die Daten für das Display berechnet, alles was größer ist als 0 wird im Array um 1 vermindert und dann werden die Daten an das Display gesendet.

Primär geht es um die 2 Schleifen wo genau das passiert. Verwende ich diese Schleifen nicht und will nur einen Punkt auf meiner Matrix bewegen, funktioniert alles Tadellos.

Sobald ich die Schleifen verwende, bekomme ich mehrere Fehler:

  • Das kontinuierliche erhöhen/verringern der x/y Koordinaten funktioniert nicht mehr oder nur in 1/2 Richtungen (die Schlange bewegt sich nach der ersten Analogstick Eingabe nicht mehr von selbst und man muss den Stick gedrückt halten)
    -es tauchen 2 Punkte willkürlich auf dem Display auf, die dort nichts zu suchen haben
    -je nach dem welche Richtung am analogstick gewählt ist tauchen 1-2 extra Punkte auf der Matrix auf
    -in der obersten zeile werden 2/3 Punkte nicht angezeigt wenn die Schlange an der Position ist
  • am rechten Rand wird die Schlange um eine Zeile nach oben verschoben und am Linken Rand taucht sie dann eine Zeile weiter unten auf um sich dann wieder auf die korrekte Zeile zu verschieben

Das Fehlerbild kann ich mir absolut nicht erklären. Ich hab schon an mehrfach verwendete Variablen gedacht, konnte aber nichts finden. Der RAM kann eigentlich auch nicht voll sein...laut Kompiler verwende ich 181Byte. Flash sollte auch passen da ist er bei 22%

Programmiert ist der Tiny über einen Uno als ISP.

Hier mein Code:

#include <TinyWireM.h>

 
const int  zeile[]{0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E};    //I2C Befehl für Zeilenauswahl
const int spalte[]{0x80,0x01,0x02,0x04,0x08,0x10,0x20,0x40};    //I2C Hexzahl für einzelne Punkte (sind verschoben)


int einx = A3;                                                 //analog Stick
int einy = A2;
int Posx=0;
int Posy=0;
int x=3;                                                       
int y=4;
int zahl[7];                                                  //zeilenweise aufaddierte Hexzahl für alle Punkte einer Zeile
int laenge=3;                                                 //noch nicht verwendet
int feld[7][7];                                               //Spielfeld-Array

void LEDtest(){                                               //funktioniert

  for (int i = 0; i<8; i++)
  {   Display(zeile[i-1],0x00);
      for(int j = 0; j<8; j++)
      {
          Display(zeile[i],spalte[j]);
          delay(10);
      }
  }
  for (int i = 0; i<8; i++){Display(zeile[i],0x00);}
}






void Display(int row,int com)                                 //funktioniert
{
  TinyWireM.beginTransmission(0x70);
  TinyWireM.send(row);
  TinyWireM.send(com);
  TinyWireM.endTransmission();
}




void LEDinit()                                                //funktioniert
{ 
  TinyWireM.beginTransmission(0x70);
  TinyWireM.send(0x21);              //internal Oscilator on
  TinyWireM.endTransmission();
 
  TinyWireM.beginTransmission(0x70);
  TinyWireM.send(0xA0);            //row/int setup
  TinyWireM.endTransmission();

  TinyWireM.beginTransmission(0x70);
  TinyWireM.send(0xEF);            //dimming setup
  TinyWireM.endTransmission();

  for (int i = 0; i<8; i++){Display(zeile[i],0x00);}

  TinyWireM.beginTransmission(0x70);
  TinyWireM.send(0x81);            //blinking/ on
  TinyWireM.endTransmission();
}


void buildArray()                                            //funktioniert 
{
  for (int i = 0; i<8; i++){
    for (int j = 0;j<8;j++){ feld[i][j]=0;}
  }
  feld[4][3]=3;
  feld[4][4]=2;
  feld[4][5]=1;
}
 
void setup()                                                //funktioniert
{
  pinMode(einx, INPUT);
  pinMode(einy, INPUT);

  TinyWireM.begin();
  LEDinit();
  LEDtest();
  buildArray();
}


void beweg()
{
  if (analogRead(einx) < 292) {Posx=5;Posy=0;}                //analog Stick auslesen
  if (analogRead (einx) > 729) {Posx=1;Posy=0;}
  if (analogRead(einy) < 292) {Posy=1;Posx=0;}
  if (analogRead (einy) > 729) {Posy=5;Posx=0;}

  if (Posx==5){x--;}
  if (Posx==1){x++;}
  if (Posy==1){y++;}
  if (Posy==5){y--;}

  if (y>7){y=0;}                                              //Grenzen der 8x8 Matrix beachten
  if (y<0){y=7;}

  if (x>7){x=0;}
  if (x<0){x=7;}

  feld[y][x]=3;                                               //derzeitige Position im Feld mit 3 besetzten

  for (int i=0;i<8;i++)                                       //jede Position in feld[][] auf werte > 0 prüfen und den entsprechenden Hex-Wert aus spalte[] auf zahl[] aufaddieren
  {
    zahl[i]=0;
    for(int j=0;j<8;j++)
    {      
      if (feld[i][j] >0)
      {
        zahl[i]=zahl[i]+spalte[j];
        feld[i][j]=feld[i][j]-1;                              //jede position im feld um 1 verringern
      }
    }
    Display(zeile[i],zahl[i]);                                //alle 8 zeilen anzeigen
  }
  delay(250);
  }

  
void loop() 
{
  beweg();

//Display(zeile[7],(spalte[7]+spalte[6]));
}

Hab den Code auch schon auf nem anderen Tiny getestet (8Mhz...selbe Fehler nur schneller ^^)
Ich hoffe ihr könnt mir helfen.

Solltest du nicht besser
byte feld[8][8]; definieren ???

7 ist zu klein und int ist zu groß...

Tatsächlich...hab mir grade Arrays nochmal angeschaut...müsste wirklich überall [8] sein. Dachte weil die von 0..7 gehen müsste ich auch [7] verwenden. Das ist n guter Punkt. Werde ich nachher mal ausprobieren. Ja Byte müsste überall reichen.. aber iwie hab ich das so drin ^^' werde ich evtl. noch ändern. Danke dir :slight_smile: mal sehen ob es das war :slight_smile:

byte feld[8][8]

ist ebenfalls viel zu groß für diese zwecke.

wenn er nur ein 8x8 feld hat wo es nur pixel an/aus gibt

reicht auch

byte feld[8]

ein byte besteht aus 8 bit
damit hat man schon eine zeile mit 8 pixeln

ist dann aber auch etwas aufwändiger zu programmieren

dafür das speicherschonenste

Im Prinzip richtig. Ich will aber keine Binärzahlen in 8x8 abspeichern, sondern Zahlen von 1-x also brauch ich ja doch n 8x8 Array, in welches ich dann meine Byte oder int Werte ablege oder?
Außerdem ist der Speicherverbrauch denke ich nicht das Problem.

wenn er nur ein 8x8 feld hat wo es nur pixel an/aus gibt

Er wollte den Kopf der Schlange mit feld [ i ][ j ] = 3; markieren...

Warum auch immer... Soll der besonders hell leuchten?
Aber speichersparend ist immer gut

DAs mit der 3 mach ich wegen der Bewegung. Weil die Schlange sich im Array bewegen muss, wird sie so ins Array gesetzt: 1,2,3 -> wird gezeichnet.. dann wird 1 abgezogen: 0,1,2 und die 3 auf die neue Position gesetzt: 0,1,2,3 -> die Schlange hat sich jetzt nach rechts bewegt. Funktioniert übrigens alles wie es soll.

Falls das hier noch jemand ließt:

Experimentiere auch gerade mit nem OLED Display 128x32 i2c und hab meine eigene Schriftart gebastelt...die ist recht groß, da pro zeichen 19x32 Pixel groß. Wenn ich die Zeichen als static const int deklariere und mit PROGMEM in den Flash schreibe, zeigt mit der Compiler an, das er nur 1240 Byte Flash und 29 Byte RAM benutzt. Bei 18 Zeichen müssten das doch schon 1368 Byte allein für die Zeichen sein oder?

Nvm ich glaube es passt jetzt