Temperatursensor gibt nach Kommunikation mit nRF24L01+ nur 0.00 aus

Hallo zusammen
Ich möchte die Aussentemperatur mit dem nRF24L01+ Modul über einen ATTiny84A-PU an einen Arduino Uno mit einem zweiten nRF24L01+ Modul senden. Der Tiny bekommt seinen Strom über eine 3V Lithium Knopfzelle.
Leider bekomme ich danach auf dem Seriellen Monitor immer nur eine Temperatur von 0.00 und das nur, wenn ich das MOSI Kabel des Moduls am Arduino Uno nicht angeschlossen habe.
Kann es sein, dass die Temperatur bei der Kommunikation verloren geht?
Der Temperatursensor ist ein DS18S20. Er ist richtig angeschlossen am ATTiny, das habe ich mehrmals überprüft.
Das sind die Codes, die ich verwende:
Am Arduino UNO:

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(7, 8);
byte addresses[][6] = {"1Node", "2Node"};
boolean role;                                    // The main role variable, holds the current role identifier
boolean recieve = 1, senden = 0;   // The two different roles.
void setup () {

  Serial.begin(9600);

  //Kommunikation starten
  radio.begin();                          // Start up the radio
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.openReadingPipe(1, addresses[1]);

  radio.startListening();                 // Start listening
}
void loop (){
 if ( radio.available()) {
    float got_tempout;                                       // Variable for the received timestamp
    while (radio.available()) {                                   // While there is data ready
      radio.read( &got_tempout, sizeof(unsigned long) );             // Get the payload
    }
    Serial.println(got_tempout);
delay (1000);
}

Am ATTiny:

#include <SPI85.h>

#include "nRF24L01.h"
#include "RF24.h"
#include <OneWire.h>
#include <DallasTemperature.h>


// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10
#define CE_PIN 7
#define CSN_PIN 3
RF24 radio(CE_PIN, CSN_PIN);

byte addresses[][6] = {"1Node", "2Node"};
boolean role;                                    // The main role variable, holds the current role identifier
boolean recieve = 1, senden = 0;   // The two different roles.


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

void setup() {


  sensors.begin();
  sensors.setResolution(9);
  // Setup and configure rf radio
  radio.begin();                          // Start up the radio
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.openWritingPipe(addresses[0]);
}

void loop(void) {
  sensors.requestTemperaturesByIndex(0);
  sensors.getTempCByIndex(0);
  float tempout = sensors.getTempCByIndex(0);
  radio.write( &tempout, sizeof(float) );
}

Wenn mir jemand helfe könnte wäre ich sehr froh.
techniclover

Ich hab eine sehr ähnliche Anwendung und bei mir läuft es problemlos… Hier mein Sketch:

#include <SPI.h>
#include "RF24.h"
#include "Time.h"
#include <OneWire.h>
#include <DallasTemperature.h>

byte RaumID = 23;
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

RF24 radio(9, 10);

float Temperatur;

long letzteMeldung = 0;
long meldungsAbstand = 6000;

byte Sensoralt[9];
byte Sensor[9];

void setup()
{
  Sensor[0] = RaumID; // muss man nur einmal setzen
  
  sensors.begin();
  Serial.begin(115200);

  radio.begin();
  radio.openWritingPipe((byte*)"2Node");
  radio.setRetries(15,15); 
  radio.setPALevel(RF24_PA_LOW);       
  radio.setDataRate(RF24_1MBPS); 
  radio.startListening();
}

void loop()
{
  unsigned long aktuelleMeldung = millis();
  sensors.requestTemperatures(); 
  
  Temperatur = (sensors.getTempCByIndex(0));
  if (Temperatur >= 0)
  {Sensor[3] = byte(Temperatur);}
  else
  {Sensor[4] = (byte(Temperatur))*-1;}
  Sensor[1] = 0;
  Sensor[2] = 0;
  Sensor[5] = 0;
  Sensor[6] = 0;
  Sensor[7] = 0;
  Sensor[8] = 0;
 //if (Sensor[1] != Sensoralt[1])
  if (aktuelleMeldung - letzteMeldung > meldungsAbstand) 
    {
    letzteMeldung = aktuelleMeldung;
    printSensorArray();
    radio.stopListening();
    radio.write(Sensor, sizeof(Sensor));
    radio.startListening();
    } 
  Sensoralt[3] = Sensor[3];
}

void printSensorArray() 
{
  Serial.println(F("sende "));
  Serial.print(F(" Raum ID:      " ));
  Serial.println(Sensor[0]);
  Serial.print(F(" Temperatur : "));
  Serial.println(Temperatur);
  Serial.print(Sensor[3]);
  Serial.print(F(","));
  Serial.println(Sensor[4]);
  Serial.println(F("  "));
}

Zum Senden und empfangen sollte man die gleiche Adresse benutzen, das hilft oft.

Woher hast du den Kode für den Uno kopiert?
Den Blödsinn sollte man vom Netz nehmen.

Ich habe mir die beiden Programme selber aus dem Getting Started Sketch zusammengebaut. Es ist sehr gut möglich, dass ich etwas nicht richtig verstanden habe.
Das mit den Adressen. Ist da das Problem bei radio.openReadingPipe(...)?

techniclover:
Das mit den Adressen. Ist da das Problem bei radio.openReadingPipe(...)?

Welche Funktion ist zu beschuldigen wenn zwei Funktionen,
die mit gleichem Parameter aufgerufen werden müssen, es nicht werden?

Such dir eine Adresse aus und benutze die zum Empfangen und Senden.

Alle vorhandenen Pakete in den gleichen Puffer zu lesen, aber nur das letzte zu bearbeiten ist Quatsch,
der dir übelst im Weg steht, sobald es mehr als einen Sender gibt.
Wozu soll die 9600 Baudrate gut sein?
Warum gibt es ein delay in loop?

Es gibt ein Modul das sendet und eines das empfängt.
Wenn diese die gleiche Adresse haben müssen, an welcher Stelle muss das in das Programm. Konkret.

Da ich nur einen Sender habe, muss ich mich nicht darum kümmern.

Die Baudrate dient doch nur dazu einen Seriellen Monitor zu aktivieren? Welche sollte ich deiner Meinung nach verwenden?

Damit die Daten nicht ununterbrochen reinkommen. (Zur Analyse) Der Delay kommt dann raus

techniclover:
Es gibt ein Modul das sendet und eines das empfängt.
Wenn diese die gleiche Adresse haben müssen, an welcher Stelle muss das in das Programm. Konkret.

An beiden.

techniclover:
Da ich nur einen Sender habe, muss ich mich nicht darum kümmern.

Da das alles dein Problem ist, muss mich das nicht kümmern.

techniclover:
Die Baudrate dient doch nur dazu einen Seriellen Monitor zu aktivieren? Welche sollte ich deiner Meinung nach verwenden?

115200 oder mehr. Serielle Ausgabe bremst den Prozessor, wenn der Puffer (63 Byte) voll wird.

techniclover:
Damit die Daten nicht ununterbrochen reinkommen. (Zur Analyse) Der Delay kommt dann raus

Die Daten kommen dennoch die ganze Zeit, und eine Sekunde Däumchen drehen dient keiner Analyse.

115200 oder mehr. Serielle Ausgabe bremst den Prozessor, wenn der Puffer (63 Byte) voll wird.

  1. Kannst du mir erklären was der Unterschied der Baudraten ist?
  2. Wie kann ich immer nur die aktuellste Angabe im Puffer haben?

Quote from: techniclover on Today at 01:01 pm

Es gibt ein Modul das sendet und eines das empfängt.
Wenn diese die gleiche Adresse haben müssen, an welcher Stelle muss das in das Programm. Konkret.

An beiden.

Ist das an der Stelle des Programms gemeint?:

  radio.openReadingPipe(1, addresses[1]);

Und entschuldigung, dass dies das erste Mal ist, dass ich mit diesen Modulen arbeite und noch etwas schwierigkeiten habe.

techniclover:

  1. Kannst du mir erklären was der Unterschied der Baudraten ist?

Die Übertragungsgeschwindigkeit. Baud
Erzeugt dein Programm mehr Daten als übertragen werden können,
muss es auf die Übertragung warten und wird dafür angehalten,
bis die Ausgaben wieder in den 63 Byte Puffer passen.

techniclover:
2. Wie kann ich immer nur die aktuellste Angabe im Puffer haben?

Deine Frage ist sinnfrei. Du füllst den Puffer durch serielle Ausgaben, eine Interruptroutine leert den Puffer.

techniclover:
Ist das an der Stelle des Programms gemeint?

Wie kann mit beide eine Stelle gemeint sein?
Was ist an "Such dir eine Adresse aus und benutze die zum Empfangen und Senden." schwer zu verstehen?

Könnte es sein, dass du bisher noch keinen Blick in das Datenblatt und die Dokumentation geworfen hast?

Vielen Dank für deine Erklärung zu den Baudraten.

Wie kann mit beide eine Stelle gemeint sein?
Was ist an “Such dir eine Adresse aus und benutze die zum Empfangen und Senden.” schwer zu verstehen?

Mit beide kann keine Stelle gemeint sein. Ich habe allerdings nach einer Stelle gefragt. Da du mir keine Stelle gegeben hast, habe ich dich gefragt, ob ich das an derjenigen Stelle ändern muss, die ich nachfolgend geschriben habe. Iste es nun an dieser Stelle zu ändern?

Das Datenblatt und die Dokumentation habe ich mir selbstverständlich berreitss angessehen, nur finde ich diese Information dort nicht.

Informationen dazu zu finden finde ich recht einfach.

void openWritingPipe (const uint8_t *address)
void openReadingPipe (uint8_t number, const uint8_t *address)

Diese beiden Routinen setzen die Adressen und sollten für deine Anwendung den gleichen Parameter (const uint8_t *address) bekommen, sonst werden sie nicht miteinander reden können.

Vielen Dank.
Habe ich das richtig verstanden, dass ich nun also im Programm auf dem Tiny den Befehl
radio.openWritingPipe(addresses[0])

und im Programm auf dem UNO
radio.openReadingPipe(1, addresses[0])

verwenden muss?

Ja, das wäre bei deinen beiden Adresse eine der beiden Möglichkeiten.
Der Empfänger sollte auf die gleiche Adresse lauschen, auf der der Sender sendet.

Dann könnten die beiden miteinander kommunizieren.

Danke viel mals, du hast mir sehr geholfen.
Leider bekomme ich immernoch bloss 0.00 auch bei Baudrate 250000.

Du bremst den Empfänger, sendest aber völlig ungebremst.
Du hast Glück, dass sizeof(float) gleich sizeof(long) ist.

Was soll das dreifache Lesen der Temperatur um sie einmal zu senden?

  sensors.requestTemperaturesByIndex(0);
  sensors.getTempCByIndex(0);
  float tempout = sensors.getTempCByIndex(0);

Poste mal deine neuen korrigierten Sketche.

Wieso glaubst du dass der Tiny nicht 0.00 sendet?

Die korrigierten Sketche:
Arduino Uno

//Kommunikation
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(7, 8);
byte addresses[][6] = {"1Node", "2Node"};
boolean role;                                    // The main role variable, holds the current role identifier
boolean recieve = 1, senden = 0;   // The two different roles.

void setup () {

  Serial.begin(250000);
  //Kommunikation starten
  radio.begin();                          // Start up the radio
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.openReadingPipe(1, addresses[0]);

  radio.startListening();                 // Start listening
}
void loop () {
float got_tempout;                                       // Variable for the received timestamp
  while (radio.available()) {                                   // While there is data ready
    radio.read( &got_tempout, sizeof(got_tempout) );             // Get the payload
}

Tiny:

#include <SPI85.h>

#include "nRF24L01.h"
#include "RF24.h"
#include <OneWire.h>
#include <DallasTemperature.h>


// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10
#define CE_PIN 7
#define CSN_PIN 3
RF24 radio(CE_PIN, CSN_PIN);

byte addresses[][6] = {"1Node", "2Node"};
boolean role;                                    // The main role variable, holds the current role identifier
boolean recieve = 1, senden = 0;   // The two different roles.


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

void setup() {


  sensors.begin();
  sensors.setResolution(9);
  // Setup and configure rf radio
  radio.begin();                          // Start up the radio
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.openWritingPipe(addresses[0]);
}

void loop(void) {
  sensors.requestTemperaturesByIndex(0);
  float tempout = sensors.getTempCByIndex(0);
  radio.write( &tempout, sizeof(tempout) );
}

Du bremst den Empfänger, sendest aber völlig ungebremst.

Wie genau bremse ich den Empfänger im Programm?

Es kann sein, dass der Tiny 0.0 sendet. Da ich aber den DS18S20 bereits am Uno geteste habe und nun am Tiny genau gleich angeschlossen habe, denke ich, dass der Anschluss korrekt ist und somit eigentlich die richtige Temperatur ausgelesen werden müsste.

void loop (){
 if ( radio.available()) {
    float got_tempout;                                       // Variable for the received timestamp
    while (radio.available()) {                                   // While there is data ready
      radio.read( &got_tempout, sizeof(unsigned long) );             // Get the payload
    }
    Serial.println(got_tempout);
delay (1000);
}

Mit dem delay?

Du solltest den Sender bremsen siehe Blink without delay.

void loop () {
float got_tempout;                                       // Variable for the received timestamp
  while (radio.available()) {                                   // While there is data ready
    radio.read( &got_tempout, sizeof(got_tempout) );             // Get the payload
}

keine Ausgabe mehr?

Statt des while solltest du ein if benutzen.

Oh, Ausgabe vergessen zu kopieren.
Ausgabebefehl bleibt der gleiche.

Also so:

void loop () {
float got_tempout;                                       // Variable for the received timestamp
  if (radio.available()) {                                   // While there is data ready
    radio.read( &got_tempout, sizeof(got_tempout) );             // Get the payload
serial.println(got_tempout);
}

Dein Empfänger lässt sich in keiner Version übersetzen,
dir fehlen schließende '}' Klammern.

Eine schliessende Klammer nach radio.read
Die ist wohl auch mit dem Ausgabebefehl vergessen gegangen.

//Kommunikation
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(7, 8);
byte addresses[][6] = {"1Node", "2Node"};
boolean role;                                    // The main role variable, holds the current role identifier
boolean recieve = 1, senden = 0;   // The two different roles.

void setup () {

  Serial.begin(250000);
  //Kommunikation starten
  radio.begin();                          // Start up the radio
  radio.setAutoAck(1);                    // Ensure autoACK is enabled
  radio.openReadingPipe(1, addresses[0]);

  radio.startListening();                 // Start listening
}
void loop () {
float got_tempout;                                       // Variable for the received timestamp
  if (radio.available()) {                                   // While there is data ready
    radio.read( &got_tempout, sizeof(got_tempout) );             // Get the payload
}
serial.println(got_tempout);
}