gescheitert - Dot-Matrix-Display an MAX7219, verschiedene Helligkeiten

Hi

2.ter Versuch . ich sollte langsam lernen, daß man dem Forum NICHT trauen kann - STRG+A & STRG + V sollten bei keinem Post fehlen ... man wird halt weich, wenn's wieder ein paar Mal geklappt hat ... grmpfl
Ne ... oder??? DAS war nur der 'Du bist kein Roboter'-Scheiß??
Schreikrampf unterdrück

Edit
Vorweg: Es klappt (so) nicht! Also der Sketch hier im Eröffnungs-Post.
Einzelne Punkte in Heller gibt's in #8
Vier Texte, Die durchgescrollt werden, in #9

Lib:
[download]: "Download Max72xxPanel library", github, markruys
Der Sketch ist eine Konstellation aus den Beispielen 'Ticker' und 'MadFly' - allerdings auf millis() umgeschrieben.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4; //DIN=MOSI=D11 an Nano/Uno
int numberOfVerticalDisplays = 1;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

String tape = "Arduino";
const uint16_t wait = 573; // In milliseconds
const uint16_t flywait = 100;

int spacer = 1;
int width = 5 + spacer; // The font width is 5 pixels

void setup() {
  Serial.begin(9600);
  matrix.setIntensity(7); // Use a value between 0 and 15 for brightness

  // Adjust to your own needs
  matrix.setPosition(0, 0, 0); // (Display-Nr ab Einspeisung, X, Y)
  matrix.setPosition(1, 1, 0);
  matrix.setPosition(2, 2, 0);
  matrix.setPosition(3, 3, 0);
  //  ...
  matrix.setRotation(0, 1);    // (Display-Nr, Drehung je 90°)
  matrix.setRotation(1, 1);
  matrix.setRotation(2, 1);
  matrix.setRotation(3, 1);
}

void loop() {
  static byte sensitiv = 0;       //Stärke/Helligkeit der Anzeige, wird schrittweise angehoben
  uint32_t aktmillis = millis();  //'meine' aktuelle Uhrzeit
  static uint32_t lastchar = 0;   //letzte Weiterschiebung des Lauftext
  static byte i = 26;             //An welcher Stelle stehen wir? (Start hier nicht Null, Debug)
  if (aktmillis - lastchar > wait) {
    lastchar = aktmillis;         //nach der Wartezeit wird die Laufschrift um 1 Pixel verschoben
    i++;                          //die Uhrzeit gesichert (ok, anders herum)
    if (i >= width * tape.length() + matrix.width() - 1 - spacer) i = 0;  //und am oberen Ende auf Null umgebrochen
  }

  //Bereich aus dem Ticker-Beispiel
  matrix.fillScreen(LOW); //Display leeren
  int letter = i / width;
  int x = (matrix.width() - 1) - i % width;
  int y = (matrix.height() - 8) / 2; // center the text vertically

  while ( x + width - spacer >= 0 && letter >= 0 ) {
    if ( letter < tape.length() ) {
      matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);  //An Position den Buchstaben schreiben
    }
    letter--;
    x -= width;
  }
  //Das Schreiben des Lauftext passierte nur im Puffer der Lib, noch wurde Nichts ausgegeben!
  matrix.setIntensity(sensitiv);  //Helligkeit auf den aktuellen Wert setzen (Helligkeit der Fliege ändert sich)
  matrix.write(); // Send bitmap to display - da zuvor der Puffer gelöscht wurde, ist die Fliege nun weg.

  static uint32_t lastfly = 0;  //Die Fliege, letzte Uhrzeit der Fliege
  static byte _x = 0;           //Koordinaten, jede Fliege braucht Koordinaten :)
  static byte _y = 0;
  if (aktmillis - lastfly > flywait) {
    lastfly = aktmillis;        //Nach Fliegenwartezeit, wird die Fliege versetzt
    byte xold = _x;
    byte yold = _y;
    while (_x == xold && _y == yold) {  //und zwar so lange, bis Diese wirklich versetzt wurde
      byte richtung = random(4);
      switch (richtung) {
        case 0: if (_x) _x--; break;
        case 1: if (_x < 31) _x++; break;
        case 2: if (_y) _y--; break;
        case 3: if (_y < 7) _y++; break;
      }
    }
  }
  matrix.fillScreen(LOW); //Display leeren
  matrix.drawPixel(_x, _y, 1);  //Fliege setzen
  matrix.write(); // Send bitmap to display
  matrix.setIntensity(15);  //Helligkeit auf MAXIMUM, die Fliege ist jetzt ganz hell!

  static uint32_t lastsensitiv = 0;   //die Intensität alle x Millisekunden anheben (0...15)
  if (aktmillis - lastsensitiv >= 500) {
    lastsensitiv = aktmillis;
    sensitiv++;
    sensitiv &= 0x0F;                 //auf 4 Bit (0...15) begrenzen - eine 16 wird zur 0.
    Serial.println(sensitiv);
  }
}

