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-06-30
- Revision:
- 0:8f7c961a5966
- Child:
- 1:00cee5df0f76
File content as of revision 0:8f7c961a5966:
// Librerie
#include "mbed.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "tlc_tlm_list.h"
// Macros
#define cmd_num 32
#define buf_max_size 512
#define tlc_to_tx 16
#define tlm_size 16
#define tlm_hsk_size 912
#define tlm_hsk_sd_size 90608
#define identifier_field 5
#define max31865_buf_size 13
#define channel_size 5
#define size 1
// Serial e periferiche
Serial spacecraft(USBTX, USBRX);
Serial mima(PC_4, PC_5);
Serial max31865(PA_9, PA_10);
// Buffer
volatile int sizeBuffer;
int CMD[cmd_num];
char TLM[tlm_size];
char TLM_HSK[tlm_hsk_size];
char TLM_HSK_SD[tlm_hsk_sd_size];
char tlc_rx[buf_max_size];
char caRxPacket[max31865_buf_size];
char tempCH1[channel_size];
char tempCH2[channel_size];
char CH1_to_string[2*channel_size];
char CH2_to_string[2*channel_size];
// L16 Actuonix - Relay (spare commands)
PwmOut M1 (PA_6);
PwmOut M2 (PA_8);
DigitalOut Relay5V (PA_7);
DigitalOut Relay12V (PB_4);
DigitalOut Relay24V (PB_5);
DigitalOut Relay15_15_5V (PB_10);
float offset = 0.0f;
// Timer
Timer timer;
float TIMEOUT = 10, tTimeStart, tTimeStop, tTimeRead;
// Vars definitions
int temperature_flag;
volatile int payload_to_dec;
volatile int tlmode_option_1;
volatile int tlmode_option_2;
volatile int commandId;
volatile int nRxCharCount;
volatile int tlc_rx_length;
volatile int checkZerosIndex, checkOnesIndex;
volatile float CH1, CH2;
volatile int increment_read;
volatile int indexJ, indexT;
// Functions
void RxTelecommand();
void TxTelecommand();
void RxTelemetry();
void TxTelemetry();
void TxTemperature();
void RxTemperature();
void SpareCommand(int command);
void printMyArray(Telecommand *myArray);
void clearBuffer(char *arr, int arrLen);
void checksum_tlc(Telecommand *toCheck_tlc);
void checksum_tlm(Telemetry *toCheck_tlm);
int BinToDec(int t, int dim, char *a);
// Main
int main()
{
// Baudrate
spacecraft.baud(115200);
mima.baud(9600);
max31865.baud(115200);
// Interrupts
spacecraft.attach(&RxTelecommand, Serial::RxIrq);
//max31865.attach(&RxTemperature, Serial::RxIrq);
while (true)
{
/**********************************************************************
RICEZIONE DEI DATI DI TEMPERATURA
**********************************************************************/
if ((commandId == 0) && (payload_to_dec == 32) && (temperature_flag == 1))
{
TxTemperature();
increment_read++;
if (increment_read == 40)
{
temperature_flag = 0;
}
}
/**********************************************************************
RICEZIONE DI TELEMETRIE DA MIMA
**********************************************************************/
// Scrittura del telecomando
cmd00[(size-1)].PAYLOAD = "00000000";
if (cmd00[(size-1)].PAYLOAD != '\0')
{
checksum_tlc(&cmd00[(size-1)]);
printMyArray(&cmd00[(size-1)]);
}
// In arrivo da periferica 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]));
timer.start();
tTimeStart = timer.read();
tTimeRead = tTimeStart;
// Interrupt: entra nella routine quando riceve dalla seriale
mima.attach(&RxTelemetry, Serial::RxIrq);
// Diagnostica del pacchetto ricevuto
if (commandId == 5)
{
/* Ricezione di tutte le telemetrie. 57 parole da 16 bit contenenti
tutte le telemetrie di tipo HOUSEKEEPING. */
if (tlmode_option_1 == 0)
{
while ((sizeBuffer < tlm_hsk_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
{
tTimeRead = timer.read();
}
timer.stop();
if ((tTimeRead - tTimeStart) >= TIMEOUT)
{
sizeBuffer = 0;
clearBuffer(TLM_HSK, tlm_hsk_size);
}
else
{
TxTelemetry();
}
}
/* Ricezione di tutte le telemetrie e dati scientifici
5663 parole da 16 bit così strutturate: 57 HSKP data packets,
5606 di scientific data dell'interferometro su MIMA, */
else if (tlmode_option_2 == 0)
{
while ((sizeBuffer < tlm_hsk_sd_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
{
tTimeRead = timer.read();
}
timer.stop();
if ((tTimeRead - tTimeStart) >= TIMEOUT)
{
sizeBuffer = 0;
clearBuffer(TLM_HSK_SD, tlm_hsk_sd_size);
}
else
{
TxTelemetry();
}
}
}
/* Ricezione di un dato di telemetria da 16 bit. */
else
{
while ((sizeBuffer < tlm_size) && ((tTimeRead - tTimeStart) < TIMEOUT))
{
tTimeRead = timer.read();
}
timer.stop();
if ((tTimeRead - tTimeStart) >= TIMEOUT)
{
sizeBuffer = 0;
clearBuffer(TLM, tlm_size);
}
else
{
TxTelemetry();
}
}
}
}
/* Gestione delle routine di ricezione e trasmissione del driver */
// DORA riceve telecomando da Space/craft
void RxTelecommand()
{
while (spacecraft.readable())
{
clearBuffer(tlc_rx, sizeof(tlc_rx) / sizeof(tlc_rx[0]));
spacecraft.gets(tlc_rx, sizeof(tlc_rx));
tlc_rx_length = strlen(tlc_rx) - 2; // rimozione tag di NR
if (tlc_rx_length == tlc_to_tx)
{
int bit_B0 = 0, bit_B7 = 7, k = 0;
commandId = 0; // init
payload_to_dec = 0; // init
commandId = BinToDec(bit_B0, identifier_field, tlc_rx);
payload_to_dec = BinToDec(bit_B7, (tlc_to_tx - 1), tlc_rx);
k = commandId;
if (k == 2 || k == 15 || k == 30)
{
// Spare
break;
}
/* Gestiione della lettura della temperatura */
else if ((k == 0) && (tlc_rx[5] == '0') && (tlc_rx[6] == '0') && (payload_to_dec == 32))
{
temperature_flag = 1;
break;
}
/* Gestione delle perifieriche HW: relay, attuatori, alimentazione */
else if ((k == 0) && (tlc_rx[5] == '0') && (tlc_rx[6] == '0'))
{
//SpareCommand(payload_to_dec);
break;
}
else if (k == 5)
{
/* Istruzione che serve a scorrere il Payload e a settare un determinato flag
per consentire a DORA di aprire o meno determinati canali di comunicazione
(buffer da riempire). */
checkZerosIndex = bit_B7;
while (checkZerosIndex < tlc_to_tx)
{
if (tlc_rx[checkZerosIndex] == '0')
{
tlmode_option_1 = 0;
checkZerosIndex++;
}
else
{
tlmode_option_1 = 1;
break;
}
}
checkOnesIndex = bit_B7;
while (checkOnesIndex < tlc_to_tx)
{
if (tlc_rx[checkOnesIndex] == '1')
{
tlmode_option_2 = 0;
checkOnesIndex++;
}
else
{
tlmode_option_2 = 1;
break;
}
}
}
}
TxTelecommand();
}
}
// Trasmetti il pacchetto
void TxTelecommand()
{
for (int i = 0; i < tlc_to_tx + 1; i++)
{
mima.putc(tlc_rx[i]);
}
}
// Riceve dalla seriale mima
void RxTelemetry()
{
char data;
while((mima.readable()))
{
data = mima.getc();
if (tlmode_option_1 == 0)
{
TLM_HSK[sizeBuffer++] = data;
}
else if (tlmode_option_2 == 0)
{
TLM_HSK_SD[sizeBuffer++] = data;
}
else
{
TLM[sizeBuffer++] = data;
}
}
}
// Dora trasmette il pacchetto allo space/craft
void TxTelemetry()
{
if (tlmode_option_1 == 0)
{
for (int i = 0; i < tlm_hsk_size; i++)
{
spacecraft.putc(TLM_HSK[i]);
}
}
else if (tlmode_option_2 == 0)
{
for (int i = 0; i < tlm_hsk_sd_size; i++)
{
spacecraft.putc(TLM_HSK_SD[i]);
}
}
else
{
for (int i = 0; i < tlm_size; i++)
{
spacecraft.putc(TLM[i]);
}
}
}
/* Routines dedicate alla ricezione di dati della temperatura (Pt100) */
void RxTemperature()
{
char cReadChar;
while((max31865.readable()))
{
cReadChar = max31865.getc();
nRxCharCount++;
caRxPacket[nRxCharCount] = cReadChar;
}
}
void TxTemperature(void)
{
nRxCharCount = 0; // reset dell'indice del buffer
int y = 0, u = 0; // indici dei buffer temporanei per i due canali
for (int i = 0; i < max31865_buf_size; i++)
{
if (caRxPacket[i] == 'S')
{
indexJ = i + 1;
while (indexJ < max31865_buf_size)
{
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 < max31865_buf_size)
{
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);
spacecraft.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
}
/* Comandi spare/not used */
void SpareCommand(int command) // Spare command (Relay, L16)
{
if((command == 128) && (offset < 1.0f))
{
offset += 0.2f;
M1.write(offset);
M2.write(offset);
spacecraft.printf("> Duty Cycle %.2f / estensione \n\r", offset);
}
else if((command == 64) && (offset > 0.0f))
{
offset -= 0.2f;
M1.write(offset);
M2.write(offset);
spacecraft.printf("> Duty Cycle %.2f / estensione \n\r", offset);
}
else if (command == 1)
{
Relay5V = 0;
spacecraft.printf("\r\nRelay 5V ON\r\n");
}
else if (command == 0)
{
Relay5V = 1;
spacecraft.printf("\r\nRelay 5V OFF\r\n");
}
else if (command == 3)
{
Relay12V = 0;
spacecraft.printf("\r\nRelay 12V ON\r\n");
}
else if (command == 2)
{
Relay12V = 1;
spacecraft.printf("\r\nRelay 12V OFF\r\n");
}
else if (command == 7)
{
Relay15_15_5V = 0;
spacecraft.printf("\r\nRelay +15V, -15V, -5V ON\r\n");
}
else if (command == 6)
{
Relay15_15_5V = 1;
spacecraft.printf("\r\nRelay +15V, -15V, -5V OFF\r\n");
}
else if (command == 15)
{
Relay24V = 0;
spacecraft.printf("\r\nRelay 24V ON\r\n");
}
else if (command == 8)
{
Relay24V = 1;
spacecraft.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;
spacecraft.printf("**** SHUTTING DOWN ALL RELAYS... ****\n\r");
M1.write(offset);
M2.write(offset);
spacecraft.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);
}
}
/* Funzionalità di sistema */
// Funzione che serve a ripulire un buffer di caratteri
void clearBuffer(char *arr, int arrLen)
{
int nIndex;
for (nIndex = 0; nIndex < arrLen; nIndex++)
{
arr[nIndex] = '\0';
}
}
// Inizializzazione del set di identificativi dello Spacecraft
void CMD_REF()
{
int id = 0;
for (int i = 0; i < cmd_num; i++)
{
CMD[id++] = i;
}
}
// Trasformazione da binario a decimale per una sequenza di bit in un array
int BinToDec(int t, int dim, char *a)
{
volatile int result = 0;
while (t < dim)
{
if (a[t] == '1')
{
int raise = dim - 1 - t;
result += pow((float) 2, (float) raise);
}
else
{
result += 0;
}
t++;
}
return result;
}
// Print
void printMyArray(Telecommand *myArray)
{
for (int i = 0; i < sizeof(myArray)/sizeof(myArray[0]); i++)
{
mima.puts(myArray[i].ID);
mima.puts(myArray[i].TAG);
mima.puts(myArray[i].PAYLOAD);
mima.putc(myArray[i].LSB);
spacecraft.printf("\n\r");
}
}
// Checksum per telecomandi
void checksum_tlc(Telecommand *toCheck_tlc)
{
int ones_tlc = 0;
for (int i = 0; i < sizeof(toCheck_tlc)/sizeof(toCheck_tlc[0]); i++)
{
// contatore degli "1" nel campo "identifier"
for (int j = 0; i < sizeof(toCheck_tlc[i].ID)/sizeof(toCheck_tlc[i].ID[0]); j++)
{
if (toCheck_tlc[i].ID[j] == '1')
{
ones_tlc++;
}
}
// contatore degli "1" nel campo "tag"
for (int k = 0; i < sizeof(toCheck_tlc[i].TAG)/sizeof(toCheck_tlc[i].TAG[0]); k++)
{
if (toCheck_tlc[i].TAG[k] == '1')
{
ones_tlc++;
}
}
// contatore degli "1" nel campo "payload" (da assegnare nel file main)
for (int l = 0; i < sizeof(toCheck_tlc[i].TAG)/sizeof(toCheck_tlc[i].TAG[0]); l++)
{
if (toCheck_tlc[i].PAYLOAD[l] == '1')
{
ones_tlc++;
}
}
// Scrivi LSB
if (ones_tlc % 2 == 0)
{
toCheck_tlc[i].LSB = '0'; // If the number of ones in[B0÷B14] bits is even
}
else
{
toCheck_tlc[i].LSB = '1'; // If the number of ones in[B0÷B14] bits is odd
}
}
}
// Checksum per telemetrie housekeeping
void checksum_tlm(Telemetry *toCheck_tlm)
{
int ones_tlm = 0;
for (int i = 0; i < sizeof(toCheck_tlm)/sizeof(toCheck_tlm[0]); i++)
{
// contatore degli "1" nel campo "identifier"
for (int j = 0; i < sizeof(toCheck_tlm[i].ID)/sizeof(toCheck_tlm[i].ID[0]); j++)
{
if (toCheck_tlm[i].ID[j] == '1')
{
ones_tlm++;
}
}
// contatore degli "1" nel campo "tag"
for (int k = 0; i < sizeof(toCheck_tlm[i].TAG)/sizeof(toCheck_tlm[i].TAG[0]); k++)
{
if (toCheck_tlm[i].TAG[k] == '1')
{
ones_tlm++;
}
}
// contatore degli "1" nel campo "payload" (da assegnare nel file main)
for (int l = 0; i < sizeof(toCheck_tlm[i].TAG)/sizeof(toCheck_tlm[i].TAG[0]); l++)
{
if (toCheck_tlm[i].PAYLOAD[l] == '1')
{
ones_tlm++;
}
}
// Scrivi LSB
if (ones_tlm % 2 == 0)
{
toCheck_tlm[i].LSB = '0'; // If the number of ones in[B0÷B14] bits is even
}
else
{
toCheck_tlm[i].LSB = '1'; // If the number of ones in[B0÷B14] bits is odd
}
}
}