void printCharWithShift(char c, int shift_speed)
{
if (c<32) return;
c-=32;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
c è il carattere
CH è la tabella.
void printCharWithShift(char c, int shift_speed)
{
if (c<32) return;
c-=32;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
c è il carattere
CH è la tabella.
Allora mi sa che devi aggiungere i caratteri che vuoi alla tabella, ho cercato su internet e ho trovato questo strumento LED Matrix Editor
direi che fa al caso tuo, attiva il checkbox as byte array
I due caratteri li ho già disegnati:
4, 8, B00111000, B01010101, B01010110, B00011000, B00000000, // è CH[95]
4, 8, B00111000, B01010110, B01010101, B00011000, B00000000, // é CH[96]
Il problema è riconoscere le due lettere.
Non credo che tu possa "riconoscerlo" in automatico in quanto esci dalla codifica standard, come hai detto tu per ricercare nella matrice usa il codice ASCII vi sottrae 32 e poi copia il contenuto della matrice nel buffer per inviarlo alla matrice, il carattere è equivale a 138, la procedura standard farebbe 138-32=106 ma tu nella matrice hai indicato tale carattere alla posizione 95, quindi hai due strade, la prima definire tutti i caratteri intermedi tra 95 e 105 e indicare il tuo carattere alla posizione 106 e fare la medesima cosa per l'altro carattere, ma non lo ritengo efficiente in quanto definiresti una marea di caratteri per nulla, oppure nella procedura controlli che se ti arriva il carattere 138 gli assegni 127 (95+32) e la procedura farà il resto (sottrae 32, moltiplica e stampa), stessa cosa per gli altri caratteri non avendo più una corrispondenza "matematica" dovrai sopperire con vari if visto che i caratteri è ed é non sono consecutivi nella tabella, così come altri caratteri accentati
Purtroppo l'ho già fatto, ma non funziona...
void printCharWithShift(char c, int shift_speed)
{
if(c<32) return;
if(c<126) c-=32;
if(c==138) c=95;
if(c==139) c=96;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
...
è e é non vengono riconosciute. Se metto if(c==65), che è a (97-32=65), anziché Ciao scrive Cèao.
Se stampi sulla seriale il contenuto di c e il contenuto di buffer prima della writeSprite cosa vedi?
Ovvio che per buffer dovrai darti un po' da fare per stampare i valori a cui punta poiché stai puntando ad un array con 7 byte di dati.
Non vedo altro da suggerire, a livello logico dovrebbe andare
Ho messo un Serial.print(c) e un Serial.println(*s):
void printCharWithShift(char c, int shift_speed)
{
if(c<32) return;
Serial.println(c); // <<<<<<<<<<
if(c<126) c-=32;
if(c==138) c=95;
if(c==139) c=96;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
m.setColumn(32+buffer[0], 0);
for(int i=0; i<buffer[0]+1; i++)
{delay(shift_speed); m.shiftLeft(false, false);}
}
void printStringWithShift(char*s, int shift_speed)
{
while(*s!=0)
{
char pippo=*s;
Serial.print(*s); // <<<<<<<<<<
printCharWithShift(*s, shift_speed);
s++;
}
La "è" ha *s, ma non c (la seconda funzione chiama la prima, quindi è scritto prima *s):
QQ
uu
ee
ss
tt
oo
è
ii
ll
tt
ee
ss
tt
La butto li secondo me se prima di
if(c<32) return;
metti una serial print "QUI" e dopo
if(c<32) return;
metti una serial print "QUI NO"
Quando passi la è vedrai solo QUI e non vedrai QUI NO, perchè secondo me la è va oltre i 127 e il char viene passato con valore 11, se è così devi variare tutti i punti specificando o byte o unsigned char
11 non è:
void printCharWithShift(char c, int shift_speed)
{
if(c==11) {c=95; goto SALTA_QUI;}
if(c<32) return;
if(c<126) c-=32;
if(c==139) c=96;
SALTA_QUI:
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
m.setColumn(32+buffer[0], 0);
FUNZIONA!!!
Ho trasformato tutti i char in unsigned char. Ovviamente 232 e 233 non potevano stare in una variabile a 8 bit con il segno... (Perché una variabile char, cioè carattere, abbia il segno, è per ora un mistero, ma questa è un'altra storia! )
void printCharWithShift(unsigned char c, int shift_speed)
{
if(c<32) return;
if(c<126) c-=32;
if(c==232) c=95;
if(c==233) c=96;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
Grazie per la tua pazienza, fab!
+1
Datman:
... Perché una variabile char, cioè carattere, abbia il segno, è per ora un mistero ...
... semplicemente perché NON è definito da nessuna parte che char debba per forza essere signed o unsigned e viene lasciata libertà di implementazione (alcuni compilatori hanno un'opzione per definire il char signed o unsigned).
Io ho preso l'abitudine di usare <strdint.h> e deichiare le variabile esattamente come sono ...
uint8_t
int8_t
uint16_t
int16_t
...
... così sono sicuro del risultato
Guglielmo
P.S.: Il K&R testualmente dice: "Whether plain chars are signed or unsigned is machine-dependent, but printable characters are always positive."
Non era 11 bho ho sbagliato il conto sarà stato 12 o 10, comunque l'ipotesi era corretta, bene aver risolto.
P.S. = [MODO BURLA ON]al GOTO volevo trafiggermi con una lancia ;D [FINE MODO BURLA]
Era il modo più semplice per fare la prova
Comunque una volta ogni tanto si può usare, dai, non fa danni come String! Bisogna stare attenti a non saltare dove capita...
Fermi tutti! Dove ho sbagliato??? Non funziona più! >:(
...
Mah... Nel testo c'era scritto "è", ma sul display appariva uno sgorbio quasi quadrato... Ho riavviato (perché l'IDE aveva cominciato a "incollare" tra loro i caratteri >:( ), ho riscritto "è" e adesso funziona!
Adesso ho capito, ma è incredibile! :o
Ho provato ad aggiungere le 3 righe indicate, cercando di far apparire il numero del messaggio selezionato:
while(digitalRead(6)) // Continua a leggere l'encoder finché non premo
{
encoder();
if(E!=0)
{
nMsg+=E; E=0;
if(nMsg<1) nMsg=1;
else if(nMsg>4) nMsg=4;
delay(10);
char output[2]; // <<<<<<<<<<<<
itoa(nMsg, output, 10); // <<<<<<<<<<<<
printString(output); // <<<<<<<<<<<<
}
}
Subito dopo ho caricato e al posto della è usciva lo sgorbio!
Le ho commentate, ho ricaricato sul microcontrollore ma nulla è cambiato!
Ho riscritto la "è" (che nel testo scritto appariva già come una "è"...), ho ricaricato ed è andato bene!
Adesso sto esagerando! Ho azzardato un itoa, ma c'è qualcosa che non va, perché appaiono simboli strani...
Sto cercando di far apparire il numero del messaggio mentre ruoto l'encoder. Il resto funziona bene, ma questo no... Mi potete aiutare?
Grazie!
while(digitalRead(6)) // Continua a leggere l'encoder finché non premo
{
encoder();
if(E!=0)
{
nMsg+=E; E=0;
if(nMsg<1) nMsg=1;
else if(nMsg>4) nMsg=4;
delay(10);
// char numero[2];
// itoa(nMsg, numero, 10);
memcpy_P(buffer, CH+7*(16+nMsg), 7);
m.writeSprite(0, 7, *numero);
for(int i=0; i<8; i++)
{delay(35); m.shiftUp(false);}
}
}
Non so come, ma funziona tutto!
/* 8x8 LED Matrix MAX7219 Scrolling Text
Android Control via Bluetooth
by Dejan Nedelkovski, www.HowToMechatronics.com
Based on the following library:
GitHub | riyas-org/max7219 https://github.com/riyas-org/max7219
https://howtomechatronics.com/tutorials/arduino/8x8-led-matrix-max7219-tutorial-scrolling-text-android-control-via-bluetooth/
*/
#include <MaxMatrix.h>
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
// R E D4 D5 D6 D7
LiquidCrystal lcd(8,9,10,11,12,13);
byte dIn=8; // DIN pin of MAX7219 module
byte clk=9; // CLK pin of MAX7219 module
byte cs=10; // CS pin of MAX7219 module
byte maxInUse=2; // Number of MAX7219's connected
MaxMatrix m(dIn, cs, clk, maxInUse);
SoftwareSerial Bluetooth(12, 11); // Rx, Tx per il modulo Bluetooth.
byte buffer[10];
char incomebyte;
// ----------------------------------------------------
int velocita=50; // 0...100
unsigned long pausa=3000; // Pausa in millisecondi.
int brightness=3;
unsigned char testo[4][100]= // nMsg va da 1 a N; gli indici dei testi vanno da 0 a N-1.
{
// n.1, indice 0
"Trovate i nostri video su www.youtube.com/mariachescioglieinodi",
// n.2, indice 1
"Questo è il testo 2",
// n.3, indice 2
"Questo qui è il testo 3",
// n.4, indice 3
"Testo numero quattro"
};
void(* Riavvia)(void) = 0;
// ----------------------------------------------------
int count=0;
char indicator;
int scrollSpeed=30;
unsigned long t0; // Per la pausa in printCharWithShift().
unsigned long t1; // Per la pressione prolungata del tasto.
uint8_t nMsg=1;
int E; // Risultato della routine encoder(): 1, -1, 0.
uint8_t S; // Lettura dei due valori dell'encoder.
uint8_t So;// Lettura precedente dell'encoder.
int X; // Usato in encoder() per evitare letture multiple.
PROGMEM const unsigned char CH[] = {
// Prima colonna 2a 3a 4a Quinta colonna
3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space CH[0]
1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '
3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // * CH[10]
5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4 CH[20]
4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <
3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =
3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // > CH[30]
4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H CH[40]
3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R CH[50]
4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash CH[60]
2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat
4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d
4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e
3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f CH[70]
4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p CH[80]
4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s
3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t
4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u
5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v
5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w
5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x
4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y
3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z CH[90]
3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~ CH[94]
4, 8, B00111000, B01010101, B01010110, B00011000, B00000000, // è CH[95]
4, 8, B00111000, B01010110, B01010101, B00011000, B00000000, // é CH[96]
};
void setup()
{
Serial.begin(9600);
pinMode(4, INPUT_PULLUP); // Encoder A
pinMode(5, INPUT_PULLUP); // Encoder B
pinMode(6, INPUT_PULLUP); // Pulsante
if(!digitalRead(6)) selezione();
if(velocita>100) velocita=100;
scrollSpeed=110-velocita;
if(EEPROM.read(1)>9) EEPROM.update(1,1);
nMsg=EEPROM.read(1); if(nMsg>9) nMsg=1;
Serial.println(nMsg);
delay(500);
m.init(); // MAX7219 initialization
m.setIntensity(brightness); // initial led matrix intensity, 0-15
Bluetooth.begin(9600); // Default communication rate of the Bluetooth module
// Bluetooth.begin(38400); // Default communication rate of the Bluetooth module
}
void loop()
{
unsigned char* text=testo[nMsg-1]; // nMsg va da 1 a N; gli indici dei testi vanno da 0 a N-1.
printStringWithShift(text, scrollSpeed); // Printing the text
if(Bluetooth.available()) // Checks whether data is comming from the serial port
{
indicator=Bluetooth.read(); // Starts reading the serial port, the first byte from the incoming data
if(indicator=='1') // If we have pressed the "Send" button from the Android App, clear the previous text
{
for(int i=0; i<100; i++)
{text[i]=0; m.clear();}
while(Bluetooth.available()) // Read the whole data/string comming from the phone and put it into text[] array.
{
incomebyte=Bluetooth.read();
text[count]=incomebyte;
count++;
}
count=0;
}
else if(indicator=='2') // Adjusting the Scrolling Speed
{
String sS=Bluetooth.readString();
scrollSpeed=150-sS.toInt(); // Milliseconds, subtraction because lower value means higher scrolling speed
}
else if(indicator=='3') // Adjusting the brightness
{
String sB=Bluetooth.readString();
brightness=sB.toInt();
m.setIntensity(brightness);
}
} // END if Bluetooth available
} // END loop
void selezione()
{
char numero[2];
itoa(nMsg+10, numero, 10);
printString(numero);
while(!digitalRead(6)); // Attende che venga lasciato il pulsante.
while(digitalRead(6)) // Continua a leggere l'encoder finché non premo
{
encoder();
if(E!=0)
{
nMsg+=E; E=0;
if(nMsg<1) nMsg=1;
else if(nMsg>4) nMsg=4;
delay(10);
char numero[2];
itoa(nMsg+10, numero, 10);
printString(numero);
}
}
}
void printCharWithShift(unsigned char c, int shift_speed)
{
if(c<32) return;
if(c<126) c-=32;
if(c==232) c=95;
if(c==233) c=96;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(32, 0, buffer);
m.setColumn(32+buffer[0], 0);
for(int i=0; i<buffer[0]+1; i++)
{delay(shift_speed); m.shiftLeft(false, false);}
}
void printStringWithShift(unsigned char*s, int shift_speed)
{
while(*s!=0)
{
if(!digitalRead(6)) {selezione(); EEPROM.update(1,nMsg); while(!digitalRead(6)); Riavvia();}
printCharWithShift(*s, shift_speed);
s++;
}
if(*s==0)
{
t0=millis();
while(millis()-t0<pausa)
{
printCharWithShift(' ', shift_speed);
}
}
}
void printString(unsigned char*s)
{
int col=6;
while(*s!=0)
{
if(*s<32) continue;
unsigned char c=*s-32;
memcpy_P(buffer, CH+7*c, 7);
m.writeSprite(col, 0, buffer);
m.setColumn(col+buffer[0], 0);
col+=buffer[0]+1;
s++;
}
}
void encoder()
{
// PD 76543210
// S=3-(PIND>>3)&B00000011; Serviva per l'encoder su PD3 e PD4.
// S=3-PIND&B00000011; Gli I/O 0 e 1 sono PD0 e PD1, perciò non devo scorrere a destra.
S=3-((PIND>>4)&B00000011); // Gli I/O 4 e 5 sono PD4 e PD5, perciò devo scorrere a destra di 4 bit.
// Il valore binario di S rappresenta A e B. Il centrale dell'encoder è a massa, quindi faccio complemento a 3 (11).
S^=S>>1; // Faccio XOR (^) fra S (gray) e il suo bit 1, facendolo scorrere a Dx: AB XOR A,
// ottenendo un binario che per ogni scatto fa 0-1-2-3-0 oppure 0-3-2-1-0.
if (S!=So && S==0) X=0;
if (X==0)
{
if (So==1&&S==2)
{E=1; X=1;;}
if (So==3&&S==2)
{E=-1; X=1;;}
if (S==0)
{E=0; X=0;}
So=S;
}
}
In qualunque momento è possibile interrompere lo scorrimento e visualizzare un altro messaggio;
Mentre si ruota l'encoder, appare il numero del messaggio selezionato.
Purtroppo, al cambio del messaggio ho dovuto fare risorso al fantomatico puntatore alla locazione zero, perché i buffer rimanevano carichi... Non ho trovato una soluzione semplice diversa.