Sowohl die Fluggeschwindigkeit der Fliege, wie die Laufgeschwindigkeit des Text ist im Sketch einstellbar.
Die Schrittzeit der Helligkeitsänderung ist fest auf 500ms, sollte kein Problem sein, Das anzupassen.
Die Fliege ist super hell, der Text, je nach Helligkeit (läuft ja hoch), immer heller.
Leider zerbröselt Es mir den Text, ich bekomme Flimmern auf einzelne der 8x8er Matrix-Displays.
Dürfte eine Schwebung aus den laufend einprasselnden neuen Daten und der internen Frequenz des MAX sein - sieht auf jeden Fall nicht sonderlich schön aus - für eine weniger aufdringliche Information unter einem hellen Punkt so nicht zu gebrauchen.

Wer will, kann's ja Mal einspielen, das Display wird bei mir über den per USB versorgten Arduino Nano bestromt - Das klappt NICHT, wenn der Arduino per V_in versorgt wird!!
(und ist auch nicht die feine englische Art ... also nicht nachmachen, da der ganze Display-Strom über die Nano-Leiterbahnen drüber muß)

MfG

auf deutsch: Was soll der Sketch können und wie kann man dir helfen?

Hi

Der Sketch sollte verschieden hell angezeigte 'Dinge' auf dem 4x 8x8-Dot-Matrix-Display anzeigen.
War ein Versuch, im Nachbar-Thread die Anzeige für die Befüllung des Karton (5x5 Stellplätze, 8 Ebenen) anzuzeigen, wo das aktuelle Teil hin gehört (der hellere Punkt).
Die bereits liegenden Teile wären dann dunkler.
Das scheint aber nicht ohne Weiteres hinzubekommen zu sein.
Zugegeben, ich benutze 4 Stück der 8x8 Dot-Matrix-Displays, also 4 MAX7219 in DaisyChain.
Somit könnte, bei nur Einem, die Datenrate steigen und die Störung weg sein.
Da die Störung aber wie eine Schwebung aussieht, wird sich Das wahrscheinlich nur verschieben.

Mir ist hier wohl nicht zu helfen - wenn Einer die Anzeige flackerfrei zum Laufen bekommt, freue ich mich aber schon über eine funktionierende(re) Lösung.

MfG

hab die 8x8 auch nur in den 4er Gruppen. Eigentlich denk ich mir mit der simplen Led-Control ein und ausschalten kann ja nicht die Hexerei sein, ... theoretisch. In der Praxis würde ich wohl eine 8x8 Neopixel-Matrix nehmen, fertig. :slight_smile:

Hallo,

ich wollte dir schon hier antworten, ist aber separat besser aufgehoben.

