ESP32

Transferir uma imagem jpg por serial – ESP8266 e ESP32

Nesse penúltimo artigo da série sobre manipulação de dados binários, vamos ver como transferir uma imagem jpg por serial para o sistema de arquivos padrão do ESP8266/ESP32, o SPIFFS. Para ficar mais interessante, vamos transferir uma imagem jpg e exibí-la no browser.

Conceitos

Nesse e nesse artigo você encontra informações importantes sobre manipulação de dados binários. Agora, para transferir dados binários por um meio, precisamos escrever e ler em formato binário (óbvio?).

No SPIFFS não foi possível utilizar o estilo POSIX para escrever arquivos, apesar de disponível. Provavelmente esse recurso pode ser utilizado para escrever em um cartão SD, mas no SPIFFS devemos utilizar os recursos da própria API.

Normalmente utilizamos o modo “wb” para escrever arquivos binários, mas no SPIFFS simplesmente utilizamos “w” e para escrever o dado binário, utilizamos write.

Na escrita da imagem jpg por serial, optei por escrever byte a byte invés de passar o buffer. Também escrevi uma singela condicional para comparar os dois últimos bytes do buffer a partir do quinto byte, afim de procurar a assinatura do footer para pressupor que a transferência do arquivo de imagem foi completamente transferido. É só uma prova de conceito, não espere nenhum tratamento especial no código.

Uma coisa importante a se ter em mente é que, após subir um firmware para o ESP32 (poderia ser o 8266, mas estou utilizando o 32), se abrir a serial ainda terá mensagem do último estado. Isso significa que deve-se reiniciar o ESP32 para releitura das rotinas desse código.

Transferir uma imagem jpg por serial

O primeiro passo é definir como provar o conceito. Para tal, configurei um servidor web no ESP32. Estou utilizando a IDE Atom com PlatformIO para programar, devido aos recursos de auto-completação, abas paralelas etc. Instale a biblioteca ESPAsyncWebServer antes de compilar o código disposto mais adiante.

Uma imagem jpg é um arquivo binário. Poderia ser qualquer coisa que desejasse; um firmware, um executável de windows, um arquivo com compressão etc. A imagem utilizada foi essa:

 imagem jpg por serial

Ela tem 3940 bytes e sua transferência deve levar em torno de 12 segundos. É um tempo altíssimo para transferir 4kB, mas  lembre-se que estamos fazendo uma transferência por serial com baudrate de 115200 (115200 0’s e 1’s por segundos). Coloque-a  no mesmo diretório que for escrever o código Python.

Eu utilizei o bpython3 para escrever em fluxo, mas poderia ser um arquivo a ser executado, sem problemas, desde que esteja no mesmo nível de diretório do arquivo ou que o caminho completo para o arquivo seja passado.

Para monitorar a serial, criei uma task (se não sabe como criar uma task no ESP32, dê uma lida nos artigos relacionados através desse menu). Uma função escrever os dados para arquivo quando o buffer condizer com uma imagem jpg. Após subir a imagem, reinicie o ESP32 (sem problemas repetir o processo antes de reiniciar).

O código para transferir a imagem jpg por serial no ESP32 ficou assim:

Após subir o firmware e reiniciar o ESP32, abra um terminal (se estiver utilizando Linux), instale a biblioteca serial e execute o comando bpython3.

Antes de seguir, abra um browser e digite a URL (substituindo o IP pelo do seu ESP32):

Como ainda não tem arquivo, deve aparecer isso:

browser - imagem jpg por serial

Deixe o browser aberto e siga com o resto do processo.

O código para transferir a imagem jpg por serial com Python em um PC não deve funcionar em  Python2:

Preferi enviar byte a byte. Se quiser modificar, fazer melhor, mais bonito, mais eficiente, fique à vontade. Eu tive um bug que nem estou interessado em resolver; tive que enviar duas vezes seguidas (as duas linhas do laço for). Funcionou, para o conceito é o que importa.

Após enviar a imagem, reinicie o ESP32 e atualize o browser. Se tudo der certo, você verá isso:

browser ok - imagem jpg por serial

Próximo artigo relacionado

Pretendo finalizar a série no próximo artigo, onde devemos ser capazes de transferir a mesma imagem por rádio frequência, possivelmente utilizando LoRa, mas poderia ser também um NRF24L01, veremos.

Até a próxima!