Space / Mbed 2 deprecated DORAv4

Dependencies:   mbed

Revision:
2:fcdd048a4a9e
Parent:
1:db73b542b7bc
Child:
3:b58e8c4438cd
diff -r db73b542b7bc -r fcdd048a4a9e main.cpp
--- a/main.cpp	Fri Jun 10 08:41:49 2022 +0000
+++ b/main.cpp	Tue Jun 21 18:27:11 2022 +0000
@@ -1,5 +1,7 @@
 #include "mbed.h"
 #include <math.h>
+#include <string.h>
+#include <stdlib.h>
 
 /*
 TO-DO: i dati arrivano in DigitalIn e DigitalOut, anziché essere della classe Serial.
@@ -12,35 +14,42 @@
 */
 
 // ************* INFO *******************
-// master-slave: slave MIMA comunica con DORA con collegamento UART (tx, rx, gnd)
-// PC S/C sends packets to DORA -> MIMA (STM32) -> PC
 
 //  ------                  ------------
 // | MIMA | ---- DORA ---- | SPACE/CRAFT |
 //  ------                  ------------
 
+// testato con 26LS31 e 26LS32 + Arduino 
+
 // ************ DEFINE ******************
 // definisce dimensione pacchetto inviato da pc
 // telecommand: 15 bit + 1 di controllo
 #define PACKETSIZE 20           // lunghezza massima della stringa trasmissibile prima di interrupt
 #define PACKET 15               // 15 bit, 1 di parità di controllo
 #define PACKET_CHECKED 16       // COMMAND IDENTIFIER + TAG + PAYLOAD + PARITY CHECK
+#define TELEMETRY_SIZE 16
+#define PACKETDIM 13
 #define IDENTIFIER 5
 #define TAG 2
 #define PAYLOAD 8
 #define CMD_NUM 32
-#define OPTION_1 10            // 57 * 16
-#define OPTION_2 90608          // 5663 * 16
+#define TLM_OPTION_1 912        // 57 * 16
+#define TLM_OPTION_2 90608      // 5663 * 16
 #define tb 7                    // bit sampling period
-#define BufferXOR 175           // 2800/16 - 1
 #define word 16
+#define CHANNEL 2800
+#define TLM_NUM 57
 
 
 // ************ CN7+USB ******************
 Serial SC(USBTX, USBRX);                // A4 TX, A6 RX - DATA OUT, DATA IN
 
 // ************** CN10 *******************
-Serial MIMA(PC_4, PC_5);              // TERZO - TERZULTIMO -> D0 e D1 non vanno bene! Risorse già occupate
+Serial MIMA(PC_4, PC_5);
+//Serial ARDUINO(PA_0, PA_1);
+Serial MAX31865(PA_9, PC_0);
+Serial ARDUINO(PB_6, PC_10);
+
 
 // ************** TIMER *****************
 Timer t;
@@ -57,72 +66,175 @@
 DigitalOut Relay24V (PB_5);             // D4
 DigitalOut Relay15_15_5V (PB_10);       // D6 | +15, -15, -5
 float offset = 0.0f;
+
+// **************** VARS *****************
+volatile int nIndex;                        // indice per clear del buffer
+char getPacket[PACKETSIZE];                 // buffer - pacchetto inviato di dimensione max PACKETSIZE
+char PacketChecked[PACKET_CHECKED];         // lato Space/Craft
+char TLM[TELEMETRY_SIZE];                   // telemetry format
+char TLM_HSK[TLM_OPTION_1];                 // lato MIMA: CMD05 -> option 1 (ALL HSKP)
+char TLM_HSK_SD[TLM_OPTION_2];              // lato MIMA: CMD05 -> option 2 (HSKP+SD)
+
+volatile int LEN;                           // numero di bit da ricevere per ricezione corretta 
+volatile int commandId;                     // CMDXX per telecomando
+volatile int payloadDec;                    // trasformo il payload in decimale per comandi spare
+volatile int sizeBuffer;                    // indice del buffer di ricezione
+volatile unsigned char data;                // in arrivo da MIMA per telemetria
+volatile int indexTemp;                     // indice del buffer di caratteri in arrivo da arduino/max31865
 volatile char ch;
 
-// DATA_OUT_CLOCK.write(0) -> wait_ms(7) -> DATA_OUT_CLOCK.write(0) -> wait_ms(7)
+int base = 2;                               // base per l'esponenziale (conversione binary to decimal)
+int CMD[CMD_NUM];                           // CMD in decimale
+int TLM_ID[TLM_NUM];                        // TLM in decimale
 
-// *********** VARIABLES *****************
-volatile int nIndex;                    // indice del pacchetto per lo "spacchettamento"
-char getPacket[PACKETSIZE];             // buffer - pacchetto inviato di dimensione max PACKETSIZE
-char PacketChecked[PACKET_CHECKED];     // lato Space/Craft
-char TLM[OPTION_1];                     // lato MIMA per check
-char TLM_SD[OPTION_2];                  // lato MIMA per check
+volatile int tlmode_option_1;               // TLMODE: 57 words
+volatile int tlmode_option_2;               // TLMODE: 5663 words (57 + 5606 scientific data word)
+volatile int interferogram_option_1;        // TLMODE: 57 words
+volatile int interferogram_option_2;        // TLMODE: 5663 words (57 + 5606 scientific data word)
 
