Добавление nRF24L01 в проект
У меня есть проект уровня жидкости, который в настоящее время использует Oled-дисплей. Я только что обнаружил существование модуля беспроводной связи nRF24L01, и это именно то, что мне нужно, чтобы сделать мой проект более удобным для пользователя.
В конце концов, я хочу иметь приборную панель, которая объединяет всю мою информацию в одном месте, но пока я просто хочу выяснить, как получить передачу моего проекта уровня жидкости, а также получить данные на другом Arduino и просмотреть их на последовательном мониторе. Как и все, что он делает, это распечатывает "?" на последовательном мониторе.
У меня есть этот скетч на уровне жидкости проекта Arduino:
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
SSD1306AsciiAvrI2c oled;
#define I2C_ADDRESS 0x3C
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
double SensorAnalogValue;
uint8_t calculation=1;
String Show_value;
//create an RF24 object
RF24 radio(9, 8); // CE, CSN
//address through which two modules communicate.
const byte address[6] = "00001";
void setup()
{
Serial.begin(9600);
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.setFont(CalLite24);
oled.clear();
radio.begin();
//set the address
radio.openWritingPipe(address);
//Set module as transmitter
radio.stopListening();
}
void loop()
{
SensorAnalogValue = analogRead(A0) * 5.0 / 1023.0;
if (SensorAnalogValue < 1.726) {
calculation=0;
Show_value="Low";
}
if (SensorAnalogValue > 4.04) {
calculation=0;
Show_value="High";
}
if(calculation!=0){
// Serial.println(SensorAnalogValue);
Show_value=(String)Liquid_Volume(SensorAnalogValue);
}
Serial.println(SensorAnalogValue);
oled.setCursor(20, 0);
oled.print(Show_value);
oled.print(" L");
oled.println(" ");
oled.print(Show_value);
oled.print("L");
oled.println(" ");
delay(500);
oled.clear();
radio.write(&Show_value, sizeof(Show_value));
delay(1000);
calculation=1;
}
int Liquid_Volume(double Volt) {
double A = 2.81842;
double B = -11.00151 ;
double C = 14.4765 ;
double D = 28.73579 ;
return A * Volt * Volt * Volt + B * Volt * Volt + C * Volt + D;
}
А в Приемнике есть вот что:
//Include Libraries
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//create an RF24 object
RF24 radio(9, 8); // CE, CSN
//address through which two modules communicate.
const byte address[6] = "00001";
void setup()
{
while (!Serial);
Serial.begin(9600);
radio.begin();
//set the address
radio.openReadingPipe(0, address);
//Set module as receiver
radio.startListening();
}
void loop()
{
//Read the data if available in buffer
if (radio.available())
{
char Show_value[32] = {0};
radio.read(&Show_value, sizeof(Show_value));
Serial.println(Show_value);
}
}
Я думаю, что проблема заключается в следующем:
radio.write(&Show_value, sizeof(Show_value));
Я считаю, что "radio.write" используется вроде как Serial.print или oled.print, но я действительно не понимаю часть "sizeof", может быть, в этом и проблема?
@SV Savannah, 👍0
1 ответ
radio.write(&Show_value, sizeof(Show_value));
Я считаю, что "radio.write" используется как Serial.print или oled.print, но я действительно не понимаю часть "sizeof", может быть, в этом проблема?
Вроде того. Есть две взаимосвязанные проблемы. Главный из них заключается в том, что фактические данные строки
не содержатся с самим фактическим строковым
типом. Он распределяется в куче. Класс String содержит указатель на него и некоторые числа для отслеживания выделенного размера и используемой суммы.
Итак, первая проблема заключается в том, что вы не читаете память, которая на самом деле содержит текст внутри строки.
sizeof(Show_value)
вычисляет размер в байтах самого класса String, который представляет собой размер указателя и пары целых чисел, около 6 байт, а не размер содержимого строки.
Таким образом, вы посылаете указатель (адрес памяти), с которым получатель не знает, что делать, и некоторую информацию о том, сколько было выделено и использовано, но ничего о содержимом строки.
Попробуйте:
radio.write(Show_value.c_str(), Show_value.length());
функция .c_str()
возвращает указатель на само фактическое содержимое строки. А .length ()
- это фактический размер используемой части выделенной области строки
в куче.
Тем не менее, лучше избегать String
там, где это разумно возможно.
Что касается:
Означает ли это также, что мне нужно
заменить radio.read(&Show_value, sizeof(Show_value));
Так и будет. Сделать это немного сложнее, так как .c_str()
дает const char *
; String
не предназначен для того, чтобы сделать доступ для записи к своим базовым данным таким простым.
Не взламывая свой путь вокруг ожиданий String
, это потребовало бы использования временного буфера. Что-то вроде:
char buffer[33] = ""; // Примечание: это фактически заполнит весь буфер '\0', что некоторых удивляет.
// Идея вышеизложенного состоит в том, чтобы вместить максимальный размер пакета RH24L01 в 32 байта плюс место для нулевого терминатора.
radio.read(buffer, sizeof buffer - 1); /// Мы делаем доступным только 32-байтовый фрагмент для вызова .read() и оставляем последний байт для его значения '\0', чтобы в любом случае принудительно завершить нулевое завершение
String s = buffer;
Это предполагает, что вы либо заполняете пакет байтами, либо включаете в него нулевой терминатор, либо и то, и другое. Если вы используете динамический размер полезной нагрузки, а не инициализируете массив с помощью = "";
, то его можно оставить неинициализированным, а полученный размер пакета можно использовать для размещения нулевого терминатора в нужном месте.
Вы можете обернуть это в функцию, если планируете делать это часто. Но опять же, вероятно, будет лучше, если вы сможете просто использовать массив и не работать со строкой
.
- вопрос по трубке nRF24L01
- Как подключить NodeMCU к NRF24L01
- Переключение каналов NRF24l01
- Использование функции уровня сигнала модуля nRF24L01
- Как автоматически сбросить nrf24l01+ с кодом?
- NRF24L01+ PA не работает с Arduino Mega (работает с Nano)
- Пустое значение не игнорируется, как должно быть.
- Не получаем данные от NRF24L01
Спасибо timemage, Означает ли это также, что мне нужно заменить radio.read (и значение Show_, значение размера(Значение Show_)); С: radio.read(Значение шоу.c_str(), Значение шоу.длина()); В скетче получения?, @SV Savannah
Я обновил, чтобы попытаться решить эту проблему, которая более или менее соответствует "да" первой части, "нет" второй. Я собираюсь немного закончить, так что это написано наспех, но должно придать ответу некоторую форму. Вашей второй части приведенного выше комментария не существовало, когда я начал обновлять вопрос., @timemage
Я упустил тот факт, что вы уже более или менее делаете вышеописанное в отношении наличия буфера и его заполнения, просто не добавляя дополнительное пространство байтов или не присваивая его "Строке". Если единственное, что вы делаете со строкой, - это отправляете ее через "Serial", вы можете переключиться с "println ()" на использование "write ()" с аргументом size, установленным на правильный номер, и в этом случае вам вообще не нужно завершать., @timemage