Costruzione stringa

Salve ragazzi,

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)?

Grazie a tutti :wink:

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?

Grazie

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.

Ciao.

union Frame
{
	struct s
	{
		uint32_t idCode;
		uint16_t networkDataLength;
		uint16_t reservation;
		uint8_t packetType;
		uint8_t cardType;
		uint8_t cardId;
		uint8_t protocolCode;
		uint8_t additionalInformation;
		uint8_t packetDataLength;
		uint8_t packetNumber;
		uint8_t lastPacketNumber;
		uint8_t cc;
		uint8_t windowNO;
		uint8_t dataType;
		uint8_t levelOfAlignment;
		uint8_t displayAreaX;
		uint8_t displayAreaY;
		uint8_t displayAreaWidth;
		uint8_t displayAreaHeight;
		uint8_t font;
		uint8_t colorR;
		uint8_t colorG;
		uint8_t colorB;
	} s;
	uint8_t a[28];
};

Questo potrebbe essere il tipo Frame per la parte di dimensione fissa del pacchetto.

@blasted

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);
}

Credo che su Text[12] ci voglia uno 0b iniziale :).

Buongiorno,
grazie a tutti per l'aiuto. La stringa verrà inviata tramite ethernet (TCP). Il modulo che ho a disposizione è il enc28j60.

Per le prove posso utilizzare anche la seriale.

Grazie

Ragazzi, ho un problema.
Esaminando quello che esce dalla seriale, utilizzando come trasmissione dati questo comando:
Serial.write(Text,20);

04 01 01 40 20 cb 86 20 20 20 c3 8d c3 89 c3 8a c3 8a

ho notato che vengono saltati tutti i caratteri 0x00
la stringa dovrebbe essere
04 00 01 01 00 40 20 cb 86 20 20 20 c3 8d c3 89 c3 8a c3 8a

Cosa può essere?

SukkoPera:
Credo che su Text[12] ci voglia uno 0b iniziale :).

Si hai ragione, volevo scriverlo pure io ma me ne sono dimenticato.

blasted:
Ragazzi, ho un problema.
Esaminando quello che esce dalla seriale, utilizzando come trasmissione dati questo comando:
Serial.write(Text,20);

04 01 01 40 20 cb 86 20 20 20 c3 8d c3 89 c3 8a c3 8a

ho notato che vengono saltati tutti i caratteri 0x00
la stringa dovrebbe essere
04 00 01 01 00 40 20 cb 86 20 20 20 c3 8d c3 89 c3 8a c3 8a

Cosa può essere?

Posta sempre il codice aggiornato.

semplicemente non li visualizza il serial monitor, ma le invii.
potresti fare così:

for (i = 0; i < 20; ++i)
    Seria.println(Text[i],HEX);

Però così vengono manipolati i dati e non vanno bene per inviarli al dispositivo.

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';
}

Scarica un terminale che supporti la visualizzazione HEX. Quello di Arduino è fortemente sconsigliato in questi casi.

#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.

Ragazzi penso che manca un pezzo

quando faccio il ciclo for

for( x = 0; x< len1; x++){
Text[x+16]= testo;
}

vado a prendere un valore in ascii e lo memorizzo insieme a dei valori in HEX.
Quindi penso che dovrei convertirlo da ascii ad HEX.

Esiste qualche funzione o devo fare qualche calcolo particolare?

grazie

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.

'a' == 0x61 == 97 == 10100001
dillo come ti pare......

Perfetto, grazie della spiegazione. domani mattina provo!

Buonasera,

la stringa pian piano si sta generando.
Ho ancora qualche piccolo problema

A5 68 32 01 7B FF 16 00 00 00 04 00 01 01 00 00 00 00 00 40 00 20 88 FF
FF FF 04 00 01 01 00 00 00 00 FF FF AE

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.

Il protocollo lo trovate qui: http://postimg.org/image/50yn5li5p/

#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;
}