// SENAI-SP
// Pós Graduação em Sistemas Embarcados
// Disciplina: Protocolos de Comunicação
// Aluno: Marcos Flávio Soares
// Turma 11SE - 11.09.2022
// Exercício 3 - Mestre-escravo com tamanho variável (2nd byte), timeout e endereço no último byte
// Formato da mensagem(n bits): |comando|Tamanho|Param1|Param2...n|CS-checksum|ENDereço|
// Mensagem de teste: !0A >>OK, !0B >> Erro de Endereço
// Mensagem de teste: !1"A >>OK , !1"B >> Erro de Endereço
// Mensagem de teste: !2"uA >> OK, !2"uB >> Erro de Endereço, !2"cA >> Erro de CS
//
#define TIMEOUT 5000 // timeout de 11ms (Com o delay de 10ms, às vezes passa, às vezes falha)
int i = 0;
unsigned long ti, t; // Tempo a ser medido
char endereco= 'A';
int* rx = malloc(sizeof(char) * 3);
int16_t n = 0;
void setup()
{
pinMode(3, OUTPUT);
digitalWrite(3, LOW);
Serial.begin(9600);
Serial.println("Exercicio 2 Marcos");
}
void loop()
{
uint16_t ret = RX();
if(ret == 6)
{
// timeout
Serial.println("Tamanho de Mensagem inválido");
Serial.println("Mensagem Abortada!"); //Eco
}
else if(ret == 5)
{
// timeout
Serial.println("Erro de Timeout");
Serial.println("Mensagem Abortada!"); //Eco
}
else if(ret == 3)
{
// Tratamento do vetor rx[]
Serial.println("OK");
for(int k = 0; k < n; k++)
{
Serial.print((char)*(rx+k)); //Eco
}
Serial.print("\n");
}
else if(ret == 2)
{
Serial.println("Erro de CS");
for(int k = 0; k < n; k++)
{
Serial.print((char)*(rx+k)); //Eco
}
Serial.print("\n");
}
else if(ret == 1)
{
Serial.println("Erro de Endereco");
for(int k = 0; k < n; k++)
{
Serial.print((char)*(rx+k)); //Eco
}
Serial.print("\n");
}
free(rx);
delay(200);
i = (i+1) % 2;
digitalWrite(3, i);
}
uint16_t RX()
{
int16_t soma;// Soma dos dados para checksum com tamanho variável
int16_t tamanho = 0;
if (Serial.available() > 0)
{
ti = millis();
n = 0;
soma = 0;
while(n < tamanho + 3)
{
delay(10); // Atraso incluído para provocar o timeout na simulação;
if (Serial.available() > 0)
{
t = millis(); // Recebeu um caractere >> atualiza o tempo final
//DEBUG
//Serial.println(t);
//Serial.println(ti);
//Serial.println(t - ti);
//Serial.println(TIMEOUT);
if ((t - ti) >= TIMEOUT)
{
while (Serial.available() > 0) // esvazia o buffer serial
{
Serial.read();
rx[n] = 0;
n++;
}
return 5;
}
rx[n] = Serial.read();
if(rx[n] < ' ')
{
return 4;
}
if(n == 1)
{
tamanho = (int) (rx[n] > 47 && rx[n] < 58 ? rx[n] - 48 : -1);
if(tamanho == -1)
{
while (Serial.available() > 0) // Tamanho inválido - esvazia o buffer serial
{
Serial.read();
rx[n] = 0;
n++;
}
return 6;
}
char temp = rx[0];
rx =(int*) realloc(rx, (tamanho + 3) * sizeof(char));
rx[0] = temp;
}
n++;
ti = millis(); // Restaura o tempo inicial depois de receber o caractere
}
}
if(rx[tamanho + 2] == endereco)
{
if(tamanho == 0 || tamanho == 1)
{
return 3; // Sem Checksum
}
else
{
for (int j = 0; j <= tamanho; j++)
{
soma = soma + rx[j];
}
if(rx[tamanho + 1] == soma)
{
return 3; // Pacote OK
}
else
{
return 2; // Erro de checksum
}
}
}
else
{
return 1; // Erro de endereco
}
}
else
{
return 0; //semdado
}
}