Ich dachte du kennst einen Trick den ich noch nicht kenne. Deswegen die Frage. :wink:
Zu deiner Theorie. Es funktioniert leider schon theoretisch nicht. Sobald du die gesamte Anzeige dunkel schaltest flimmert und flackert alles. Das ist der gleiche Effekt wie beim LCD Display wenn die Leute statt Zeile überschreiben das gesamte Display löschen. Darf man nicht machen. Es gelten die gleichen Regeln. Man kann beim MAX weder einzelne Digits noch einzelne Segmente unterschiedlich hell steuern. Ich kenne auch keinen anderen fertigen IC der das kann. Ich meine ich finde den MAX trotzdem sehr gut, das wäre jedoch der fette i Punkt gewesen.

Einzel Digit Helligkeitssteuerung könnte man ohne MAX mit einem Schieberegister für Segmente und 8 Transistoren für die Digits realisieren. Die 8 Transistoren steuern individuell die Digithelligkeit. Das kann man mit verschachtelten "Servopulsen" am Port machen. Die Pulse sind individuell lang. Nur das alles mit höherer Frequenz abläuft. Der MAX pulst seine Digits mit allen 8 zum Bsp. mit etwas über 700Hz an.

Ob man einzelne Segmente in der Helligkeit steuern kann bin ich mir noch nicht sicher. Die Theorie reift noch. Man müßte laut erster Überlegung alle 2x8 Leitungen mit Transistoren einzeln steuern. Ganz ohne irgendwelchen Schieberegistern. Der Softwareaufwand wird vermutlich expotentiell steigen. Wobei die Digits mit fester Frequenz ihrer Multiplexaufgabe nachkommen könnten und sich der gesamte Aufwand auf die Segmentleitungen konzentrieren dürfte. Eine Segmentleitung bekommt einen längeren Impuls als die Andere. Maximale Segmentpulslänge ist die Digitpulslänge. Soweit meine erste Theorie dazu.

postmaster-ino:
Vorweg: Es klappt nicht!

Danke für Dein Eingeständnis und Deine Ehrlichkeit!

Hi