+volatile int ch1_errorDetected;
+int ch1_intChecksum[word];                  
+char ch1_checksumWord[word];                // checksum sul pacchetto elaborato
+char ch1_checksumReceived[word];            // checksum ricevuto
 
-volatile int LEN;                       // numero di bit da ricevere per ricezione corretta 
-volatile int commandId;
-volatile int payloadDec; 
-volatile int sizeBuffer;
-volatile unsigned char data;            // in arrivo da MIMA per telemetria
+char CH1_to_string[20];                     // *temperatura canale 1
+char CH2_to_string[20];                     // *temperatura canale 2
+char tempCH1[10];                           // temperatura canale 1
+char tempCH2[10];                           // temperatura canale 2
+volatile int indexJ = 0;                    // indice riempimento canale 1
+volatile int indexT = 0;                    // indice riempimento canale 2
+volatile float CH1, CH2;                    // valore in float (da stringa)
+volatile int nRxCharCount;                  // indice riempimento buffer from:MAX31865
+char caRxPacket[PACKETDIM];                 // buffer from:MAX31865
+volatile int temperature_flag;              // flag per print su richiesta
 
-int base = 2;                           // base per l'esponenziale (conversione binary to decimal)
-int CMD[CMD_NUM];                       // CMD in decimale
-
-volatile int option_1 = 0;              // default
-volatile int option_2 = 0;
-
-int tempCheck[word];                    // temp
-char checksumWord[word];                // checksum sul pacchetto elaborato
-char checksumReceived[word];            // checksum ricevuto
+volatile int ch2_errorDetected;             // flag: errore di trasmissione
+int ch2_intChecksum[word];                  //     
+char ch2_checksumWord[word];                // checksum sul pacchetto elaborato
+char ch2_checksumReceived[word];            // checksum ricevuto
 
 // ************** SETUP *******************
 void CMD_REF();                             // crea la lista dei comandi
+void TLM_ID_REF();                          // crea la lista delle telemetrie
 void clearBuffer(char *arr, int arrLen);    // ripulisce il buffer di ricezione
-void checksum(char *a, int aSize);          // effettua checksum
-void RxTelecommand();
-void TxTelecommand();
-void RxTelemetry();
-void TxTelemetry();
-void ActuatorControl(int command);           // controllo L16 e Relay
-
+void clearIntBuffer(int *y, int s);
+void Checksum(char *a);                     // effettua checksum sui dati del CH1
+void RxTelecommand();                       // riceve da Spacecraft
+void TxTelecommand();                       // trasmette a MIMA
+void RxTelemetry();                         // riceve da MIMA
+void TxTelemetry();                         // trasmette a Spacecraft
+void SpareCommand(int command);             // controllo L16, Relay, periferiche
+void GetTemperature();
+void ReadTemperature();
+const char* MIMA_OPERATING_MODE(char *s);
+int  BinToDec(int t, int dim, char *a);
 
 // *********************************************************************
 
 
-// ************** MAIN *******************
 int main()
 {
-    // baudrate
+    // Setup per trasmissione seriale
     SC.baud(115200);
+    MAX31865.baud(115200);
     MIMA.baud(9600);
+                
+    SC.printf("******* Test DORA Communication *******\r\n");
+    
+    // Flag per ricezione
+    tlmode_option_1 = 1;
+    tlmode_option_2 = 1;
+    
+    // Temperatura
+    nRxCharCount = 0;
+    clearBuffer(caRxPacket,PACKETDIM);  
+    
+    // Gestione interrupt seriale
+    SC.attach(&RxTelecommand, Serial::RxIrq); // arriva telecomando da PC
+    MAX31865.attach(&GetTemperature, Serial::RxIrq); // arriva dato da MAX31865 via Arduino
     
-    // Setup PWM
-    M1.period_us(1000); 
-    M2.period_us(1000);
+    // Ciclo principale
+    while (true)
+    {
+        /* *********************************************************************
+                         RICEZIONE TEMPERATURA DA MAX31865
+        ********************************************************************* */   
+        
+        if ((commandId == 0) && (payloadDec == 32) && (temperature_flag == 1))
+        {
+            ReadTemperature();
+            temperature_flag = 0;
+        }
+        
+                
+        /* *********************************************************************
+                         RICEZIONE DI TELEMETRIE DA MIMA
+        ********************************************************************* */
+
+        sizeBuffer = 0; // reset 
+        clearBuffer(TLM, sizeof(TLM)/sizeof(TLM[0]));
+        clearBuffer(TLM_HSK, sizeof(TLM_HSK)/sizeof(TLM_HSK[0]));
+        clearBuffer(TLM_HSK_SD, sizeof(TLM_HSK_SD)/sizeof(TLM_HSK_SD[0]));
+        
+        clearIntBuffer(ch1_intChecksum, sizeof(ch1_intChecksum)/sizeof(ch1_intChecksum[0]));
+        clearIntBuffer(ch2_intChecksum, sizeof(ch2_intChecksum)/sizeof(ch2_intChecksum[0]));
+        clearBuffer(ch1_checksumWord, sizeof(ch1_checksumWord)/sizeof(ch1_checksumWord[0]));
+        clearBuffer(ch2_checksumWord, sizeof(ch2_checksumWord)/sizeof(ch2_checksumWord[0]));
 
-    // Setup Relay: default (pull-up)
-    Relay5V = 1;
-    Relay12V = 1;
-    Relay15_15_5V = 1; // +15, -15, -5
-    Relay24V = 1;
-    
-    // diagnostic
-    SC.printf("*******Starting... *******\n\r");
+        t.start();
+        tTimeStart = t.read();  // in secondi 
+        tTimeRead = tTimeStart;
+        
+        MIMA.attach(&RxTelemetry, Serial::RxIrq);   // entra in questa routine quando riceve un carattere dalla seriale del SERIAL
+        
+        if (commandId == 5) // TLMODE
+        {
+            if (tlmode_option_1 == 0)
+            {
+                while (sizeBuffer < TLM_OPTION_1 && ((tTimeRead - tTimeStart) < TIMEOUT))
+                {
+                    tTimeRead = t.read();
+                }
+
+                t.stop();
 
-    // interrupt
-    SC.attach(&RxTelecommand, Serial::RxIrq);
-    MIMA.attach(&RxTelemetry, Serial::RxIrq);
+                if ((tTimeRead - tTimeStart) >= TIMEOUT)
+                {
+                    sizeBuffer = 0;
+                    clearBuffer(TLM_HSK, TLM_OPTION_1);
+                    //SC.printf("Timestamp: %f\n\r", tTimeRead);
+                }
+                else
+                {
+                    TxTelemetry();
+                }
+            }
+            else if (tlmode_option_2 == 0)
+            {
+                while (sizeBuffer < TLM_OPTION_2 && ((tTimeRead - tTimeStart) < TIMEOUT))
+                {
+                    tTimeRead = t.read();
+                }
 
+                t.stop();
+
+                if ((tTimeRead - tTimeStart) >= TIMEOUT)
+                {
+                    sizeBuffer = 0;
+                    clearBuffer(TLM_HSK_SD, TLM_OPTION_1);
+                    //SC.printf("Timestamp: %f\n\r", tTimeRead);
+                }
+                else
+                {
+                    Checksum(TLM_HSK_SD);
+                    if (ch1_errorDetected == 0 && ch2_errorDetected == 0) // no checksum error flags
+                    {
+                        TxTelemetry();
+                    }
+                }
+            }
+        }
+    }
 }
 
 
