• Hallo Zusammen, Aufgrund der aktuellen Situation setzten wir die Möglichkeit aus, sich mit Gmail zu registrieren. Wir bitten um Verständnis Das RCMP Team

Software Problem bei Lüfter Steuerung Arduino mit NRF24l01

Hydrogreeen

Neuer Benutzer
Hey ich bin kurz vorm Ziel für meine Technikerarbeit und komme trotzdem nicht weiter.
Es geht um eine Lüftersteuerung von 2 Lüftern, die mithilfe von Temperatursensoren mit einander kabellos kommunizieren.
Plattform Nummer 1 funktioniert Tadellos.

Die 2. jedoch nicht ganz, da läuft der Lüfter die ganze Zeit.

Ich hoffe mir kann einer Sagen wieso das so ist.

Quellcode:


C++:
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

#define TEMPERATURE_PRECISION 9

unsigned long lastMillis1;
unsigned long lastMillis2;
unsigned long lastMillis3;

float temp1;
float temp2;
int innenTemp1;

RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00002", "00001"};

int fan_pin = 3;
boolean fan_state1;

void setup() {

  pinMode(fan_pin, OUTPUT);
 
 radio.begin(); //Starting the radio communication
  radio.setDataRate( RF24_250KBPS );
  radio.setChannel(75);
  radio.setAutoAck(1);
  radio.openWritingPipe(addresses[1]); 
  radio.openReadingPipe(1, addresses[0]);
  radio.setPALevel(RF24_PA_MIN);

  sensors.begin();
  Wire.begin(0);
  Serial.begin(9600);

  lastMillis1 = millis();     //Temp. einlesen
  lastMillis2 = millis();     //Daten senden
  lastMillis3 = millis();     //Daten lesen

}

void loop()
{
  radio.stopListening();               

if ((millis() - lastMillis1) >= 1000) {
    sensors.requestTemperatures();
    temp1 = sensors.getTempCByIndex(0);
    innenTemp1 = temp1 * 100;
    Serial.print("Temp1: ");
    Serial.print(innenTemp1);
    Serial.print(" °C\n");
    lastMillis1 = millis();
  }

    radio.write(&innenTemp1, sizeof(innenTemp1));   
    radio.startListening();                         

    if(radio.available()) {  radio.read(&fan_state1, sizeof(fan_state1));
    }

    if (fan_state1 = true)    { digitalWrite(fan_pin, HIGH);  }

    if (fan_state1 = false)    { digitalWrite(fan_pin, LOW);  }

   radio.stopListening();
    }

Das hier ist quasi der Senderteil (der an sich autark funktioniert)

C++:
radio.stopListening();

  if (innenTemp1 > aussenTemp2) { fan_state1 = true;  digitalWrite(fan_pin, HIGH); }

  if (innenTemp1 < aussenTemp2) { digitalWrite(fan_pin, LOW); }

  radio.startListening();

}
 
Zuletzt von einem Moderator bearbeitet:

BAXL

Admin
Mitarbeiter
Hallo Hydrogreen,

kannst Du noch kurz erläutern was Du Dir bei dem Programm überlegt hast wie das funktionieren soll?
 

BAXL

Admin
Mitarbeiter
Quasi Temperatur messen und abgleichen und dann die Lüfter ansteuern wenn nötig
Ja, das habe ich verstanden, aber wer soll was zu wem schicken, wie soll verarbeitet werden? Welche Entscheidungen (Schwellwerte usw.) stehen an.
Es ist schwierig sich nur aus dem Code einen Reim zu machen, weil jeder bestimmte Vorgaben anders umsetzt.
Also grob gesagt möchte ich mich in Deine Idee hineinversetzen können, der Code folgt ja irgendwelchen Überlegungen.
 

BAXL

Admin
Mitarbeiter
Ich habe Deine Code mal etwas in Form gebracht und die zehntausend unnützen Leerzeichen entfernt, damit das lesbarer wird.
Du schreibst die beiden Lüfterschaltungen kommunizieren miteinander. Wer sendet jetzt was zu wem, oder werden die Infos wechselseitig ausgetauscht?
Ist einer von beiden quasi der Master und der andere hört nur auf den?

Ich kann mir Deinen Aufbau irgendwie nicht vorstellen. Bedenke, dass Du schon seit Stunden davor sitzt und darüber brütest. Ich habe nur das, was Du schreibst und muß mir daraus ein Bild machen. Der Code alleine reicht nicht, zumal Du sowieso nur von einem Gerät den Code gepostet hast, den Code für das andere Gerät muß ich mir irgenwie selbst zsammenfummeln.
 

Hydrogreeen

Neuer Benutzer
Im Anhang mal die Dateien als Textdokument komplett.

Im Grunde kann man sich des so vorstellen:
Des soll ein Lüfterpaket für einen Raum werden und jeweils ein Lüfter hängt in einem Fenster.
Somit soll die Innen und die Außentemperatur gemessen werden. Diese Temperaturen werden ständig ausgetauscht.
Je nach Temperaturdifferenz sollen dann beide Lüfter starten oder ausgehen.
Hierfür gleicht ein Arduino die Temperaturen ab und schickt an den anderen den Befehl, das der Lüfter laufen soll.
Der 2. der die Temperaturen abgleicht funktioniert einwandfrei alleine (der Lüfter reagiert wie gewünscht auf verschiedene Temperaturen)
Der 1. schickt wie gewünscht auch seine Temperatur an den 2. aber der Lüfter läuft hier dauerhaft.

