Hallo Zusammen,
Ich hoffe das ich hier im Richtigen Unterforum bin. Ich habe eine Frage bezüglich der 2 Wege Kommunikation via nRF24L01 zwischen einem Raspberry Pi 3 und einem Adroino Nano.
Grundsätzlich steht die Verbindung, der RPi sendet etwas und der Nano antwortet (RPi ist Master) wenn allerdings der Nano etwas senden soll sagt das Skript in der Ausgabe, zwar: "Empfangen... ***" "Send response" auf dem Nano kommt dieses aber nicht an und dieser versucht erneut zu senden (Time error). Weiter steht wenn ich den Serial Monitor vom Nano öffne nicht "Now sending ... B002003" sondern "Now sending ... 308". Ich hoffe das ihr mir helfen könnt ich habe beide Scripte angehängt:
Das ganze soll aus zurzeit insgesamt 4 Nanos und einem RPi 3 gebaut werden. Es ist am ende eine Hausautomatisierung. Der Nano Code ist vom Gerät "2" die Schnittstelle zur Alarmanlage. Ich hoffe ihr könnt mir helfen wo der Fehler liegt.
RPi:
#!/usr/bin/env python
#
# Konfiguration
#
from __future__ import print_function
import spidev
import sys
import os
from datetime import timedelta
import time
from RF24 import *
import RPi.GPIO as GPIO
irq_gpio_pin = None
radio = RF24(22, 0);
#
# Befehle
#
button_pin = 16 # GPIO number
codeOn = "Turn LED on"
codeOff = "Turn LED off"
A1_mess = "A001001"
A1_magnet = "A001002"
A2_status_ein = "B002001"
A2_status_aus = "B002002"
A2_alarm = "B002003"
A2_hier = "B002004"
A3_D_ein = "C003001"
A3_D_aus = "C003002"
A4_mess = "D004001"
#
# Variabelen
#
p1 = 0
p2 = 0
Val = 0
p3 = 0
mess = 0
roll_round = 0
send_code = 'Empty_String'
code = 'ABCDEFG'
payload_size = 32
receive_payload = 0
receive_new_payload = 0
err_cound = 0
empfangen = 0
sende_Val = 0
verz_A1 = 4
verz_A1_ms = verz_A1 * 60 * 60 * 10
print(verz_A1_ms)
send_now = 0 # Variabele, dass gesendet werden soll sch_h = 21 # Stunde zu der gegossen werden soll sch_m = 0 # Minute zu der gegossen werde soll sperr = 0 delay = 0
verz_ein = 0
verz_aus = 0
next_ein = 1
next_aus = 0
# Merker Error Device
err_1 = 0
err_2 = 0
err_3 = 0
err_4 = 0
err_5 = 0
#
# Kommunikationsblog
#
def sendCode(code):
# The payload will always be the same, what will change is how much of it we send.
# First, stop listening so we can talk.
radio.stopListening()
# Take the time, and send it. This will block until complete
radio.write(code[:payload_size])
# Now, continue listening
radio.startListening()
# Wait here until we get a response, or timeout
started_waiting_at = millis()
timeout = False
while (not radio.available()) and (not timeout):
if (millis() - started_waiting_at) > 5000:
timeout = True
# Describe the results
if timeout:
return False
else:
# Grab the response, compare, and send to debugging spew
len = radio.getDynamicPayloadSize()
receive_payload = radio.read(len)
return True
pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2]
min_payload_size = 1
max_payload_size = 32
payload_size_increments_by = 1
next_payload_size = min_payload_size
inp_role = 'none'
send_payload = b'abcdefghijklmnopqrstuvwxyz0123456789'
millis = lambda: int(round(time.time() * 1000))
#print('pyRF24/examples/pingpair_dyn/')
radio.begin()
radio.enableDynamicPayloads()
radio.setRetries(5,15)
radio.printDetails()
# forever loop
while 1:
zeit = time.localtime()
# Rollen auswahl
if (send_now == 1):
inp_role = '1'
roll_round = 0
else:
if (roll_round < 1):
print(' -- awaiting transmission -- ')
roll_round += 1
inp_role = '0'
time.sleep(0.1)
# Empfaengerrolle
if inp_role == '0':
if irq_gpio_pin is not None:
# set up callback for irq pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(irq_gpio_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(irq_gpio_pin, GPIO.FALLING,
callback=try_read_data)
radio.openWritingPipe(pipes[1])
radio.openReadingPipe(1,pipes[0])
radio.startListening()
elif inp_role == '1':
print(' -- starting transmission -- ')
radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1,pipes[1])
else:
print(' -- ERROR --')
# Sender Rolle
if (inp_role == '1'): # ping out
# First, stop listening so we can talk.
radio.stopListening()
radio.write(code[:payload_size])
print("Now sending ... ", code)
# Now, continue listening
radio.startListening()
# Wait here until we get a response, or timeout
started_waiting_at = millis()
timeout = False
while (not radio.available()) and (not timeout):
if (millis() - started_waiting_at) > 5000:
timeout = True
# Describe the results
if timeout:
print('failed, response timed out.')
err_cound += 1
time.sleep(60)
print('tray aggain')
else:
# Grab the response, compare, and send to debugging spew
len = radio.getDynamicPayloadSize()
receive_payload = radio.read(len)
print("transmission succesful")
code = send_code
err_cound = 0
send_now = 0
if (err_cound == 5):
os.system("/home/pi/tg/send_script P*** '5
Transmissionen fehlgeschlagen' ") print(err_cound, "
Transmissionen fehlgeschlagen")
if (err_cound == 10):
os.system("/home/pi/tg/send_script P*** '10
Transmissionen fehlgeschlagen, reset des Befehls' ")
print(err_cound, " Transmissionen fehlgeschlagen")
if (err_cound == 10):
if (code == A1_mess or code == A1_magnet):
os.system("/home/pi/tg/send_script P***
'Empaefnger 1 antwortet nicht' ") print(err_cound, "
Transmissionen fehlgeschlagen") print("Empfaenger 1 antwortet
nicht") code = send_code
err_cound = 0
send_now = 0
err_1 = 1
elif (code == A2_hier):
os.system("/home/pi/tg/send_script P***
'Empaefnger 2 antwortet nicht' ") print(err_cound, "
Transmissionen fehlgeschlagen") print("Empfaenger 2 antwortet
nicht") code = send_code
err_cound = 0
send_now = 0
err_2 = 1
elif (code == A3_D_ein or code == A3_D_aus):
os.system("/home/pi/tg/send_script P***
'Empaefnger 3 antwortet nicht' ") print(err_cound, "
Transmissionen fehlgeschlagen") print("Empfaenger 3 antwortet
nicht") code = send_code
err_cound = 0
send_now = 0
err_3 = 1
elif (code == A4_mess):
os.system("/home/pi/tg/send_script P***
'Empaefnger 4 antwortet nicht' ") print(err_cound, "
Transmissionen fehlgeschlagen") print("Empfaenger 4 antwortet
nicht") code = send_code
err_cound = 0
send_now = 0
err_4 = 1
if (zeit.tm_hour == 9 and zeit.tm_min == 59):
err_1 = 0
err_2 = 0
err_3 = 0
err_4 = 0
err_5 = 0
os.system("/home/pi/tg/send_script P*** 'Alle
Empfaenger wieder auf empfang' ")
else:
# Pong back role. Receive each packet, dump it out, and send
it back
# if there is data ready
if irq_gpio_pin is None:
# no irq pin is set up -> poll it
if radio.available():
while radio.available():
len = radio.getDynamicPayloadSize()
receive_new_payload = radio.read(len)
time.sleep(2)
# First, stop listening so we can talk
radio.stopListening()
# Send the final one back.
radio.write(receive_new_payload)
print("Empfangen: ", receive_new_payload)
empfangen = receive_new_payload
print('Sent response.')
sende_Val = 1
# Now, resume listening so we catch the next
packets. radio.startListening()
else:
# callback routine set for irq pin takes care for reading -
# do nothing, just sleeps in order not to burn cpu by
looping time.sleep(1)
#
# Hauptprogramm
#
# Script 433 Ein
if ( (zeit.tm_hour == 20 and zeit.tm_min == 40) and send_now == 0 and not sperr == 1 and err_3 == 0): code = A3_D_ein
send_now = 1
sperr = 1
print("next Code: ", code)
next_ein = 0
next_aus = 1
verz_ein = 0
elif (next_ein == 1):
verz_ein += 1
# Script 433 Aus
if ( (zeit.tm_hour == 21 and zeit.tm_min == 10) and send_now == 0 and not sperr == 1 and err_3 == 0): code = A3_D_aus
send_now = 1
sperr = 1
print("next Code: ", code)
next_aus = 0
next_ein = 1
verz_aus = 0
elif (next_aus == 1):
verz_aus += 1
if (delay > 200):
sperr = 0
elif (sperr >=1):
delay += 1
time.sleep (0.1)
# Script Gartenbewaesserung
# Messung
if ( (zeit.tm_hour == 8 and zeit.tm_min == 55) or (zeit.tm_hour ==
20 and zeit.tm_min == 55) or (zeit.tm_hour == 21 and zeit.tm_min ==
55) and send_now == 0 and err_1 == 0): code = A1_mess send_now = 1
print("next Code: ", code)
p1 = 0
elif (mess == 0):
p1 += 1
time.sleep(0.1)
# Vorgarten
# Messung
if ( (zeit.tm_hour == 8 and zeit.tm_min == 40) or (zeit.tm_hour ==
18 and zeit.tm_min == 55) or (zeit.tm_hour == 20 and zeit.tm_min ==
55) and send_now == 0 and err_4 == 0): code = A4_mess send_now = 1
print("next Code: ", code)
p1 = 0
# Auswertung Epfangene Daten
if (sende_Val == 1):
# Garten
if (empfangen == "VAL_LOW___"):
print("Auswertung: VAL LOW")
os.system("/home/pi/tg/send_script P*** 'Sensor
sendet VAL LOW' ") sende_Val = 0
p3 = 1
elif (empfangen == "NASS______"):
print("Auswertung: Nass")
os.system("/home/pi/tg/send_script P*** 'Sensor
sendet Nass' ") sende_Val = 0
p3 = 1
elif (empfangen == "FEUCHT____"):
print("Auswertung: Feucht")
os.system("/home/pi/tg/send_script P*** 'Sensor
sendet Feucht' ") sende_Val = 0
p3 = 1
elif (empfangen == "TROCKEN___"):
print("Auswertung: Trocken")
os.system("/home/pi/tg/send_script P*** 'Sensor
sendet Trocken' ") sende_Val = 0
p3 = 1
elif (empfangen == "SENSOR_DEF"):
print("Auswertung: Sensor Defekt")
os.system("/home/pi/tg/send_script P*** 'Sensor
sendet Sensor Defekt' ") sende_Val = 0
p3 = 1
elif (empfangen == "__ERROR___"):
print("Auswertung: Messung Error")
os.system("/home/pi/tg/send_script P*** 'Sensor
ERROR' ") sende_Val = 0
p3 = 1
# Vorgarten
elif (empfangen == "VG_VAL_LOW"):
print("Auswertung: Vorgarten Val LOW")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Val Low' ") sende_Val = 0
elif (empfangen == "VG_NASS___"):
print("Auswertung: Vorgarten Nass")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Nass' ") sende_Val = 0
elif (empfangen == "VG_FEUCHT_"):
print("Auswertung: Vorgarten Feucht")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Feucht' ") sende_Val = 0
elif (empfangen == "VG_TROCKEN"):
print("Auswertung: Vorgarten Trocken")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Trocken' ") sende_Val = 0
elif (empfangen == "VG_SENSOR_"):
print("Auswertung: Vorgarten Sensor Defekt")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Sensor Defekt' ") sende_Val = 0
elif (empfangen == "VG_ERROR__"):
print("Auswertung: Vorgarten Error")
os.system("/home/pi/tg/send_script P***
'Vorgarten sendet Error' ") sende_Val = 0
# Alarmanlage
elif (empfangen == "B002003___"):
print("Alarmanlage ausgelsoest")
os.system("/home/pi/tg/send_script P***
'Alarmanlage ausgeloest' ") sende_Val = 0
elif (empfangen == "B002001___"):
print("Alarmanlage ein")
os.system("/home/pi/tg/send_script P***
'Alarmanlage eingeschaltet' ") sende_Val = 0
elif (empfangen == "B002002___"):
print("Alarmanlage aus")
os.system("/home/pi/tg/send_script P***
'Alarmanlage ausgeschaltet' ") sende_Val = 0
# Magnetventil
if (empfangen == "TROCKEN___" and err_1 == 0):
if (zeit.tm_hour == sch_h and zeit.tm_min == sch_m):
print("Es ist: {2}".format(sch_h, sch_m, time.strftime( "%H:%M",zeit)) ) if (send_now == 0 and p3 == 1):
code = A1_magnet
send_now = 1
os.system("/home/pi/tg/send_script P*** 'Es wird gegossen wenn das Signal ertoent' ") print("next Code: ", code)
p3 = 0
if ( (zeit.tm_hour == 10 and zeit.tm_min == 26) and send_now == 0
and err_2 == 0): code = A2_hier
send_now = 1
print("next Code: ", code)
p1 = 0
Alles anzeigen
Nano:
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
//
// Hardware configuration
//
// Set up nRF24L01 radio on SPI bus plus pins 7 & 8
RF24 radio(7,8);
//
// Topology
//
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
//
// Variabelen
//
// Alarmanlage
int statusPin = 2; // Pin auf dem der Status abgelegt ist
int alarmPin = 3; // Pin auf dem der Status Alarmausgelöst abgelegt ist
int M_status = 0; // Merker auf dem der Status gespeichert ist
int M_alarm = 0; // Merker auf dem der Alarm gespeichert ist
int M_send = 0; // Merker welcher code gesendet werden soll
int alarmState = 0;
int statusState = 0;
// Allgemein
int radio_Val = "12345";
int payload_size = 10; // Übertragungsgröße
int CYempf = 0;
int send_err_cound = 0; // Zähler wie viele Send Errors waren
int send_now = 0; // Aktiv wenn gesendet werden soll
// Befehle
String A2_Status_ein = "B002001";
String A2_Status_aus = "B002002";
String A2_Alarm = "B002003";
String A2_Hier = "B002004";
int init_status = LOW;
//
// Role management
int roleVAR = LOW;
// The various roles supported by this sketch
typedef enum { role_ping_out = 1, role_pong_back } role_e;
// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
// The role of the current running sketch
role_e role;
//
// Payload
//
char receive_payload[32+1]; // +1 to allow room for a terminating NULL char
char send_new_payload[32+1];
void setup(void)
{
//
// Print preamble
//
Serial.begin(115200);
// Serial.println(F("RF24/examples/pingpair_dyn/"));
Serial.print(F("setup ROLE: "));
Serial.println(role_friendly_name[role]);
//
// I/Os
//
pinMode(statusPin, INPUT);
pinMode(alarmPin, INPUT);
//
// Setup and configure rf radio
//
radio.begin();
// enable dynamic payloads
radio.enableDynamicPayloads();
// optionally, increase the delay between retries & # of retries
radio.setRetries(5,15);
}
void loop(void)
{
//
// Role
//
// read the roleVAR, establish our role
if ( roleVAR ){
role = role_ping_out;
}
else{
role = role_pong_back;
}
//
// Open pipes to other nodes for communication
//
// This simple sketch opens two pipes for these two nodes to communicate
// back and forth.
// Open 'our' pipe for writing
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
if ( role == role_ping_out )
{
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
}
else
{
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]);
}
//
// Start listening
//
radio.startListening();
//
// Sender Teil
// Ping out role. Repeatedly send the current time
//
if (role == role_ping_out)
{
// First, stop listening so we can talk.
radio.stopListening();
// Take the time, and send it. This will block until complete
// Hier muss alles rein was gesendet werden soll!
if (M_send == 1) {
radio_Val = "B002001___";
}
else if (M_send == 2) {
radio_Val = "B002002___";
}
else if (M_send == 3) {
radio_Val = "B002003___";
}
else {
radio_Val = "__ERROR___";
}
Serial.print(F("Now sending ... "));
Serial.println(radio_Val);
radio.write( radio_Val, payload_size );
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 10000 )
timeout = true;
// Describe the results
if ( timeout )
{
Serial.println(F("Failed, response timed out."));
send_err_cound += 1;
}
else
{
// Grab the response, compare, and send to debugging spew
uint8_t len = radio.getDynamicPayloadSize();
// If a corrupt dynamic payload is received, it will be flushed
if(!len){
return;
}
radio.read( send_new_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
Serial.print(F("Got response size= "));
Serial.print(len);
Serial.print(F(" value= "));
Serial.println(send_new_payload);
send_err_cound = 0;
send_now = 0;
}
if (send_err_cound >= 5){
Serial.print(" Fehlerhafte übertragungen: ");
Serial.println(send_err_cound);
send_now = 0;
send_err_cound = 0;
}
else {
}
}
//
// Empfaenger teil
// Pong back role. Receive each packet, dump it out, and send it back
//
if ( role == role_pong_back )
{
// if there is data ready
while ( radio.available() )
{
// Fetch the payload, and see if this was the last one.
uint8_t len = radio.getDynamicPayloadSize();
// If a corrupt dynamic payload is received, it will be flushed
if(!len){
continue;
}
radio.read( receive_payload, len );
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
Serial.print(F("recived size= "));
Serial.print(len);
Serial.print(F(" value= "));
Serial.println(receive_payload);
//
// HIER SIND DIE AUSFÜHRUNGEN:
//
// Es wird nur geantwortet, wenn der Code auch von diesem Gerät bearbeitet werden sollte, sonst nicht
// Einfach Prüfen ob der Sensor da ist
if (A2_Hier.equals(String(receive_payload))) {
// First, stop listening so we can talk
radio.stopListening();
// Send the final one back.
radio.write( receive_payload, len );
Serial.println(F("Sent response."));
// Now, resume listening so we catch the next packets.
radio.startListening();
}
}
}
// Rollen wechsel
if ( roleVAR ){
Serial.println(" -- awaiting transmission -- ");
roleVAR = LOW;
delay(500);
} else {
if ( send_now == 1 ){
Serial.println(" -- sending transmission -- ");
roleVAR = HIGH;
delay(500);
CYempf = 0;
}
}
//
// Normales Programm
//
alarmState = digitalRead(alarmPin);
statusState = digitalRead(statusPin);
if (alarmState == HIGH and M_alarm == 0) {
M_send = 3;
M_alarm = 1;
Serial.println("Alarm ausgeloest");
send_now = 1;
}
else if (alarmState == LOW and M_alarm == 1) {
M_alarm = 0;
}
else if (statusState == HIGH and M_status == 0) {
M_send = 1;
M_status = 1;
Serial.println("Status Alarm ein");
send_now = 1;
}
else if (statusState == LOW and M_status == 1) {
M_send = 2;
M_status = 0;
Serial.println("Status Alarm aus");
send_now = 1;
}
}
// vim:cin:ai:sts=2 sw=2 ft=cpp
Alles anzeigen