NRF24L01 e valori stampati male su display RX

Salve ragazzi.
Sto tentando di far comunicare i valori di sensori da due Trasmettitori ad un Ricevitore con display touchscreen.
I dati che vengono stampati sul display si sovrappongono ciclicamente e non ne comprendo il motivo.

La configurazione è la seguente:

  • al Trasmettitore Uno è collegato un NRF24L01 ed un DHT-22
  • al Trasmettitore Due è collegato un NRF24L01, un ESP8266, un DHT-11 e 3 DHT-22
  • al Ricevitore è collegato un NRF24L01.

Quando sono tutti alimentati, i trasmettitori inviano i valori ma il ricevitore li stampa in modo anomalo, sovrapponendo in alcuni casi o non facendo comparire i valori dell’uno o dell’altro trasmettitore. Credevo fosse un problema del caricamento della visualizzazione dei valori su display e pertanto ho inserito il delay(500) ma non ho risolto nulla e ho notato che lo stesso problema avviene nel monitor seriale.

Ho bisogno di un vostro aiuto. Allego gli sketch e dato che mi sono arenato, spero in una vostra dritta. Grazie.

Ricevitore.ino (7.22 KB)

Trasmettitore_MEGA.ino (1.49 KB)

Trasmettitore_Wemos.ino (1013 Bytes)

Ma... due trasmettitori sullo stesso canale e che trasmettono contemporaneamente???

Ciao docdoc, grazie per la risposta. Purtroppo tutto mi è nuovo e sinceramente è terribile ::slight_smile: sentirsi ignoranti ma si deve pur partire per imparare qualcosa di nuovo :smiley: . Premesso ció, il canale a cui ti riferisci è il 115? Grazie per l'aiuto.

Eh, si, se stanno sullo stesso canale si disturbano a vicenda perché parliamo di un mezzo "fisico" con una stessa portante.

Ma mentre è possibile avere un trasmettitore e due ricevitori, se hai due trasmettitori dovresti anche avere due ricevitori ognuno impostato sul canale corrispondente e rendere così la trasmissione (e ricezione) dati dei due client indipendenti tra loro.

Alternative? Beh, farli dialogare in TCP/IP ad esempio non va bene? Il "master" lo imposti come Access Point (a meno che non sia possibile comunque averli tutti già nella stessa rete WiFi) ed i dati puoi mandarli anche semplicemente come broadcast UDP (io ho fatto così per un progetto di ripetitore di telecomando, cosa che evita persino di dover configurare l'IP del master). Ovviamente definendo un tuo protocollino (es. il primo byte del pacchetto è l'ID del client seguito dai dati), con o senza conferma (ad esempio, anche se potrebbe non essere necessario, il server potrebbe mandare un pacchetto ACK di risposta ad ogni pacchetto ricevuto). Ci sono tante possibili soluzioni cambiando tecnologia di comunicazione...

Okay docdoc, in pratica mi stai dicendo che, per via della tecnologia che utilizzo, non potró mai far dialogare i due trasmettitori con il singolo ricevitore , vero? Abbandono il progetto in favore della tecnologia che mi consigli? Per indirizzarmi meglio, quali sono i termini da ricercare col motore di ricerca?
Grazie per l'aiuto.

Si, ma devi solo cambiare la modalità di comunicazione.

La trasmissione su uno stesso canale va attivata su un solo device per volta, e dato che i due non possono "sincronizzarsi" tra loro, si "pestano i piedi".

Quindi come dicevo, o sul master installi un secondo ricevitore e lo imposti su un canale differente, oppure potresti passare ad una connessione di rete visto che già usi una Wemos se non erro, per l'altro ti potrebbe bastare o usare anche qui una Wemos, oppure aggiungergli un modulo ESP.

La prima soluzione è quella più "indolore" in quanto con poche modifiche hardware e software potresti risolvere, soprattutto se non hai pratica di comunicazione di rete.

La seconda soluzione invece è quella che preferisco perché ti dà maggiori possibilità anche di estensioni future.
come suggerito, potresti per semplicità usare l'invio dei dato come pacchetti UDP broadcast, che il master riceverà ed in base al primo byte capire da quale client è arrivato ed agire di conseguenza. Se vuoi comunque approfondire questo aspetto prova a cercare con google cose tipo "arduino comunicazione udp" per trovare pagine come QUESTA. Ma ovviamente se vorrai intraprendere questa strada, se trovi difficoltà apri un nuovo topic e posso anche darti una mano visto che sono cose che ho già implementato.