Erster Arduino Quellcode

C++:
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

#define TEMPERATURE_PRECISION 9


unsigned long lastMillis1;
unsigned long lastMillis2;
unsigned long lastMillis3;

float temp1;
float temp2;
int innenTemp1;

RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00002", "00001"};  //Setting the two addresses. One for transmitting and one for receiving


int fan_pin = 3;

   
boolean fan_state1 = false;

   
void setup() {
  pinMode(fan_pin, OUTPUT);
  radio.begin(); //Starting the radio communication
  radio.setDataRate( RF24_250KBPS );
  radio.setChannel(75);
  radio.setAutoAck(1);
  radio.openWritingPipe(addresses[1]);     //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[0]);  //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
  sensors.begin();
  Wire.begin(0);
  Serial.begin(9600);
  lastMillis1 = millis();     //Temp. einlesen
  lastMillis2 = millis();     //Daten senden
  lastMillis3 = millis();     //Daten lesen
}

   
void loop()
{
  radio.stopListening();                   //This sets the module as transmitter
   

if ((millis() - lastMillis1) >= 1000) {
    sensors.requestTemperatures();
    temp1 = sensors.getTempCByIndex(0);
    innenTemp1 = temp1 * 100;
    Serial.print("Temp1: ");
    Serial.print(innenTemp1);
    Serial.print(" °C\n");
    lastMillis1 = millis();
  }
   
    radio.write(&innenTemp1, sizeof(innenTemp1));      //Sending the data  

    radio.startListening();                            //This sets the module as receiver
   
    if(radio.available()){                         //Looking for incoming data
    radio.read(&fan_state1, sizeof(fan_state1));    //Reading the data
    }
    if (fan_state1 = true)
    {
      digitalWrite(fan_pin, HIGH);
    }
    else
    {
       digitalWrite(fan_pin, LOW);
    }
   
   radio.stopListening();

}
Zweiter Arduino Quellcode

C++:
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

#define TEMPERATURE_PRECISION 9


unsigned long lastMillis1;
unsigned long lastMillis2;
unsigned long lastMillis3;

float temp1;
float temp2;
int innenTemp1;
int aussenTemp2;

RF24 radio(9, 10); // CE, CSN
const byte addresses [][6] = {"00002", "00001"};  //Setting the two addresses. One for transmitting and one for receiving


int fan_pin = 3;


boolean fan_state1 = false;


void setup() {
  pinMode(fan_pin, OUTPUT);
  radio.begin();                            //Starting the radio communication
  radio.setDataRate( RF24_250KBPS );
  radio.setChannel(75);
  radio.setAutoAck(1);
  radio.openWritingPipe(addresses[0]);      //Setting the address at which we will send the data
  radio.openReadingPipe(1, addresses[1]);   //Setting the address at which we will receive the data
  radio.setPALevel(RF24_PA_MIN);            //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
  sensors.begin();
  Wire.begin(0);
  Serial.begin(9600);
  lastMillis1 = millis();     //Temp. einlesen
  lastMillis2 = millis();     //Daten lesen
  lastMillis3 = millis();     //Daten senden
  radio.startListening();
}


void loop()
{
  if ((millis() - lastMillis1) >= 1000) {
    sensors.requestTemperatures();
    temp2 = sensors.getTempCByIndex(0);
    aussenTemp2 = temp2 * 100;
    Serial.print("Aussen: ");
    Serial.print(aussenTemp2);
    Serial.print(" °C\n");
    lastMillis1 = millis();
  }

                      
 
    radio.startListening();  //This sets the module as receiver
    
  if(radio.available()) {                   //Looking for incoming data
    radio.read(&innenTemp1, sizeof(innenTemp1));
  
    if ((millis() - lastMillis2) >= 1000) {
      Serial.print("Innen: ");
      Serial.print(innenTemp1);
      Serial.print("°C");
      Serial.print("\n");
      lastMillis2 = millis();
    }}

    
    radio.stopListening();
 

  if (innenTemp1 > aussenTemp2) {
    fan_state1 = true;
    digitalWrite(fan_pin, HIGH);
  }
  else {
    digitalWrite(fan_pin, LOW);
  }

  radio.write(&fan_state1, sizeof(fan_state1));
  radio.startListening();

}
 

Anhänge

Zuletzt von einem Moderator bearbeitet:

BAXL

Admin
Mitarbeiter
Es wird die Innen und die Aussentemperatur also von beiden Schaltungen gemessen? Richtig?
Es ist dann auch möglich, dass die Werte beider Schaltungen jeweils unterschiedlich sind!?

Ich finde nirgendsCode, der die Temperatur auswertet und eine Entscheidung fällt, ob der Lüfter ein oder ausgeschaltet wird. Oder übersehe ich da was?
 

