我无法使NRF24L01通信(对许多arduinos来说都是树莓派)持续工作

时间:2019-09-02 08:40:39

标签: django arduino raspberry-pi celery serial-communication

我正在使用主从协议和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);

}

我希望每次都可以使用它,以便它不会显示“超时”。

0 个答案:

没有答案