Progetto domotico con sensori nRF24L01

Ciao a tutti. Ho realizzato tempo fa un progetto composto da due schede arduino che dialogano attraverso sensori nRF24L01 per il controllo domotico di un riscaldamento.

Arduino Uno A è collegato a Raspberry Pi e comunica i dati via seriale che poi vengono scritti su un database sql con uno script in python. I dati che vengono comunicati sono:

  • la temperatura di un sensore collegato ad Arduino Uno A e la temperatura di un sensore collegato ad un altro Arduino uno che chiamerò B che ha anch’esso un sensore di temperatura.

Il tutto funziona a dovere e ci sono delle interazioni per l’accensione e lo spegnimento di un relè collegato all’Arduino uno B.

Oggi volevo collegare una terza scheda arduino (Arduino Uno C) per rilevare un terzo valore di temperatura (esterna) ma quando collego anche il terzo, modificando adeguatamente lo script ogni tanto (molto spesso direi) il valore che proviene dal secondo sensore (collegato all’Arduino Uno B per capirci) mi da un valore pari a “ovf” anzichè quello corretto.

Qualcuno saprebbe svelarmi l’arcano??

Vi posto qui sotto il codice.

Codice Arduino Uno A

#include <SPI.h>
#include <nRF24L01p.h>
#include <OneWire.h> 

int DS18S20_Pin = A0; //DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin);  // on digital pin 2
nRF24L01p receiver(7,8);//CSN,CE

 float dati;
float incomingByte;

int dati2;
void setup()
{
  Serial.begin(9600);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  receiver.channel(90);
  receiver.RXaddress("Artur");
  receiver.TXaddress("Artur");  
  receiver.init();
  pinMode(2, OUTPUT);    
        
}
void loop()
  {
    String esterno = "";

    float cucina = getTemp();
    incomingByte=Serial.read();
   if (incomingByte =='L') {
     digitalWrite(2, LOW);
     dati2 = 2;
} 
  if (incomingByte =='H') {
    digitalWrite(2, HIGH);
      dati2 = 1;}        
 delay(150);    
 if(receiver.available()){
        receiver.read();
        receiver.rxPL(esterno);
         if(receiver.available()){
        receiver.read();
        receiver.rxPL(dati);
       }
        if (esterno.length() > 2) {
          if (dati != NULL) {
        Serial.print(esterno);
        Serial.print(" ");
        delay(900);
        Serial.print("camera:");
        Serial.print(dati);
        Serial.print(" cucina:");
        Serial.print(cucina);
        Serial.println(" ");
    delay(900);
    receiver.txPL(dati2);
    receiver.send(SLOW);
    Serial.println(dati2);
 delay(900);}
        }
 }}
 
 
 
  
 
 float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  return TemperatureSum;
  
}

Codice Arduino Uno B

#include <SPI.h>
#include <nRF24L01p.h>
#include <OneWire.h> 

int DS18S20_Pin = A1; //DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin);  // on digital pin 2
float dati;
int dati2;
nRF24L01p transmitter(7,8);//CSN,CE
float incomingByte;


void setup(){
    delay(150);
  Serial.begin(9600);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  transmitter.channel(90);
  transmitter.TXaddress("Artur");
  transmitter.RXaddress("Artur");
  transmitter.init();
  pinMode(4, OUTPUT);    
  

}

void loop(){
  float temperature = getTemp();
   float dati= temperature;   
   Serial.println(dati);
   transmitter.txPL(dati);
   transmitter.send(SLOW);
   delay(3000);
   transmitter.read();
   transmitter.rxPL(dati2);
   Serial.println(dati2);
   if (dati2 == 1) {
     if (dati < 20.00) {
   digitalWrite(4, HIGH);
   delay(200);
     } else {
     digitalWrite(4, LOW);
     delay(200);}
     }   
   
  if (dati2 == 2) {
     digitalWrite(4, LOW);}
     delay(200);
 
 }
 
 
 
 
 float getTemp(){
  //returns the temperature from one DS18S20 in DEG Celsius

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  return TemperatureSum;
  
}

Arduino Uno C

#include <SPI.h>
#include <nRF24L01p.h>

nRF24L01p transmitter(7,8);//CSN,CE

void setup(){
  delay(150);
  Serial.begin(9600);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  transmitter.channel(90);
  transmitter.TXaddress("Artur");
  transmitter.init();  
}

void loop(){
   String esterno = "esterno:4.00";
   Serial.println(esterno);
   transmitter.txPL(esterno);
   transmitter.send(SLOW);
   delay(3000);
 
 }

credo di aver capito perchè il valore ogni tanto è su ovf.

La scheda Arduino Uno C invia una stringa provvisoria (e non un float) e il ricevitore riceve i dati. Il problema è che li riceve senza un ordine quindi ogni tanto riceve un float e lo stampa mentre ogni tanto riceve una stringa e va in ovf..

Credo sia così perchè se provo ad inviare un float l'alternanza non è più tra ovf e il valore float inviato da B ma bensì un'alternanza del float inviato da C e da B.

il problema ora è quindi un altro.

Come faccio a mettere un pò d'ordine tra i dati che ricevo in input sul ricevitore?? come faccio a dire questo l'ho ricevuto da B e questo da C ? la stampa dei dati ricevuti è ogni tanto prima B e ogni tanto prima C quindi non c'è un ordine prefissato.

Qualcuno ha qualche consiglio su come posso provare a risolvere?

Ciao,
Visto che è passato un po' di tempo penso tu abbia risolto. Cmq io ho risolto cosi:

  • uso le librerie MIRF
  • Passo una struct con i vari dati che mi servono
  • per evitare casini ho anche inserito una password (come ultimo valore della struct) tra i vari dati passati. La prima cosa che faccio quando leggo la struct è controllare la password, se è giusta vuol dire che il dato è passato correttamente e procedo.

Ciao
Pietro