Existem várias maneiras de escrever um protocolo serial, dependendo da funcionalidade desejada e da verificação de erros necessária.
Algumas das coisas comuns que você vê nos protocolos ponto a ponto são:
Fim da mensagem
Os protocolos ASCII mais simples têm apenas uma sequência de caracteres no final da mensagem, geralmente \r
ou \n
é isso que é impresso quando a tecla Enter é pressionada. Protocolos binários podem usar 0x03
ou algum outro byte comum.
Início da mensagem
O problema de ter apenas o final da mensagem é que você não sabe quais outros bytes já foram recebidos ao enviar sua mensagem. Esses bytes seriam prefixados para a mensagem e causariam uma interpretação incorreta. Por exemplo, se o Arduino acabou de acordar, pode haver algum lixo no buffer serial. Para contornar isso, você inicia uma sequência de mensagens. No seu exemplo ^
, em protocolos binários frequentemente0x02
Verificação de erros
Se a mensagem puder ser corrompida, precisamos de uma verificação de erro. Pode ser uma soma de verificação ou um erro de CRC ou outra coisa.
Escape Characters
Pode ser que a soma de verificação seja adicionada a um caractere de controle, como o byte 'start of message' ou 'end of message', ou a mensagem contenha um valor igual a um caractere de controle. A solução é introduzir um caractere de escape. O caractere de escape é colocado antes de um caractere de controle modificado para que o caractere de controle real não esteja presente. Por exemplo, se um caractere inicial for 0x02, usando o caractere de escape 0x10, podemos enviar o valor 0x02 na mensagem como o par de bytes 0x10 0x12 (caractere de controle XOR do byte)
Número do pacote
Se uma mensagem estiver corrompida, poderemos solicitar um reenvio com uma mensagem nack ou tentar novamente, mas se várias mensagens forem enviadas, apenas a última mensagem poderá ser reenviada. Em vez disso, o pacote pode receber um número que rola após um certo número de mensagens. Por exemplo, se esse número for 16, o dispositivo transmissor poderá armazenar as últimas 16 mensagens enviadas e, se alguma estiver corrompida, o dispositivo receptor poderá solicitar um reenvio usando o número do pacote.
comprimento
Frequentemente, em protocolos binários, você vê um byte de comprimento que informa ao dispositivo receptor quantos caracteres há na mensagem. Isso adiciona outro nível de verificação de erro, como se o número correto de bytes não tivesse sido recebido, e ocorreu um erro.
Específico para Arduino
Ao criar um protocolo para o Arduino, a primeira consideração é a confiabilidade do canal de comunicação. Se você estiver enviando pela maioria dos meios sem fio, XBee, WiFi, etc, já existe uma verificação de erros e novas tentativas e, portanto, não faz sentido colocá-las em seu protocolo. Se você enviar o RS422 por alguns quilômetros, será necessário. As coisas que eu incluiria são o início e o final dos caracteres da mensagem, como você fez. Minha implementação típica se parece com:
>messageType,data1,data2,…,dataN\n
A delimitação das partes dos dados com uma vírgula permite uma análise fácil e a mensagem é enviada usando ASCII. Os protocolos ASCII são ótimos porque você pode digitar mensagens no monitor serial.
Se você deseja um protocolo binário, talvez para diminuir o tamanho das mensagens, será necessário implementar escape se um byte de dados puder ser o mesmo que um byte de controle. Os caracteres de controle binário são melhores para sistemas em que o espectro completo de verificação de erros e novas tentativas é desejado. A carga útil ainda pode ser ASCII, se desejado.