ho una apparecchiatura che per poterla “pilotarla” ha bisogno di ricevere una stringa nel seguente formato (vedi immagine in allegato).
Ho alcuni problemi nella costruzione della stessa.
Ho alcuni dubbi su come procedere nella costruzione della stringa, qual’è il costrutto giusto da utilizzare?
Come devo scrivere i valori HEX nella mia stringa.
char Text[220];
void CCText(char * testo){
int len1=0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
while (testo[len1] != '\0') //analizzo lunghezza testo
len1++;
for(int x=0;x<len1;x++)
{
Text[16 + x]=testo[x]; //copio byte a byte
Text[x+1]='\0';
}
}
scrivento in questo modo ho problemi nel cercare il carattere di fine stringa. Praticamente non viene mai trovato.
Mentre scrivendo in quest’altro modo:
Text[0]=‘04’;
il carattere di fine stringa lo trovo, però ho problemi quando vado a buttarlo fuori. Praticamente si mangia tutti gli 0. Mi mette fuori solo il 4 anzichè 04.
Come posso ovviare a questo problema?
Problema due: posso passare in questo modo il testo da elaborare nella mia funzione? (char * testo)?
Io se fossi in te adopererei una struct con union ad un array per la parte di lunghezza fissa, in piu un array o meglio stringa per la parte variabile, è un sistema piu ordinato.
Con un po di dimestichezza tra union e struct puoi fare un bel lavoro.
il problema è che tu lavori con il testo ma quello è un vettore di byte, ovvero quando cerchi di estrarre len tu ti fermi a 1 perché '\0' == 0.
Potresti usare una struttura (l'union è irrilevante) che contenga il protocollo nel giusto ordine e inviare direttamente quello.
Poi a che serve ricavare il len quando sai già che è 16?
cosa devi pilotare? un display? come funziona? cosa devi fare?
È una specie di pesa, viene pesato un'oggetto e poi viene inviato tramite questo protocollo in una scheda che lo memorizza in un display.
Qualcuno cortesemente può farmi un piccolo esempio?
Giusto per capire come iniziarmi a muovere.
Giusto per la cronaca come potrei scrivere un valore hex in un vettore char?
int x;
for(x=0;x<len1;x++) {
Text[16 + x]=testo[x]; //copio byte a byte
}
Text[16 + x + 1]='\0';
Secondo me devi aggiungere il terminatore di stringa alla fine.
Dovrebbe funzionare anche aggiungendo ‘\0’ dentro il for, l’importante è partire da 16, altrimenti aggiungi ‘\0’ a partire da x+1.
Testa il protocollo per bene, mantenendo il codice attuale. Poi se vuoi puoi tentare di creare delle API, tipo
setColor, setCol, setRow, print, ecc.
char Text[220];
void CCText(char * testo){
int len1 = 0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
while (testo[len1] != '\0') //analizzo lunghezza testo
len1++;
for(int x=0;x<len1;x++)
{
Text[16 + x]=testo[x]; //copio byte a byte
}
Text[16+x] = '\0';
}
questo va bene, ora devi dire cosa devi fare.
certamente non puoi inviare il buffer Text come se fosse una stringa.
Ora dicci come invii i dati(Seriali,SPI,I2c) e se il buffer in quel modo è gia pronto da essere inviato.
Io comunque farei cosi:
char Text[220];
void CCText(char * testo){
int len1 = 0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
Serial.write(Text,16);
Serial.print(testo);
}
Si il for l’avevo pensato anche io. Ma c’è questo problema.
la stringa in uscita dal for è 4011000004002068FFFFFFFFFFFFFFFFFFFFFFFF4011
si “mangia” gli 0: 04 00 01 ecc.
Sto analizzando i dati in uscita tramite HyperTerminal poichè dal serial monitor non esce niente
void loop() {
int len1;
CCText("ciao");
while (Text[len1] != '\0') // questa parte continua a non andare
len1++; // praticamente vorrei vedere la lunghezza del vettore in automatico
Serial.write(Text,20);
Serial.println();
delay(1000);
}
void CCText(char * testo){
int len1 = 0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
while (testo[len1] != '\0') //analizzo lunghezza testo
len1++;
int x;
for( x = 0; x< len1; x++){
Text[x+16]= Text[x];
}
Text[x+16+1]= '\0';
}
#define DEBUG 1
void loop()
{
int len1 = CCText("ciao");
#ifdef DEBUG
byte i;
for( i =0; i < len1; ++i)
{
if (Text[i] >= 0 && Text[i] <= 0x0F )
Serial.print('0');
Serial.print(Text[i],HEX);
}
Serial.println("");
#else
Serial.write(Text,len1);
#endif
delay(1000);
}
int CCText(char * testo){
int len1 = 0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
while (testo[len1] != '\0') //analizzo lunghezza testo
len1++;
int x;
for( x = 0; x< len1; x++){
Text[x+16]= testo[x];
}
Text[x+16]= '\0';
return len1+16;
}
Non è il massimo ma dovrebbe andare, praticamente lasciando così vedi il risultato sul serial monitor, togliendo “#define debug” invece invii correttamente il buffer al dispositivo.
Questo perché il dispositivo vuole un vettore di valori, mentre il serial monitor vuole dei caratteri.
Scusa ma rispondo dal cellulare, ho finito di editare.
ascii è la codifica dei caratteri, hex è il formato di un numero. Ad ogni carattere ascii corrisponde un byte rappresentabile in formato esadecimale, non esiste conversione sono solo metodi per scrivere la stessa cosa.
La prima parte della stringa è giusta, i problemi iniziano quando devo inserire la lunghezza del CC
avevo pensato di scrivere in questo modo:
CompString[6]=lunghezzaCC; //lung CC
CompString[7]=lunghezzaCC<<8; //lung CC
LunghezzaCC lo ricevo dalla funzione, lo traslo di 8 posizioni (poichè è una int) e lo inserisco nel vettore. Non so perchè ma esce sballato.
Secondo problema: alla funzione ho passato i caratteri “ciao” ma nella stringa, quella che costruisco, non compare.
Problema più grosso di tutti: come si fa il checksum su due byte?
nella descrizione del protocollo sta scritto:
Two bytes, checksum。 Lower byte in the former。The sum of each byte from " Packet type " to “ Packet data” content
se io sommo tutto, la somma è su un byte. Non su due.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
char CompString[250];
char CCString[250];
char Text[220];
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
mySerial.println("Hello, world?");
}
void loop() // run over and over
{
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
int len1;
int i;
len1=CostStringa(CCText("ciao"));
for (i = 0; i < len1; ++i)
mySerial.write(CompString[i]);
delay(10000);
}
//costruzione stringa totale
int CostStringa(int lunghezzaCC){
CompString[0]=0xa5; //start code
CompString[1]=0x68; //Recognition of this type of packet
CompString[2]=0x32; //Fixed Type Code
CompString[3]=0x01; //ID
CompString[4]=0x7B; //ID
CompString[5]=0xFF; //ID
CompString[6]=lunghezzaCC; //lung CC
CompString[7]=lunghezzaCC<<8; //lung CC
CompString[8]=0x00;
CompString[9]=0x00;
int a;
for(a=0; a<=lunghezzaCC; a++)
{
CompString[10+a]=Text[a];
}
CompString[10 + a + 1]=0xff;
CompString[10 + a + 2]=0xff;
CompString[10 + a + 3]=0xae;
return (10 + a + 4);
}
//parte testo
int CCText(char * testo){
int len1 = 0;
Text[0]=0x04; // CC=04 invio testo statico
Text[1]=0x00; //Numero finestra da 0 a 7
Text[2]=0x01; //Invio testo semplice
Text[3]=0x01; // allineamento (0 sinistra, 1 centro, 2 destra)
Text[4]=0x00; //Coordinata X dell'area del display (byte alto)
Text[5]=0x00; //Coordinata X dell'area del display (byte basso)
Text[6]=0x00; //Coordinata Y dell'area del display (byte alto)
Text[7]=0x00; //Coordinata Y dell'area del display (byte basso)
Text[8]=0x00; //Lunghezza area display (byte alto)
Text[9]=0x40; //Lunghezza area display (byte basso)
Text[10]=0x00; //Altezza area display (byte alto)
Text[11]=0x20; //Altezza area display (byte basso)
Text[12]=0b10001000; //Font
Text[13]=0xff; //colore rosso
Text[14]=0xff; //colore verde
Text[15]=0xff; //colore blu
while (testo[len1] != '\0') //analizzo lunghezza testo
len1++;
int x;
for( x = 0; x< len1; x++){
Text[x+16]= Text[x];
}
Text[x+16+1]= 0x00;
return x+18;
}