Array (Dot-Matrix-Zeichen) per 'Position' ansprechen

Hi

Aktuell versuche ich mich in der Ansteuerung einer DOT-Matrix vom fernen China-Mann.
Dieser hat mir eine 4-fach 8x8 DOT-Matrix, basierend auf dem MAX7219 geschickt.
Das Ansteuern klappt auch so weit, wobei bisher nur zufällig Pixel gesetzt werden um dann das Display 'frei zu schieben'.
Dazu habe ich die Library LedControl.h erweitert und tut auch so, wie gewünscht.

Nun möchte ich Zeichen auf das Display ausgeben - dafür wollte ich einen 5x5-Dot-Matrix-Font kopieren
font 5x5 auf dafont.com

Unten ist ersichtlich, wie ich die Fünf speichere.

Die Einzel-Bits kann ich mit _5[0...4] bekommen.

Nun hätte ich aber gerne noch ein Array, in Dem ich diese Arrays einsortiere.
Angedacht ist z.B. zeichen("A").
Das soll ein Zeiger auf das Zeichen 'A' sein, ein zeichen("5"); sollte dann auf die Fünf zeigen.
Wobei diese "5" dann 0x35 entsprechen sollte - also dem ASCII-Zeichen-Code.

Mit & und * bin ich etwas am experimentieren, komme aber nicht wirklich auf 'einen grünen Zweig'.

const byte _5[]={   B11111,   //_5[0]
                    B10000,   //_5[1] ...
                    B11110,
                    B00001,
                    B11110
};
const byte _Z[5]={&_5};  //_Z[5] zeigt nun auf den Anfang des Array _5[]
int *i=_Z[5];          //was es hier mit dem * auf sich hat, erschließt sich mir nicht, i müsste als Pointer funktionieren
int a=*i;       //hier müsste ich jetzt an die Einzelwerte heran kommen

Was mache ich jetzt mit Meinem a ??

Warum das Ganze?
Ich möchte die Zeichen frei platzieren, dafür brauche ich die Bits.
Die Quelle der Zeichen wird eine User-Eingabe sein oder der aktuelle Wochentag/die aktuelle Uhrzeit.
Somit denke ich, einen flexiblen Zugriff auf meine Tabelle (Die bisher nur aus der einen Fünf besteht) zu brauchen, damit ich so durch zeichenweises abarbeiten eines String die Zeichen bekomme, womit ich meine Punkte auslesen kann, um Diese in die Matrix einzurechnen.

Wer hat Lust, mir Da auf die Sprünge zu helfen?

Wenn Ihr noch ein paar Minuten Zeit habt, packe ich in den Folgepost die abgeänderte Library
(Hiermit bitte ich um Korrekturen, falls ich darin Bockmist verzapft habe)

MfG

/*
 *    LedControl.h - A library for controling Leds with a MAX7219/MAX7221
 *    Copyright (c) 2007 Eberhard Fahle
 * 
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 * 
 *    This permission notice shall be included in all copies or 
 *    substantial portions of the Software.
 * 
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef LedControl_h
#define LedControl_h

#include <avr/pgmspace.h>

#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

/*
 * Segments to be switched on for characters and digits on
 * 7-Segment Displays
 */
const static byte charTable [] PROGMEM  = {
    B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
    B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000,
    B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,
    B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
    B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000,
    B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000,
    B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000,
    B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00010101,B00011101,
    B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
    B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
};

class LedControl {
    private :
        /* The array for shifting the data to the devices */
        byte spidata[16];
        /* Send out a single command to the device */
        void spiTransfer(int addr, byte opcode, byte data);

        /* We keep track of the led-status for all 8 devices in this array */
        byte status[64];
        /* Data is shifted out of this pin*/
        int SPI_MOSI;
        /* The clock is signaled on this pin */
        int SPI_CLK;
        /* This one is driven LOW for chip selectzion */
        int SPI_CS;
        /* The maximum number of devices we use */
        int maxDevices;

    public:
        /* 
         * Create a new controler 
         * Params :
         * dataPin		pin on the Arduino where data gets shifted out
         * clockPin		pin for the clock
         * csPin		pin for selecting the device 
         * numDevices	maximum number of devices that can be controled
         */
        LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

