Dot Matrix Laufschrift

Hallo,

mich macht gerade mein Code etwas zu schaffen. Wie die Überschrift vermuten lässt geht es um eine Led Dot Matrix. Insgesamt sind 4 8x8 Matrizen aneinander gekoppelt.

Funktion ist erst einmal soweit wie folgt eingebunden.

Laufschrift von x-beliebiger Länge wird auf den Matrizen in einer Dauerschleife ausgegeben. Nach jeder beendeten Zeichenkette folgt ein kleiner Abstandshalter (space). Sollten weniger Spalten für einen Text benötigt werden, als maximale Spalten zur Verfügung stehen, wird dieser ebenfalls wiederholt. (1)

Da ich jetzt unnötig den kompletten Source-Code reinstellen wollte, stelle ich die entsprechend wichtigen Funktionen nur rein. Der komplette Source Code ist noch nicht ganz aufgeräumt und dürfte dem einen oder anderen nicht viel sagen. Auf Anfrage auch den kompletten Code.

Wichtig wäre mir evtl auch, dass ich durch unnötige Variablenlängen (int16_t) evtl. den ganzen Speicher wieder etwas drücken kann. Dieser ist bei den Bastelarbeiten im Vergleich zur vorherigen Version doch etwas angestiegen. Wobei die Performance (auch wenn ungetestet) etwas schnell geworden sein könnte, da ich nicht mehr jedes einzelnes Char einzeln durchrechnen muss, wie die maximale Breite ist.

Genutzt wird ein Atmega328P. Ansonsten ist die UART Schnittstelle für Debugging sowie DS3231 miteingebunden in das Projekt. Wobei die in dieser Funktion keinen Einfluss haben.

Demo: Dropbox - Error

				Program Memory Usage 	:	6180 bytes   18,9 % Full
				Data Memory Usage 		:	294 bytes   14,4 % Full

// Die eigene Laufschriftfunktion

void max7219_puts_scroll(char *s)
{
	const uint8_t space = 6;							// Abstand zwischen den Wiederholungen in Spalten
	uint16_t size_str = max7219_width_string(s);	// Benoetigte Spalten fuer einen kompletten String
	
	int16_t start = 0;
	static int16_t x;										// Durchlaufender Versatz

	for(uint8_t c = 0; c < strlen(s); c++)
	{
		// Liest die Breite eines Zeichens aus. Breite fest definiert als 0. Stelle
		for(uint8_t i = 0; i < pgm_read_byte(&font_bold[s[c]][0])+1; i++)
		{
			for(int y = 0; y < MAX7219_MAX_COL / size_str; y++)	// 1)
			{
				max7219_write_buffer(start-x+(y*(size_str + space)), pgm_read_byte(&font_bold[s[c]][i+1]));
			}
			start++;
		}
	}

	if(x++ > (size_str+space)-2) x = 0;
	_delay_ms(80); // just debugging
}
const char font_bold[256][9] PROGMEM={
	{0x00},	// 0x00
	{0x08,0x7E,0x81,0xA9,0x8D,0x8D,0xA9,0x81,0x7E},	// 0x01
	{0x08,0x7E,0xFF,0xD7,0xF3,0xF3,0xD7,0xFF,0x7E},	// 0x02
	{0x08,0x70,0xF8,0xFC,0x7E,0xFC,0xF8,0x70,0x00},	// 0x03
	{0x07,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10},		// 0x04
	{0x07,0x1C,0x5C,0xF9,0xFF,0xF9,0x5C,0x1C},		// 0x05
	{0x07,0x08,0x1C,0x3D,0xFF,0x3D,0x1C,0x08},		// 0x06
	{0x01,0x30},												// 0x07 Benutzdefiniertes Zeichen: !Alarm1 && Alarm2
	{0x01,0x06},												// 0x08 Benutzdefiniertes Zeichen: Alarm1 && !Alarm2
	{0x01,0x36},												// 0x09 Benutzdefiniertes Zeichen: Alarm1 && Alarm1
[...]
uint16_t max7219_width_string(char *s)
{
	uint8_t width = 0;
	uint8_t i = 0;
	while(i < strlen(s))
	{
		width += pgm_read_byte(&font_bold[s[i]][0]);
		i++;
	}
	return width + (i-1);
}
void max7219_write_buffer(int16_t col, uint8_t value)
{
	if(col > MAX7219_MAX_COL || col < 0) return;
	max7219_buffer[col] = value;
}

Hab die Passage nocheinmal neu überdacht. Text kommt von Rechts und läuft nach links bis das letzte Zeichen auf dem Display erloschen ist und beginnt je nach Einstellung x mal von vorne oder unendlich.

		static int start = 5;
		static uint32_t last_output_millis;
		if(millis() - last_output_millis >= 20)
		{
			last_output_millis = millis();
			
			m
void max7219_puts_scroll1(char *s, int8_t *run)
{
	int16_t size_str = max7219_width_string(s);
	static int16_t offset = MAX7219_MAX_COL;
	int16_t x = offset;
	
	if(*run == 0) return;
	// Ausfuehren, solange noch mindesten 1 Durchlauf ansteht,
	// oder -1 fuer unendlich Durchlaeufe
	else if(*run < 0 || *run > 0)
	{
		for(uint8_t c = 0; c < strlen(s); c++)
		{
			// Spalten des Zeichens ermitteln (0 - 8 Spalten)
			uint8_t size_char = pgm_read_byte(&font_bold[s[c]][0]);
			
			for(uint8_t i = 0; i < size_char; i++)
			{
				max7219_buffer_write(i+x, pgm_read_byte(&font_bold[s[c]][i+1]));
			}
			
			// Leere Spalte nach jedem Zeichen schreiben
			max7219_buffer_write(x+size_char, 0x00);
			
			x += size_char+1;
		}
		
		// Speicher an MAX7219 senden
		max7219_buffer_send();
		
		// Wenn Ende erreicht, von vorne anfangen
		if(--offset < 0 - size_str ) { offset = MAX7219_MAX_COL; *run -= 1; }
	}
}

Falls es Dich interessiert, Aaron Liddiment hat das ganze für RGB LED Setups und FastLED geschrieben.

Ist sehr flexibel konfigurierbar.

Gruß

Helmuth

Hi Helmuth,

werde mir mal anschauen, was dort genau gemacht wird. Ist zwar nicht auf den MAX7219 portierbar, aber vielleicht finde ich Hinweise, welche sich bei mir positiv auf das Programm auswirken. Vorhin mal mit dem Logic Analyser dran gewesen. 6ms für das übertragen in das Array und abschicken fand ich schon recht lang.