Code:
	// Ein 24*16 Ascii-Bild                                                    3.5.10 mic
// Mit neuen Erkenntnissen ein Versuch, diese umzusetzen. Ziel war möglichst
// schnell einen Überblick über den Bildinhalt einzulesen und ohne zu Scrollen
// im Terminal darzustellen. Dazu verwende ich anstelle des Loaders ein anderes
// Terminalprogramm: https://www.roboternetz.de/phpBB2/viewtopic.php?t=54087
// Es funktioniert aber in dieser Version auch mit dem RP6Loader!
// Es werden in einem Halbbild(!) von 24 Linien jeweils die 16 Zeilenwerte am Stück
// eingelesen. Das ergibt zwar ein extrem verzerrtes Bild, aber mit 90°-Drehung
// und mit Ausgabe der Werte im Hexformat hat man so durchaus ein Bildgefühl ;)
#include "RP6RobotBaseLib.h"
#define vt100_Black        0 // VT100 Farbdefinitionen
#define vt100_Red          1
#define vt100_Green        2
#define vt100_Yellow       3
#define vt100_Blue         4
#define vt100_Magenta      5
#define vt100_Cyan         6
#define vt100_White        7
#define vt100_Reset			0
#define vt100_Bright			1
#define vt100_Dim				2
#define vt100_Underscore	4
#define vt100_Blink			5
#define vt100_Reverse		7
#define vt100_Hidden			8
uint8_t c; // freies Char
uint16_t x, y;
uint8_t std, min, sec;
void init(void);
void setMotorPWM(uint8_t power_links, uint8_t power_rechts);
void vt100_cls(void);
void vt100_set_cursor(uint8_t line, uint8_t column);
void vt100_set_color(uint8_t foreground, uint8_t background);
void vt100_set_attrib(uint8_t attrib);
void vt100_writeGrafic(uint8_t *string);
void vt100_writeGraficAt(uint8_t line, uint8_t column, uint8_t *string);
void Bild_aufnehmen(void)
{
	// Variablen dürfen NICHT global sein!
	uint8_t bildspeicher[24][16], *bildzeiger;
	uint8_t zeile, sync, c;
	zeile=30; // 30 Zeilen am Bildanfang überlesen
	// Warten auf langen Syncbereich = Bildstart
	cli();
	do{sync=0;while (ADCH > 20);while (ADCH < 30) sync++;}while (sync < 40);
	for(c=0; c<24; c++) // 24 Zeilen einlesen
	{
		bildzeiger=&bildspeicher[c][0];
		sync=15; // 15 Werte sollen am Stück gelesen werden
		while(zeile--){while (ADCH > 20);while (ADCH < 30);} // auf Zeile warten
		*bildzeiger++=ADCH; // erster Wert!
		ADCSRA |= (1<<ADIF);
		while(sync--) // Werte 2-16 einlesen
		{
		   while(!(ADCSRA & (1<<ADIF)));
			*bildzeiger++=ADCH;
			ADCSRA |= (1<<ADIF);
		}
		zeile=10; // 10 Zeilen überlesen (30+ 24*10 = 270 Zeilen) Sind auch 11 möglich?
	}
	sei();
	// Hier kann man die Darstellung mit dem VT100-Terminal verbessern
	writeChar('\n'); // extra Vorschub für RP6Loader
	writeChar('\n');
	// vt100_set_cursor(3,1); // Bildstart bei VT100-Terminal, beim RP6Loader störend
	for(c=0; c<16; c++)
	{
		for(zeile=0; zeile<24; zeile++)
		{
			writeChar(' ');
			//writeIntegerLength(bildspeicher[23-zeile][c], HEX, 2); // Hexwerte
			writeChar((bildspeicher[zeile][c]-30)/10+'0');
  		}
		writeChar('\n');
	}
}
int main(void)
{
	init();
	vt100_cls();
	writeString_P(" Ein 24*16 Ascii-Bild per VT100                               3.5.10 mic");
	setStopwatch1(0);
	startStopwatch1();
	while(1)
	{
		if(getStopwatch1() >999) // Uhr
		{
		   setStopwatch1(0);
			sec++;
			if(sec>59) {sec=0; min++;}
			if(min>59) {min=0; std++;}
			if(std>23) std=0;
			vt100_set_cursor(26,72);
			writeIntegerLength(std,10,2);
			writeChar(':');
			writeIntegerLength(min,10,2);
			writeChar(':');
			writeIntegerLength(sec,10,2);
			
			Bild_aufnehmen(); // Bildrefresh nach einer Sekunde
		}
	}
	return(0);
}
void init(void)
{
   initRobotBase();
   //DDRC |= (SCL | SDA);         // Servopins auf Ausgang setzen
   //TIMSK |= (1 << TOIE1);       // Die Timer1 Overflow-ISR zur Servoansteuerung
	extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
	ADMUX = (1<<REFS1) | (1<<REFS0)  | (1<<ADLAR) | 4;
// setzte free running triggern
	SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaller /2
	ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1)  | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
	ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
	ADCSRA |= (1<<ADSC);
// und noch die wohl eher unnötige Initiallesung
	while (!(ADCSRA & (1<<ADIF)));
	ADCSRA |= (1<<ADIF);
	//powerON();
}
// Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
{
extern uint8_t mleft_ptmp, mright_ptmp;
	if(power_links > 210) power_links = 210;
	if(power_rechts > 210) power_rechts = 210;
	mleft_power=mleft_ptmp=power_links;
	mright_power=mright_ptmp=power_rechts;
	OCR1BL = power_links;
	OCR1AL = power_rechts;
	if(power_links || power_rechts)
		TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
	else
		TCCR1A = 0;
}
void vt100_cls(void)
{
	writeString_P("\x1B[2J"); // clear screen ESC [ 2 J
	writeString_P("\x1B[H"); // cursor home ESC [ H
}
void vt100_set_cursor(uint8_t line, uint8_t column)
{
   writeString_P("\x1B["); // set cursor position  ESC [ Pl ; Pc H
   writeInteger(line, 10);
   writeString_P(";");
   writeInteger(column, 10);
   writeString_P("H");
}
void vt100_set_color(uint8_t foreground, uint8_t background)
{
	writeString_P("\x1b[");
	writeInteger(30+foreground, 10);
	writeString_P(";");
	writeInteger(40+background, 10);
	writeString_P("m");
}
void vt100_set_attrib(uint8_t attrib)
{
	writeString_P("\x1b[");
	writeInteger(0, 10);
	writeString_P(";");
	writeInteger(attrib, 10);
	writeString_P("m");
}
void vt100_writeGrafic(uint8_t *string)
{
	while(*string)
		writeChar(128|*string++); // Grafikzeichen mit gesetztem Bit7 senden
}
void vt100_writeGraficAt(uint8_t line, uint8_t column, uint8_t *string)
{
	vt100_set_cursor(line, column); // Cursor postionieren
	while(*string)
		writeChar(128|*string++); // Grafikzeichen mit gesetztem Bit7 senden
}
 Das Bild wird einmal in der Sekunde neu dargestellt, mit ZOC steht dabei das Bild still und wird nicht hochgescrollt.
Lesezeichen