venerdì 20 giugno 2025

NanoProtoBuf Esp32 IDF

Su Esp32 (e piu' in generale sui microcontrollori) la libreria Protobuf non puo' funzionare e quindi si deve usare nanopb (nano proto buffer)  https://github.com/nanopb/nanopb

Il seguente progetto e' stato creato usando il plugin Esp-Idf di VSCode

Per utilizzarla si deve prima installare il compilare protoc e poi scaricare e compilare il pacchetto nanopb da GitHub ...questo servira' come plugin per protoc

Si procede  quindi con il seguente comando che genera i file sensor.pb.c e sensor.pb.h dove sono inserite le classi per la lettura scrittura del file sensor.proto. questi due file sono da inserire nella main del progetto mentre i file pb_common.c pb_common.h pb_decode.c pb_decode.h pc_encode.c e pb_encode.h si inseriscono nel folder nanopb all'interno del folder main  

protoc --plugin=protoc-gen-nanopb=/home/luca/nanopb/generator/protoc-gen-nanopb --nanopb_out=./ --proto_path=/home/luca/nanopb/generator/proto sensor.proto

sensor.proto

syntax = "proto3";

message SensorData {
int32 id = 1;
float temperature = 2;
float humidity = 3;
}

Si modifica quindi il file CMakeLists.txt per puntare i nuovi file

idf_component_register(
SRCS
"main.c"
"sensor.pb.c"
"nanopb/pb_encode.c"
"nanopb/pb_decode.c"
"nanopb/pb_common.c"
INCLUDE_DIRS
"."
"nanopb"
)

e si puo' compilare questo semplice programma di esempio sull'utilizzo di nanopb 

#include <stdio.h>

#include "sensor.pb.h"
#include "pb_encode.h"
#include "pb_decode.h"

#include "driver/uart.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

void app_main(void)
{
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};



uart_driver_install(UART_NUM_0, 1024, 0, 0, NULL, 0);
uart_param_config(UART_NUM_0, &uart_config);

const char *msg = "Hello from UART0 via USB!\n";
uart_write_bytes(UART_NUM_0, msg, strlen(msg));


vTaskDelay(pdMS_TO_TICKS(3000));
printf("USB CDC active\n");

vTaskDelay(pdMS_TO_TICKS(500)); // Delay to let USB CDC connect


uint8_t buffer[128];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

SensorData da = SensorData_init_zero;
da.id = 42;
da.temperature = 23.5;
da.humidity = 55.2;

if (pb_encode(&stream, SensorData_fields, &da)) {
size_t message_length = stream.bytes_written;
// Send buffer over serial, BLE, etc.
} else {
//Serial.println("Encoding failed!");
}

size_t message_length = stream.bytes_written;

SensorData da_r = SensorData_init_zero;
//int received_length = 0;
pb_istream_t str = pb_istream_from_buffer(buffer, message_length);

while(1){
if (pb_decode(&str, SensorData_fields, &da_r)) {
char str_out[32];
snprintf(str_out, sizeof(str_out), "%.2f\n", da_r.humidity);
uart_write_bytes(UART_NUM_0, str_out, strlen(str_out));
printf("Temp: %.2f, Humidity: %.2f\n",da_r.temperature, da_r.humidity);
} else {
uart_write_bytes(UART_NUM_0, "Decoding error\n", strlen("Decoding error\n"));
printf("Error decoding\n");
}

vTaskDelay(pdMS_TO_TICKS(1000));}

}

 

 

 

Nessun commento:

Posta un commento

Montagne frattali

 Negli anni 90 quando i miei amici matematici leggevano (Ri)creazioni al calcolatore di Dewdney (vedi anche pag. 107 del libro The Magic Mac...