        /*
         * Gets the number of devices attached to this LedControl.
         * Returns :
         * int	the number of devices on this LedControl
         */
        int getDeviceCount();

        /* 
         * Set the shutdown (power saving) mode for the device
         * Params :
         * addr	The address of the display to control
         * status	If true the device goes into power-down mode. Set to false
         *		for normal operation.
         */
        void shutdown(int addr, bool status);

        /* 
         * Set the number of digits (or rows) to be displayed.
         * See datasheet for sideeffects of the scanlimit on the brightness
         * of the display.
         * Params :
         * addr	address of the display to control
         * limit	number of digits to be displayed (1..8)
         */
        void setScanLimit(int addr, int limit);

        /* 
         * Set the brightness of the display.
         * Params:
         * addr		the address of the display to control
         * intensity	the brightness of the display. (0..15)
         */
        void setIntensity(int addr, int intensity);

        /* 
         * Switch all Leds on the display off. 
         * Params:
         * addr	address of the display to control
         */
        void clearDisplay(int addr);

        /* 
         * Set the status of a single Led.
         * Params :
         * addr	address of the display 
         * row	the row of the Led (0..7)
         * col	the column of the Led (0..7)
         * state	If true the led is switched on, 
         *		if false it is switched off
         */
        void setLed(int addr, int row, int col, boolean state);

        /* 
         * Set all 8 Led's in a row to a new state
         * Params:
         * addr	address of the display
         * row	row which is to be set (0..7)
         * value	each bit set to 1 will light up the
         *		corresponding Led.
         */
        void setRow(int addr, int row, byte value);

        /* 
         * Set all 8 Led's in a column to a new state
         * Params:
         * addr	address of the display
         * col	column which is to be set (0..7)
         * value	each bit set to 1 will light up the
         *		corresponding Led.
         */
        void setColumn(int addr, int col, byte value);

        /* 
         * Display a hexadecimal digit on a 7-Segment Display
         * Params:
         * addr	address of the display
         * digit	the position of the digit on the display (0..7)
         * value	the value to be displayed. (0x00..0x0F)
         * dp	sets the decimal point.
         */
        void setDigit(int addr, int digit, byte value, boolean dp);

        /* 
         * Display a character on a 7-Segment display.
         * There are only a few characters that make sense here :
         *	'0','1','2','3','4','5','6','7','8','9','0',
         *  'A','b','c','d','E','F','H','L','P',
         *  '.','-','_',' ' 
         * Params:
         * addr	address of the display
         * digit	the position of the character on the display (0..7)
         * value	the character to be displayed. 
         * dp	sets the decimal point.
         */
        void setChar(int addr, int digit, char value, boolean dp);

//bypostmasterino

		/*
		 *Liest Pixel aus
		 */
		byte seeLed(int addr, int row, int column);

        /* 
         * Shift the Display up
         */
        void shiftUp();

        /* 
         * Shift the Display down
         */
        void shiftDown();
        /* 
         * Shift the DIsplay left
         */
        void shiftLeft();
        /* 
         * Shift the DIsplay right
         */
        void shiftRight();

};

#endif	//LedControl.h
/*
 *    LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221
 *    Copyright (c) 2007 Eberhard Fahle
 * 
 *    Permission is hereby granted, free of charge, to any person
 *    obtaining a copy of this software and associated documentation
 *    files (the "Software"), to deal in the Software without
 *    restriction, including without limitation the rights to use,
 *    copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the
 *    Software is furnished to do so, subject to the following
 *    conditions:
 * 
 *    This permission notice shall be included in all copies or 
 *    substantial portions of the Software.
 * 
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 *    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *    OTHER DEALINGS IN THE SOFTWARE.
 */


#include "LedControl.h"

//the opcodes for the MAX7221 and MAX7219
#define OP_NOOP   0
#define OP_DIGIT0 1
#define OP_DIGIT1 2
#define OP_DIGIT2 3
#define OP_DIGIT3 4
#define OP_DIGIT4 5
#define OP_DIGIT5 6
#define OP_DIGIT6 7
#define OP_DIGIT7 8
#define OP_DECODEMODE  9
#define OP_INTENSITY   10
#define OP_SCANLIMIT   11
#define OP_SHUTDOWN    12
#define OP_DISPLAYTEST 15

LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
    SPI_MOSI=dataPin;
    SPI_CLK=clkPin;
    SPI_CS=csPin;
    if(numDevices<=0 || numDevices>8 )
        numDevices=8;
    maxDevices=numDevices;
    pinMode(SPI_MOSI,OUTPUT);
    pinMode(SPI_CLK,OUTPUT);
    pinMode(SPI_CS,OUTPUT);
    digitalWrite(SPI_CS,HIGH);
    SPI_MOSI=dataPin;
    for(int i=0;i<64;i++) 
        status[i]=0x00;
    for(int i=0;i<maxDevices;i++) {
        spiTransfer(i,OP_DISPLAYTEST,0);
        //scanlimit is set to max on startup
        setScanLimit(i,7);
        //decode is done in source
        spiTransfer(i,OP_DECODEMODE,0);
        clearDisplay(i);
        //we go into shutdown-mode on startup
        shutdown(i,true);
    }
}

int LedControl::getDeviceCount() {
    return maxDevices;
}

void LedControl::shutdown(int addr, bool b) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(b)
        spiTransfer(addr, OP_SHUTDOWN,0);
    else
        spiTransfer(addr, OP_SHUTDOWN,1);
}

void LedControl::setScanLimit(int addr, int limit) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(limit>=0 && limit<8)
        spiTransfer(addr, OP_SCANLIMIT,limit);
}

void LedControl::setIntensity(int addr, int intensity) {
    if(addr<0 || addr>=maxDevices)
        return;
    if(intensity>=0 && intensity<16)	
        spiTransfer(addr, OP_INTENSITY,intensity);
}

void LedControl::clearDisplay(int addr) {
    int offset;

    if(addr<0 || addr>=maxDevices)
        return;
    offset=addr*8;
    for(int i=0;i<8;i++) {
        status[offset+i]=0;
        spiTransfer(addr, i+1,status[offset+i]);
    }
}

void LedControl::setLed(int addr, int row, int column, boolean state) {
    int offset;
    byte val=0x00;

    if(addr<0 || addr>=maxDevices)
        return;
    if(row<0 || row>7 || column<0 || column>7)
        return;
    offset=addr*8;
    val=B10000000 >> column;
    if(state)
        status[offset+row]=status[offset+row]|val;
    else {
        val=~val;
        status[offset+row]=status[offset+row]&val;
    }
    spiTransfer(addr, row+1,status[offset+row]);
}

void LedControl::setRow(int addr, int row, byte value) {
    int offset;
    if(addr<0 || addr>=maxDevices)
        return;
    if(row<0 || row>7)
        return;
    offset=addr*8;
    status[offset+row]=value;
    spiTransfer(addr, row+1,status[offset+row]);
}

void LedControl::setColumn(int addr, int col, byte value) {
    byte val;

    if(addr<0 || addr>=maxDevices)
        return;
    if(col<0 || col>7) 
        return;
    for(int row=0;row<8;row++) {
        val=value >> (7-row);
        val=val & 0x01;
        setLed(addr,row,col,val);
    }
}

void LedControl::setDigit(int addr, int digit, byte value, boolean dp) {
    int offset;
    byte v;

    if(addr<0 || addr>=maxDevices)
        return;
    if(digit<0 || digit>7 || value>15)
        return;
    offset=addr*8;
    v=pgm_read_byte_near(charTable + value); 
    if(dp)
        v|=B10000000;
    status[offset+digit]=v;
    spiTransfer(addr, digit+1,v);
}

void LedControl::setChar(int addr, int digit, char value, boolean dp) {
    int offset;
    byte index,v;

    if(addr<0 || addr>=maxDevices)
        return;
    if(digit<0 || digit>7)
        return;
    offset=addr*8;
    index=(byte)value;
    if(index >127) {
        //no defined beyond index 127, so we use the space char
        index=32;
    }
    v=pgm_read_byte_near(charTable + index); 
    if(dp)
        v|=B10000000;
    status[offset+digit]=v;
    spiTransfer(addr, digit+1,v);
}