Weshalb sollte ich Euch belügen?
Hatte halt meine Idee geäußert und in der Theorie sieht Die gar nicht so schlecht aus.
(ich bin auch noch nicht ganz fertig mit dem Sketch ... hatte heute einen spontanen Einfall ... - ob's der i-Punkt wird ... kA)

Und gar eine Niederlage eingestehen ... pöh :wink:
Bin der Meinung, daß ich wohl nicht der Einzige bin, Dem Die Idee kommt - also warum das suchende Volk nicht hier hin locken und direkt sagen, daß Es zumindest mir nicht gelungen ist (also bis jetzt ... und dann die Weltherrschaft).

Habe mir die Lib noch nicht so genau angeschaut, denke, die Intensität wird auf alle MAX angewendet - somit sollte Es möglich sein, das Problem auf die Displays einzugrenzen, auf Denen Was hell erscheinen soll.
Das könnte man händisch machen, also nur dem einen Display die andere Helligkeit übermitteln (Löschen, Helligkeit einstellen, Punkt o.Ä. zeichnen).

Da das menschliche Auge eigentlich träge ist, kam mir heute die Idee, einfach im 20ms-Rythmus das Eine oder das Andere anzuzeigen.
Dort dürften die Artefakte wesentlich weniger werden, da die Anzeige 'alle Zeit der Welt' hat, um den aktuellen Kram anzuzeigen.

Test steht aus und noch habe ich erst drei Threads im Forum durch :slight_smile:

MfG

ich hab mir gedacht, schaltest halt den Pixel ein oder aus in einem Duty-Cycle von 1 zu 10.
ist nicht schön, man nimmt ein flimmern wahr.

Wahrscheinlich braucht es ein echtes SPI und dann etwas mehr Studium vom Datenblatt.

Ich lass das jetzt, mir fehlt da der Anwendungszweck.
So als Irrweg stell ich meine Variante trotzdem ein:

#include "NoiascaLedControl.h"  // rückwärtskompatibel zur originalen LedControl

LedControl lc = LedControl(9, 7, 8, 1);

/* we always wait a bit between updates of the display */
unsigned long delaytime = 100;

void setup() {
  lc.shutdown(0, false);
  lc.setIntensity(0, 8);
  lc.clearDisplay(0);
  lc.setLed(0, 0 , 1, true); // nur zum Vergleich dauerhaft ein
}

void tickLedBrightness(int addr, int row, int col, boolean state, byte brightness, byte current)
{
  if (current % (10-brightness)==0)
    lc.setLed(addr, row, col, state);
  else
    lc.setLed(addr, row, col, false);
}


void loop() {
  static byte i = 0;
  tickLedBrightness(0, 1, 1, true, 9, i);         // voll
  tickLedBrightness(0, 1, 2, true, 3, i);         // min
  tickLedBrightness(0, 2, 1, true, 8, i);
  tickLedBrightness(0, 3, 1, true, 7, i);
  tickLedBrightness(0, 4, 1, true, 6, i);
  tickLedBrightness(0, 5, 1, true, 5, i);
  tickLedBrightness(0, 6, 1, true, 4, i);
  tickLedBrightness(0, 7, 1, true, 3, i);
  i++;
}

Hi

Vorweg: Denke, zumindest einen i-Punkt bekommen wir hin

Der 2.te Versuch:

//Forensketch
//https://forum.arduino.cc/index.php?topic=665290.0
//gescheiterter Versuch, auf Dot-Matrix-Display verschiedene Helligkeiten anzuzeigen
//im Grunde klappt Das, aber hier wird z.B. die Laufschrift stark gestört.

//Wesentlich besseres Ergebnis, wenn die einzelnen Teil-Anzeigen für eine gewisse Zeit alleine die Anzeige einnehmen.
//bei einem 4x 8x8er Display waren ab 8ms Umschaltzeit keine Artefakte mehr zu sehen
//bei 3Stk 8x 4x4 (Matrix 32x24 Pixel in ZickZack) ging's ab 10, 12 ist halbwegs brauchbar.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4; //DIN=MOSI=D11 an Nano/Uno
int numberOfVerticalDisplays = 3;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

String tape = "Arduino";
const uint16_t wait = 47; // In milliseconds
const uint16_t flywait = 10;
const uint16_t switchwait = 12; //Zeit zwischen Umschalten der Anzeige
//8 ist bei einem 4x 8x8 ok
//bei 3x 4x 8x8 ergibt 8 erneut Artefakte

int spacer = 1;
int width = 5 + spacer; // The font width is 5 pixels
/*
   0/0
       / 08 09 10 11
       \ 07 06 05 04 \
      -> 00 01 02 03 /
*/
void setup() {
  Serial.begin(9600);
  Serial.print(matrix.width());
  Serial.print('x');
  Serial.println(matrix.height());
  matrix.setIntensity(7); // Use a value between 0 and 15 for brightness

  // Adjust to your own needs
  matrix.setPosition(0, 0, 2); // (Display-Nr ab Einspeisung, X, Y) - 0/0 links oben
  matrix.setPosition(1, 1, 2);
  matrix.setPosition(2, 2, 2);
  matrix.setPosition(3, 3, 2);
  matrix.setPosition(4, 3, 1);
  matrix.setPosition(5, 2, 1);
  matrix.setPosition(6, 1, 1);
  matrix.setPosition(7, 0, 1);
  matrix.setPosition(8, 0, 0);
  matrix.setPosition(9, 1, 0);
  matrix.setPosition(10, 2, 0);
  matrix.setPosition(11, 3, 0);
  matrix.setRotation(0, 1);    // (Display-Nr, Drehung je 90°)
  matrix.setRotation(1, 1);
  matrix.setRotation(2, 1);
  matrix.setRotation(3, 1);
  matrix.setRotation(4, 3);
  matrix.setRotation(5, 3);
  matrix.setRotation(6, 3);
  matrix.setRotation(7, 3);
  matrix.setRotation(8, 1);
  matrix.setRotation(9, 1);
  matrix.setRotation(10, 1);
  matrix.setRotation(11, 1);
  for (byte i = 0; i < 24; i++) {
    matrix.drawPixel(i, i, 1);
    matrix.write();
    delay(100);
  }
}

void loop() {
  static byte sensitiv = 0;       //Stärke/Helligkeit der Anzeige, wird schrittweise angehoben
  uint32_t aktmillis = millis();  //'meine' aktuelle Uhrzeit

  static bool soll_laufschrift = true;
  static uint32_t lastswitch = 0;
  if (aktmillis - lastswitch >= switchwait) {
    soll_laufschrift ^= 1; //xor - gibt den 'Abstand' zurück - wenn vorher 0, dann jetzt 1 und umgekehrt.
    lastswitch = aktmillis;
  }
  int16_t x=0;
  int16_t y=0;
    static byte i = 26;             //An welcher Stelle stehen wir? (Start hier nicht Null, Debug)  
  if (soll_laufschrift) {
    //Im Wechsel Lauftext bzw. Fliege anzeigen - hier Lauftext
    static uint32_t lastchar = 0;   //letzte Weiterschiebung des Lauftext
    if (aktmillis - lastchar > wait) {
      lastchar = aktmillis;         //nach der Wartezeit wird die Laufschrift um 1 Pixel verschoben
      i++;                          //die Uhrzeit gesichert (ok, anders herum)
      if (i >= width * tape.length() + matrix.width() - 1 - spacer) {
        //wir haben den Text so weit durchgescrollt, daß Er komplett aus dem Display wieder raus ist
        i = 0;
        //y++;
        //if (y == (matrix.height() - 8)) y = 0;
        y = random((matrix.height() - 8));//8=Höhe der Zeichen
        Serial.print("Hoehe:");
        Serial.println(y);
      }
    }

    //Bereich aus dem Ticker-Beispiel
    matrix.fillScreen(LOW); //Display leeren
    int16_t letter = i / width;
    x = (matrix.width() - 1) - i % width;


    while ( x + width - spacer >= 0 && letter >= 0 ) {
      if ( letter < tape.length() ) {
        matrix.drawChar(x, y, tape[letter], HIGH, LOW, 1);  //An Position den Buchstaben schreiben
      }
      letter--;
      x -= width;
    }
    //Das Schreiben des Lauftext passierte nur im Puffer der Lib, noch wurde Nichts ausgegeben!
    matrix.setIntensity((sensitiv < 0x10) ? sensitiv : 0x1F - sensitiv); //Helligkeit auf den aktuellen Wert setzen (Helligkeit der Fliege ändert sich)
    matrix.write(); // Send bitmap to display - da zuvor der Puffer gelöscht wurde, ist die Fliege nun weg.
  } else {
    //Hier die MadFly
    static uint32_t lastfly = 0;  //Die Fliege, letzte Uhrzeit der Fliege
    static byte _x = 0;           //Koordinaten, jede Fliege braucht Koordinaten :)
    static byte _y = 0;
    if (aktmillis - lastfly > flywait) {
      lastfly = aktmillis;        //Nach Fliegenwartezeit, wird die Fliege versetzt
      byte xold = _x;
      byte yold = _y;
      while (_x == xold && _y == yold) {  //und zwar so lange, bis Diese wirklich versetzt wurde
        byte richtung = random(4);
        switch (richtung) {
          case 0: if (_x) _x--; break;
          case 1: if (_x < (matrix.width() - 1)) _x++; break;
          case 2: if (_y) _y--; break;
          case 3: if (_y < (matrix.height() - 1)) _y++; break;
        }
      }
    }
    matrix.fillScreen(LOW); //Display-Puffer leeren
    matrix.drawPixel(_x, _y, 1);  //Fliege setzen
    matrix.drawPixel(57-i,y,1); //i-Punkt
    matrix.write(); // Send bitmap to display
    matrix.setIntensity(15);  //Helligkeit auf MAXIMUM, geht direkt ans Display!
  }

  static uint32_t lastsensitiv = 0;   //die Intensität alle x Millisekunden anheben (0...15)
  if (aktmillis - lastsensitiv >= 500) {
    lastsensitiv = aktmillis;
    //sensitiv++;
    sensitiv &= 0x1F;                 //auf 4 Bit (0...15) begrenzen - eine 16 wird zur 0.
    //Serial.println(sensitiv);
  }
}

Noch ist ein Überbleibsel zur Helligkeitsänderung enthalten - wird in dem Beispiel aber nicht aktiv genutzt.
Habe etwas mehr gespielt, weshalb nun auch drei der Display zusammen gekommen sind.

Per Video ist so ziemlich Nichts zu erkennen - auf dem Foto sieht der i-Punkt gleich viel heller aus, als die Schrift, gell?

Die Fliege ist ebenfalls auf maximaler Helligkeit und - nur ein Pixel - hier ist die Kamera wohl etwas langsam, alle 47ms wird die Laufschrift Einen weiter geschoben.

Gelöst wurde Das so, daß alle x Millisekunden die andere Information angezeigt wird und dafür eben die Helligkeit eingestellt wird - aber die Anzeige zeigt diese x Millisekunden nur diese Information an.
Immer im Wechsel - Das klappt hier ganz gut.

MfG

PS: Die Forensoftware mag mich gerade nicht sonderlich ... werde wohl ein/zwei Züge brauchen, bis ich das Bild hier drin habe ...

Hi

Erneuter Versuch - mehrere Texte werden über das Display gescrollt.
Die Texte müssen (warum auch immer) ungefähr die gleiche Länge haben - sonst 'starten' Diese nicht erneut ... noch nicht gefunden, wo ich Da einen Fehler habe.

//Forensketch
//https://forum.arduino.cc/index.php?topic=665290.0
//gescheiterter Versuch, auf Dot-Matrix-Display verschiedene Helligkeiten anzuzeigen
//im Grunde klappt Das, aber hier wird z.B. die Laufschrift stark gestört.

//Wesentlich besseres Ergebnis, wenn die einzelnen Teil-Anzeigen für eine gewisse Zeit alleine die Anzeige einnehmen.
//bei einem 4x 8x8er Display waren ab 8ms Umschaltzeit keine Artefakte mehr zu sehen
//bei 3Stk 8x 4x4 (Matrix 32x24 Pixel in ZickZack) ging's ab 10, 12 ist halbwegs brauchbar.

//Take 3 ...
//mehrere Texte in unterschiedlicher Helligkeit durchscrollen.
//Bis 4 Texte geht halbwegs, die ganz dunklen Texte flackern ab und zu.

using millis_t = decltype(millis());

millis_t printdelay = 3; //alle ... ms einen anderen Text

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

int pinCS = 10; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI )
int numberOfHorizontalDisplays = 4; //DIN=MOSI=D11 an Nano/Uno
int numberOfVerticalDisplays = 3;

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

