Declaração do problema
Ao desenvolver o próximo dispositivo no microcontrolador, deparei-me com uma situação em que era necessário o registro contínuo de uma grande quantidade de dados. O dispositivo teve que salvar um conjunto de dados que consistia em um registro de data e hora e seis medições ADC de 100 vezes por segundo em um cartão SD (vamos chamar esse conjunto de dados de pacote) e depois analisar esses dados em um computador na forma de gráficos. Também foi necessário em paralelo com a gravação de dados em um cartão SD, transferindo-os via UART. Esses dados deveriam ocupar o mínimo de espaço possível, pois existem muitos dados. Ao mesmo tempo, era necessário separar de alguma forma esses pacotes, porque os dados estavam em um fluxo contínuo. Tendo vasculhado a Internet nada de bom, não encontrei, por isso foi decidido criar meu próprio protocolo e bibliotecas para ele.
E então ele apareceu - Protocolo de streaming de pacotes (PSP1N)
Como resultado de algumas considerações, foi decidido o seguinte: no protocolo, os dados serão transmitidos em pacotes constituídos por N bytes, em que o primeiro bit de cada byte é alocado ao sinal de bit inicial para sincronização de pacotes (daí o nome do protocolo), os sete bits restantes são alocados aos dados. A sequência e o tamanho dos dados são conhecidos antecipadamente.
Um exemplo:
Alocamos 32 bits para o registro de data e hora, 60 bits para as medições ADC (6 canais de 10 bits cada), totalizando 92 bits. Como você pode transferir 7 bits de dados úteis em um byte, o pacote será composto por 14 bytes (92 bits / 7 bits = 13,14 ... arredondado para 14). Existem 112 bits de informação em 14 bytes, dos quais 14 bits são ocupados pelo atributo start bit de 92 bits de dados úteis, existem 6 bits não utilizados (nos quais podemos escrever mais algumas informações, mas por uma questão de simplicidade, não as usaremos).

Onde o 7º bit é o sinal do bit inicial (indica o início do pacote), 6,5,4,3,2,1,0 são bits de dados.
O lado receptor também sabe que recebe um pacote de 14 bytes no qual o primeiro bit do primeiro byte é o bit inicial (1) (nos bytes restantes, os bits iniciais são 0); em seguida, nos bits de dados, na ordem 32 bits do carimbo de data / hora, 10 bits da medição ADC. 1, depois 10 bits do ADC # 2 e assim por diante ...
Da mesma forma, ocorre a gravação no cartão SD e a leitura do mesmo de acordo com o protocolo. No total, para um dia de gravação em um cartão SD, obtemos 115,4 MB de informações (14 bytes x 100 medições por segundo x 3600 seg x 24 horas).
Essa estrutura de dados ainda é conveniente, porque no futuro podemos selecionar blocos de dados de qualquer lugar do arquivo e exibi-los na forma de gráficos, não carregando o arquivo inteiro na RAM (que pode atingir várias dezenas de gigabytes). E também podemos implementar a rolagem conveniente desses gráficos carregando os pacotes necessários.

É hora de iniciar a implementação de software para o microcontrolador
Nós escrevemos a biblioteca para o microcontrolador em C ++.
Por conveniência, crie uma classe:
class PSP { public: void init(byte startBit, byte* arrayByte, byte sizeArrayByte); void pushData(byte sizeBit, uint32_t value); byte* popData(); protected: byte startBit;
Com o método de inicialização, acho que tudo está claro:
void PSP::init(byte startBit, byte* arrayByte, byte sizeArrayByte) { this->startBit = startBit; this->arrayByte = arrayByte; this->sizeArrayByte = sizeArrayByte; }
O método de adicionar dados é mais complicado: aqui, por manipulações astutas, colocamos os dados em nossa matriz de bytes.
void PSP::pushData(byte sizeBit, uint32_t value) { byte free; byte y; int remBit = 0;
Método para obter uma matriz de bytes de um pacote:
byte* PSP::popData() { position = 0;
E, finalmente, algumas funções auxiliares:
Resumir
Como resultado do trabalho realizado, o protocolo compacto para streaming de dados PSP1N e bibliotecas prontas que podem ser baixadas do GitHub aqui "nasceu". Neste repositório você encontrará:
- Exemplo de uso da biblioteca ExampleColsolePSP1N / C #
- PSP1N_CPP / contém a biblioteca PSP para trabalhar com o protocolo e um exemplo de uso no Arduino
- Biblioteca PSP1N_CSHARP / protocolo para .NET
Para demonstrar a operação do protocolo, você pode exibir o esboço no Arduino e, no exemplo ExampleSerialPortRead no computador, receber dados do microcontrolador através da porta COM. Lá, esses dados são descriptografados e exibidos em um aplicativo de console. Falarei sobre a biblioteca escrita em C # para o lado receptor outra vez.
TestingConsole:

UPDATE (31/03/19): Alterado o algoritmo de codificação e decodificação