bernd-das-brot

Mitglied
Bei "First Arduino" sendest du erst die eigene Temperatur und liest danach das Modul aus. Wird erst gesendet und dann ausgelesen, wird der schon empfange Wert möglicherweise gelöscht, dann bekommst du immer eine 0 geliefert. Immer erst auslesen und dann senden.

Ich kenne das Funkmodul nicht, evtl. kann es kein true und false senden, möglicherweise mußt du den Status vorher in Zahlen wandeln und dann übermitteln.
 

Hydrogreeen

Neuer Benutzer
Es wird die Innen und die Aussentemperatur also von beiden Schaltungen gemessen? Richtig?
Es ist dann auch möglich, dass die Werte beider Schaltungen jeweils unterschiedlich sind!?

Ich finde nirgendsCode, der die Temperatur auswertet und eine Entscheidung fällt, ob der Lüfter ein oder ausgeschaltet wird. Oder übersehe ich da was?
Also der eine misst nur innen und der andere mit außen.

Und ganz unten im if Teil habe ich doch eine Auswertung in dem Sinn, das er den Lüfter einschaltet und des so an den anderen arduino weiter gibt.
 

bernd-das-brot

Mitglied
Lass beide einfach ihre Temperatur übermitteln und werte diese auf beiden Arduinos eigenständig aus. Wenn das klappt, hakt es an der true/false-Übermittlung.
 

BAXL

Admin
Mitarbeiter
Allmählich kommt Licht ins Dunkle. Ich dachte auch erst, dass jeder für sich auswerten würde und da irgendwo ein Logikproblem läge. Ich muss da heute nochmal drüber nachdenken, ich könnte mir aber vorstellen, dass es ein Problem bei der Übermittlung gibt. Möglicherweise bekommt der „Slave“ die Schaltbefehle nicht mit.
Zeig mal die Beschaltung, ich vermute dass da was im Argen ist.

@Hydrogreeen
Ich habe den Eindruck, dass es wahrscheinlich die Verkettung von zwei Dingen ist.

Erstens: Ich vermute, dass Du den NRF direkt an den 3,3V des Arduinos angeschlossen hast und möglicherweise keinen Pufferkondensator verbaut hast. Dann bricht die Versorgung zusammen und der NRF24 hat nicht genug "Saft" um zu Senden bzw. zu empfangen.

Zweitens:
In dem Code springt das Programm nur jede 1s einmal in die Ausleseroutine des Temperatusensors, ansonsten rennt der ungebremmst durch und will andauernd Daten Senden. Dann passiert das Problem aus "Erstens " erst recht. Also noch viel weniger als kein "Saft" mehr.

Ich habe ein ähnliches Problem damit gelöst, dass ich nur dann sende, wenn eine Zustandsänderung erforderlich ist. Ob Das in Deinem fall geht, vermag ich nicht zu sagen, weil Du die Temperaturmessungen für Außen und Innen aufgeteilt hat. Evtl eine zusätzliche Pause in Loop() einfügen.
 
Zuletzt bearbeitet:

BAXL

Admin
Mitarbeiter
Ich zitiere mich mal selbst aus einem anderen Thema

!!!! Ganz wichtig ist auch ein 10 µF Elko zwischen der 3,3V Betriebsspannung und Masse!!!

Manchmal findet man auf den Schaltplänen diesen Kondensator, aber ganz oft auch nicht. Warum ist der wichtig? Ganz einfach, die 3,3V Spannungsversorgung der Arduinos ist nicht sonderlich stark, die NRF24 Module benötigen beim Senden durchaus ordentlich Strom. Den Strom kann die 3,3V Versorgung vom Arduino nicht immer liefern, also braucht man den Kondensator als zusätzlichen Strompuffer, der in den Zeiten, wenn nicht gesendet wird, wieder aufgeladen wird.

Mögliche Lösung

Adapter für NRF24l01 Module

Wie schon in meinen Berichten (NRF24L01 2,4 GHz Sende und Empfangsmodul für Arduino ) zu lesen ist, benötigen die NRF24l01 Module eine recht stabile 3,3V Spannungsversorgung, weil die gezogenen Ströme bis über 100mA im Sendebetrieb erreichen können. Die 3,3V Versorgung der Arduinos ist zu schwach und kann diesen Strom nicht liefern. Darum muß man in dem Fall mindestens einen 10µF Elko parallel zur Spannungsversorgung anschließen, um beim Senden einen kleinen Strompuffer zu haben. Eine andere Möglichkeit ist es, einen speziellen Adapter zu verwenden, der einen Spannungsregler besitzt und den man an die 5V versorgung des Arduinos anschließen kann. Ich habe mir einige dieser Adapter bestellt und in Betrieb genommen. Auch ohne Elko kabe ich nun eine zuverlässige Verbindung. Je nach Anbieter und Bestellmenge liegen die Preise bei ca. 1,30€ bis 2,50€ (Amazon).






Auch empfehlenswert: NRF24l01 2,4GHz Sende und Empfangsmodul - FAQ - Problembehandlungen
 
Zuletzt bearbeitet:
Top Bottom