//bypostmasterino
byte LedControl::seeLed(int addr, int row, int column) {
	byte state;
    int offset;
    byte val=0x00;

    if(addr<0 || addr>=maxDevices)
        return;
    if(row<0 || row>7 || column<0 || column>7)
        return;
    offset=addr*8;
    val=B10000000 >> column;
	return (status[offset+row] && val);
}



void LedControl::shiftUp() {
        //status[Displaynummer*8+Zeile]
		//        maxDevices
		//	spiTransfer(i,OP_DISPLAYTEST,0); Displaynummer, Befehl, Wert
		// Status[Display[0-3] x 8 + Zeile[0-7]] -> spiTransfer(Display[0-3],Zeile+1[0-7],Status[Display*8+Zeile]


//von zeile 7-0 lesen und auf Zeile+1 speichern
//Zeile 0 leeren

	for(int display=0;display<maxDevices;display++){
		for( int i=7;i>0;i--){
			status[display*8+i]=status[display*8+i-1];
			spiTransfer(display,i+1,status[display*8+i]);
		}
		status[display*8]=0;
		spiTransfer(display,1,0);
	}
/*
		status[7]=status[6];
		status[6]=status[5];
		status[5]=status[4];
		status[4]=status[3];
		status[3]=status[2];
		status[2]=status[1];
		status[1]=status[0];
		status[0]=0;
	spiTransfer(0,1,status[0]);
	spiTransfer(0,2,status[1]);
	spiTransfer(0,3,status[2]);
	spiTransfer(0,4,status[3]);
	spiTransfer(0,5,status[4]);
	spiTransfer(0,6,status[5]);
	spiTransfer(0,7,status[6]);
	spiTransfer(0,8,status[7]);
*/

}

void LedControl::shiftDown() {
	for(int display=0;display<maxDevices;display++){
		for( int i=0;i<7;i++){
			status[display*8+i]=status[display*8+i+1];
			spiTransfer(display,i+1,status[display*8+i]);
		}
		status[display*8+7]=0;
		spiTransfer(display,8,0);
	}

}

void LedControl::shiftLeft() {
	for (int i=0;i<8;i++){
		for(int display=0;display<=maxDevices;display++){
			status[display*8+i]=status[display*8+i]>>1;
			if (display<maxDevices){
				if ((status[(display+1)*8+i]%2)){
					status[display*8+i]+=128;
				}
			}
			spiTransfer(display,i+1,status[display*8+i]);
		}
	}


}

void LedControl::shiftRight() {
	for (int i=0;i<8;i++){
		for(int display=maxDevices-1;display>=0;display--){
			status[display*8+i]=status[display*8+i]*2+(1 && status[display*8+i-8]>127);
			spiTransfer(display,i+1,status[display*8+i]);
		}
	}

}




void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
    //Create an array with the data to shift out
    int offset=addr*2;
    int maxbytes=maxDevices*2;

    for(int i=0;i<maxbytes;i++)
        spidata[i]=(byte)0;
    //put our device data into the array
    spidata[offset+1]=opcode;
    spidata[offset]=data;
    //enable the line 
    digitalWrite(SPI_CS,LOW);
    //Now shift out the data 
    for(int i=maxbytes;i>0;i--)
        shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]);
    //latch the data onto the display
    digitalWrite(SPI_CS,HIGH);
}

Hallo,
ich hoffe ich verstehe dich richtig...
Du möchtest also Zeichen aus einem 5x5 Font an eine 32x8 Matrix senden und dort anzeigen lassen??

matrix.jpg

Falls JA ...
dann ist mein erster spontanter Gedanke dazu: Du brauchst eine Art "Video-RAM 32x8" welches für diese Zielmatrix zunächst als Speicher steht (in Byte gerechnet: 256 Byte). Aus diesem "Video-RAM" kannst du dann direkt die Bytes (8x4) auslesen und an die Matrix übertragen. Fertig. Etwas tricky aber nicht sonderlich schwierig wäre dann vorher die Übertragung der 5x5 Zeichen aus deinem "Zeichengenerator" in 5er-Schritten an das "Video-RAM". Beachte: Die gezeigten 5x5-Zeichen "kleben" aber direkt aneinander. Du müsstest also noch 1 Bit weiter schieben (6er Schritte) ... oder dir einen andern Font selbst malen (5x7 mit "Rand" oder so). Falls Speichermangel aufkommt: Solange die LEDs einfarbig sind, kannst du das "Video-RAM" sogar in einem BIT-Array unterbringen. Dann brauchst du dafür lediglich 32 Byte.