antonio85:
non potró mai far dialogare i due trasmettitori con il singolo ricevitore

Assolutamente NO!
Il modulo radio nRF24L01 può gestire in parallelo fino a 6 “data pipes” e può anche funzionare in rete mesh, volendo.
Di solito nelle librerie ci sono anche i relativi esempi sul come fare.

nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf (1.06 MB)

cotestatnt:
Il modulo radio nRF24L01 può gestire in parallelo fino a 6 “data pipes” e può anche funzionare in rete mesh, volendo.

Interessante, non sapevo del MultiCeiver e della libreria RF24Network (io conoscevo solo la nRF24L01)!

Quindi all’OP potrebbe bastare impostare il MultiCeiver su 2 canali separati, guardando gli esempi della libreria. Meglio così!

docdoc:
Interessante, non sapevo del MultiCeiver e della libreria RF24Network

Si, io ho sempre usato questa libreria RF24/MulticeiverDemo.ino at master · nRF24/RF24 · GitHub
Rimangono comunque dei dispositivi "non facili da usare" soprattutto per i neofiti, quindi se l'OP può facilmente migrare verso una soluzione WiFi sottoscrivo il consiglio.

@docdoc, grazie della pazienza. Prima di cambiare metodo di comunicazione, per non vanificare tante ore di test (per lo più a casaccio :sweat_smile: ) coi nrf24l01, io tenterei l'installazione di un secondo nrf24l01 sul ricevitore, che ne dici?

Altrimenti, potrei tentare di far trasmettere i dati dal tx 1 al tx 2 il quale potrebbe trasmetterli al rx, includendo quelli del tx 1; che ne dite? Potrebbe essere una soluzione?

La configurazione è la seguente:

  • al Tx 1 è collegato un NRF24L01 ed un DHT-22
  • al Tx 2 è collegato un NRF24L01, un ESP8266, un DHT-11 e 3 DHT-22
  • al Ricevitore, (dotato di display) è collegato un NRF24L01.

@cotestatnt Grazie per l'interessante documentazione ma essendo neofita impiegherò tempo per studiarla.

antonio85:
Altrimenti, potrei tentare di far trasmettere i dati dal tx 1 al tx 2 il quale potrebbe trasmetterli al rx, includendo quelli del tx 1; che ne dite? Potrebbe essere una soluzione?

Ma perché vuoi complicarti la vita in questo modo?
Se guardi l'esempio di cui ho messo il link, fa più o meno quello che ti serve. Lo carichi su ciascun "nodo" TX o RX che sia, poi con il serial monitor li puoi impostare come RX (1 dispositivo) oppure come TX (tutti gli altri).
Capito il meccanismo, se non hai questa bisogno di questa flessibilità nella configurazione, fai due firmware distinti riportando solo le istruzioni necessarie.

Okay Ragazzi, alla fine ho trovato una soluzione che funziona benino nonostante i dati del trasmettitore 1 non vengono stampati immediatamente sul display, impiegando anche piú di un’ora. Ovviamente il problema è che non ho idea di cosa ho copiato e di come funziona. Questa soluzione l’ho trovata su questo forum.
Potreste aiutarmi a capire un pó tutto? Ad esempio, questo passaggio a cosa serve?

int address = 0x28; // 28 is the address
byte byte1, byte2, byte3, byte4;

Allego anche gli sketch completi nel caso vogliate darmi qualche indicazione su come migliorarli nella forma, o nel caso possano essere utili a qualche utente ai primi passi come me.

Trasmettitore 1

int address = 0x28; // 28 is the address
byte byte1, byte2, byte3, byte4;

struct dataStruct {
  float t1;
  float h1;
} transmitter1_data;

unsigned char ADDRESS1[5]  =
{
  0xb2, 0x43, 0x88, 0x99, 0x45
}; // Define a static TX address
//just change b1 to b2 or b3 to send to other pip on resciever

void setup()
{
  printf_begin();
  radio.setRetries(13, 15);
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_1MBPS); //set datarate to 250kbps 2MBPS 1MBPS
  radio.openWritingPipe(ADDRESS1);
  radio.openReadingPipe(1, ADDRESS1);
  radio.stopListening();
  radio.printDetails();
}

void loop()
{
  bool ok = radio.write(&transmitter1_data, sizeof(transmitter1_data));

  if (ok)
  {
    Serial.println("Pipe 1");
    Serial.println(transmitter1_data.t1);
    Serial.println(transmitter1_data.h1);
  }
  else
  {
    Serial.println("it failed to send");
  }
  delay(5000);
 }

Trasmettitore 2