@@ -130,6 +242,7 @@
 
 
 // ************** FUNCTIONS *******************
+// init CMD
 void CMD_REF()
 {
     for (int i = 0; i < CMD_NUM; i++)
@@ -138,6 +251,15 @@
     }
 }
 
+// init TLM
+void TLM_ID_REF()
+{
+    for (int i = 0; i < TLM_NUM; i++)
+    {
+        TLM_ID[i] = i;
+    }
+}
+
 // clear
 void clearBuffer(char *arr, int arrLen)
 {
@@ -147,33 +269,39 @@
     }
 }
 
+// clear 
+void clearIntBuffer(int *y, int s)
+{
+    for (nIndex = 0; nIndex < s; nIndex++)
+    {
+        y[nIndex] = '\0';
+    }
+}
+
 // DORA riceve telecomando da SC
 void RxTelecommand()
 {
-    CMD_REF();  // carica vettore dei comandi
+    CMD_REF();
 
-    while (SC.readable())   // finché sulla porta USB arrivano dati, esegui
+    while (SC.readable()) 
     {
-        clearBuffer(getPacket, sizeof(getPacket) / sizeof(getPacket[0]));   // clear the buffer
-        SC.gets(getPacket, sizeof(getPacket));  // leggi la stringa in ingresso
+        clearBuffer(getPacket, sizeof(getPacket)/sizeof(getPacket[0])); 
+        SC.gets(getPacket, sizeof(getPacket));  
         LEN = strlen(getPacket) - 2;    // calcola la sua lunghezza ignorando i tag \r\n
         ch = getPacket[0];
 
         if (LEN != PACKET)
         {
-            if (LEN == 1)
-            {
-                SC.printf("> Bit number: %i is not equal to 15  // no tele-command\n\r", LEN);  // diagnostica        
-            }
+            SC.printf("> Bit number: %i is not equal to 15  // no tele-command\n\r", LEN);  // diagnostica  
         }
         else
         {
             for (int n = 0; n < LEN; n++)
             {
-                PacketChecked[n] = getPacket[n];    // riempi il nuovo array
+                PacketChecked[n] = getPacket[n];
             }
 
-            // ***CONTROLLO DEI BIT - LSB: EVEN/ODD ***
+            // *** CONTROLLO DEI BIT - LSB: EVEN/ODD ***
             int ones = 0;
             int check = 0;
             while (check < PACKET)
@@ -220,8 +348,8 @@
             // poi ho due bit che mi specificano se i dati in arrivo sono una o più parole,
             // dopodiché ho un payload da 8 bit e per concludere ho LSB (parity bit)
             // MSB IIII TT PPPPPPPP PC
-
-            // ***COMMAND IDENTIFIER ***
+ 
+            /* ** COMMAND IDENTIFIER ** */
             int CMDIndex = 0;   // puntatore dell'identificativo
             commandId = 0;
 
@@ -229,21 +357,8 @@
             int B9 = PacketChecked[9];
             int B11 = PacketChecked[11];
 
-            // trasformo l'identificatore in numero
-            while (CMDIndex < IDENTIFIER)
-            {
-                if (PacketChecked[CMDIndex] == '1')
-                {
-                    int raise = IDENTIFIER - 1 - CMDIndex;
-                    commandId += pow((float) base, (float) raise);
-                }
-                else
-                {
-                    commandId += 0;
-                }
-
-                CMDIndex++;
-            }
+            // trasformo l'identificatore in numero decimale intero
+            commandId = BinToDec(CMDIndex, IDENTIFIER, PacketChecked);
 
             // scorro la lista di comandi disponibli e verifico se il comando trasmesso rientra
             // nella lista, altrimenti finisco in uno dei 3 SPARE
@@ -262,70 +377,100 @@
                     }
                     else if (k == 0 && PacketChecked[5] == '0' && PacketChecked[6] == '0') // CMD0 - spare
                     {
-                        payloadDec = 0; // inizializzazione del payload in formato digitale
-                        int counter = 7;    // parto dal settimo bit
+                        int counter = 7; // parto dal settimo bit
+                        payloadDec = 0;  // inizializzazione del payload in formato digitale
 
-                        while (counter < PACKET)
-                        {
-                            if (PacketChecked[counter] == '1')
-                            {
-                                int raise = PACKET - 1 - counter;
-                                payloadDec += pow((float) base, (float) raise);
-                            }
-                            else
-                            {
-                                payloadDec += 0;
-                            }
+                        payloadDec = BinToDec(counter, PACKET, PacketChecked);        
 
-                            counter++;
-                        }
-
-                        ActuatorControl(payloadDec);
+                        SpareCommand(payloadDec);
                         break;
                     }
                     else if (k == 1) // CMD01
                     {
-                        if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '0' &&
-                            PacketChecked[13] == '0' &&
-                            PacketChecked[14] == '1')
+                        SC.printf("> CMD %i, CODE: MIMA MODE\n\r", k);
+                        
+                        SC.printf("%s\n\r", MIMA_OPERATING_MODE(PacketChecked));
+                        
+                    }
+                    else if (k == 3)
+                    {
+                        SC.printf("> CMD %i, CODE: LDth_On_Off - On/Off of Laser Diode thermal control loop\n\r", k);
+                    }
+                    else if (k == 4)
+                    {
+                        SC.printf("> CMD %i, CODE: IRth_On_Off - On/Off of IR sensor thermal control loop\n\r", k);
+                    }
+                    else if (k == 5)
+                    {
+                        int checkZerosIndex = 7;
+                        while (checkZerosIndex < PACKET_CHECKED)
                         {
-                            SC.printf("> Setting MIMA... Sleeping mode\n\r");
-                        }
-                        else if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '0' &&
-                            PacketChecked[13] == '1' &&
-                            PacketChecked[14] == '0')
-                        {
-                            SC.printf("> Setting MIMA... Awake mode\n\r");
-                        }
-                        else if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '0' &&
-                            PacketChecked[13] == '1' &&
-                            PacketChecked[14] == '1')
-                        {
-                            SC.printf("> Setting MIMA... Calibration mode\n\r");
+                            if (PacketChecked[checkZerosIndex] == '0')
+                            {
+                                tlmode_option_1 = 0;
+                                checkZerosIndex++;
+                            }
+                            else
+                            {
+                                tlmode_option_1 = 1;
+                                break;
+                            }
                         }
