RS485: utilizzo della libreria RS485_protocol di Nick Gammon

Ciao a tutti,

sto utilizzando la libreria "RS485_protocol" di Nick Gammon; riesco a trasmettere (o almeno così mi sembra) ma non a ricevere... Del resto sto utilizzando l'esempio scritto dall'autore su questa pagina: Gammon Forum : Electronics : Microprocessors : RS485 communications senza capire come utilizzare la funzione recvMsg: negli esempi scritti dall'autore si utilizza un vettore di dimensione 10 (buf[10]) per ricevere 3 byte:

  // receive response  
  byte buf [10];
  byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);

Qualcuno mi sa spiegare perché 10?

Grazie!

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

Dopo che avrai fatto quanto su richiesto ...

... se studi con attenzione l'articolo da te postato (... ed in particolare il paragrafo intitolato "Error checking protocol") ... vedrai che capisci da solo il perché :wink:

Guglielmo

Scusate tutti, non volevo nascondere nulla piuttosto non tediare nessuno con informazioni di contorno, che tuttavia mi rendo conto sono apprezzate in questo forum. Ho conoscenze scolastiche di elettronica analogica, digitale e qualcosa mi sono studiato di C. Col C++ litigo soprattutto.

Mi occupo per hobby di piccoli progetti che realizzo su schede Arduino, Particle e per ultimo ESP32; in particolare ho sviluppato varie applicazioni musicali midi, per il trattamento real time della tastiera, perloppiù ho approfondito la generazione di arpeggi.

Quest'ultimo progettino, per cui scrivo, è relativo alla gestione remotizzata di un gruppo di motori elettrici; l'architettura che ho previsto è su tre livelli: un'app Blynk per l'utente, un dispositivo master con funzionalità di internet-hub (realizzato con un ESP32-WROO32) ed una serie di slave (realizzati con Arduino Nano) ciascuno dei quali è in prossimità dei motori e ne regola la velocità/verso di rotazione. La comunicazione tra master e slave avverrebbe utilizzando dispositivi RS485.

Ho riletto la parte dell'articolo che mi hai indicato, e anche il codice scritto in RS485_protocol.cpp... Alla fine mi pare di aver capito. Volendo trasmettere un payload di 3 byte, sulla linea vengono trasmessi:
1 byte STX
3 byte payload
3 byte complementari del payload
1 byte ETX
1 byte CRC
1 byte complementare di CRC

totale 10 byte, ok (?).

Credo anche di aver capito che recvMsg restituisce il numero di byte di paylod ricevuti (nell'esempio 3, se tutto è andato liscio).

Sempre dalla lettura di RS485_protocol.cpp però leggo che recvMsg richiede un timeout:

byte recvMsg (AvailableCallback fAvailable,   // return available count
              ReadCallback fRead,             // read one byte
              byte * data,                    // buffer to receive into
              const byte length,              // maximum buffer size
              unsigned long timeout)          // milliseconds before timing out
  {

che nell'esempio di Nick Gammon non compare... Nick ha omesso qualcosa o (molto più probabilmente) sbaglio io?

Grazie

Sun_Ra:
... Nick ha omesso qualcosa o (molto più probabilmente) sbaglio io?

... invece di guardare il .cpp, guarda il .h e ... scoprirai l'arcano :smiley:

Guglielmo

... Ecco perché odio il C++!! :-X
Riproverò verificando le configurazioni del master e dello slave...
Grazie!!
Sandro

Sun_Ra:
... Ecco perché odio il C++!! :-X

:smiley: :smiley: :smiley: :smiley: ... non sei il solo, te lo assicuro :wink:

Guglielmo

Risolto!! ;D ;D

Ho calcolato il tempo richiesto a svuotare il buffer coi 10byte a 28.8Kb/s, e servono almeno 2.8ms contro i 660µs dell'esempio di Gammon, che probabilemte si riferisce ad un caso leggermente diverso:

digitalWrite (ENABLE_PIN, HIGH);  // enable sending
sendMsg (fWrite, msg, sizeof msg);
delayMicroseconds (660);
digitalWrite (ENABLE_PIN, LOW);  // disable sending

Con delay(4) il dato viene correttamente trasmesso e ricevuto!! Domani cercherò di migliorare il codice tentando la soluzione più elegante proposta:

digitalWrite (ENABLE_PIN, HIGH);  // enable sending
sendMsg (fWrite, msg, sizeof msg);
while (!(UCSR0A & (1 << UDRE0)))  // Wait for empty transmit buffer
UCSR0A |= 1 << TXC0;  // mark transmission not complete
while (!(UCSR0A & (1 << TXC0)));   // Wait for the transmission to complete
digitalWrite (ENABLE_PIN, LOW);  // disable sending

Ma temo che i registri abbiano nomi diversi su ESP32..

Intanto grazie ancora, e a presto!
Sandro

Sun_Ra:
Ma temo che i registri abbiano nomi diversi su ESP32..

... sicuramente SI, quelli sono i nomi dei registri del ATmega328P e sicuramente l'ESP ha altri registri ed altre modalità per programmare la seriale ... ti toccherà un lungo studio del datasheet ... ::slight_smile:

Guglielmo