Pannello Test CBE 742 – Protocollo

Nel camper di mio padre c’è un MPPT CBE PRM350 e relativo pannello CBE PT742 che indica (o meglio, dovrebbe indicare) quanto attualmente producono i pannelli.

Purtroppo a volte segna 0 A anche a produzione attiva (e le batterie si stanno ricaricando – se fossero cariche dovrebbe giustamente segnare 0 A).

Ho deciso di studiare come funziona, non so se riuscirò a ripararlo o meno, ma intanto riporto qui i risultati, magari serviranno a qualcuno.

Il tutto è basato su un Microchip Technology AVR128DA32 alimentato a 3.3V.

Si capisce subito che del connettore a 8 pin vengono usati solo i 4 centrali. Testando con il multimetro si trovano i primi due: GND e +12V. Il voltaggio che mostra il display è campionato proprio dai +12V.

Per l’amperaggio mostrato però ci sarà una certa forma di comunicazione tra MPPT e pannello, tramite i rimanenti due pin.

Ma quale protocollo di comunicazione? Mi collego ai due pin, e su uno dei due, quello che battezzerò “RX”, osservo questo:

Sembra una comunicazione seriale. Un bit singolo dura circa 440us, ed è un valore che ritorna molte volte ad es, il primo low è di 880us.

In un secondo “ci stanno” 1/0,000440 s = 2270 baud, che si avvicina molto al valore standard di 2400 baud.

Provo a collegare il mio logic analyzer cinese e con PulseView e decoder seriale 8N1 2400 ricevo dei pacchetti che “hanno un senso”: c’è sempre uno start byte AA e i valori cambiano con il variare degli ampere.

AA 00 55 FF
AA 00 54 FE
AA 01 53 FE
AA 01 58 03

Il primo è sempre AA

ll secondo cambia in base alla grandezza visualizzata: è la parte “grossa” del valore. Ogni unità vale 100 decimi di ampere.

Il terzo è la parte “fine” del valore: decimi di ampere da 0 a 99.

L’ultima (e qui mi sono fatto aiutare da ChatGPT, lo ammetto), è il checksum calcolato così:

checksum = (1 Byte + 2 Byte + 3 Byte) & 0xFF

Quindi negli esempi catturati abbiamo:

AA 00 55 FF → 0×100 + 85 = 85  →  8,5 A
AA 00 54 FE → 0×100 + 84 = 84  →  8,4 A
AA 01 53 FE → 1×100 + 83 = 183 → 18,3 A
AA 01 58 03 → 1×100 + 88 = 188 → 18,8 A

Ma quindi cosa va storto?

Esattamente non lo so, dato che durante il test funzionava, ma VMax 2,38 V e VPP 1,77 V sul pin RX mi sembrano decisamente bassi per logica a 3,3 V.

Lo stage RX sul pannellino sembra essere resistenza serie 1,5 k , zener 3.3 , pin PC1 del AVR128DA32.

Secondo me il cavo di comunicazione è troppo lungo o ci sono resistenze di pull up mancanti/troppo alte.

Per ora mi fermo qui, perché sto valutando il cambio batterie con nuove al litio, e questo mi porta verso la sostituzione del CBE PRM350 con qualcosa di piu’ serio, tipo Victron MPPT 100/30.

Vi lascio con uno sketch Arduino di prova (in realtà ESP8266 dato che gira nativamente a 3.3v) e video di “vittoria” riguardo la decodifica del protocollo.

Una potenziale applicazione potrebbe essere: decodificare protocollo Victron VE.Direct e creare un “traduttore” per mantenere lo stesso pannello che è già montato nel mobile del camper.

// =============================================================
//  Simulatore protocollo seriale CBE MPPT350 → PT742
//  WEMOS D1 Mini / ESP8266
// =============================================================

#include <SoftwareSerial.h>

// -------------------------------------------------------------
// PIN CONFIG
// -------------------------------------------------------------
// TX verso PT742
// D2 = GPIO4
#define PIN_TX D2

SoftwareSerial cbeSerial(-1, PIN_TX);	// RX non usato -> -1

// -------------------------------------------------------------
// PARAMETRI SIMULAZIONE
// -------------------------------------------------------------

int corrente_dA = 83; // corrente Decimi Ampere inviata
int corrente_max_dA = 200; // max 20.0A
int corrente_min_dA = 50;  // min  5.0A

// Intervallo invio
int intervallo_ms = 100;

// Direzione rampa
int direzione = 1;

// -------------------------------------------------------------

void setup() {
  // Debug USB
  Serial.begin(115200);
  delay(500);

  Serial.println();
  Serial.println("Avvio simulatore CBE MPPT350");

  cbeSerial.begin(2400);

  delay(200);
}

void loop() {
  invia_corrente(corrente_dA);

  // Debug
  Serial.print("Invio: ");
  Serial.print(corrente_dA / 10.0, 1);
  Serial.println(" A");

  // Rampa
  corrente_dA += direzione;

  if (corrente_dA >= corrente_max_dA)
    direzione = -1;

  if (corrente_dA <= corrente_min_dA)
    direzione = +1;

  delay(intervallo_ms);
}

// -------------------------------------------------------------
// INVIO PACCHETTO
// -------------------------------------------------------------
void invia_corrente(int valore_dA) {
  byte sync = 0xAA;
  byte msb = (byte)(valore_dA / 100);
  byte lsb = (byte)(valore_dA % 100);
  byte checksum = (sync + msb + lsb) & 0xFF;

  cbeSerial.write(sync);
  cbeSerial.write(msb);
  cbeSerial.write(lsb);
  cbeSerial.write(checksum);

  cbeSerial.flush();
}

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.