-                        else if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '1' &&
-                            PacketChecked[13] == '0' &&
-                            PacketChecked[14] == '0')
+                        
+                        int checkOnesIndex = 7;
+                        while (checkOnesIndex < PACKET_CHECKED)
                         {
-                            SC.printf("> Setting MIMA... Observation mode\n\r");
+                            if (PacketChecked[checkOnesIndex] == '1')
+                            {
+                                tlmode_option_2 = 0;
+                                checkOnesIndex++;
+                            }
+                            else
+                            {
+                                tlmode_option_2 = 1;
+                                break;
+                            }
                         }
-                        else if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '1' &&
-                            PacketChecked[13] == '0' &&
-                            PacketChecked[14] == '1')
+                    }
+                    else if (k == 6)
+                    {
+                        int checkZerosIndex = 7;
+                        while (checkZerosIndex < PACKET_CHECKED)
                         {
-                            SC.printf("> Setting MIMA... Auto-test mode\n\r");
+                            if (PacketChecked[checkZerosIndex] == '0')
+                            {
+                                interferogram_option_1 = 0;
+                                checkZerosIndex++;
+                            }
+                            else
+                            {
+                                interferogram_option_1 = 1;
+                                break;
+                            }
                         }
-                        else if (PacketChecked[11] == '0' &&
-                            PacketChecked[12] == '1' &&
-                            PacketChecked[13] == '1' &&
-                            PacketChecked[14] == '0')
+                        
+                        int checkOnesIndex = 7;
+                        while (checkOnesIndex < PACKET_CHECKED)
                         {
-                            SC.printf("> Setting MIMA... Full testing mode\n\r");
+                            if (PacketChecked[checkOnesIndex] == '1')
+                            {
+                                interferogram_option_2 = 0;
+                                checkOnesIndex++;
+                            }
+                            else
+                            {
+                                interferogram_option_2 = 1;
+                                break;
+                            }
+                        } 
+                        
+                        if (interferogram_option_1 == 0)
+                        {
+                            SC.printf("> CMD %i, START interferogram acquisition\n\r", k);
+                        }
+                        else if (interferogram_option_2 == 0)
+                        {
+                            SC.printf("> CMD %i, STOP interferogram acquisition\n\r", k);
                         }
                     }
                     else if (k == 7) // CMD07
@@ -367,6 +512,11 @@
                             SC.printf("BBT2 telemetry: feedback signal in the thermal control. BBT1 only for monitoring\n\r");
                         }
                     }