const byte maxlang = 20;
typedef struct {
  char  text[maxlang + 1]; //Anzeigetext + /0
  byte    sensity;        //Helligkeit 0...15
  millis_t  wait;
  int16_t x;              //Koordinate
  int16_t y;              //dito
  millis_t  lastmillis;
  bool    left;           //nach links scrollen?
  byte    lang;
} anzeige_t;

anzeige_t text[] = {
  {"AAAAA", 0, 177},  //nicht angegebene Werte werden wohl mit 0 initialisiert - ungeprüft
  {"BBBBB", 5, 77},    //Warnungen werden wegen der fehlenden Werte ausgegeben
  {"01234", 15, 333}, //*anmerk*
  {"DDDDD", 9, 200},
//  {"EEE", 11, 634},
};
const byte anztexte = sizeof(text) / sizeof(text[0]); //Anzahl an Texte berechnen

const byte spacer = 1;   //Lücke zwischen den Buchstaben
const uint16_t width = 5 + spacer; // The font width is 5 pixels
/*  Anordnung der einzelnen Matrix-Displays
   0/0
       / 08 09 10 11
       \ 07 06 05 04 \
      -> 00 01 02 03 /
*/
void setup() {
  Serial.begin(9600);
  Serial.print(matrix.width());
  Serial.print('x');
  Serial.println(matrix.height());

  // Adjust to your own needs
  matrix.setPosition(0, 0, 2); // (Display-Nr ab Einspeisung, X, Y) - 0/0 links oben
  matrix.setPosition(1, 1, 2); // da in der unteren Zeile eingespeist wird, Y=2
  matrix.setPosition(2, 2, 2);
  matrix.setPosition(3, 3, 2);
  matrix.setPosition(4, 3, 1);
  matrix.setPosition(5, 2, 1);
  matrix.setPosition(6, 1, 1);
  matrix.setPosition(7, 0, 1);
  matrix.setPosition(8, 0, 0);
  matrix.setPosition(9, 1, 0);
  matrix.setPosition(10, 2, 0);
  matrix.setPosition(11, 3, 0);
  matrix.setRotation(0, 1);    // (Display-Nr, Drehung je 90°)
  matrix.setRotation(1, 1);
  matrix.setRotation(2, 1);
  matrix.setRotation(3, 1);
  matrix.setRotation(4, 3);
  matrix.setRotation(5, 3);
  matrix.setRotation(6, 3);
  matrix.setRotation(7, 3);
  matrix.setRotation(8, 1);
  matrix.setRotation(9, 1);
  matrix.setRotation(10, 1);
  matrix.setRotation(11, 1);
  for (byte i = 0; i < anztexte; i++) {
    Serial.print("Text ");
    Serial.print(i);
    Serial.print(':');
    Serial.print(text[i].text);
    Serial.print(" Wartezeit:");
    Serial.print(text[i].wait);
    Serial.print(" Helligkeit:");
    Serial.println(text[i].sensity);

  }
  for (byte i = 0; i < 24; i++) {
    matrix.drawPixel(i, i, 1);
    matrix.write();
    delay(50);
  }
}