Falls NEIN ...
Vielleicht lieferst du noch mehr Informationen und/oder andere Kollegen haben vielleicht noch bessere Ideen

LG, Rudi

matrix.jpg

Meinst Du sowas wie bei meinem MP3-Player, wo der Künstlername und der Musiktitel angezeigt werden?

Da wird der Wert eines ASCII-Zeichens genommen und damit ein Zeiger auf den Font berechnet. Die nicht darstellbaren Zeichen können abgezogen werden. Bei gleicher Zeichenbreite ist das einfach, bei proportional mit einer Zeichenbreitentabelle schon etwas aufwändiger, aber machbar.

Zur Inspiration: Library for modular scrolling LED matrix text displays

Hallo agmue,
nur zum Verständnis: Die darzustellenden Zeichen sind vorher in der LIB(?) mit fester Größe (5x7 mit Rand) definiert und werden lediglich durch Zeichencodes aufgerufen??
(Wäre m.E. für den geplanten 5x5 Zeichensatz wahrscheinlich nicht im Sinne von @postmaster-ino)
Gruß, Rudi

Die darzustellenden Zeichen sind vorher mit fester Höhe von 8 Pixeln und variabler Breite (proportional) definiert und werden durch Zeichencodes aufgerufen. Sieht so aus, zuerst die Breite:

4, B01111110, B00010001, B00010001, B01111110, B00000000, // A 90° nach rechts
...
 3, B01000001, B01111111, B01000001, B00000000, B00000000, // I
...
 5, B01111111, B00000010, B00001100, B00000010, B01111111, // M

Zur leichteren Positionierung des Zeigers verbrauchen alle Zeichen sechs Bytes.

Ist nicht auf meinem Mist gewachsen (GitHub - nineff/MaxMatrix2: Arduino Library for MAX7219 Serially Interfaced, 8-Digit, LED Display Drivers), habe es nur für meine Bedürfnisse und meinen Geschmack (8 Pixel hoch) angepaßt.

RudiDL5:
(Wäre m.E. für den geplanten 5x5 Zeichensatz wahrscheinlich nicht im Sinne von @postmaster-ino)

Kann sein. Da Du wohl schon alle Kartons ausgepackt hast, kann ich mich ja entspannt zurücklehnen :smiley:

Hallo agmue,
besten Dank für die Infos. Ich glaube ich muss mir so ein Teil tatsächlich mal zulegen um ein besseres Gespür dafür zu bekommen. Aber auch im Selbstbau würde ich das auf die Reihe bekommen. Kennst mich ja :wink:

Da Du wohl schon alle Kartons ausgepackt hast, kann ich mich ja entspannt zurücklehnen

Nix da, Zurücklehnen ist verboten! Der "große Tag" ist am 14.11.
Zwischendurch hat so ein Suchtlappen wie ich immer mal 10 Min. übrig, um zwischen den Karton-Bergen kurz ins Forum zu stolpern...
:smiley:

Hi

Danke schon Mal für die Antworten.
Den oben verlinkten Font (5x5, Da gibt es auch Andere freie Fonts) bekomme ich schon als Bit-Zahl in den Code - Da sehe ich nicht das Problem.

Hatte Heute auf der Heimfahrt ‘Freizeit’ und mir gingen so ein paar Gedanken durch den Kopf.
Ich dachte mir, daß ich die Zeichen, wie oben gezeigt (ebenfalls nicht auf meinem Mist entstanden, wirklich nur kopiert :confused: ) als Array ablege.

Dann prüfe ich im Programm auf die Zeichen:
0-9
A-Z
a-z
äöüßÄÖÜ
: .
und setze So den Beginn des Bit-Satzes.