+                    
+                    else if ((k == 0) && (payloadDec == 32))
+                    {
+                        temperature_flag = 1;
+                    }
 
                 }
                 
@@ -403,7 +553,7 @@
                 SC.printf("NOT USED\n\r");
             }
 
-            // ***PAYLOAD ***
+            // diagnostica: payload
             SC.printf("> Payload: ");
             for (int IndexPayload = 7; IndexPayload < PACKET; IndexPayload++)
             {
@@ -420,10 +570,12 @@
     }
 }
 
+
 /* ***************************************************************** */
 
+
 // DORA trasmette telecomando a MIMA
-void TxTelecommand()
+void TxTelecommand()                                                                // Tx Telecommand
 {
     for (int i = 0; i < PACKET_CHECKED + 1; i++)
     {
@@ -434,252 +586,456 @@
 
 /* ***************************************************************** */
 
-// DORA riceve telemetrie/telemetrie+scientific data da MIMA
-void RxTelemetry()
+
+// DORA riceve telemetria da MIMA
+void RxTelemetry(void)                                                              // Rx Telemetry
 {
-    // aggiungere timeout, perché non so se raggiungo il numero dei caratteri
-
-    while (MIMA.readable())
-    {        
-        // char prova = MIMA.getc();
-        // SC.printf("> Text: %c\n\r", prova);
-        // check del payload per scelta del buffer
-        // 00000000 -> Option 1: transfer all Housekeeping and Status telemetries (from TLM00 to TLM56)
-        // 11111111 -> Option 2: transfer telemetries and scientific data packets (from TLM00 to TLM5662)
-
-        int j = 7;
-        while (j < PACKET_CHECKED)
-        {
-            if (PacketChecked[j] == '0')
-            {
-                j++;
-            }
-            else
-            {
-                option_1 = 1;
-                break;
-            }
-        }
-
-        int k = 7;
-        while (k < PACKET_CHECKED)
-        {
-            if (PacketChecked[k] == '1')
-            {
-                k++;
-            }
-            else
-            {
-                option_2 = 1;
-                break;
-            }
-        }
-
-        if (commandId == 5) // TLMODE
+    while((MIMA.readable()))
+    {
+        data = MIMA.getc(); // prendi carattere in arrivo
+        
+        if (tlmode_option_1 == 0)
         {
-            // STARTCH1 - 2800 scientific points - CHECKSUM - ENDCH1
-            // STARTCH2 - 2800 scientific points - CHECKSUM - ENDCH2
-            // 5606 words
-            if (option_1 == 0)
-            {
-                sizeBuffer = 0;   // reset 
-                clearBuffer(TLM, sizeof(TLM)/sizeof(TLM[0]));
-                
-                t.start();
-                tTimeStart = t.read(); // in secondi 
-                tTimeRead = tTimeStart;
-                
-                while (sizeBuffer < OPTION_1 && ((tTimeRead - tTimeStart) < TIMEOUT))
-                {
-                    data = MIMA.getc(); // prendi carattere in arrivo
-                    TLM[sizeBuffer++] = data;
-                    tTimeRead = t.read();          
-                }
-                
-                tTimeRead = t.read();
-                
-                if ((tTimeRead - tTimeStart) >= TIMEOUT)
-                {
-                    sizeBuffer = 0;
-                    clearBuffer(TLM, OPTION_1);
-                    SC.printf("> Time elapsed: %f \n", tTimeRead);
-                } 
-                
-            }
-            else if (option_2 == 0)
-            {
-                sizeBuffer = 0;
-                clearBuffer(TLM_SD, sizeof(TLM_SD)/sizeof(TLM_SD[0]));
-
-                while (sizeBuffer < OPTION_2)
-                {
-                    data = MIMA.getc(); // prendi carattere in arrivo
-                    TLM_SD[sizeBuffer++] = data;
-                }
-            }
+            TLM_HSK[sizeBuffer++] = data;
+        } 
+        else if (tlmode_option_2 == 0)
+        {
+            TLM_HSK_SD[sizeBuffer++] = data;
+        }
+        else 
+        {
+            TLM[sizeBuffer++] = data;
+        }
             
-        }
-        
-        TxTelemetry();
     }
 }
 
-/* ***************************************************************** */
-
-// integrità dei dati ricevuti da MIMA 
-void checksum(char *a, int aSize) 
-{
-    volatile int temp;
-    volatile int var;
-    volatile int p = 0;
-  
-    for (int i = word; i < 2*word; i++) 
-    {
-        for (int j = 2*i; j < aSize; j+=i)
-        {
-            if (j == 2*i) 
-            {
-                temp = (int)(a[i] ^ a[j]); 
-            } else
-            {
-                temp = temp ^ (int)a[j];   
-            }
-
-        }
-
-        tempCheck[p++] = temp; // vettore del checksum in int
-    }
-    
-    for (int i = 0; i < word; i++) // trasformo in char
-    {
-        if (tempCheck[i] == 0 || tempCheck[i] == 48)
-        {
-            checksumWord[i++] = '0';
-        } 
-        else if (tempCheck[i] == 1 || tempCheck[i] == 49)
-        {
-            checksumWord[i++] = '1';
-        }
-    }
-    
-    
-    volatile int t = 0;
-    // confronto
-    for (int i = 2801*word; i < 2802*16; i++) 
-    {
-        checksumReceived[t++] = TLM_SD[i];
-    }
-    
-    for (int i = 0; i < word; i++) 
-    {
-        if (checksumWord[i] != checksumReceived[i])
-        {
-            SC.printf("\n\r> ERROR detected: BIT n. %i\n\r", i+1);
-            break;
-        }         
-    }
-            
-    
-}
 
 /* ***************************************************************** */
 
+
 // DORA trasmette dati verso Space/craft
-void TxTelemetry()
+void TxTelemetry()                                                                  // Tx Telemetry
 {
-    // The data are read on the falling-edge of the DATA_CLOCK_OUT signal
-    if (option_1 == 0)
+    if (tlmode_option_1 == 0)
     {
-        SC.printf("\n\r> Receiving 57 words from MIMA... \n\r");
+        SC.printf("\n\r> Receiving 57 words (all HSK) from MIMA... \n\r");
         
-        for (int i = 0; i < OPTION_1; i++)
+        for (int i = 0; i < TLM_OPTION_1; i++)
         {
-            SC.putc(TLM[i]);
-        }
+             SC.putc(TLM_HSK[i]);
+             ARDUINO.putc(TLM_HSK[i]);
+        } 
         
+        // parsing del pacchetto da 16 bit * 57 parole
         SC.printf("\n\r");
     }
-    else if (option_2 == 0)
+    else if (tlmode_option_2 == 0)
     {
-        SC.printf("Receiving 5663 words...\n\r");
+        SC.printf("\n\r> Receiving 5663 words (HSK + Scientific Data) from MIMA... \n\r");
         
-        for (int i = 0; i < OPTION_2; i++)
+        for (int i = 0; i < TLM_OPTION_2; i++)
         {
-            if (i % word == 0)
-            {
-                SC.printf("\n\r");
-            }
-            else 
-            {
-                SC.putc(TLM_SD[i]);
-            }
+           
+            SC.putc(TLM_HSK_SD[i]);
+            ARDUINO.putc(TLM_HSK_SD[i]);
         }
         
+        // parsing del pacchetto da 16 bit * 57 parole
+        SC.printf("\n\r");
+    }
+    else 
+    {
+        SC.printf("\n\r> Receiving Telemetry from MIMA... \n\r");
+        
+        for (int i = 0; i < TLM_OPTION_2; i++)
+        {
+            SC.putc(TLM[i]);
+            ARDUINO.putc(TLM[i]);
+        }
+        
+        // parsing del pacchetto da 16 bit
+        // TLM_parsing(TLM);
         SC.printf("\n\r");
     }
     
 }
 
+
+/* ***************************************************************** */
+
+
+void TLM_parsing(char *tlm_buf) 
+{
+    // identificatore
+    int tlm_identifier = BinToDec(0, IDENTIFIER, tlm_buf); 
+    volatile int single_word = 0, first_word = 0, second_word = 0;
+    
+    if (tlm_buf[5] == '0' && tlm_buf[6] == '0')
+    {
+        // single word
+        single_word = 1;
+    }
+    else if (tlm_buf[5] == '0' && tlm_buf[6] == '1')
+    {
+        // 1st word
+        first_word = 1;
+    }
+    else if (tlm_buf[5] == '1' && tlm_buf[6] == '0')
+    {
+        // 2nd word
+        second_word = 1;
+    }
+    else if (tlm_buf[5] == '1' && tlm_buf[6] == '1')
+    {
+        // not used
+    }
+    
+    if (commandId == 1)
+    {
+        if ((tlm_identifier == 25) && (first_word == 1))
+        {
+            SC.printf("%s\n\r", MIMA_OPERATING_MODE(tlm_buf));
+        }
+    }
+}
+
+
+/* ***************************************************************** */
+
+// integrità dei dati ricevuti da MIMA: Channel 1 - Channel 2
+void Checksum(char *a)                                                              // Checksum
+{
+    volatile int temp, var, ai_int, aj_int, p = 0;
+  
+    for (int i = word; i < 2*word; i++) 
+    {
+        volatile int ch1_start = i+word;
+        
+        for (int j = ch1_start; j < CHANNEL*word; j+=word)
+        {
+            if (j == ch1_start) 
+            {
+                ai_int = a[i] - '0';    // '1'/'0' char -> int 1/0
+                aj_int = a[j] - '0';    // '1'/'0' char -> int 1/0
+                temp = ai_int ^ aj_int; // XOR
+            } else
+            {
+                aj_int = a[j] - '0';
+                temp = temp ^ aj_int;   
+            }
+
+        }
+        ch1_intChecksum[p++] = temp; // vettore del checksum in int
+    }
+    
+    for (int i = 0; i < word; i++) // trasformo in char
+    {
+        if (ch1_intChecksum[i] == 0)
+        {
+            ch1_checksumWord[i++] = '0';
+        } 
+        else if (ch1_intChecksum[i] == 1)
+        {
+            ch1_checksumWord[i++] = '1';
+        }
+    }
+    
+    // confronto tra checksum ricevuto e checksum elaborato
+    volatile int t = 0;
+    for (int i = (CHANNEL+1)*word; i < (CHANNEL+2)*word; i++) 
+    {
+        ch1_checksumReceived[t++] = TLM_HSK_SD[i];
+    }
+    
+    ch1_errorDetected = 0;
+    
+    for (int i = 0; i < sizeof(ch1_checksumWord)/sizeof(ch1_checksumWord[0]); i++) 
+    {
+        if (ch1_checksumWord[i] != ch1_checksumReceived[i])
+        {
+            ch1_errorDetected = 1;
+            SC.printf("\n\r> CH1 Channel Checksum ERROR detected: BIT n. %i\n\r", (i+1));
+            break;
+        }         
+    }  
+    
+    
+    /***** CHANNEL 2 *****/
+    
+    p = 0;
+    int ch2_limit = (2*CHANNEL+4);
+    for (int i = (CHANNEL+4)*word; i < ch2_limit*word; i++) 
+    {
+        volatile int ch2_start = i+word;
+        
+        for (int j = ch2_start; j < (ch2_limit+CHANNEL)*word; j+=word)
+        {
+            if (j == ch2_start) 
+            {
+                ai_int = a[i] - '0';    // '1'/'0' char -> int 1/0
+                aj_int = a[j] - '0';    // '1'/'0' char -> int 1/0
+                temp = ai_int ^ aj_int; // XOR
+            } else
+            {
+                aj_int = a[j] - '0';
+                temp = temp ^ aj_int;   
+            }
+
+        }
+        ch2_intChecksum[p++] = temp; // vettore del checksum in int
+    }
+    
+    for (int i = 0; i < word; i++) // trasformo in char
+    {
+        if (ch2_intChecksum[i] == 0)
+        {
+            ch2_checksumWord[i++] = '0';
+        } 
+        else if (ch1_intChecksum[i] == 1)
+        {
+            ch2_checksumWord[i++] = '1';
+        }
+    }
+    
+    // confronto tra checksum ricevuto e checksum elaborato
+    t = 0;
+    for (int i = (CHANNEL+4)*word; i < (2*CHANNEL+4)*word; i++) 
+    {
+        ch2_checksumReceived[t++] = TLM_HSK_SD[i];
+    }
+    
+    ch2_errorDetected = 0; // flag
+    
+    for (int i = 0; i < sizeof(ch2_checksumWord)/sizeof(ch2_checksumWord[0]); i++) 
+    {
+        if (ch2_checksumWord[i] != ch2_checksumReceived[i])
+        {
+            ch2_errorDetected = 1;
+            SC.printf("\n\r> CH2 Channel Checksum ERROR detected: BIT n. %i\n\r", (i+1));
+            break;
+        }         
+    }     
+}
+
+
 /* ***************************************************************** */
 
 // controllo dell'attuatore e dei relay
-void ActuatorControl(int command) 
-{
-        SC.printf("\n\r *** L16 ACTUATONIX - RELAY CONTROL *** \n\r"); // leggibilità
-        
-        // *** estensione/ritrazione dell'attuatore ***
-        if((command == 128) && (offset < 1.0f)) { 
-            offset += 0.2f; 
-        } else if((command == 64) && (offset > 0.0f)) {
-            offset -= 0.2f; 
+void SpareCommand(int command)                                                      // Spare command (Relay, L16)
+{        
+    if((command == 128) && (offset < 1.0f)) 
+    { 
+        offset += 0.2f; 
+        M1.write(offset);
+        M2.write(offset); 
+        SC.printf("> Duty Cycle %.2f / estensione \n\r", offset);    
+    } 
+    else if((command == 64) && (offset > 0.0f)) 
+    {
+        offset -= 0.2f; 
+        M1.write(offset);
+        M2.write(offset); 
+        SC.printf("> Duty Cycle %.2f / estensione \n\r", offset);  
+    }
+    else if (command == 1) 
+    {
+        Relay5V = 0;
+        SC.printf("\r\nRelay 5V ON\r\n");       
+    } 
+    else if (command == 0) 
+    {
+        Relay5V = 1;
+        SC.printf("\r\nRelay 5V OFF\r\n");
+    } 
+    else if (command == 3) 
+    {
+        Relay12V = 0;
+        SC.printf("\r\nRelay 12V ON\r\n");           
+    }  
+    else if (command == 2) 
+    {
+        Relay12V = 1;
+        SC.printf("\r\nRelay 12V OFF\r\n");
+    } 
+    else if (command == 7) 
+    {
+        Relay15_15_5V = 0;
+        SC.printf("\r\nRelay +15V, -15V, -5V ON\r\n");     
+    } 
+    else if (command == 6) 
+    {
+        Relay15_15_5V = 1;
+        SC.printf("\r\nRelay +15V, -15V, -5V OFF\r\n");
+    } 
+    else if (command == 15) 
+    {
+        Relay24V = 0;
+        SC.printf("\r\nRelay 24V ON\r\n");        
+    } 
+    else if (command == 8) 
+    {
+        Relay24V = 1;
+        SC.printf("\r\nRelay 24V OFF\r\n");   
+    } 
+    else if (command == 255) 
+    {
+        Relay5V = 1;
+        Relay12V = 1;
+        Relay15_15_5V = 1; // +15, -15, -5
+        Relay24V = 1;
+        offset = 0.0f;
             
-        // *** gestione accensione/spegnimento relay alimentazione ***
-        }    // Relay 5V
-          else if (command == 1) {
-            Relay5V = 0;
-            SC.printf("\r\nRelay 5V ON\r\n");
-        } else if (command == 0) {
-            Relay5V = 1;
-            SC.printf("\r\nRelay 5V OFF\r\n");
-                    
-            // Relay 12V
-        } else if (command == 3) {
-            Relay12V = 0;
-            SC.printf("\r\nRelay 12V ON\r\n");
-               
-        }  else if (command == 2) {
-            Relay12V = 1;
-            SC.printf("\r\nRelay 12V OFF\r\n");
-               
-            // Relay +15V, -15V, -5V
-        } else if (command == 7) {
-            Relay15_15_5V = 0;
-            SC.printf("\r\nRelay +15V, -15V, -5V ON\r\n");
-               
-        } else if (command == 6) {
-            Relay15_15_5V = 1;
-            SC.printf("\r\nRelay +15V, -15V, -5V OFF\r\n");
-        
-            // Relay 24V
-        } else if (command == 15) {
-            Relay24V = 0;
-            SC.printf("\r\nRelay 24V ON\r\n");
-               
-        } else if (command == 8) {
-            Relay24V = 1;
-            SC.printf("\r\nRelay 24V OFF\r\n");   
-            
-            // RESET
-        } else if (command == 255) {
-            // spegni tutto
-            Relay5V = 1;
-            Relay12V = 1;
-            Relay15_15_5V = 1; // +15, -15, -5
-            Relay24V = 1;
-        }
-            
+        SC.printf("**** SHUTTING DOWN ALL RELAYS... ****\n\r");
+        M1.write(offset);
+        M2.write(offset); 
+        SC.printf("> Duty Cycle %.2f / extension \n\r", offset);
+    }
+    else if ((command == 128) || (command == 64) && (Relay12V == 1))
+    {
+        offset = 0.0f;
         M1.write(offset);
         M2.write(offset); 
-                    
-        SC.printf("> Duty Cycle %.2f / estensione \n \r", offset);   
+    }                   
+}
+
+
+/* ***************************************************************** */
+
+// (t = indice da cui partire, dim = dimensione array, *a = array in input)
+int BinToDec(int t, int dim, char *a)                                               // Binary to decimal conversion
+{
+    volatile int result = 0;
+
+    while (t < dim)
+    {
+        if (a[t] == '1')
+        {
+            int raise = dim - 1 - t;
+            result += pow((float) base, (float) raise);
+        }
+        else
+        {
+            result += 0;
+        }
+        t++;
+    }
+    return result;
+}
+
+
+/* ***************************************************************** */
+
+
+// TEMPERATURA
+void GetTemperature(void)                                                           // Get temperature from MAX31865-Arduino
+{
+    char cReadChar; 
+    
+    while((MAX31865.readable()))
+    {
+        cReadChar = MAX31865.getc();
+        nRxCharCount++; 
+        caRxPacket[nRxCharCount] = cReadChar;
+    }
 }
+
+
+/* ***************************************************************** */
+
+
+void ReadTemperature(void)                                                          // Read temperature float value 
+{
+    nRxCharCount = 0; // indice
+
+    int y = 0, u = 0; // indici
+
+    for (int i = 0; i < PACKETDIM; i++)
+    {
+        if (caRxPacket[i] == 'S')
+        {
+            indexJ = i + 1;
+
+            while (indexJ < PACKETDIM)
+            {
+                if (caRxPacket[indexJ] == ';')
+                {
+                    break;
+                }
+                else
+                {
+                    tempCH1[y++] = caRxPacket[indexJ];
+                }
+
+                indexJ++;
+            } // se trova ; esce dall'istruzione e salva il valore di uscita dell'indice
+
+            indexT = indexJ + 1;
+
+            while (indexT < PACKETDIM)
+            {
+                if (caRxPacket[indexT] == 'P')
+                {
+                    break;
+                }
+                else
+                {
+                    tempCH2[u++] = caRxPacket[indexT];
+                }
+
+                indexT++;
+            }
+            
+            // trasforma il dato da sequenza di caratteri a numero float utile per analisi
+
+            strcpy(CH1_to_string, tempCH1);
+            CH1 = atof(CH1_to_string);
+
+            strcpy(CH2_to_string, tempCH2);
+            CH2 = atof(CH2_to_string);
+
+            SC.printf("> TEMPERATURE - CH1: %4.8f[Celsius], CH2: %4.8f[Celsius]\n\r", CH1, CH2);
+
+            break;
+        }
+    }
+
+    wait_ms(150); // pausa per garantire sincronizzazione tra riempimento buffer e svuotamento
+}
+
+
+/* ***************************************************************** */             // MIMA OPERATING MODE
+
+
+const char* MIMA_OPERATING_MODE(char *s)
+{
+    if (s[7] == '0' && s[8] == '0' && s[9] == '0' && s[10] == '1')
+    {
+        return "> Setting MIMA... Sleeping mode";
+    }
+    else if (s[7] == '0' && s[8] == '0' && s[9] == '1' && s[10] == '0')
+    {
+        return "> Setting MIMA... Awake mode";
+    }
+    else if (s[7] == '0' && s[8] == '0' && s[9] == '1' && s[10] == '1')
+    {
+        return "> Setting MIMA... Calibration mode";
+    }
+    else if (s[7] == '0' && s[8] == '1' && s[9] == '0' && s[10] == '0')
+    {
+        return "> Setting MIMA... Observation mode";
+    }
+    else if (s[7] == '0' && s[8] == '1' && s[9] == '0' && s[10] == '1') 
+    {
+        return "> Setting MIMA... Auto-test mode";
+    }
+    else if (s[7] == '0' && s[8] == '1' && s[9] == '1' && s[10] == '0')
+    {
+        return "> Setting MIMA... Full testing mode";
+    }
+    
+    return "\0";
+}
+
+
+/* ***************************************************************** */