Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp
- Committer:
- paologiorgio
- Date:
- 2022-08-01
- Revision:
- 2:155d07b145c6
- Parent:
- 1:00cee5df0f76
File content as of revision 2:155d07b145c6:
// Librerie #include "mbed.h" #include <math.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> // Macros #define config 2 // 0: spacecraft, 1: mima, 2: no diagnostic #define PACKETDIM 15 // temperature #define word 1 #define packet 2 // 2 bytes #define channel_size 10 // temeprature channel from sen30202 #define CMD05_1 40 #define CMD05_2 41 #define TLMODE_HSK 0 #define TLMODE_HSKSD 127 #define CMD00 0 #define CMD02 16 #define TEMP_QUERY 32 #define CMD15_R 121 #define CMD15 120 #define ALL_RELAY_OFF 42 #define ALL_RELAY_ON 85 #define ENABLE_12V 1 #define DISABLE_12V 0 #define ENABLE_5V 3 #define DISABLE_5V 2 #define ENABLE_15V 7 #define DISABLE_15V 6 #define ENABLE_24V 15 #define DISABLE_24V 8 #define CMD31 241 #define RESET_GLOBAL_VARS 127 // Definizione periferiche Serial spacecraft(PC_1, PC_0); //Serial spacecraft(USBTX, USBRX); // se pc connesso direttamente all'stm32 Serial mima(PC_4, PC_5); /* se si desidera utilizzare il pc come mima Serial mima(PC_1, PC_0); Serial spacecraft(PC_4, PC_5); */ Serial max31865(PA_0, PA_1); // L16 Actuonix: AnalogOut actuonix(PA_4); PwmOut actuonix_dig(PB_3); float offset; float offset_dig; // Relay DigitalOut Relay5V(PA_7); DigitalOut Relay12V(PB_4); DigitalOut Relay24V(PB_5); DigitalOut Relay15_15_5V(PB_10); // Buffer: telecommand volatile int rxTlcPtr; int rxTlcDataCounter = 0; char rx_TLC[word+1]; char data_TLC[word+1]; // Buffer: standard telemetry (1 frame da 16 bit o 2 frame da 16 bit ciascuno) volatile int rxTlmPtr; int rxTlmDataCounter = 0; char rx_TLM[word+1]; char data_TLM[word+1]; // Buffer: TLMODE telemetry option 1 (tutte le housekeeping telemetries) volatile int rxTlmOpt1Ptr; int rxTlmOpt1DataCounter = 0; char rx_TLMOpt1[word+1]; char data_TLMOpt1[word+1]; // Buffer: TLMODE telemetry option 2 (housekeeping + data dall'interferometro) volatile int rxTlmOpt2Ptr; int rxTlmOpt2DataCounter = 0; char rx_TLMOpt2[word+1]; char data_TLMOpt2[word+1]; // Timer: 3 contatori differenti a seconda del numero di bytes da ricevere Timer timer; Timer rx; Timer rx_wide; float rxWindow = 6 /*seconds, TBA */, rxTimeStart, rxTimeStop, rxTimeRead; // standard teleemtry + hsk float rx_wideWindow = 300 /*seconds, TBA */, rx_wideTimeStart, rx_wideTimeStop, rx_wideTimeRead; // full hsk+scientific data float TIMEOUT = 3 /*seconds */, tTimeStart, tTimeStop, tTimeRead; // telecommand // TLMODE: definizione dei vari flag, assegnazioni di variabili volatile int tlmode_option_1, tlmode_option_2, tlmode_tlm; volatile char payload; volatile bool TlcSend; volatile bool Spare; volatile char dataIn; // SC-MIMA communication: TX/RX void RxTelecommand(void); void TxTelecommand(void); void RxTelemetry(void); void TxTelemetry(void); // System utility void clearBuffer(char *arr, int arrLen); // Richiesta temperatura char tempCH1[channel_size]; char tempCH2[channel_size]; volatile int j; // first channel index volatile int t; // second channel index volatile char caRxPacket[PACKETDIM]; // temperature buffer volatile char nRxCharCount; // temperature char counter // Routines dedicate alla ricezione di dati della temperatura (Pt100) void SerialeRxInterrupt(void) { char cReadChar; while ((max31865.readable())) { cReadChar = max31865.getc(); nRxCharCount++; caRxPacket[nRxCharCount] = cReadChar; } if (nRxCharCount == PACKETDIM) { nRxCharCount = 0; } } // Main int main() { // config 0: il mio pc come spacecraft // config 1: il mio pc come mima // Baudrate spacecraft.baud(9600); mima.baud(9600); max31865.baud(115200); // Diagnostica if (config == 0) { spacecraft.printf(" Avvio Spacecraft... \n\r"); } else if (config == 1) { mima.printf(" Avvio MIMA... \n\r"); } // Setup per temperatura int nIndex; nRxCharCount = 0; for (nIndex = 0; nIndex < PACKETDIM; nIndex++) { caRxPacket[nIndex] = 0; } // Setup per Actuonix L16->PWM actuonix_dig.period_us(1000); offset_dig = actuonix_dig.read(); offset = actuonix.read(); // Setup per Relay: 1 = OFF (1->OFF, 0->ON) Relay5V = 1; Relay12V = 1; Relay15_15_5V = 1; Relay24V = 1; // Bool flags TlcSend = false; // Interrupts max31865.attach(&SerialeRxInterrupt, Serial::RxIrq); spacecraft.attach(&RxTelecommand, Serial::RxIrq); mima.attach(&RxTelemetry, Serial::RxIrq); // Diagnostica if (config == 0) { spacecraft.printf(" ... Ready to send... \n\r"); } else if (config == 1) { mima.printf(" ... Ready to send... \n\r"); } // Main loop while (true) { // Inizializza contatore caratteri in arrivo e flag di ricezione comando Spare rxTlcPtr = 0; Spare = false; // Setup per RX (uno dei flag verrà attivato solo via invio di un telecomando) // se tutti i flag sono su "1", dora non trasmetterà nulla verso spacecraft tlmode_option_1 = 1; tlmode_option_2 = 1; tlmode_tlm = 1; // Timer timer.start(); tTimeStart = timer.read(); tTimeRead = tTimeStart; // Finché non raggiungo la dimensione richiesta (16 bit, 2 byte), // resto in attesa di dati da spacecraft, all'interno della finestra di ricezione while ((rxTlcPtr < packet) && ((tTimeRead - tTimeStart) < TIMEOUT)) { tTimeRead = timer.read(); } timer.stop(); // Se ho ricevuto 2 byte nella finestra di ricezione, preparo un array di data // per ricomporre il frame da 16 bit e inviarlo a mima tramite dora if ((rxTlcPtr == packet) && ((tTimeRead - tTimeStart) < TIMEOUT)) { __disable_irq(); memcpy(data_TLC, rx_TLC, rxTlcPtr); rxTlcDataCounter = rxTlcPtr; // Legge il contenuto del payload ignorando il LSB payload = data_TLC[1] >> 1; // Diagnostica if (config == 0) { spacecraft.printf("\n\r .... Telecomando ricevuto su DORA! \n\r"); } else if (config == 1) { mima.printf("\n\r .... Telecomando ricevuto su DORA! \n\r"); } // Visualizza i byte inviati for (int i = 0; i < sizeof(data_TLC) / sizeof(char); i++) { if (config == 0) { spacecraft.printf("> Carattere: %i \n\r", (int) data_TLC[i]); } else if (config == 1) { mima.printf("> Carattere: %i \n\r", (int) data_TLC[i]); } } // add a null just in case the received data didn't have one at the end data_TLC[rxTlcDataCounter] = 0; // hw control: set-point init offset = actuonix.read(); // legge il valore attuale dell'attuatore offset_dig = actuonix_dig.read(); // RX settings // Si prepara alla ricezione di telemetrie standard in caso di invio di telecomandi // differenti dal CMD05 (TLMODE) if (((int) data_TLC[0] != CMD05_1) || ((int) data_TLC[0] != CMD05_2)) { tlmode_option_1 = 1; tlmode_option_2 = 1; tlmode_tlm = 0; } // Controllo dell'attuatore lineare L16 (comando Spare) if ((int) data_TLC[0] == CMD00) { offset = (int) payload; offset = offset / 100; offset_dig = (int) payload; offset_dig = offset_dig / 100; actuonix_dig.write(offset_dig); actuonix.write(offset); Spare = true; } // Richiesta delle temperature. Data: SXXX.XX;YYY.YYP > START/CH1;CH2/END // Controllo del flusso di dati proveniente dalla Seriale else if (((int) data_TLC[0] == CMD02) && ((int) payload == TEMP_QUERY)) { // Cleaning buffers clearBuffer(tempCH1, sizeof(tempCH1) / sizeof(char)); clearBuffer(tempCH2, sizeof(tempCH2) / sizeof(char)); // Index setup nRxCharCount = 0; int y = 0, u = 0; t = 0; j = 0; // global for (int i = 0; i < PACKETDIM; i++) { if (caRxPacket[i] == 'S') { // Indice sul quale cade la prima cifra del canale 1 j = i + 1; while (j < PACKETDIM) { if (caRxPacket[j] == ';') { break; } else { tempCH1[y++] = caRxPacket[j]; } j++; } // Indice sul quale cade la prima cifra del canale 2 t = j + 1; while (t < PACKETDIM) { if (caRxPacket[t] == 'P') { break; } else { tempCH2[u++] = caRxPacket[t]; } t++; } break; } } // Invia i dati a Spacecraft spacecraft.puts(tempCH1); spacecraft.puts(";"); // split ch1-ch2 data spacecraft.puts(tempCH2); Spare = true; } else if (((int) data_TLC[0] == CMD15_R) && ((int) payload == ALL_RELAY_OFF)) { Relay5V = 1; Relay12V = 1; Relay15_15_5V = 1; Relay24V = 1; Spare = true; } else if (((int) data_TLC[0] == CMD15) && ((int) payload == ALL_RELAY_ON)) { Relay5V = 0; Relay12V = 0; Relay15_15_5V = 0; Relay24V = 0; Spare = true; } else if (((int) data_TLC[0] == CMD15)) { if (((int) payload == DISABLE_12V)) { Relay12V = 1; Spare = true; } else if (((int) payload == ENABLE_12V)) { Relay12V = 0; // since the linear actuator is driven by 12V power offset = actuonix.read(); offset_dig = actuonix_dig.read(); actuonix.write(offset); actuonix.write(offset_dig); Spare = true; } else if (((int) payload == DISABLE_5V)) { Relay5V = 1; Spare = true; } else if (((int) payload == ENABLE_5V)) { Relay5V = 0; Spare = true; } else if (((int) payload == DISABLE_15V)) { Relay15_15_5V = 1; Spare = true; } else if (((int) payload == ENABLE_15V)) { Relay15_15_5V = 0; Spare = true; } else if (((int) payload == DISABLE_24V)) { Relay24V = 1; Spare = true; } else if (((int) payload == ENABLE_24V)) { Relay24V = 0; Spare = true; } } else if (((int) data_TLC[0] == CMD05_1) && ((int) payload == TLMODE_HSK)) { tlmode_option_1 = 0; tlmode_option_2 = 1; tlmode_tlm = 1; rxTlmPtr = 0; rxTlmOpt1Ptr = 0; rxTlmOpt2Ptr = 0; if (config == 0) { spacecraft.printf("\n\r ... Sono entrato in TLMODE 1 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Sono entrato in TLMODE 1 ... \n\r"); } } else if (((int) data_TLC[0] == CMD05_2) && ((int) payload == TLMODE_HSKSD)) { tlmode_option_2 = 0; tlmode_option_1 = 1; tlmode_tlm = 1; rxTlmPtr = 0; rxTlmOpt1Ptr = 0; rxTlmOpt2Ptr = 0; if (config == 0) { spacecraft.printf("\n\r ... Sono entrato in TLMODE 2 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Sono entrato in TLMODE 2 ... \n\r"); } } // Reset global vars else if (((int) data_TLC[0] == CMD31) && ((int) payload == RESET_GLOBAL_VARS)) { nRxCharCount = 0; rxTlcPtr = 0; rxTlmOpt1Ptr = 0; rxTlmOpt2Ptr = 0; rxTlcDataCounter = 0; rxTlmOpt1DataCounter = 0; rxTlmOpt2DataCounter = 0; tlmode_tlm = 1; tlmode_option_1 = 1; tlmode_option_2 = 1; for (nIndex = 0; nIndex < PACKETDIM; nIndex++) { caRxPacket[nIndex] = 0; } clearBuffer(data_TLC, sizeof(data_TLC) / sizeof(char)); clearBuffer(data_TLM, sizeof(data_TLM) / sizeof(char)); clearBuffer(data_TLMOpt1, sizeof(data_TLMOpt1) / sizeof(char)); clearBuffer(data_TLMOpt2, sizeof(data_TLMOpt2) / sizeof(char)); Spare = true; if (config == 0) { spacecraft.printf("\n\r ... Reset variabili effettuato! ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Reset variabili effettuato! ... \n\r"); } } // Invia il telecomando a MIMA se non è Spare if (!Spare) { TxTelecommand(); } // Telecommand sent, flags set if (config == 0) { spacecraft.printf("\n\r ... Telecomando inviato a MIMA ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Telecomando inviato a MIMA ... \n\r"); } // Ripulisci il buffer di ricezione telecomando clearBuffer(rx_TLC, sizeof(rx_TLC) / sizeof(char)); clearBuffer(data_TLC, sizeof(data_TLC) / sizeof(char)); if (config == 0) { spacecraft.printf("\n\r ... Ho ripulito i buffer di ricezione TLC .... \n\r"); } else { mima.printf("\n\r ... Ho ripulito i buffer di ricezione TLC .... \n\r"); } __enable_irq(); // now he's ready to receive new data } // end-if:telecommand else if ((tTimeRead - tTimeStart) >= TIMEOUT) { rxTlcPtr = 0; for (int i = 0; i < packet; i++) { rx_TLC[i] = '\0'; data_TLC[i] = '\0'; } if (config == 0) { spacecraft.printf(" n\r ... Telecommand RX timeout ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Telecommand RX timeout ... \n\r"); } } // end-else-if:telecommand+timeout // Telemetry /* DORA si predispone a ricevere lato mima solo se un comando che non sia Spare è stato inviato, onde evitare ritardi (sul prossimo telecomando) dovuti a Timeout indesiderati. Sostanzialmente attende due byte (ricompone il frame) e li invia a spacecraft all'interno della finestra di trasmissione. */ if ((!Spare) && (TlcSend)) { if ((tlmode_option_1 == 1) && (tlmode_option_2 == 1) && (tlmode_tlm == 0)) // standard telemetry { clearBuffer(data_TLM, sizeof(data_TLM) / sizeof(char)); rx.start(); rxTimeStart = rx.read(); rxTimeRead = rxTimeStart; while (((rxTimeRead - rxTimeStart) < rxWindow)) { if (rxTlmPtr == packet) { __disable_irq(); memcpy(data_TLM, rx_TLM, rxTlmPtr); rxTlmDataCounter = rxTlmPtr; rxTlmPtr = 0; data_TLM[rxTlmDataCounter] = 0; TxTelemetry(); __enable_irq(); // Diagnostic if (config == 0) { spacecraft.printf("\n\r ... Ricevuto Telemetry Standard ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Ricevuto Telemetry Standard ... \n\r"); } } // update rxTimeRead = rx.read(); } rx.stop(); if ((rxTimeRead - rxTimeStart) >= rxWindow) { if (config == 0) { spacecraft.printf("\n\r ... Scattato il timeout in Telemetry ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Scattato il timeout in Telemetry ... \n\r"); } rxTlmPtr = 0; for (int i = 0; i < packet; i++) { rx_TLM[i] = '\0'; data_TLM[i] = '\0'; } } // end-else-if:telecommand-send+timeout TlcSend = false; } // end-if-send-telecommand else if ((tlmode_option_1 == 0) && (tlmode_option_2 == 1) && (tlmode_tlm == 1)) // all housekeeping teemetries { clearBuffer(data_TLMOpt1, sizeof(data_TLMOpt1)/sizeof(char)); rx.start(); rxTimeStart = rx.read(); rxTimeRead = rxTimeStart; while (((rxTimeRead - rxTimeStart) < rxWindow)) { if (rxTlmOpt1Ptr == packet) { __disable_irq(); memcpy(data_TLMOpt1, rx_TLMOpt1, rxTlmOpt1Ptr); rxTlmOpt1DataCounter = rxTlmOpt1Ptr; rxTlmOpt1Ptr = 0; data_TLMOpt1[rxTlmOpt1DataCounter] = 0; TxTelemetry(); __enable_irq(); // Diagnostic if (config == 0) { spacecraft.printf("\n\r ... Ricevuto Telemetry Opt 1 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Ricevuto Telemetry Opt 1 ... \n\r"); } } // update rxTimeRead = rx.read(); } rx.stop(); if ((rxTimeRead - rxTimeStart) >= rxWindow) { if (config == 0) { spacecraft.printf("\n\r ... Scattato il timeout in Telemetry Opt 1 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Scattato il timeout in Telemetry Opt 1 ... \n\r"); } rxTlmOpt1Ptr = 0; for (int i = 0; i < packet; i++) { rx_TLMOpt1[i] = '\0'; data_TLMOpt1[i] = '\0'; } } // end-else-if:telecommand-send+timeout TlcSend = false; } // end-else-if-send-telecommand else if ((tlmode_option_1 == 1) && (tlmode_option_2 == 0) && (tlmode_tlm == 1)) // all hsk + inteferogram data { clearBuffer(data_TLMOpt2, sizeof(data_TLMOpt2)/sizeof(char)); rx_wide.start(); rx_wideTimeStart = rx_wide.read(); rx_wideTimeRead = rx_wideTimeStart; while (((rx_wideTimeRead - rx_wideTimeStart) < rx_wideWindow)) { if (rxTlmOpt2Ptr == packet) { __disable_irq(); memcpy(data_TLMOpt2, rx_TLMOpt2, rxTlmOpt2Ptr); rxTlmOpt2DataCounter = rxTlmOpt2Ptr; rxTlmOpt2Ptr = 0; data_TLMOpt2[rxTlmOpt2DataCounter] = 0; TxTelemetry(); __enable_irq(); // Diagnostic if (config == 0) { spacecraft.printf("\n\r ... Ricevuto Telemetry Opt 2 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Ricevuto Telemetry Opt 2 ... \n\r"); } } // update rx_wideTimeRead = rx_wide.read(); } rx.stop(); if ((rx_wideTimeRead - rx_wideTimeStart) >= rx_wideWindow) { if (config == 0) { spacecraft.printf("\n\r ... Scattato il timeout in Telemetry Opt 2 ... \n\r"); } else if (config == 1) { mima.printf("\n\r ... Scattato il timeout in Telemetry Opt 2 ... \n\r"); } rxTlmOpt2Ptr = 0; for (int i = 0; i < packet; i++) { rx_TLMOpt2[i] = '\0'; data_TLMOpt2[i] = '\0'; } } // end-else-if:telecommand-send+timeout TlcSend = false; } // end-2nd-else-if-send-telecommand } } // end-while:true } // end-Main /* ************************************************************ */ /* ******* SYSTEM INTERRPUTS MANAGEMENT AND FUNCTIONS ********* */ /* ************************************************************ */ // Interrupt: DORA receives a byte from Spacecraft void RxTelecommand(void) { char txChar; while (spacecraft.readable()) { txChar = spacecraft.getc(); if (rxTlcPtr < packet) { rx_TLC[rxTlcPtr++] = txChar; } } } // Interrupt: DORA receives a byte from MIMA void RxTelemetry(void) { char rxChar; while (mima.readable()) { rxChar = mima.getc(); if (tlmode_tlm == 0) // Standard telemetry message { rx_TLM[rxTlmPtr++] = rxChar; } else if (tlmode_option_1 == 0) // TLMODE 1 (all housekeeping telemetries) { rx_TLMOpt1[rxTlmOpt1Ptr++] = rxChar; } else if (tlmode_option_2 == 0) // TLMODE 2 (hsk+scientific data) { rx_TLMOpt2[rxTlmOpt2Ptr++] = rxChar; } } } // Once received a full telecommand frame, send it to MIMA void TxTelecommand(void) { for (int i = 0; i < packet; i++) { mima.putc(data_TLC[i]); } TlcSend = true; } // Once received a full telemetry frame, send it to Spacecraft void TxTelemetry(void) { if (tlmode_tlm == 0) { for (int i = 0; i < packet; i++) { spacecraft.putc(data_TLM[i]); } } else if (tlmode_option_1 == 0) { for (int i = 0; i < packet; i++) { spacecraft.putc(data_TLMOpt1[i]); } } else if (tlmode_option_2 == 0) { for (int i = 0; i < packet; i++) { spacecraft.putc(data_TLMOpt2[i]); } } } // Reset void clearBuffer(char *arr, int arrLen) { int myIndex; for (myIndex = 0; myIndex < arrLen; myIndex++) { arr[myIndex] = '\0'; // terminatore } }