So lese ich die Bits aus, berechne, ob Diese überhaupt gesehen werden können und gebe Diese ggf. dann aus.
Um Speicher zu sparen, könnte man diese Bits noch press aneinander setzen - muß aber erst Mal nicht sein.

Noch Mal, was ich eigentlich vor habe, kam wohl nicht so ganz rüber:

eBay-Link Dot-Matrix-Display
Dieses Display soll mir als Anzeige für eine Datums-Uhr mit Zusatz-Funktionen dienen.
Dabei möchte ich den Wochentag, das Datum, die Zeit über das Display scrollen - links, rechts, rauf, runter bekomme ich ja schon hin (die erweiterte Library).
Dann sollen noch Geburtstage angezeigt werden - Diese, denke ich mir, kommen per Terminal und/oder per Drehencoder in den Speicher.
Als Schmankerl soll das Teil noch ‘Jubiläen’ anzeigen - da mein Bruder vor geraumer Zeit geheiratet hat, wollte ich auch so Was wie 111111111 Sekunden, was ~3,5 Jahre wären, oder 44332211, was knapp unter 1,5 Jahre wären, anzeigen lassen.

Dann schwebt mir noch vor, ob man den Text nicht auf einer Eisenbahn reinfahren lassen könnte - habe ja noch 3 Pixel ‘Höhe’ … (Hello Kitty bekomme ich wohl nicht hin, da steht die Nichte wohl mehr drauf)

Ob ein Pixel sichtbar ist, brauche ich z.B., wenn die Uhrzeit hochgescrollt wird, da Diese auch beim rein/rausscrollen aktualisiert werden soll.

Dauert aber noch - aktuell wird das Display nur voll-gepixelt und dann leer gescrollt.

Nachtrag:
In der Lib ist bereits ein Array für die ganzen Pixel vorhanden - 64 Byte für maximal 8 Stück der 8x8 Matrix.
Da habe ich vor, dieses Array auf 5 Stück ‘einzukürzen’, daß ich Platz habe, wo ich die neuen Zeichen rein kopiere, um Diese dann beim Links-Scrollen ins Display zu schieben.
So kann ich alle 6 geschobenen Pixel den neuen Buchstaben eintragen und gut.
Wie sehr hoch/runter Scrollen zum Zuge kommt - wird sich zeigen - bei 3 Pixel ‘Spielraum’ ist ja nicht so viel möglich.

MfG

RudiDL5:
Ich glaube ich muss mir so ein Teil tatsächlich mal zulegen um ein besseres Gespür dafür zu bekommen. Aber auch im Selbstbau würde ich das auf die Reihe bekommen. Kennst mich ja :wink:

Na klar :slight_smile:

Mein Erstzteil mit altem Sketch funktioniert sogar noch (ein durchlaufendes “Hallo”):

IMG_9454.png

postmaster-ino:
Dann prüfe ich im Programm auf die Zeichen:
0-9
A-Z
a-z

Diese Zeichensätze legt man wie in der ASCII Tabelle an. Angefangen mit dem Leerzeichen. Dann muss man nur vom aktuellen Zeichen 0x20/32 abziehen und man hat die Position des Buchstabens auf 0 bezogen. Wenn man ein zwei-dimensionales Array hat ist das direkt der Index im Array. Bei einem ein-dimensionalen Array braucht man nur noch eine Multiplikation mit der Anzahl der Bytes pro Zeichen

z.B.

B00000000, B00000000, B00000000, B00000000, B00000000,   //Bytes 0 - 4
B01011111, B00000000, B00000000, B00000000, B00000000,   //Bytes 5 - 9
B01011111, B00000000, B00000000, B00000000, B00000000,   //Bytes 10 - 14

0 * 5 = 0
1 * 5 = 5
2 * 5 = 10

Hi

Ja, schon klar - hatte schon auf einem 80286er in Assembler User-Eingaben in Dez/Hex umgewandelt.
Das Abziehen von 0x30 für 0-9 und ein weiteres Abziehen von 7 ab 'A' sind mir bekannt.
Da ich aber nicht alle Zeichen aufnehmen werde, werde ich wohl die 'Umwandlung' der Bit-Position hard-codieren.
Der interne Zeichensatz ist ja auch nur hard-codiert, denke auch nicht, daß ich 'Live' weitere Zeichen hinzufügen möchte, wo dann eine hard-codierung hinderlich wäre.