int address = 0x28; // 28 is the address
byte byte1, byte2, byte3, byte4;

struct dataStruct2 {
  float t5;
  float h5;
} transmitter2_data;

unsigned char ADDRESS0[5]  =
{
  0xb0, 0x43, 0x88, 0x99, 0x45
}; // Define a static TX address
//just change b1 to b2 or b3 to send to other pip on resciever

void setup()
{
printf_begin();
  radio.setRetries(15, 15);
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_1MBPS); //set datarate to 250kbps 2MBPS 1MBPS
  radio.openWritingPipe(ADDRESS0);
  radio.openReadingPipe(0, ADDRESS0);
  radio.stopListening();
  radio.printDetails();
 }

void loop()
{
  transmitter2_data.h5 = dht5.readHumidity();
  transmitter2_data.t5 = dht5.readTemperature();

  bool ok = radio.write(&transmitter2_data, sizeof(transmitter2_data));

  if (ok)
  {
    Serial.println("Pipe 2");
    Serial.println(transmitter2_data.t5, 0);
    Serial.println(transmitter2_data.h5, 0);
    delay(6000);
  }
  else
  {
    Serial.println("it failed to send");
    delay(5000);
  }
 }

Ricevitore

#define PLOAD_WIDTH  32  // 32 unsigned chars TX payload
byte pip;
byte pload_width_now;
byte newdata;
unsigned char rx_buf[PLOAD_WIDTH] = {0};

struct dataStruct {
  float t1;
  float h1;

} transmitter1_data;

struct dataStruct2 {
  float t5;
  float h5;
} transmitter2_data;

unsigned char ADDRESS1[5]  =
{
  0xb2, 0x43, 0x88, 0x99, 0x45
}; // trasmettitore 1

unsigned char ADDRESS0[5]  =
{
  0xb0, 0x43, 0x88, 0x99, 0x45
}; // trasmettitore 2

void setup()
{
  radio.begin();
  printf_begin();
  radio.setDataRate(RF24_1MBPS); //set datarate to 250kbps 2MBPS 1MBPS
  radio.enableDynamicPayloads();
  radio.openWritingPipe(ADDRESS0);
  radio.openWritingPipe(ADDRESS1);
  radio.openReadingPipe(0, ADDRESS0);
  radio.openReadingPipe(1, ADDRESS1);
  radio.startListening();
  radio.printDetails();
  delay(5000);
}

void loop()
{
 if ( radio.available(&pip) )
  {
    // Fetch the payload, and see if this was the last one.
    pload_width_now = radio.getDynamicPayloadSize();

    // If a corrupt dynamic payload is received, it will be flushed
    if (!pload_width_now) {

    }
    else
    {

      radio.read( rx_buf, pload_width_now );

      newdata = 1;

      // Spew it
      Serial.print(F("Data on pip= "));
      Serial.print(pip);
      Serial.print(F(" Got data size="));
      Serial.print(pload_width_now);
      Serial.print(F(" data="));
      for (byte i = 0; i < pload_width_now; i++)
      {
        Serial.print(" ");
        Serial.print(rx_buf[i]);                              // print rx_buf
      }
      Serial.print(" ");
    }
  }
  if (newdata == 1)
  {
    newdata = 0;

    if (pip == 0 && pload_width_now == sizeof(transmitter2_data))
    {
      memcpy(&transmitter2_data, rx_buf, sizeof(transmitter2_data));
      Serial.println("");
      Serial.println("");
      Serial.print(" Temp5p ");
      Serial.println(transmitter2_data.t5, 0);
      Serial.print(" Umi 5p ");
      Serial.println(transmitter2_data.h5, 0);
    }

    Serial.println("");

    if (pip == 1 && pload_width_now == sizeof(transmitter1_data))
    {
      memcpy(&transmitter1_data, rx_buf, sizeof(transmitter1_data));
      Serial.println("");
      Serial.println("");
      Serial.print(" Temp1p ");
      Serial.println(transmitter1_data.t1, 0);
      Serial.print(" Umi 1p ");
      Serial.println(transmitter1_data.h1, 0);
    }
    delay(5000);
  }
}

trasmettitore_1.ino (4.3 KB) trasmettitore_2.ino (2.3 KB) ricevitore_con_display.ino (11.0 KB)

Hai poi risolto?
Io ti consiglio di usare la rf24network
Io ho creato un master che legge realtime 4 comparatori digitali mitutoyo ed un encoder rotativo.

In pratica crei una rete dove tutti parlano con tutti contemporaneamente.

Trovi dei tutorial in rete