Visualizzazione post con etichetta ProtoBuf. Mostra tutti i post
Visualizzazione post con etichetta ProtoBuf. Mostra tutti i post

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));}

}

 

 

 

venerdì 11 marzo 2022

Protocol Buffers in Golang

 Protocol Buffers (protobuf) e' una libreria di Google per la serializzazione di dati. Con il termine serializzazione si intende il processo di tradurre una "data structure" (array, struttura, albero binario.....) in un file che conservi oltre che i dati anche la struttura. Una forma tipica di serializzazione sono i file in formato JSON

Per utilizzare protobuf con GoLang si parte dalla definizione della struttura in file .proto. Un semplice modello puo' essere il seguente

syntax = "proto3";

package main;
import "google/protobuf/timestamp.proto";


message Person {
string name = 1;
int32 id = 2;
string email = 3;
google.protobuf.Timestamp last_updated = 5;
}

da notare che il file .proto deve avere lo stesso package del codice che lo utilizzera'

i numeri di fianco ai vari campi sono univoci

il file .proto deve essere compilato tramite il compilatore protoc. Su Debian l'installazione del compilatore avviene mediante

apt install protobuf-compiler
apt install golang-goprotobuf-dev

si crea il file .proto nella stessa directory del sorgente Go e si compila con

protoc --go_out=. *.proto

questo genera un nuovo file con estensione .go. Se si apre il file con editor di testo si osserva che oltre alla struttura dei dati sono state create delle funzioni tipo helper che facilitano l'immissione e gestione della struttura dati

per gestire i dati all'interno del progetto Go, nel caso si usino tipo dati di uso comune tipo datetime gia' formalizzati in protobuf si deve scaricare la loro definizione per esempio

go get github.com/golang/protobuf/ptypes/timestamp

i dati di un protobuf possono essere salvati su un file ma questo sara' binario e non immediatamente human readable

package main

import (
"fmt"
"io/ioutil"
"log"

proto "github.com/golang/protobuf/proto"
)

// apt install protobuf-compiler

// per compilare il file proto
// protoc --go_out=. *.proto

// go get github.com/golang/protobuf/ptypes/timestamp

func main() {
dati_persona := &Person{
Name: "Luca",
Id: 51, //per poco ancora
}

data, err := proto.Marshal(dati_persona)
if err != nil {
log.Fatal("marshaling error: ", err)
}

fmt.Println(data)

out, err := proto.Marshal(dati_persona)
if err != nil {
log.Fatalf("Serialization error: %s", err.Error())
}
if err := ioutil.WriteFile("dati.bin", out, 0644); err != nil {
log.Fatalf("Write File Error: %s ", err.Error())
}
fmt.Println("Write Success")

//Read from file
in, err := ioutil.ReadFile("dati.bin")
if err != nil {
log.Fatalf("Read File Error: %s ", err.Error())
}
dati_persona2 := &Person{}
err2 := proto.Unmarshal(in, dati_persona2)
if err2 != nil {
log.Fatalf("DeSerialization error: %s", err.Error())
}

fmt.Println("Read Success")
fmt.Printf("Nome %s\n", dati_persona2.GetName())
}




Analisi MNF su spettri di riflettanza di plastica

Devo cerca di lavorare su spettri di riflettanza di plastica e la prima domanda e': quale sono le bande significative? Sono partito dal ...