我正在使用主从协议和NRF24L01模块进行Raspberry Pi与Arduino的通信。在我的情况下,Raspberry Pi是主机,它通过特定管道(十六进制地址)请求网络中一个Arduino的无线电响应。我还在项目中使用Django和Celery,所以我写了一个celery @task来收集Arduino的响应信息。我的问题是,在大多数情况下,当我为了与另一个Arduino交谈而更换管道时,Arduino不会感觉到无线电信号,因此RPi的请求只是超时了。我敢打赌,接收完信息后,我不会在@task中正确“清理”连接。我尝试了许多不同的方法,但都没有成功。任何帮助表示赞赏。
我以为也许与我的任务和GPIO.cleanup()函数有关,但这并不能解决我的问题。我已经一遍又一遍地测试,看看是否可以弥补失去连接的情况,但是我没有成功。我还看到有时Arduino甚至无法从Raspberry Pi接收无线电信号。
tasks.py:
# ============== CELERY ================
from __future__ import absolute_import, unicode_literals
from celery import task
# ============== RADIO =================
import RPi.GPIO as GPIO
from .lib_nrf24 import NRF24
import spidev
# ============== OTHER =================
import datetime
import time
from .models import *
def convert_hex(addr):
hex_addr = int(addr, 16)
return hex_addr
@task
def send_radio(sensor_name, action):
GPIO.setmode(GPIO.BCM)
sensor = Sensor.objects.get(name=sensor_name)
reading_pipe = list(map(convert_hex, sensor.writing_pipe.split("/")))
writing_pipe = list(map(convert_hex, sensor.reading_pipe.split("/")))
pipes = [writing_pipe, reading_pipe]
radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 17)
radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MAX)
radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()
radio.printDetails()
radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])
if action == 'request':
message = list(sensor_name + '/' + "request")
while len(message) < 32:
message.append(0)
start = time.time()
radio.write(message)
radio.startListening()
sensor = Sensor.objects.get(name=sensor_name)
plant = Plant.objects.get(sensor=sensor)
while not radio.available(0):
time.sleep(1 / 100)
if time.time() - start > 5:
print("Timed out.")
sensor.timeout = True
sensor.save()
break
receivedMessage = []
radio.read(receivedMessage, radio.getDynamicPayloadSize())
string = ""
radio.stopListening()
for n in receivedMessage:
if (n >= 32 and n <= 126):
string += chr(n)
arr = string.split('/')
print(arr)
GPIO.cleanup()
Arduino代码:
#include<SPI.h>
#include<RF24.h>
#include<stdio.h>
#include<stdlib.h>
String input;
String sensor_name = "sensor_2";
char sensor_na#include<SPI.h>
#include<RF24.h>
#include<stdio.h>
#include<stdlib.h>
String input;
String sensor_name = "sensor_2";
char sensor_name_char[] = "sensor_2/";
String first_value = "";
String second_value = "";
String request = "request";
char hum_soil[100];
char hum_air[100];
char temp[100];
char string_data[200];
// CE, CSN pins
RF24 radio(9, 10);
int umiditatePamant;
int umiditateAer;
int temperaturaAer;
void setup(void){
while(!Serial);
Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(0x76);
radio.openWritingPipe(0xF0F0F0F0E2LL);
const uint64_t pipe = (0xE8E8F0F0E2LL);
radio.openReadingPipe(1, pipe);
radio.enableDynamicPayloads();
radio.powerUp();
}
void loop(void){
radio.startListening();
char receivedMessage[32] = {0};
if(radio.available()){
radio.read(receivedMessage, sizeof(receivedMessage));
String stringMessage(receivedMessage);
radio.stopListening();
input = stringMessage;
for (int i = 0; i < input.length(); i++) {
if (input.substring(i, i+1) == "/") {
first_value = input.substring(0, i);
second_value = input.substring(i+1);
if (first_value == sensor_name){
if (second_value == request){
strcat(string_data, sensor_name_char);
if(radio.write(string_data, sizeof(string_data))){
Serial.println(string_data);
}
else{
Serial.println("Failed");
}
memset(string_data, 0, 200);
}
}
break;
}
}
}
delay(100);
}me_char[] = "sensor_2/";
String first_value = "";
String second_value = "";
String request = "request";
char hum_soil[100];
char hum_air[100];
char temp[100];
char string_data[200];
// CE, CSN pins
RF24 radio(9, 10);
int umiditatePamant;
int umiditateAer;
int temperaturaAer;
void setup(void){
while(!Serial);
Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(0x76);
radio.openWritingPipe(0xF0F0F0F0E2LL);
const uint64_t pipe = (0xE8E8F0F0E2LL);
radio.openReadingPipe(1, pipe);
radio.enableDynamicPayloads();
radio.powerUp();
}
void loop(void){
radio.startListening();
char receivedMessage[32] = {0};
if(radio.available()){
radio.read(receivedMessage, sizeof(receivedMessage));
String stringMessage(receivedMessage);
radio.stopListening();
input = stringMessage;
for (int i = 0; i < input.length(); i++) {
if (input.substring(i, i+1) == "/") {
first_value = input.substring(0, i);
second_value = input.substring(i+1);
if (first_value == sensor_name){
if (second_value == request){
strcat(string_data, sensor_name_char);
if(radio.write(string_data, sizeof(string_data))){
Serial.println(string_data);
}
else{
Serial.println("Failed");
}
memset(string_data, 0, 200);
}
}
break;
}
}
}
delay(100);
}
我希望每次都可以使用它,以便它不会显示“超时”。