#include <LiquidCrystal.h>
#include "MTScrollText.h"
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// "Hello pico!" è in RAM.
char *myString = "Hello pico!";
uint32_t millisOldTime = 0;
uint8_t speedScroll = 30; // un carattere ogni 30ms
// myScrollD( 20 ) occupa 16 colonne sul display
MTScrollText myScroll( 16 );
/*
"MauroTec Software Lun 31 Gen 2022"
" 00:00:00 WokWi Simulator ";
#define LEN_TEXT 59
char textBuff[LEN_TEXT + 1] = {0};
Invece di contare manualmente il numero di caratteri
di cui è composta la stringa da visualizzare (textBuff)
uso strlen che viene risolto al momento della compilazione
e ricavo in lenText la lughezza per creare textBuff.
Nota che la string literal "MauroTec ... non si trova in
RAM e quindi non ci sono controidicazioni.
*/
#define LEN_TEXT lenText
const int lenText = strlen("[MauroTec Software], millis() vale "
"4294967295 ");
char textBuff[lenText + 1] = {0};
/* Il compilatore ha messo textBuff in RAM all'indirizzo
0x172 dove si vede che ci sono 46 spazi, quindi lenText
vale 46.
*/
void showRam() {
// spazzoliamo tutta la ram cella per cella.
// come da datasheet inizio da 0x100
const char *ptrToRam = (char*)0x100;
// mi servono 16 caselle da 0÷15
uint8_t counter15 = 15;
Serial.print(F("addr\t0123456789ABCDEF"));
// Nota per il 328 RAMEND vale 2303
for (uint16_t t=0; t<=(RAMEND-0x100); t++) {
if (counter15 == 15) {
Serial.print("\n");
Serial.print((uint16_t)ptrToRam, HEX);
Serial.print("\t");
}
if ((counter15 > -1) && (counter15 < 16)) {
// vogliamo vedere i caratteri quindi
// dal puntatore con * otteniamo il puntato
// e poi il cast a char
char b = (char)*ptrToRam++;
// se b non è rappresentabile
// stampo il punto ".".
if ((b < 32) || (b > 126)) {
Serial.print(".");
} else {
Serial.print(b);
}
}
counter15--;
counter15 = counter15 % 30;
}
Serial.println();
}
void reverseClear( uint8_t r, uint8_t c, uint8_t len) {
for (int8_t col=c+len; col >c-1; col--) {
lcd.setCursor(col, r);
lcd.print(' ');
delay(20);
}
}
void letter(const char c, const uint8_t col) {
for (char i=32; i<=c; i++) {
lcd.setCursor(col, 0);
lcd.print(i);
delay(1);
}
}
void setup()
{
Serial.begin(115200);
lcd.begin(16, 2);
// inizializza e stabilisce la lunghezza di textBuff
memset(textBuff, ' ', LEN_TEXT);
myScroll.setText(textBuff);
Serial.println(LEN_TEXT);
// questi caratteri non sono in RAM
letter( 'M', 4 );
letter( 'A', 5 );
letter( 'U', 6 );
letter( 'R', 7 );
letter( 'O', 8 );
letter( 'T', 9 );
letter( 'E', 10 );
letter( 'C', 11 );
delay(200);
reverseClear(0, 4, 8);
delay(100);
lcd.setCursor(4, 0);
lcd.print("MAUROTEC");
showRam();
uint32_t zero = 0;
uint32_t uno = 1;
if (0-1 < 0) {
Serial.println("0-1 < 0");
}
if (zero-uno < zero) {
Serial.println("zero-uno < zero");
}
Serial.println(zero-uno);
millisOldTime = millis();
Serial.println(myString);
} // end void setup()
uint8_t gCounter = 0;
uint32_t millisCont = 0;
void loop() {
// tutte le string literal in sprintf sono in RAM.
sprintf(textBuff, "%s %#9ul ",
"[MauroTec Software], millis() vale",
millis()
);
if (millis() - millisOldTime >= speedScroll) {
millisOldTime = millis();
gCounter++;
if (gCounter == 70)
myScroll.restart(); // riavvio da capo lo scorrimento
else if (gCounter == 150) {
myScroll.clear(); //fermo lo scorrimento e resetto il buffer
// lcd.setCursor(0, 1);
// ferma lo scorrimento, resetta il buffer
// e pulisce la riga.
// lcd.print(myScroll.clear());
}
const char *scrollBuff = myScroll.doScroll();
lcd.setCursor(0, 1);
if (myScroll.isScroll()) {
lcd.print(scrollBuff);
} else {
if (gCounter == 0) {
// dopo un myScroll.clear() il buffer
// è composto da 16 spazi e lo usiamo
// per pulire la riga
lcd.print(scrollBuff);
lcd.setCursor(0, 1);
// la string literal seguente è in RAM
lcd.print("gCounter = ");
lcd.print(gCounter);
} else if (gCounter == 30) {
myScroll.setScroll(true);
} else if (gCounter == 190) {
lcd.print(scrollBuff);
lcd.setCursor(0, 1);
// la string literal seguente NON è in RAM
lcd.print(F("not Scroll text "));
}
}
}
} // end void loop()