Chiedo aiuto a qualche esperto !!!  :o

Sono giorni che impazzisco su questo pezzo di codice e proprio non riesco a venirne a capo !!! E' un pezzo del protocollo di comunicazione che vorrei utilizzare per la domotica. Il programma per ora dovrebbe fare questo:

inviare questo comando F0 00 01 00 00 00 00 84 00 F1

F0 = Inizio comando
00 = Sono il master
01 = Messaggio destinato allo slave
00 = Hai qualcosa da comunicarmi ?
00 = /
00 = /
00 = /
00 = /
84 = 1° Byte di controllo di integrità del messaggio
00 = 2° Byte di controllo di integrità del messaggio
F1 = Fine comando

se lo slave risponde con F0 01 00 03 AA AA 00 00 00 F1 setto le uscite corrispondenti al 5° e 6° byte ovvero AA ... ovvero 1010101010101010 ... ovvero l'uscita 1, 3, 5, 7, 9, 11, 13 e 15

se poi lo slave invia anche F0 01 00 04 FF FF 00 00 00 F1 resetto le uscite corrispondenti al 5° e 6° byte ovvero FF ... ovvero 1111111111111111 ... ovvero l'uscita 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

Quindi ricapitolando il 4°byte indica il comando (03=setta uscita, 04=resetta uscita, 05=inverti uscita) e il 5° e il 6° byte rappresentano "quali" uscite verranno settate, resettate o invertite.

Ok, il problema è questo: al primo invio tutto funziona bene, al secondo invio stranamente non cambia di stato nessun'uscita, e dal terzo invio in poi esegue il comando ma con le uscite del comando precedente ... mi spiego meglio:

se invio

  • Setta 1, 2, 3
  • Resetta 4, 5, 6
  • Inverti 7, 8, 9
  • Resetta 10
  • Setta 11, 12

L'arduino esegue queste operazioni

  • Setta le uscite 1, 2, 3
  • Non esegue niente
  • Inverte le uscite 4, 5, 6
  • Resetta le uscite 7, 8, 9
  • Setta l'uscita 10
/*Struttura messaggio*/
byte InizioTrasmissione = B11110000;
byte IDmittente;
byte IDdestinatario;
byte Comando;
byte Puntatore;
byte ValoreMSB;
byte ValoreLSB;
byte ControlloIntegritaR;
byte ControlloIntegritaC;
byte FineTrasmissione = B11110001;

/*ID Dispositivi*/
byte IDmaster = B00000000;
byte IDslave1 = B00000001;
byte IDslave2 = B00000010;
byte IDslave3 = B00000011;
byte IDslave4 = B00000100;
byte IDslave5 = B00000101;
byte IDslave6 = B00000110;
byte IDslave7 = B00000111;
byte IDslave8 = B00001000;
byte IDslave9 = B00001001;
byte IDslave10 = B00001010;

/*Comandi*/
byte InterrogaNodo = B00000000;
byte NienteDaComunicare = B00000001;
byte TxRxOk = B00000010;
byte SetOut = B00000011;
byte ResetOut = B00000100;
byte InvertOut = B00000101;
byte EseguiFunzione = B00000110;
byte InterrogaInDigit = B00000111;
byte ComunicaInDigit = B00001000;
byte InterrogaInAnalog = B00001001;
byte ComunicaInAnalog = B00001010;
byte InterrogaVarabile = B00001011;
byte ComunicaVariabile = B00001100;

/*Costanti*/
byte ByteVuoto = B00000000;