void loop() {
  static byte textnr = 0;       //Nummer des aktuell behandelten Text
  static bool first = true;     //wird die Seite zum ersten Mal aufgebaut?
  static millis_t lastchange = 0;
  millis_t aktmillis = millis(); //aktuelle Uhrzeit für diese Runde auslesen

  //alle x ms die Anzeige wechseln
  if (aktmillis - lastchange >= printdelay) {
    lastchange = aktmillis;
    textnr++;
    textnr %= anztexte;
    first = true; //Anzeige (soll) sich ändern
    matrix.setIntensity(text[textnr].sensity);  //Helligkeit zur neuen Anzeige anpassen
    //Serial.println(textnr);
  }

  //alle Texte scrollen (wenn Zeit vorbei)
  for (byte i = 0; i < anztexte; i++) {
    if (aktmillis - text[i].lastmillis >= text[i].wait) {
      if (i == textnr) {
        first = true; //Anzeige hat sich verändert, Ausgeben
      }
      int16_t xposition = text[i].x;
      if (text[i].left) {
        text[i].x--;   //wenn Wartezeit vorbei, dann x nach Links verschieben
      } else {
        text[i].x++;   //nach Rechts schieben
      }
      //Ist Text rausgescrollt?
      if (xposition > matrix.width() || xposition < -(text[textnr].lang)) {
        //Ja, neue Richtung auswürfeln
        text[i].left = i%2;//random(2); //0...1
        //Und Text außerhalb platzieren
        if (text[i].left) {
          text[i].x = matrix.width();
        } else {
          text[i].x = -(text[i].lang);
        }
        text[i].y = random(0, matrix.height() - 8);
      }
      text[i].lastmillis = aktmillis;
    }
  }

  if (first) { //wenn sich die Anzeige geändert hat, Text ausgeben
    int16_t x = text[textnr].x;
    int16_t y = text[textnr].y;
    matrix.fillScreen(LOW); //Display-Puffer leeren, wir schreiben neuen Inhalt
    for (byte i = 0; i < maxlang ; i++) {
      //Zeichen Nummer i ausgeben
      char zeichen = text[textnr].text[i];
      if (zeichen) {
        matrix.drawChar(x + i * width, y, zeichen, HIGH, LOW, 1); //An Position den Buchstaben schreiben
      } else {
        text[textnr].lang = i * width-1;
        break;
      }
    }
    matrix.write();
    first = false;
  }
}

