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