nrf24l01 принимает данные только один раз при включении
- Войдите на сайт для отправки комментариев
Пт, 29/12/2017 - 07:03
Здравствуйте, не судите строго, в ардуино новичек. Есть такая проблема. Имеются две ардуино с модулями nrf24l01, одна передает другой показания температуры с датчика DHT22, проблема заключается в следующем, данные температуры передаются только один раз, при включении приемника, что бы обновить данные приходится нажимать кнопку рестарт на ардуино. Вообще не могу понять в чем проблема. код приемника ниже. Заранее спасибо, не пинайте сильно)))))))))
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
byte tT;
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
byte recieved_data[2]; // массив принятых данных
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
lcd.init();
lcd.backlight();
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() {
while (radio.available()){
radio.read( &recieved_data, sizeof(recieved_data) ); // читаем входящий сигнал
tT = recieved_data[0];
tT = map(tT, 0, 200, -98, 101); // конвертируем данные
lcd.setCursor(0, 0);
lcd.print(tT);
Serial.println(recieved_data[0]);
lcd.setCursor(0, 1);
int i;
i++;
lcd.print(i); // добавил для проверки работает ли в принципе цикл
}
}
проверял на передатчике значение массива с температурой через серийный монитор, значения меняются при изменении температуры на датчике
Сам разобрался.
Удалил из скетча на приемнике и передатчике строку
radio.enableAckPayload();и все за работалоТему можно закрыть
Добрый день! Нужна помощь. У меня похожая проблема, данные принимаются и отображаются на экране, но когда выключаю передатчик, приемник продолжает отображать последнее значение температуры. Скетчи брал за основу с https://github.com/liamjack/Arduino-NRF24L01-Thermometer, но переделал для led индикатора. Буду использовать в качестве термостата, поэтому и необходимо в случае ошибки с приемом данных "бить тревогу". Подскажите как исправить
Вот мои старания:
#include <EEPROM.h> //#include <MsTimer2.h> //#include <Led4Digits.h> // Radio #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <RF24_config.h> #include <avr/sleep.h> #include <avr/wdt.h> // -- Global variables -- //#define OUT 5 // выход для Buzzer //byte pos; float tempOUT = 15; float errorT = -55; int buttonPlus=A0; int buzerPin = 5; // int analog=0; RF24 radio(9,10); void setupRadio() { // Initiate the radio radio.begin(); radio.setAutoAck(1); // Define the number of retries sending a packet radio.setRetries(15,15); // Define the radio's broadcast channel (0 - 127) // Must be the same on the sensor and the master node radio.setChannel(17); // Define the radio's bitrate (using cards lowest bitrate) radio.setDataRate(RF24_250KBPS); // Define the radio's power amplifier level (RF24_PA_MIN for debugging, RF24_PA_HIGH for longest range) radio.setPALevel(RF24_PA_HIGH); // Enable dynamic payloads for packets radio.enableDynamicPayloads(); // Open reading pipe radio.openReadingPipe(1, 0xE8E8F0F0E1LL); // Start listening for packets radio.startListening(); } int packetCounter = 0; int anodPins[] = {2, 3, 4}; // Задаем пины для кажого разряда int segmentsPins[] = {7, 6, 8, 15, 16, 17, 18, 19}; //Задаем пины для каждого сегмента (из 7 + 1(точка)) int pinIn = A0; void setup() { for (int i = 0; i < 3; i++) pinMode(anodPins[i], OUTPUT); for (int i = 0; i < 8; i++) pinMode(segmentsPins[i], OUTPUT); pinMode(pinIn, INPUT); pinMode(buzerPin, OUTPUT); wdt_disable(); delay(8000); wdt_enable(WDTO_8S); //пробуждение каждые 8 сек // MsTimer2::set(2, timerInterrupt); // задаем период прерывания по таймеру 2 мс // MsTimer2::start(); // разрешаем прерывание по таймеру // Initiate serial connection Serial.begin(57600); // RF Radio setup setupRadio(); } //{A, B, C, D, E, F, G,DP} int seg[12][8] = { {1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0 {0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1 {1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2 {1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3 {0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4 {1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5 {1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6 {1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7 {1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8 {1, 1, 1, 1, 0, 1, 1, 0}, //Цифра 9 {0, 0, 0, 0, 0, 0, 1, 0}, //Знак - {0, 0, 0, 0, 0, 0, 0, 0} //Пустой разряд }; int err[3][8] = { //{0, 0, 0, 0, 0, 0, 0, 0}, //Пусто {1, 0, 0, 1, 1, 1, 1, 0}, //E {0, 0, 0, 0, 1, 0, 1, 0}, //r {0, 0, 0, 0, 1, 0, 1, 0} //r }; static int arr[3][8]; // Переменная-массив для хранения данных, которые не нужно каждый раз пересчитывать float value=0.0; int counter = -1; //int numindex = 0; void loop() { counter += 1; if ((counter % 100) == 0) { // Пауза между сменами 100 мс counter = 0; { if(radio.available()) { float temperature = 0; // Read the packet received into the temperature variable if(!radio.available()) { // Read the packet received into the temperature variable float errorT = 0; errorT = -55; getDigits(errorT); Serial.println("ACK not received by client."); } if(!radio.read(&temperature, sizeof(float))) { // The sensor did not receive the ACK packet // tone(5, 3000,1000); errorT = -55; getDigits(errorT); Serial.println("ACK not received by client."); } else value = temperature; getDigits(value); Serial.println(temperature); if(tempOUT>temperature) tone(5, 3000,1000); else digitalWrite(5, LOW); } // if(analog>690&&analog<700)//здесь я сравниваю //значение входящего сигнала не с конкретной цифрой //а с определенным диапазоном от 690 до 700 //это нужно для того чтобы исключить влияние погрешностей резисторов // { // digitalWrite(9,HIGH); // digitalWrite(10,LOW); // } // if(analog>785&&analog<795) // { // digitalWrite(9,LOW); // digitalWrite(10,HIGH); // } // if(analog>860&&analog<870) // { // digitalWrite(9,HIGH); // digitalWrite(10,HIGH); // } // if(analog<100) // { // digitalWrite(9,LOW); // digitalWrite(10,LOW); // } if (digitalRead(buttonPlus) == LOW) { tempOUT-=0.05; if (-55 > tempOUT) tempOUT = 0; delay(27); Serial.println(tempOUT); getDigits(tempOUT); // getDigits(ceil(tempOUT)); } // Делаем проверку, если вход под номером 9 (buttonPlus) имеет состояние 5 В. Увеличиваем значение переменной яркости на 5 единиц. else if (analogRead(buttonPlus) < 800) { tempOUT+=0.05; if (tempOUT > 125) tempOUT = 0; delay(27); Serial.println(tempOUT); getDigits(tempOUT); //getDigits(ceil(tempOUT)); } // Делаем проверк } displayMessage(arr); } } void getDigits (float value) { // Serial.println(value); //Serial.println(tempOUT); // Выдаем ошибку на те значения, которые не можем показать if ((value >= 10000) || (value <= -1000)){ // (value > -0.01 && value < 0.001) for (int i = 0; i < 3; i++) { // Каждый разряд по очереди for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты arr[i][k] = err[i][k]; } } return; // Выходим } int digits = 3; // У нас 4 разряда if (value < 0) digits = 2; // Из-за минуса один символ убирается*/ // Делим число на 2 группы - отдельно целую часть и дробную. int intPart = (int)abs(value); int intLength = ((String)intPart).length(); // Смотрим, сколько разрядов занимает целая часть // На дробную часть у нас остается разрядов: digits-intLength int fracPart = (int)((abs(value) - abs(intPart)) * 10); // *1000 Мы можем показать максимум 3 знака после запятой - 0,000 int fracDigits = digits - intLength; fracPart = (((String)fracPart).substring(0, fracDigits)).toInt(); // Собираем строку для отображения String output = (value < 0) ? "-" : ""; output += (String)intPart; String outputFrac = (digits - intLength < 0) ? "" : ((String)"." + ((String)fracPart).substring(0, digits - intLength)); //String outputFrac = ((digits - intLength <= 0) || (fracPart == 0)) ? "" : ((String)"." + ((String)fracPart).substring(0, digits - intLength)); output += (String)outputFrac; // Дополняем символы спереди, если цифр слишком мало, например для "-1" делаем " -1" String spaces = " "; digits = 3; if (~output.indexOf(".")) digits += 1; if (output.length() < digits) output = spaces.substring(0, digits - output.length()) + output; // Формирум данные для показа: int dig = -1; for (int i = 0; i < output.length(); i++) { String _char = output.substring(i, i + 1); if (_char != ".") dig += 1; // Точка не занимает сегмент - увеличиваем на 1 int actualdigit = 11; // По умолчанию пустой символ if ((_char == "-")) { actualdigit = 10; } else if (_char == " " || _char == ".") { } else { actualdigit = _char.toInt(); } if (_char == ".") { arr[dig][7] = 1; // Если нужно - ставим точку } else { for (int n = 0; n <= 7; n++) { arr[dig][n] = seg[actualdigit][n]; } } } } void displayMessage(int dig[3][8]) { for (int i = 0; i < 3; i++) { // Каждый разряд по очереди for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты digitalWrite(segmentsPins[k], ((dig[i][k] == 1) ? LOW : HIGH)); } digitalWrite(anodPins[i], HIGH); delay(1); digitalWrite(anodPins[i], LOW); } }Я на приёмнике, при каждом приёме сбрасываю счётчик. Если счётчик не сбрасывается 10 - 30 мин. включаю ALARM. Но есть другая проблема, Если температура и напряжение ИП стабильны и не меняются длительное время, загорается ALARM. NRF24L01 не воспринимает второй пакет если он такой же как предыдущий.
Flush_rx не помогает.