Как использовать передатчик и приемник для условной отправки строковых сообщений получателю?
Я работаю над проектом по созданию монитора растений, который работает снаружи с помощью 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 и ареометра. значения воды и света и отправляет их на подчиненный микроконтроллер-приемник, проводка правильная.
Подчиненный (приемник) обрабатывает значения от передатчика и печатает их на последовательном мониторе. Получаемое им сообщение будет зависеть от таких условий, как пороговые значения освещенности и пороговые значения значений воды, проще говоря, если значения света или воды превышают определенное значение. или ниже определенного значения, для каждой ситуации будет отправляться разное сообщение.
@Mario Ronci, 👍3
Обсуждение1 ответ
Я разобрался с проблемой.
Код был беспорядочным, но после некоторого устранения неполадок операторы if не имели смысла, не имели хорошего потока и были слишком сложными. Я скопировал и вставил некоторый код, не разобравшись в нем.
Это сработало, когда я сосредоточился на одном компоненте, как сказал @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);
}
результат:
Видео
- Как автоматически сбросить nrf24l01+ с кодом?
- Как я могу прервать задержку() при нажатии кнопки?
- Новый код приводит к звуковому шуму
- Печать string and integer LCD
- Как преобразовать строку в массив байтов
- вопрос по трубке nRF24L01
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
на данный момент ваш пост эквивалентен "Мне нужна помощь в постройке автомобиля"... пожалуйста, сосредоточьтесь только на одной проблеме... начните со канала связи... забудьте все о светодиодах, воде и растениях... сосредоточьтесь на отправке одного байта между двумя устройствами, не более того, @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.