Die Anzeige bleibt unverändert, wenn sich während der Anzeigezeit (hier aktuell 3 ms) Nichts ändert.
Bei größeren Verzögerungszeiten bekommt man schnell blinkende Texte :).

MfG

Beim Ursprungsthema ging es doch um eine Matrix mit verschiedenen hell leuchtenden Punkten.
Wofür so da scrollen über mehrere Bausteine brauchbar sein?

Gruß Tommy

Hi

Weil ich's kann?
Die Nummer 2 ist ohne größere Probleme auf ein 4er Modul anzupassen - die Nummer drei auch, davon ab.
Nur wird man bei der Drei, da dort mehrere (4) Texte in verschiedenen Helligkeiten gescrollt werden, nicht viel sehen - auf nur einem Display-Streifen - alle Texte wären immer auf der gleichen Y-Höhe - wo sollten Sie auch hin, ist ja drüber/drunter kein Display mehr.

Am Thema hat Sich Nichts geändert, sind immer noch 8x8er DOT-Matrix-Displays, Die in DasyChain angereiht werden.
Der freundliche Chinese liefert halt schon 4 Davon in einer Reihe (auch sieht Scrolltext auf einem einzelnen Display ... überarbeitungswürdig aus).

Der erste Sketch war die Umsetzung der reinen Idee, wie ich Das im Nachbar-Thread ersonnen hatte - halt nicht sonderlich erfolgreich - aber auch ein schlechtes Beispiel kann Einem was bringen - wenn's nur ist, daß man Das selber nicht mehr herausfinden muß.

