Передача температуры 18д20 через nRF24L01 с одной промини на другую
- Войдите на сайт для отправки комментариев
Чт, 06/06/2019 - 21:37
Здравтвуйте! В ардуино новичек. Мой второй проект привел меня к багу. Суть проекта - передача температуры 18д20 через nRF24L01 с одной промини на другую. Очень долго не мог решить проблему (замолкания)... пока случайно не продублил одну строчку... С одной строкой radio.write показание появляются на приемнике только 1 раз... С дублированием строки - цикл идет как надо... Помогите, мне страшно
Передатчик:
#include <SPI.h> // библиотека для работы с шиной SPI
#include "nRF24L01.h" // библиотека радиомодуля
#include "RF24.h" // ещё библиотека радиомодуля
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte counter;
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
sensors.begin();
radio.begin(); //активировать модуль
radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток)
radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(32); //размер пакета, в байтах
radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных
radio.setChannel(0x60); //выбираем канал (в котором нет шумов!)
radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
//должна быть одинакова на приёмнике и передатчике!
//при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //начать работу
radio.stopListening(); //не слушаем радиоэфир, мы передатчик
}
void loop() {
delay(4000);
float data[1];
sensors.requestTemperatures();
float temp1 = (float) sensors.getTempCByIndex(0);
data[0] = (float) temp1; // заполняем массив
radio.write(&data, sizeof(data[2]));
radio.write(&data, sizeof(data[2]));
}
Приемник:
#include <SPI.h> // библиотека для работы с шиной SPI
#include "nRF24L01.h" // библиотека радиомодуля
#include "RF24.h" // ещё библиотека радиомодуля
//#include <OneWire.h>
//#include <DallasTemperature.h>
//#define ONE_WIRE_BUS 2
//OneWire oneWire(ONE_WIRE_BUS);
//DallasTemperature sensors(&oneWire);
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte counter;
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
radio.begin(); //активировать модуль
radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0,15); //(время между попыткой достучаться, число попыток)
radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(32); //размер пакета, в байтах
radio.openReadingPipe(1,address[0]); //хотим слушать трубу 0
radio.setChannel(0x60); //выбираем канал (в котором нет шумов!)
radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
//должна быть одинакова на приёмнике и передатчике!
//при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //начать работу
radio.startListening(); //начинаем слушать эфир, мы приёмный модуль
}
void loop() {
float data[1];
if (radio.available())
{ // проверяем не пришло ли чего в буфер.
radio.read(&data, sizeof(data)); // читаем данные и указываем сколько байт читать
Serial.print("Temp: ");
Serial.print(data[0]);
Serial.println(" *C");
}
delay(2000);
}
В приемнике убери 48 стоку . В передатчеке делаете массив из нескольких переменных, а принимаете 1 переменную ? ЗАЧЕМ.
Понимаю, что глупо спрашивать, но почему
floatdata[1], аsizeof(data[2])?floatdata[1] -размер массива, компилятор заложит инструкции, которые выделят память под этот массив. radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакетВопрос был к топикстартеру
#include <SPI.h> // библиотека для работы с шиной SPI #include "nRF24L01.h" // библиотека радиомодуля #include "RF24.h" // ещё библиотека радиомодуля #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); // для Меги byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte counter; void setup() { Serial.begin(9600); //открываем порт для связи с ПК sensors.begin(); radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных radio.setChannel(0x60); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.stopListening(); //не слушаем радиоэфир, мы передатчик } void loop() { delay(4000); float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data)); }В приемнике 48 строку уберите, пусть всегда слушает, а передатчик каждые 4 сек. будет слать температуру.
Сделал все по вашим советам. Приемник выдает значение только при ресете передатчика... цикла нет( может он и есть, но что-то не так)
Передатчик:
#include <SPI.h> // библиотека для работы с шиной SPI #include "nRF24L01.h" // библиотека радиомодуля #include "RF24.h" // ещё библиотека радиомодуля #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); // для Меги byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte counter; void setup() { Serial.begin(9600); //открываем порт для связи с ПК sensors.begin(); radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных radio.setChannel(0x60); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.stopListening(); //не слушаем радиоэфир, мы передатчик } void loop() { delay(4000); float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data)); }Приемник:
#include <SPI.h> // библиотека для работы с шиной SPI #include "nRF24L01.h" // библиотека радиомодуля #include "RF24.h" // ещё библиотека радиомодуля //#include <OneWire.h> //#include <DallasTemperature.h> //#define ONE_WIRE_BUS 2 //OneWire oneWire(ONE_WIRE_BUS); //DallasTemperature sensors(&oneWire); RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); // для Меги byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte counter; void setup() { Serial.begin(9600); //открываем порт для связи с ПК radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0,15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openReadingPipe(1,address[0]); //хотим слушать трубу 0 radio.setChannel(0x60); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.startListening(); //начинаем слушать эфир, мы приёмный модуль } void loop() { float data[1]; if (radio.available()) { // проверяем не пришло ли чего в буфер. radio.read(&data, sizeof(data)); // читаем данные и указываем сколько байт читать Serial.print("Temp: "); Serial.print(data[0]); Serial.println(" *C"); } }Вот так все работает. Цикл пашет. Когда строка продублированна... Иначе - данные прописываются приемником только 1 раз....
#include <SPI.h> // библиотека для работы с шиной SPI #include "nRF24L01.h" // библиотека радиомодуля #include "RF24.h" // ещё библиотека радиомодуля #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); // для Меги byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte counter; void setup() { Serial.begin(9600); //открываем порт для связи с ПК sensors.begin(); radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных radio.setChannel(0x60); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.stopListening(); //не слушаем радиоэфир, мы передатчик } void loop() { delay(4000); float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data)); radio.write(&data, sizeof(data)); }Попробуйте перед отправкой данных сделать задержку 50 мс.
Не сработало... проовал так:
void loop() { delay(4000); float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); data[0] = (float) temp1; // заполняем массив //radio.write(&data, sizeof(data)); delay(50); radio.write(&data, sizeof(data)); }и 10 и 100 мс. Однако вот так работает:
void loop() { delay(4000); float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data)); delay(10); radio.write(&data, sizeof(data)); }Но, опять же, при увелчичении паузы работать перестает(((
На этом канале 0x60 больше не кого нет? Попробуйте перейти на другой.
void loop() { float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); delay(50); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data));}
попробуйте так, дать время для считывания показания, а потом делать массив и отправка.
Ничего не вышло... пересел на 6e канал - тут тоже чисто. Та же ситуация... Приемник прописывает только 1 раз...
#include <SPI.h> // библиотека для работы с шиной SPI #include "nRF24L01.h" // библиотека радиомодуля #include "RF24.h" // ещё библиотека радиомодуля #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); // для Меги byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб byte counter; void setup() { Serial.begin(9600); //открываем порт для связи с ПК sensors.begin(); radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[0]); //мы - труба 0, открываем канал для передачи данных radio.setChannel(0x6e); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.stopListening(); //не слушаем радиоэфир, мы передатчик } void loop() { float data[1]; sensors.requestTemperatures(); float temp1 = (float) sensors.getTempCByIndex(0); delay(50); data[0] = (float) temp1; // заполняем массив radio.write(&data, sizeof(data)); delay(4000);}Питания для НРФ 3.3 вольта берете отдельно не от ардуино?
И ардуинка и НРФ и Датчик питаются от отдельной платы питания 3.3 через конденсатор... Вообще ардуинка 328р 16мгц 5v... но на 3.3 вроде работает...
Ардуино питайте 5 в. не каких 3.3 в. , а НРФ 3.3 в. и отдельно с электролитом еще и керамику ставят. У меня НРФки работают отлично, главно канал чистый найти, питание, ну и с временными задержками тут поигратся надо, если это все отрепетировать то работает четко.
Это нужно логические уровни согласовывать?) Может оставить двойную строку? :D Или лучше все по уму доделать...
NRF24L01 толерантны к 5V TTL (но не по питанию). А по-уму лучше всегда доделывать, да.
2 года назад делал метиостанцию, до сих пор работает.Принцип работы пришло 118 , замеряется с датчиков показания темп. , влажность и атмосф. давление, получается масив из 3 переменных и отправляется.
#include <SPI.h> //библиотека для работы с шиной SPI #include "nRF24L01.h" //библиотека радиомодуля #include "RF24.h" //ещё библиотека радиомодуля #include <dht11.h> #include <Wire.h> #include <BMP085.h> RF24 radio(9,10); //"создать" модуль на пинах 9 и 10 Для Уно //RF24 radio(9,53); //для Меги byte address[][6] = {"1Node","2Node","3Node","4Node","5Node","6Node"}; //возможные номера труб byte massiv[4]; BMP085 dps = BMP085(); long Pressure = 0; dht11 sensor; void setup(){ radio.begin(); //активировать модуль radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл radio.setRetries(0,15); //(время между попыткой достучаться, число попыток) radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал radio.setPayloadSize(32); //размер пакета, в байтах radio.openWritingPipe(address[1]); //мы - труба 1, открываем канал для передачи данных radio.openReadingPipe(1,address[0]); //хотим слушать трубу 0 radio.setChannel(4); //выбираем канал (в котором нет шумов!) radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS //должна быть одинакова на приёмнике и передатчике! //при самой низкой скорости имеем самую высокую чувствительность и дальность!! radio.powerUp(); //начать работу radio.startListening(); //начинаем слушать эфир, мы приёмный модуль Wire.begin(); dps.init(); } void loop() { int data[3]; if(radio.available()>0){ //Принимаем по радио не пришло ли чего в буфер radio.read(massiv, 1); //читаем данные if(massiv[0] == 118){ //если пришло 118 (Какая темп. влажность) // РАБОТА С МЕГА radio.stopListening(); //не слушаем радиоэфир, мы передатчик sensor.read(8); // читаем градусник dps.getPressure(&Pressure); delay(50); data[0] = int(sensor.temperature); // заполняем массив data[1] = int(sensor.humidity); data[2] = int(Pressure/133.3); radio.write(&data, sizeof(data)); // отправляем данные и указываем сколько байт пакет delay(10); } } radio.startListening(); //начинаем слушать эфир, мы приёмный модуль radio.setChannel(4); //выбираем канал (в котором нет шумов!) radio.openReadingPipe(1,address[0]); //хотим слушать трубу 0 }Обратите внимание на временные задержки 50 и 10 мс, без них у меня принимало 1 раз и дальше тишина, типичный Ваш случай. Попробуйте свой код подогнать к этому.
Простите, а как у Вас выглядел приёмник? Пытаюсь разобраться) метод опроса у Вас, как мне кажется, на много энергоэффективнее)
У Вас каждые 4 сек. передатчик отправляет данные, у меня при необходимости, вот кусок кода.
/* РАБОТА С МЕТЕО СТАНЦИЕЙ */ if (val=='D'){ // Какая температура, влажность radio.setChannel(4); //выбираем канал (в котором нет шумов!) radio.stopListening(); //не слушаем радиоэфир, мы передатчик delay(50); massiv[0] = 118; radio.write(massiv, 1); //передаем 118 (Какая температура, влажность) radio.startListening(); //начинаем слушать эфир, мы приёмный модуль radio.openReadingPipe(0,address[1]); //хотим слушать трубу 1 delay(100); if(!radio.available()>0){ //если получаем пустой ответ Serial.println("HHHHH"); //отправляем в порт } else{ while(radio.available()){ // если в ответе что-то есть radio.read(&data, sizeof(data)); // читаем данные и указываем сколько байт читать Serial.print("Humidity:"); Serial.print(data[1]); Serial.print(" "); Serial.print("Temperature:"); Serial.print(data[0]); Serial.print(" "); Serial.print("Pressure:"); Serial.println(data[2]); } } radio.printDetails(); //перезагрузка nRF24 delay(50); radio.setChannel(115); //выбираем канал (в котором нет шумов!) massiv[0]=0; }jinik, в своем коде из сообщения #12 попробуйте в строке 18 отказаться от подтверждения - поставьте radio.setAutoAck(0); А строки 19 и 20 вообще закомментируйте.
Не поленился собрал это устройство, датчика температуры не нашел . отправлял temp1 = 20; В монитор порта каждые 4 сек идет Temp: 20.00 *C. Все работает. Либо на этом канале еще что то есть, лабо НРФки- плохой контакт, питание , и т.д. . попробуйте НРФки поменять.