Denke, meinen Knoten im Gehirn ist vorerst aufgelöst, da ich 'nur' den Anfang des Font-Array brauche und eben den Offset, wo sich das Zeichen befindet.
In Assembler würde ich ein Label setzen, hier wohl eher mit dem Pointer-Zeug - beim nächsten Stillstand komme ich aber wieder angekrochen :wink:

MfG

Hi

Ne, ich bekomme Es nicht hin.
Im Programm werden die Zeichen in Arrays gepackt:

//dafont.com 5x5-dots.font

//0x21 = 33dez "!"
const byte _AUSRUF[] = {  B00100,
                          B00100,
                          B00100,
                          B00000,
                          B00100
                       };
//0x22 = 34dez """
const byte _DOPPELHOCHKOMMA[] = { B01010,
                                  B01010,
                                  B00000,
                                  B00000,
                                  B00000
                                };

Im Code sind die Zeichen 0x21 (!) - 0x7A (z) lückenlos enthalten, sollte also aus einem String heraus ‘einfach’ an die Bitmuster kommen können.

Leider meckert die IDE laufend, wenn ich versuche, mit einem Pointer auf _AUSRUF zu zeigen.

    int zeichen;
    zeichen=&_AUSRUF;//[0];// + id;
    /*
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs" "-IE:\Arduino\sketchbook\libraries\LedControl\src" "C:\Users\posti\AppData\Local\Temp\arduino_build_806571\sketch\MAX7219_DotMatrix_Library_umgeschrieben.ino.cpp" -o "C:\Users\posti\AppData\Local\Temp\arduino_build_806571\sketch\MAX7219_DotMatrix_Library_umgeschrieben.ino.cpp.o"
E:\Arduino\sketchbook\own_sketch\MAX7219_DotMatrix_Library_umgeschrieben\MAX7219_DotMatrix_Library_umgeschrieben.ino: In function 'void setzezeichen(byte, byte, byte, byte, boolean)':

E:\Arduino\sketchbook\own_sketch\MAX7219_DotMatrix_Library_umgeschrieben\MAX7219_DotMatrix_Library_umgeschrieben.ino:764:12: warning: invalid conversion from 'const byte (*)[5] {aka const unsigned char (*)[5]}' to 'int' [-fpermissive]

     zeichen=&_AUSRUF;//[0];// + id;

            ^

E:\Arduino\sketchbook\own_sketch\MAX7219_DotMatrix_Library_umgeschrieben\MAX7219_DotMatrix_Library_umgeschrieben.ino:763:9: warning: variable 'zeichen' set but not used [-Wunused-but-set-variable]

     int zeichen;

         ^

Wobei die Declaration int zeichen; eine Zeile VOR der Pointer-Zuweisung steht, somit die Warnung, daß ‘zeichen’ nicht benutzt wird, eigentlich so nicht sein kann.

Mein Vorhaben war eigentlich, daß ich so an den Anfang des gewünschten Zeichen springen kann
Startadresse + (ID-33)*5 (das erste mögliche Zeichen ist ASCII 33 = ! somit Position 0, *5, da jeweils 5 Byte übersprungen werden müsen)
wobei ‘zeichen’ der Pointer sein soll und ich die Entfernung zum gewünschten Startbyte addiere.

  • klappt nicht wirklich -

Von da wollte ich die 5 Bytes lesen, um an die Bitmuster zu kommen - soweit komme ich aber noch nicht.

Wie kann ich mit dem Pointer arbeiten (das Beispiel in der Referenz läuft mit einer Variable, daran habe ich mich eigentlich orientiert, wobei dort der Pointer nicht verändert wird) Referenz Pointer

Oder bin ich auf einem Irrweg und Das geht viel einfacher?

Dann noch: Egal, wie viele Zeichen ich per const byte als Array im Code angebe, die Programmgröße verändert sich NICHT - habe somit zusätzlich die Befürchtung, daß die Arrays gar nicht angelegt werden, wobei die Fehlermeldung (in den Code als Kommentar kopiert, die IDE ist in einer VM) von ungleichen Dateitypen spricht, das Anfangs-Array _AUSRUF also vorhanden sein müsste.

Im Anhang (wenn Alles klappt) der 5x5-Font als Array-Haufen, Zeichen 0x21 (!) bis 0x7A (z) lückenlos enthalten - vll. kann’s Wer gebrauchen.
(diese Datei hätte ich gerne per Include eingebunden, so als Schmankerl - klappt natürlich auch nicht, da Es sich hierbei nicht um eine C+±Datei handelt)

MfG

font5x5.txt (16 KB)

postmaster-ino:
Leider meckert die IDE laufend, wenn ich versuche, mit einem Pointer auf _AUSRUF zu zeigen.

    int zeichen;

zeichen=&_AUSRUF;//[0];// + id;
    /*

Alter Merksatz: Der Name eines Arrays ist (bereits) ein Pointer.

Gruß Tommy

Hi

Aber ich bekomme ja den Inhalt von _AUSRUF[0], wenn ich _AUSRUF[0] verwende.
Klar hätte ich gerne genau diese Daten, wenn ich mit der ID 33 (= ! ) komme, aber wenn ich ID 34 (= " ) komme, hätte ich aber gerne den Inhalt von "_AUSRUF + 5 Byte".

Moment - kann ich _AUSRUF[5] aufrufen, um an das erste Byte hinter _AUSRUF zu kommen?
In den Beispielen wird dann ja von 'zufälligen Daten' geredet, könnte ich Mal probieren.

MfG

ich aber gerne den Inhalt von “_AUSRUF + 5 Byte”.

Was meinst du was die Zahl in den eckigen Klammern bedeutet?

Wenn du es mit Zeigern machen willst sind Stichworte “Zeigerarithmetik” und “Dereferenzierung”

Hi

Ok, nun setze ich den Wert in der Klammer auf die Zeichen-Nummer * 5.
Aber es sieht so aus, daß das Array weg-optimiert wird - hatte ja oben schon angedeutet, daß sich die PRogrammgröße beim Kompilieren nicht ändert, egal wie viele Zeichen ich per const angelegt habe.
Einzig das erste Zeichen, das Ausrufezeichen, ist vorhanden.
Das 2.te Zeichen, Anführungszeichen/Gänsefüßchen/DoppelHochkomma wird als "*** *" ausgegeben, Was ich so nicht in der Definition wieder finde - auch wird nur eine Zeile (die Unterste des Zeichen) so gesetzt, der Rest bleibt leer.

Der Versuch, einfach das Array von _AUSRUF[(233-33)*5] aufzublasen ließ zwar das Programm größer werden
5798 Byte Programmspeicher und 839 Byte dynamischer Speicher
zu
5354 Byte Programmspeicher und 395 Byte dynamischer Speicher
Aber zusätzliche Zeichen kamen nicht bei raus.

Hey, das Forum gefällt mir - gerade der Rechner abgeschmiert und der Post ist noch vorhanden :slight_smile:

Zu Referenzierung - Das soll doch wohl der & und * Vorsatz bewirken (wobei mir der Unterschied zwischen * und & noch suspekt ist).
Zeigerarithmetik werde ich mir Mal zu Gemüte führen, befürchte aber, daß Das im Arduino-Umfeld, der englischen Sprache wegen, wieder anders heißt.

... in 286er Assembler brauchte man 'nur' das Register in eckige Klammern packen und schon wurde die Speicherstelle der Nummer des Register, statt des Register benutzt - und hier optimiert mir der Compiler meine Tabelle weg.

Wie nennt sich das Stichwort, daß der Compiler die Arrays in Ruhe (und in dieser Reihenfolge) lässt?

MfG

Felder mit Konstanten werden meines Wissens nach nicht wegoptimiert.

Ich hatte Dir Links zu funktionierenden Beispielen mit Fontdefinitionen angeboten, da könntest Du mal spicken gehen:

const unsigned char CH[] PROGMEM = { ... };
byte sprite[10];
char zeichen;
memcpy_P(sprite, CH + 5 * zeichen, 5); // Ziel, Zeiger, Länge