Проблемы с передачей данных через RF24

У меня есть три RF24, все они подключены к одному arduino-uno каждый. У первого есть датчики, которые передают данные второму, а второй передает их третьему. Первый переход с RF24 #1 на RF24 #2 прошел успешно, но с RF24 #2 на RF24 #3, похоже, возникла проблема.

Код для RF24 #1 (я только что скопировал настройку и зациклил другие функции для датчиков, я думаю, что в этом нет необходимости):

//Libraries for temperature
#include <OneWire.h>
#include <DallasTemperature.h>
#define motor1 8
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

//for pH meter
#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;

//for NRF24L01
RF24 radio(7, 8); // CE, CSN
const uint64_t waddress = 0xB00B1E50D2LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;
int LID = 4, LOD = 6;

//for ultrasonic
const int trigPin = 3;
const int echoPin = 4;
long duration, inches, cm, meter;


void setup(void)
{
  // start serial port
  radio.begin();
  radio.openWritingPipe(waddress);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();

  pinMode(LED, OUTPUT);
  // Start up the library
  sensors.begin();
}

/*
   Main function, get and show the temperature
*/


void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue, voltage;
  if (millis() - samplingTime > samplingInterval)
  {
    pHArray[pHArrayIndex++] = analogRead(SensorPin);
    if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
    voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
    pHValue = 3.5 * voltage + Offset;
    samplingTime = millis();
  }
  if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    digitalWrite(LED, digitalRead(LED) ^ 1);
    // call sensors.requestTemperatures() to issue a global temperature
    // request to all devices on the bus

    sensors.requestTemperatures(); // Send the command to get temperatures

    // After we got the temperatures, we can print them here.
    // We use the function ByIndex, and as an example get the temperature from the first sensor only.

    //Serial.print(pHValue,2);
    //Serial.print(",");
    //Serial.print(sensors.getTempCByIndex(0));

    radio.write(&data, sizeof(data));

    data.ph = (pHValue);
    data.temperature = (sensors.getTempCByIndex(0));
    Serial.print(data.ph);
    Serial.print(data.temperature);
    Serial.print(data.Do);
  }
}

RF24 #2

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const uint64_t raddress = 0xB00B1E50D2LL;
const uint64_t waddress = 0xB00B1E50B1LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;


void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(waddress);
  radio.openReadingPipe(1, raddress);
  radio.setPALevel(RF24_PA_MIN);
}


void loop() {
  radio.startListening();

  while (radio.available()) {
    radio.read(&data, sizeof(data));
    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
  }
  if (radio.write(&data, sizeof(data))) {
    Serial.println(" delivery failed");
  }
  radio.stopListening();
  delay(200);
}

RF24 #3

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int lid = 2 , lod = 4;
RF24 radio(7, 8); // CE, CSN
const uint64_t raddress = 0xB00B1E50B1LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;


void setup() {
  Serial.begin(9600);

  radio.begin();
  radio.openReadingPipe(2, raddress);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  pinMode(lid, OUTPUT);
  pinMode(lod, OUTPUT);
}


void loop() {
  unsigned long startTimer = millis();
  bool timeout = false;

  while (!radio.available() && !timeout) {
    if (millis() - startTimer > 500 )
    {
      timeout = true;
    }
    // radio.read(&temperature, sizeof(temperature));
    //radio.read(&Do, sizeof(Do));
  }
  if (timeout) {
    Serial.println("Failed to receive data");
  }
  else {
    radio.read(&data, sizeof(data));

    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
  }
}

Последовательный монитор для RF24 #2 отображает:

 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
6.92,28.25,7.20,15.00,38.00
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
6.91,28.25,7.20,15.00,38.00

Последовательный монитор RF24 #3:

0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00

Иногда RF24 #3 получает данные и печатает их непрерывно. Я не знаю, почему. Большую часть времени он отображает вышесказанное.

Изменить: Редакция

Обновление: Оказывается, RF24 #3 продолжает печатать, даже если RF24 #2 отключен/не включен.

, 👍0


1 ответ


0

Вы всегда должны вызывать stopListening() прямо перед тем, как писать(). Также функция write() возвращает значение true при доставке сообщений, поэтому ваше условие неверно. Попробуйте изменить loop() во втором узле на:

void loop() {   
  while (radio.available()) {
    radio.read(&data, sizeof(data));
    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);

    radio.stopListening();
    if (!radio.write(&data, sizeof(data))) {
      Serial.println("Delivery failed");
    }
    radio.startListening();
  }
}

Если пакет доступен, он считывается, распечатывается и пересылается. Цикл третьего узла() также должен быть настроен на что-то вроде:

bool new_data = false;

void loop() {
  if (radio.available()) {
    radio.read(&data, sizeof(data));

    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
    new_data = true;
  }
  if (new_data) {
    // do stuff
    new_data = false;
  }
}

Данные отправляются в 32-байтовой полезной нагрузке, и весь ваш пакет составляет 20 байт (без заполнения), при условии, что значение с плавающей точкой = 4 байта. Таким образом, полный пакет либо прибыл, либо нет; нет смысла ждать в одном месте. new_data позволяет вам знать, когда появляются новые данные, очевидно, и вы снимаете флаг, когда закончите обработку данных. Таким образом, вы можете делать другие вещи, пока ждете, пока появится пакет.

,