Как использовать передатчик и приемник для условной отправки строковых сообщений получателю?

Я работаю над проектом по созданию монитора растений, который работает снаружи с помощью Arduino, который собирает значения света и воды из окружающей среды, а затем использует nRF24L01 с антенной, и я столкнулся с препятствием в коде. с использованием передатчика и приемника, полный код приведен ниже.

Будем благодарны за любую помощь, я несколько недель пытался разобраться в этом.

Код передатчика

/*
 * NAME: <Mario Ronci>
 * Healthy Plant Monitor  V2  T 
 * 
 * 
 */

 //** **/
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
//создаем объект RF24
RF24 radio(9, 8);  // CE, ДНС

//адрес, по которому общаются два модуля.
const byte address[6] = "00001";


int ldrValue;
int sensorPin = A0;    // выбираем входной контакт для компаратора воды
int sensorValue = 0;
int light_threshold = 650;
int water_threshold = 850;
String dark_message = " ALERT:Plant is Dark!";
String bright_message =" Brightness Achieved! ";
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";
//String Engineeringinfo = "Марио Рончи 2023";


void setup() {

  pinMode(LDR, INPUT);
  pinMode(POT, INPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  Serial.begin(9600);
  Serial.println(engineerinfo);
  // поместите сюда свой код установки для однократного запуска:
radio.begin();
  //устанавливаем адрес
  radio.openWritingPipe(address);
  //Установим модуль как передатчик
  radio.stopListening();


}

//Проверяет, получает ли растение достаточно света,//
//принимая приемлемое или неприемлемое значение освещенности
//из LDR и печатаем значение на последовательный монитор
//и если значение освещенности приемлемо

void ldrCheck(int device, int duration1,int duration2){

ldrValue = analogRead(device);

if(ldrValue >= light_threshold)

{
  messageLight = light_message + String(ldrValue);
  sendByteMessage(); // Вызов функции для отправки байтового сообщения
   delay(duration1);//Подождите некоторое время перед отправкой следующего сообщения

  
}

if(ldrValue < light_threshold){
  messageLight = dark_message + String(ldrValue)
  byte messageBytes[message.length() + 1]; // Создаем массив байтов для хранения сообщения
  delay(duration2);
}

void sendByteMessage() {
  byte messageBytes[message.length() + 1]; // Создаем массив байтов для хранения сообщения

  // Преобразуем строковое сообщение в массив байтов
  message.getBytes(messageBytes, message.length() + 1);

  // Отправляем массив байтов через передатчик
  radio.write(&messageBytes, sizeof(messageBytes));
}

}

////Проверяет, получает ли растение достаточно воды,//
//приняв приемлемое или неприемлемое значение гидратации
//из LDR и печатаем значение на последовательный монитор
//и если значение гидратации приемлемое, загорится желтый светодиод
//и моргаем, если нет, то будет выведено сообщение на последовательный монитор
//чтобы предупредить вас



//********* Примечание: замените POT на код ареометра **********//
void potCheck(int device,int duration3){

potValue = analogRead(device2);

if(potValue > water_threshold)
{
  Serial.print(potValue);
  Serial.println(water_message1);
  

}

else{
  Serial.println(water_message2);
    
}

}

//Проверяет, получает ли растение достаточно воды и света
//, если это не так, он выведет сообщение на последовательный монитор
//чтобы предупредить вас, и если его будет достаточно, он напечатает
//сообщение на последовательный монитор о том, что растение здоровое

void healthyCheck(int led_4,int duration4,int duration5){

if((ldrValue >= light_threshold) && (potValue > water_threshold)){
digitalWrite(led_4, HIGH);
Serial.println(healthy_message);
delay(duration4);
}

else{
digitalWrite(led_4,HIGH);
delay(duration5);
digitalWrite(led_4,LOW);
delay(duration5);
Serial.println(unhealthy_message);

}


}



void loop(){

//Это вызывает функцию/метод

//передатчик вызова в цикле


ldrCheck(LDR, 1000,100 );
sendByteMessage(LDR)
potCheck();
healthyCheck(2000,800);


}




Код получателя

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>


//Создаем объект RF24

RF24 radio(9,8) ; //CE,ДНС

//адрес, по которому общаются два модуля.

const byte address[6]  = "00001";

void setup() {

while(!Serial);
 Serial.begin(9600);

 radio.begin();

 //устанавливаем адрес
 radio.openReadingPipe(0, address);

 //устанавливаем модуль как получатель
 radio.startListening();
  
}

void loop() {
  //Читаем данные, если они доступны в буфере
  
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.print(ldrValue);
    Serial.println(light_message);
  }

В чем конкретно вам нужна помощь?

Я пытаюсь изменить исходный код для работы с функциями передатчика и приемника. раньше у меня был код, в котором использовались светодиоды, что означало, что монитор установки включал определенные цветные светодиоды в зависимости от состояния. Теперь во второй версии этого проекта я решил покончить со светодиодами и поставить перед собой цель обеспечить связь между компонентами извне для отправки сообщения о состоянии установки внутри, где другой Arduino будет печатать на последовательный монитор

Мне нужна помощь в том, чтобы код передатчика работал с условными операторами. Я не понимаю, куда вставить каждый фрагмент кода, чтобы передатчик отправлял сообщение приемнику и печатал его на последовательном мониторе. Он должен работать как компоненты принимают входные данные из среды, например ldr, затем это значение сохраняется и применяется к if statment, если x является этим значением, то отправляется это сообщение, а затем передатчик отправляет сообщение получателю, который печатает его на последовательном мониторе

Что вы пробовали?

Я попытался создать отдельную переменную для сообщения, которое хочу отправить вместе со значениями аналогового датчика от ldr. (Я еще не добрался до ареометра, я только подключил к нему проводку) Поверните ldr из int в строку, а затем вызовите переменную в функции байтового сообщения внутри функции для проверки значений ldr. Затем в коде приемника я попробовал протестировать, написав Serial Print для каждого значения, но это не работает, и я думаю, это потому, что значение выходит за рамки. Не в том же скетче.

В чем, по вашему мнению, проблема?

Я думаю, что это может быть порядок кода и/или синтаксис, возможно, если я помещу код передатчика вне функции проверки ldr, это сработает, но я не уверен. Возможно также, что типы данных представляют собой строки и целые числа, и изменить их на байты не так просто, как я думал.

Фактическая сборка и компоненты

Мастер (передатчик) получает входные данные из окружающей среды с помощью LDR и ареометра. значения воды и света и отправляет их на подчиненный микроконтроллер-приемник, проводка правильная.

Подчиненный (приемник) обрабатывает значения от передатчика и печатает их на последовательном мониторе. Получаемое им сообщение будет зависеть от таких условий, как пороговые значения освещенности и пороговые значения значений воды, проще говоря, если значения света или воды превышают определенное значение. или ниже определенного значения, для каждой ситуации будет отправляться разное сообщение.

, 👍3

Обсуждение

на данный момент ваш пост эквивалентен "Мне нужна помощь в постройке автомобиля"... пожалуйста, сосредоточьтесь только на одной проблеме... начните со канала связи... забудьте все о светодиодах, воде и растениях... сосредоточьтесь на отправке одного байта между двумя устройствами, не более того, @jsotola

Хорошо, я понял, что нужно работать шаг за шагом. Но я уже мог отправить сообщение на трансивер и распечатать его на последовательном мониторе, но когда я добавил код, в котором я добавил условные операторы if, он развалился. Это моя проблема: могу ли я отправить сообщение, используя условные обозначения?, @Mario Ronci

у вас беспорядок в коде... он не отформатирован должным образом... кажется, есть лишние фигурные скобки, но это не сразу бросается в глаза... сделайте себе одолжение и отформатируйте свой код, а затем проверьте его... правильно отформатированный код выглядит примерно так... https://www.programiz.com/cpp-programming/examples/vowel-consonant- Frequency-string ... например, невозможно угадать, какой код выполняется при выполнении оператора if ... вы никогда не должны видеть две последовательные закрывающие скобки на одинаковом уровне отступа, как в вашем коде, @jsotola

Я бы реструктурировал код. Сторона передатчика должна регулярно собирать данные из окружающей среды (значение света, значение воды, другие значения для здоровья) и объединять эти элементы необработанных данных в одно форматированное сообщение (структуру C++) для передачи. Получатель, получив такое сообщение, распаковывает его, интерпретирует и генерирует какие-либо сообщения на дисплее и т. д. Это соответствует вашему текстовому описанию рядом с картинками, но не вашему коду. Кстати, откуда в приемнике берутся значения ldrValue и light_message?, @6v6gt

Используйте Ctrl+T в IDE, чтобы попытаться лучше отформатировать код. (Меню «Инструменты» -> «Автоформат»)., @Nick Gammon

Говорите, радиочасть работает? Но когда вы добавляете «условный» код, этого не происходит? Что я делаю со своими удаленными радиоустройствами с батарейным питанием, так это всегда отправляю «безусловное» сообщение и использую его как «сердцебиение». Чтобы определить, разряжена ли батарея дистанционного передатчика. Не устанавливайте это слишком часто, если вы используете батареи, так как это приведет к их дополнительному разряду. Но для тестирования просто временно добавьте отправку в функцию LOOP., @st2000

@MarioRonci, можешь ли ты выделить, о каких конкретно условных утверждениях ты говоришь?, @Nick S.


1 ответ


3

Я разобрался с проблемой.

  1. Код был беспорядочным, но после некоторого устранения неполадок операторы if не имели смысла, не имели хорошего потока и были слишком сложными. Я скопировал и вставил некоторый код, не разобравшись в нем.

  2. Это сработало, когда я сосредоточился на одном компоненте, как сказал @jstola. Только фоторезистор, поэтому главное — добавить условие, затем превратить строку в байтовое сообщение, а затем цикл void отправляет байтовое сообщение получателю Arduino. Затем в следующей части на последовательном мониторе появились символы, и это было странно. Поэтому я поэкспериментировал с типом данных char вместо строки и сработал. Также используйте Chatgpt для получения помощи по синтаксису.

Теперь у меня есть база для работы. Итак, следующий шаг — заняться ареометром.

Код передатчика — только с фоторезистором

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Создаем экземпляр объекта RF24

const byte address[6] = "00001"; // Устанавливаем адрес канала

int ldrValue;
int sensorPin = A2;    // Выбираем входной контакт для LDR
int light_threshold = 650;
String light_message = "Plant has enough light :";
String dark_message ="Alert: Plant is Dark! :" ;
String water_message1 = " Plant has enough water.";
String water_message2 = " Need Water...!";
String healthy_message = "Plant is Healthy!";
String unhealthy_message = "Unhealthy...!";


void setup() {
  
  pinMode(sensorPin, INPUT);
  radio.begin();
  radio.openWritingPipe(address);
  radio.stopListening();

}

void loop() {
  ldrCheck(sensorPin, 1000, 100);
}

void ldrCheck(int device, int duration1, int duration2) {
  ldrValue = analogRead(device);

  if (ldrValue >= light_threshold) {
    String message = light_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration1);
  }
  else {
    String message = dark_message + String(ldrValue);
    sendByteMessage(message);
    delay(duration2);
  }
}

void sendByteMessage(String message) {
  byte messageBytes[message.length() + 1];
  message.getBytes(messageBytes, message.length() + 1);
  radio.write(&messageBytes, sizeof(messageBytes));
}  

Код приемника - только с фоторезистором

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(9, 8); // Создаём экземпляр объекта RF24

byte address[6] = "00001"; // Устанавливаем адрес канала

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, address);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    char message[32] = ""; // Создаем массив символов для хранения сообщения
    radio.read(&message, sizeof(message));
    processMessage(message);
  }
}

void processMessage(char* message) {
  String receivedMessage = String(message); // Преобразуем массив символов в строку
  Serial.println(receivedMessage);
  delay(1000);
}


результат:

Видео

,