/*Altre variabili*/
boolean bitMessaggio[63]; // Bit della matrice per calcolare i byte di controllo
int IDcicloTxRx; // Indice della seguenza di messaggi da inviare/ricevere
byte inByte; // Numero di byte presenti nel buffer della seriale
int indexByteMessaggioRx;
byte messaggioRx[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // E' l'array che contiene i 10 byte del messaggio ricevuto
boolean statoUscita[16] = {
  LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // E' lo stato delle uscite del master

void setup()
{
  Serial.begin(9600);
  pinMode(23, OUTPUT);
  pinMode(25, OUTPUT);
  pinMode(27, OUTPUT);
  pinMode(29, OUTPUT);
  pinMode(31, OUTPUT);
  pinMode(33, OUTPUT);
  pinMode(35, OUTPUT);
  pinMode(37, OUTPUT);
  pinMode(39, OUTPUT);
  pinMode(41, OUTPUT);
  pinMode(43, OUTPUT);
  pinMode(45, OUTPUT);
  pinMode(47, OUTPUT);
  pinMode(49, OUTPUT);
  pinMode(51, OUTPUT);
  pinMode(53, OUTPUT);
}

void loop()
{

  if (Serial.available() > 0) {
    inByte = Serial.read();
    if (inByte==InizioTrasmissione){
      indexByteMessaggioRx=0;
    }
    messaggioRx[indexByteMessaggioRx] = inByte;
    indexByteMessaggioRx++;
  }

  switch (IDcicloTxRx) {

  case 0:
    IDmittente = IDmaster;
    Comando = InterrogaNodo;
    Puntatore = ByteVuoto;
    ValoreMSB = ByteVuoto;
    ValoreLSB = ByteVuoto; 
    IDdestinatario = IDslave1;
    FunzioneCalcoloChk();
    FunzioneInvioComando();
    IDcicloTxRx=1;
    break;
  case 1:
    if (messaggioRx[0]==InizioTrasmissione && messaggioRx[1]==IDslave1 && messaggioRx[2]==IDmaster && messaggioRx[3]==SetOut && messaggioRx[4]==0 && messaggioRx[9]==FineTrasmissione){ // Aggiungere i byte di controllo  
      if (bitRead(messaggioRx[6], 0)== HIGH){
        settaUscita(0);
      }
      if (bitRead(messaggioRx[6], 1)== HIGH){
        settaUscita(1);
      }
      if (bitRead(messaggioRx[6], 2)== HIGH){
        settaUscita(2);
      }
      if (bitRead(messaggioRx[6], 3)== HIGH){
        settaUscita(3);
      }
      if (bitRead(messaggioRx[6], 4)== HIGH){
        settaUscita(4);
      }
      if (bitRead(messaggioRx[6], 5)== HIGH){
        settaUscita(5);
      }
      if (bitRead(messaggioRx[6], 6)== HIGH){
        settaUscita(6);
      }
      if (bitRead(messaggioRx[6], 7)== HIGH){
        settaUscita(7);
      }
      if (bitRead(messaggioRx[5], 0)== HIGH){
        settaUscita(8);
      }
      if (bitRead(messaggioRx[5], 1)== HIGH){
        settaUscita(9);
      }
      if (bitRead(messaggioRx[5], 2)== HIGH){
        settaUscita(10);
      }
      if (bitRead(messaggioRx[5], 3)== HIGH){
        settaUscita(11);
      }
      if (bitRead(messaggioRx[5], 4)== HIGH){
        settaUscita(12);
      }
      if (bitRead(messaggioRx[5], 5)== HIGH){
        settaUscita(13);
      }
      if (bitRead(messaggioRx[5], 6)== HIGH){
        settaUscita(14);
      }
      if (bitRead(messaggioRx[5], 7)== HIGH){
        settaUscita(15);
      }
      FunzioneSvuotaMessaggioRx();
    }
    if (messaggioRx[0]==InizioTrasmissione && messaggioRx[1]==IDslave1 && messaggioRx[2]==IDmaster && messaggioRx[3]==ResetOut && messaggioRx[4]==0 && messaggioRx[9]==FineTrasmissione){ // Aggiungere i byte di controllo
      if (bitRead(messaggioRx[6], 0)== HIGH){
        resettaUscita(0);
      }
      if (bitRead(messaggioRx[6], 1)== HIGH){
        resettaUscita(1);
      }
      if (bitRead(messaggioRx[6], 2)== HIGH){
        resettaUscita(2);
      }
      if (bitRead(messaggioRx[6], 3)== HIGH){
        resettaUscita(3);
      }
      if (bitRead(messaggioRx[6], 4)== HIGH){
        resettaUscita(4);
      }
      if (bitRead(messaggioRx[6], 5)== HIGH){
        resettaUscita(5);
      }
      if (bitRead(messaggioRx[6], 6)== HIGH){
        resettaUscita(6);
      }
      if (bitRead(messaggioRx[6], 7)== HIGH){
        resettaUscita(7);
      }
      if (bitRead(messaggioRx[5], 0)== HIGH){
        resettaUscita(8);
      }
      if (bitRead(messaggioRx[5], 1)== HIGH){
        resettaUscita(9);
      }
      if (bitRead(messaggioRx[5], 2)== HIGH){
        resettaUscita(10);
      }
      if (bitRead(messaggioRx[5], 3)== HIGH){
        resettaUscita(11);
      }
      if (bitRead(messaggioRx[5], 4)== HIGH){
        resettaUscita(12);
      }
      if (bitRead(messaggioRx[5], 5)== HIGH){
        resettaUscita(13);
      }
      if (bitRead(messaggioRx[5], 6)== HIGH){
        resettaUscita(14);
      }
      if (bitRead(messaggioRx[5], 7)== HIGH){
        resettaUscita(15);
      }
      FunzioneSvuotaMessaggioRx();
    }
    if (messaggioRx[0]==InizioTrasmissione && messaggioRx[1]==IDslave1 && messaggioRx[2]==IDmaster && messaggioRx[3]==InvertOut && messaggioRx[4]==0 && messaggioRx[9]==FineTrasmissione){ // Aggiungere i byte di controllo
      if (bitRead(messaggioRx[6], 0)== HIGH){
        invertiUscita(0);
      }
      if (bitRead(messaggioRx[6], 1)== HIGH){
        invertiUscita(1);
      }
      if (bitRead(messaggioRx[6], 2)== HIGH){
        invertiUscita(2);
      }
      if (bitRead(messaggioRx[6], 3)== HIGH){
        invertiUscita(3);
      }
      if (bitRead(messaggioRx[6], 4)== HIGH){
        invertiUscita(4);
      }
      if (bitRead(messaggioRx[6], 5)== HIGH){
        invertiUscita(5);
      }
      if (bitRead(messaggioRx[6], 6)== HIGH){
        invertiUscita(6);
      }
      if (bitRead(messaggioRx[6], 7)== HIGH){
        invertiUscita(7);
      }
      if (bitRead(messaggioRx[5], 0)== HIGH){
        invertiUscita(8);
      }
      if (bitRead(messaggioRx[5], 1)== HIGH){
        invertiUscita(9);
      }
      if (bitRead(messaggioRx[5], 2)== HIGH){
        invertiUscita(10);
      }
      if (bitRead(messaggioRx[5], 3)== HIGH){
        invertiUscita(11);
      }
      if (bitRead(messaggioRx[5], 4)== HIGH){
        invertiUscita(12);
      }
      if (bitRead(messaggioRx[5], 5)== HIGH){
        invertiUscita(13);
      }
      if (bitRead(messaggioRx[5], 6)== HIGH){
        invertiUscita(14);
      }
      if (bitRead(messaggioRx[5], 7)== HIGH){
        invertiUscita(15);
      }
      FunzioneSvuotaMessaggioRx();
    }
    for (int i=0; i <= 15; i++){
      digitalWrite(23+(2*i), statoUscita[i]);
    }
    if (messaggioRx[0]==InizioTrasmissione && messaggioRx[1]==IDslave1 && messaggioRx[2]==IDmaster && messaggioRx[3]==NienteDaComunicare && messaggioRx[9]==FineTrasmissione){ // Aggiungere i byte di controllo
      IDcicloTxRx=2;
    }
    break;
  case 2:
    IDcicloTxRx =0;
    break;
  }
}
/*
Funzione che invia sul BUS un comando generico.
*/
void FunzioneInvioComando() {
  byte MessaggioTx[10] = {
    InizioTrasmissione,IDmittente,IDdestinatario,Comando,Puntatore,ValoreMSB,ValoreLSB,ControlloIntegritaR,ControlloIntegritaC,FineTrasmissione  };
  Serial.print (MessaggioTx[0], BYTE);
  Serial.print (MessaggioTx[1], BYTE);
  Serial.print (MessaggioTx[2], BYTE);
  Serial.print (MessaggioTx[3], BYTE);
  Serial.print (MessaggioTx[4], BYTE);
  Serial.print (MessaggioTx[5], BYTE);
  Serial.print (MessaggioTx[6], BYTE);
  Serial.print (MessaggioTx[7], BYTE);
  Serial.print (MessaggioTx[8], BYTE);
  Serial.print (MessaggioTx[9], BYTE);
}

/*Funzione per calcolare i 2 Byte di controllo integrità.
 Incolonnando i Byte del messaggio ottengo una matrice 8x8.
 Facendo le XOR delle righe e delle colonne ottengo i 2 byte di verifica
 
 ES:
 (Le frecce indicano l'ordine di lettura dei due byte generati dalla funzione, dal bit più significativo al bit meno significativo)
 
 1 1 1 1 0 0 0 0    0 ^
 0 0 0 0 0 0 0 0    0 |
 0 0 0 0 0 0 0 1    1 |
 0 0 0 0 0 0 0 0    0 |
 0 0 0 0 0 0 0 0    0 |
 0 0 0 0 0 0 0 0    0 |
 0 0 0 0 0 0 0 0    0 |
 1 1 1 1 0 0 0 1    1 |
 
 
 0 0 0 0 0 0 0 0
 - - - - - - - >
 
 ControlloIntegritaR = 10000100
 ControlloIntegritaC = 00000000
 
 */
void FunzioneCalcoloChk () {
  bitMessaggio[0]=bitRead(InizioTrasmissione, 0);
  bitMessaggio[1]=bitRead(InizioTrasmissione, 1);
  bitMessaggio[2]=bitRead(InizioTrasmissione, 2);
  bitMessaggio[3]=bitRead(InizioTrasmissione, 3);
  bitMessaggio[4]=bitRead(InizioTrasmissione, 4);
  bitMessaggio[5]=bitRead(InizioTrasmissione, 5);
  bitMessaggio[6]=bitRead(InizioTrasmissione, 6);
  bitMessaggio[7]=bitRead(InizioTrasmissione, 7);
  bitMessaggio[8]=bitRead(IDmittente, 0);
  bitMessaggio[9]=bitRead(IDmittente, 1);
  bitMessaggio[10]=bitRead(IDmittente, 2);
  bitMessaggio[11]=bitRead(IDmittente, 3);
  bitMessaggio[12]=bitRead(IDmittente, 4);
  bitMessaggio[13]=bitRead(IDmittente, 5);
  bitMessaggio[14]=bitRead(IDmittente, 6);
  bitMessaggio[15]=bitRead(IDmittente, 7);
  bitMessaggio[16]=bitRead(IDdestinatario, 0);
  bitMessaggio[17]=bitRead(IDdestinatario, 1);
  bitMessaggio[18]=bitRead(IDdestinatario, 2);
  bitMessaggio[19]=bitRead(IDdestinatario, 3);
  bitMessaggio[20]=bitRead(IDdestinatario, 4);
  bitMessaggio[21]=bitRead(IDdestinatario, 5);
  bitMessaggio[22]=bitRead(IDdestinatario, 6);
  bitMessaggio[23]=bitRead(IDdestinatario, 7);
  bitMessaggio[24]=bitRead(Comando, 0);
  bitMessaggio[25]=bitRead(Comando, 1);
  bitMessaggio[26]=bitRead(Comando, 2);
  bitMessaggio[27]=bitRead(Comando, 3);
  bitMessaggio[28]=bitRead(Comando, 4);
  bitMessaggio[29]=bitRead(Comando, 5);
  bitMessaggio[30]=bitRead(Comando, 6);
  bitMessaggio[31]=bitRead(Comando, 7);
  bitMessaggio[32]=bitRead(Puntatore, 0);
  bitMessaggio[33]=bitRead(Puntatore, 1);
  bitMessaggio[34]=bitRead(Puntatore, 2);
  bitMessaggio[35]=bitRead(Puntatore, 3);
  bitMessaggio[36]=bitRead(Puntatore, 4);
  bitMessaggio[37]=bitRead(Puntatore, 5);
  bitMessaggio[38]=bitRead(Puntatore, 6);
  bitMessaggio[39]=bitRead(Puntatore, 7);
  bitMessaggio[40]=bitRead(ValoreMSB, 0);
  bitMessaggio[41]=bitRead(ValoreMSB, 1);
  bitMessaggio[42]=bitRead(ValoreMSB, 2);
  bitMessaggio[43]=bitRead(ValoreMSB, 3);
  bitMessaggio[44]=bitRead(ValoreMSB, 4);
  bitMessaggio[45]=bitRead(ValoreMSB, 5);
  bitMessaggio[46]=bitRead(ValoreMSB, 6);
  bitMessaggio[47]=bitRead(ValoreMSB, 7);
  bitMessaggio[48]=bitRead(ValoreLSB, 0);
  bitMessaggio[49]=bitRead(ValoreLSB, 1);
  bitMessaggio[50]=bitRead(ValoreLSB, 2);
  bitMessaggio[51]=bitRead(ValoreLSB, 3);
  bitMessaggio[52]=bitRead(ValoreLSB, 4);
  bitMessaggio[53]=bitRead(ValoreLSB, 5);
  bitMessaggio[54]=bitRead(ValoreLSB, 6);
  bitMessaggio[55]=bitRead(ValoreLSB, 7);
  bitMessaggio[56]=bitRead(FineTrasmissione, 0);
  bitMessaggio[57]=bitRead(FineTrasmissione, 1);
  bitMessaggio[58]=bitRead(FineTrasmissione, 2);
  bitMessaggio[59]=bitRead(FineTrasmissione, 3);
  bitMessaggio[60]=bitRead(FineTrasmissione, 4);
  bitMessaggio[61]=bitRead(FineTrasmissione, 5);
  bitMessaggio[62]=bitRead(FineTrasmissione, 6);
  bitMessaggio[63]=bitRead(FineTrasmissione, 7);

  bitWrite(ControlloIntegritaR, 0, bitMessaggio[0] ^ bitMessaggio[1] ^ bitMessaggio[2] ^ bitMessaggio[3] ^ bitMessaggio[4] ^ bitMessaggio[5] ^ bitMessaggio[6] ^ bitMessaggio[7]);
  bitWrite(ControlloIntegritaR, 1, bitMessaggio[8] ^ bitMessaggio[9] ^ bitMessaggio[10] ^ bitMessaggio[11] ^ bitMessaggio[12] ^ bitMessaggio[13] ^ bitMessaggio[14] ^ bitMessaggio[15]);
  bitWrite(ControlloIntegritaR, 2, bitMessaggio[16] ^ bitMessaggio[17] ^ bitMessaggio[18] ^ bitMessaggio[19] ^ bitMessaggio[20] ^ bitMessaggio[21] ^ bitMessaggio[22] ^ bitMessaggio[23]);
  bitWrite(ControlloIntegritaR, 3, bitMessaggio[24] ^ bitMessaggio[25] ^ bitMessaggio[26] ^ bitMessaggio[27] ^ bitMessaggio[28] ^ bitMessaggio[29] ^ bitMessaggio[30] ^ bitMessaggio[31]);
  bitWrite(ControlloIntegritaR, 4, bitMessaggio[32] ^ bitMessaggio[33] ^ bitMessaggio[34] ^ bitMessaggio[35] ^ bitMessaggio[36] ^ bitMessaggio[37] ^ bitMessaggio[38] ^ bitMessaggio[39]);
  bitWrite(ControlloIntegritaR, 5, bitMessaggio[40] ^ bitMessaggio[41] ^ bitMessaggio[42] ^ bitMessaggio[43] ^ bitMessaggio[44] ^ bitMessaggio[45] ^ bitMessaggio[46] ^ bitMessaggio[47]);
  bitWrite(ControlloIntegritaR, 6, bitMessaggio[48] ^ bitMessaggio[49] ^ bitMessaggio[50] ^ bitMessaggio[51] ^ bitMessaggio[52] ^ bitMessaggio[53] ^ bitMessaggio[54] ^ bitMessaggio[55]);
  bitWrite(ControlloIntegritaR, 7, bitMessaggio[56] ^ bitMessaggio[57] ^ bitMessaggio[58] ^ bitMessaggio[59] ^ bitMessaggio[60] ^ bitMessaggio[61] ^ bitMessaggio[62] ^ bitMessaggio[63]);
  bitWrite(ControlloIntegritaC, 0, bitMessaggio[0] ^ bitMessaggio[8] ^ bitMessaggio[16] ^ bitMessaggio[24] ^ bitMessaggio[32] ^ bitMessaggio[40] ^ bitMessaggio[48] ^ bitMessaggio[56]);
  bitWrite(ControlloIntegritaC, 1, bitMessaggio[1] ^ bitMessaggio[9] ^ bitMessaggio[17] ^ bitMessaggio[25] ^ bitMessaggio[33] ^ bitMessaggio[41] ^ bitMessaggio[49] ^ bitMessaggio[57]);
  bitWrite(ControlloIntegritaC, 2, bitMessaggio[2] ^ bitMessaggio[10] ^ bitMessaggio[18] ^ bitMessaggio[26] ^ bitMessaggio[34] ^ bitMessaggio[42] ^ bitMessaggio[50] ^ bitMessaggio[58]);
  bitWrite(ControlloIntegritaC, 3, bitMessaggio[3] ^ bitMessaggio[11] ^ bitMessaggio[19] ^ bitMessaggio[27] ^ bitMessaggio[35] ^ bitMessaggio[43] ^ bitMessaggio[51] ^ bitMessaggio[59]);
  bitWrite(ControlloIntegritaC, 4, bitMessaggio[4] ^ bitMessaggio[12] ^ bitMessaggio[20] ^ bitMessaggio[28] ^ bitMessaggio[36] ^ bitMessaggio[44] ^ bitMessaggio[52] ^ bitMessaggio[60]);
  bitWrite(ControlloIntegritaC, 5, bitMessaggio[5] ^ bitMessaggio[13] ^ bitMessaggio[21] ^ bitMessaggio[29] ^ bitMessaggio[37] ^ bitMessaggio[45] ^ bitMessaggio[53] ^ bitMessaggio[61]);
  bitWrite(ControlloIntegritaC, 6, bitMessaggio[6] ^ bitMessaggio[14] ^ bitMessaggio[22] ^ bitMessaggio[30] ^ bitMessaggio[38] ^ bitMessaggio[46] ^ bitMessaggio[54] ^ bitMessaggio[62]);
  bitWrite(ControlloIntegritaC, 7, bitMessaggio[7] ^ bitMessaggio[15] ^ bitMessaggio[23] ^ bitMessaggio[31] ^ bitMessaggio[39] ^ bitMessaggio[47] ^ bitMessaggio[55] ^ bitMessaggio[63]);
}
void FunzioneSvuotaMessaggioRx(){
  messaggioRx[0]=0;
  messaggioRx[1]=0;
  messaggioRx[2]=0;
  messaggioRx[3]=0;
  messaggioRx[4]=0;
  messaggioRx[5]=0;
  messaggioRx[6]=0;
  messaggioRx[7]=0;
}

void settaUscita (int nuscita){
  statoUscita[nuscita]=HIGH;
}
void resettaUscita (int nuscita){
  statoUscita[nuscita]=LOW;
}
void invertiUscita (int nuscita){
  statoUscita[nuscita]=!statoUscita[nuscita];
}

Credo di aver risolto ... grazie lo stesso.

Praticamente è bastato mettere come condizione nell'IF "(indexByteMessaggioRx>=9"

if (indexByteMessaggioRx>=9 && messaggioRx[0]==InizioTrasmissione && messaggioRx[1]==IDslave1 && messaggioRx[2]==IDmaster && messaggioRx[3]==SetOut && messaggioRx[4]==ByteVuoto && messaggioRx[9]==FineTrasmissione)

in questo modo sono sicuro che tutti i 10 byte in arrivo dalla seriale siano stati memorizzati, probabilmente prima la condizione risultava già a TRUE ancor prima che arrivassero i byte messaggioRx[5] e messaggioRx[6]

Grazie lo stesso ! Mi rimetto al lavoro !!!