Bei Nummer 2 sind zwei einzelne Punkte heller (der i-Punkt und die 'MadFly'), allerdings schon auf dem auf 3x4 'aufgeblasenem' Display - die Fliege hat mehr Platz und der Text kann an unterschiedlichen Stellen (Y-Höhe) erscheinen - wenn halt der Platz da ist.
Bei Abänderung auf nur eine Reihe (die Zuordnung, an welcher Stelle im Koordinatensystem dann die ersten 4 Displays liegen, muß angepasst werden) stört hier die Anzeige nicht, die Fliege wuselt halt durch den Text durch.
Auch ist der i-Punkt 'hart-verdrahtet' und nicht auf das i gemappt - wenn man also den Text ändert, bleibt der i-Punkt, wo Er war.

Für die Nummer 3 ist mir in den Sinn gekommen, daß das menschliche Auge ab 25 Einzelbilder sie Sekunde eine flüssige Bewegung sieht - also warum nicht die verschiedenen Anzeigen für ein Maximum an Zeit starr in der Anzeige lassen (sofern eben nicht gescrollt wird) und DANN erst auf die nächste Anzeige umschalten - so hat jede Anzeige 'Zeit', Sich in die Netzhaut einzuarbeiten - und der Max7219 hat 'nur' den aktuellen Display-Inhalt aufzufrischen (eben in der gewählten Helligkeit). Wesentlich weniger Schwebungen!
Das klappt auch halbwegs!
Allerdings sind die Helligkeitsunterschiede nicht so, daß man die 16 möglichen Werte dabei unterscheiden könnte - selbst bei den 4 Texten sind die Unterschiede, wenn die Texte übereinander laufen, teilweise maginal - auch ändern sie die Helligkeiten teilweise während des Lauf - Was Da schief läuft - kA - für Kleinigkeiten - Wochentag+Datum und die Uhrzeit sollte man Das aber benutzen können.

Man muß ja nicht!

MfG