Trasmissione dati analogici con HC-12

Buongiorno a tutti, sto utilizzando dei moduli bluetooth HC-12. Purtroppo con questi sono riuscito ad eseguire delle prove solo per accendere/spegnere un led a distanza ma non sono riuscito a trasmettere il valore analogico della corrente rilevata, ovvero i dati vengono trasmessi e qualcosa viene ricevuto ma sembra che non ci sia alcun riferimento fra i dati inviati e quelli ricevuti. Riporto di seguito una semplificazione dei codici (in realtà l'applicazione è un po' più complicata).
Ringrazio chiunque possa aiutarmi

Trasmettitore:

#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11);
void setup() {
 Serial.begin(9600); 
 HC12.begin(9600);
 pinMode(A0, INPUT);
 } 
void loop() {
double dato = analogRead(A0);
HC12.write(dato);
delay (500); 
Serial.println(dato);
} 

Ricevitore:

#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11);
void setup() {
 Serial.begin(9600);
 HC12.begin(9600);
 } 
void loop() {
if (HC12.available()) {
 double dato =HC12.read();
 Serial.println(dato);
 delay (1000);
 }
}

Buonasera,

prima di tutto ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato, dopo di che ...

... essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… 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 tutto il succitato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà (eventuali risposte verrebbero cancellate), quindi ti consiglio di farla al più presto. :wink:

I problemi sono due, il primo è che il trasmettitore invia due dati al secondo, mentre il ricevitore legge solo una volta al secondo, e questo vuol dire ammucchiare i dati in arrivo nel buffer di ricezione fino a sovrascriverli.

Ma è il problema minore. Quello maggiore invece è comprendere cosa esattamente passa da trasmettitore a ricevitore (quali e quanti byte), e fare in modo di riceverli tutti e ricostruire il dato di partenza.

Nel trasmettitore c'è scritto: Serial.println(dato);
"dato" è il valore letto dall'ingresso A0, che può valere tra 0 e 1023, quindi basta una variabile intera int per memorizzarlo, non serve a nulla una double, anzi, complica le cose.

La funzione Serial.println trasmette una stringa di caratteri testuali, cioè tutti i byte che rappresentano i caratteri del testo trasmesso codificati in ASCII.

E qui c'è la prima (grande) scelta da fare, vogliamo trasmettere stringhe di caratteri, o direttamente i valori binari dei nostri dati? Sono due gestioni completamente diverse. Rimaniamo sulla stringa con println, e usiamo una variabile intera, non con la virgola (visto che si trasmette un valore da 0 a 1023).

Se il valore è ad esempio 150, allora la Serial.println trasmetterà cinque byte con questi valori: 49 53 48 13 10

49 = '1'
53 = '5'
48 = '0'
13 = '\r' return (CR)
10 = '\n' line feed (LF)

Ora la HC12.read() nel ricevitore, riceve solo uno alla volta questi byte. Per acquisirli tutti servono cinque letture, bisogna memorizzare i primi in un array e riconoscere gli ultimi due come fineriga. Solo a questo punto si possono riconvertire i primi (ad esempio con la funzione atoi) in valore intero.

Grazie Claudio per i chiarimenti. Quello che sto tentando di fare è trasmettere i valori della corrente assorbita dall'impianto di casa, il rilevamento viene fatto tramite un sensore SCT013 30A/1V. In realtà, guardando dei tutorial, sono riuscito nell'intento utilizzando dei moduli NFR24 ma dovrei mettere un ponte radio perché, nonostante la distanza sia ridotta il segnale non arriva a destinazione. Pensavo di risolvere il problema della distanza utilizzando gli HC-12 ma evidentemente ho sottostimato le problematiche.
Cercherò di fare tesoro delle tue informazioni per provare a sviluppare il progetto ... altrimenti ritornerò agli NFR24.

Guarda che il problema non sono gli HC12 o gli NRF24

Il problema è stabilire un protocollo tra trasmettitore e ricevitore

Senza di quello tutti i tuoi tentativi saranno fallimentari

Io personalmente amo gli HC12, che non mi hanno mai deluso, sono semplicissimi da usare e si possono (per sviluppo) sostituire con due semplici fili tra due arduino sulla stessa scrivania

Se cerchi "termoremoto non è termometro scritto sbagliato" trovi un esempio di come ho risolto io un problema simile

Io, per non saper ne leggere ne scrivere, dato che usi una println per la trasmissione userei uno dei due terminatori di riga (a te scoprire quello corretto) per azzerare una variabile intera
Poi come descritto nel K&R convertirei al volo i caratteri in arrivo in un intero senza nemmeno scomodare una atoi
E da ultimo usere l'altro terminatore di riga per far aggiornare il valore ricevuto

Magari si fa anche con un solo terminatore...

Tutto sta nel gestire il protocollo...

Ti ringrazio per le dritte. Mi studierò il tuo progetto "termoremoto non è termometro scritto sbagliato"

Andando a cercare esempi in rete direi di aver trovato una soluzione semplice al mio problema all'indirizzo HC-12 Radio Module • Wolles Elektronikkiste.
Riporto di seguito una semplificazione dei moduli sviluppati

Trasmettitore:

#include <SoftwareSerial.h>
SoftwareSerial HC12(10,11);
void setup() {
  Serial.begin(9600);
  HC12.begin(9600);
  pinMode(A0, INPUT);
}
void loop() { 
     String dataString = "";
    createDataString(dataString);
    Serial.println(dataString);
    HC12.print(dataString);
    delay (1000);
}
void createDataString(String &data){
  float dato = analogRead(A0);
  data = "*" + String(dato); 
}

Ricevitore:

#include <SoftwareSerial.h>
SoftwareSerial HC12(10,11);
void setup() {
Serial.begin (9600);
HC12.begin(9600);
}
void loop() {
float dato = 0.0;
if (HC12.available()){
dato = HC12.parseFloat();
Serial.println(dato);
delay (1000);
 }
}

scusa ma se stiamo su un Arduino tipo UNO o MEGA sta funzione "non si può vedere".
inutile la conversione ed inutile se non dannoso l'uso della String...poi lato ricevitore manca una gestione di eventuali errori sul dato ricevuto...

1 Like

Sto lavorando con arduino mini e funziona. Il dato che trasmetto è la lettura di corrente che viene convertita da un trasduttore. Per questa applicazione ho semplicemente adattato alle mie esigenze quanto proposto nel link sopra riportato, suggerito per utenti non esperti, per questo motivo la gestione degli errori non saprei proprio come farla ma francamente, per questa applicazione la ritengo superflua.

Sono basito...

Non capisco, spiegati per favore.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.