Нужна маленькая помощь (NRF24L01)
- Войдите на сайт для отправки комментариев
Вс, 19/02/2017 - 21:55
Есть скетч для пульта управления, не важно чего. Он рабочий, но есть недостаток. Пока кнопка зажата на передатчике , реле на приемнике работает. При отпускании кнопки выключается реле. Но если при зажатой кнопке на передатчике вдруг пропадает связь с приемником (например села батарейка или отошел на расстояние вне зоны радиомодуля), то реле остается включенным.
Что можно дописать, чтобы при пропадании сигнала реле автоматически отключался...
**СКЕТЧ передатчика:**
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte button = 2; // кнопка на 2 цифровом
byte button1 = 3;
byte button2 = 4;
byte button3 = 5;
byte slider = 1; // движковый потенциометр на 1 аналоговом пине
byte transmit_data[5]; // массив, хранящий передаваемые данные
byte latest_data[5]; // массив, хранящий последние переданные данные
boolean flag; // флажок отправки данных
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
pinMode(button, INPUT_PULLUP); // настроить пин кнопки
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
pinMode(button3, INPUT_PULLUP);
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_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
//должна быть одинакова на приёмнике и передатчике!
//при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //начать работу
radio.stopListening(); //не слушаем радиоэфир, мы передатчик
}
void loop() {
transmit_data[0] = !digitalRead(button); // инвертированный (!) сигнал с кнопки
transmit_data[1] = !digitalRead(button1);
transmit_data[3] = !digitalRead(button2);
transmit_data[4] = !digitalRead(button3);
transmit_data[2] = map(analogRead(slider), 0, 1023, 0, 255);
for (int i = 0; i < 4; i++) { // в цикле от 0 до числа каналов
if (transmit_data[i] != latest_data[i]) { // если есть изменения в transmit_data
flag = 1; // поднять флаг отправки по радио
latest_data[i] = transmit_data[i]; // запомнить последнее изменение
}
}
if (flag == 1) {
radio.powerUp(); // включить передатчик
radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио
flag = 0; //опустить флаг
radio.powerDown(); // выключить передатчик
}
}
**СКЕТЧ** приемника:100:
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <Servo.h>
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
byte recieved_data[5]; // массив принятых данных
byte relay = 2; // реле на 2 цифровом
byte relay1 = 3;
byte relay2 = 4;
byte relay3 = 5;
byte mosfet = 1;
Servo myservo;
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
pinMode(relay, OUTPUT); // настроить пин реле как выход
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
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_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
//должна быть одинакова на приёмнике и передатчике!
//при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //начать работу
radio.startListening(); //начинаем слушать эфир, мы приёмный модуль
}
void loop() {
byte pipeNo;
while ( radio.available(&pipeNo)) { // слушаем эфир со всех труб
radio.read( &recieved_data, sizeof(recieved_data) ); // читаем входящий сигнал
digitalWrite(relay, recieved_data[0]); // подать на реле сигнал с 0 места массива
digitalWrite(relay1, recieved_data[1]);
digitalWrite(relay2, recieved_data[3]);
digitalWrite(relay3, recieved_data[4]);
myservo.write(recieved_data[2]); // повернуть серво на угол 0..180
// значение получено с 1 элемента массива
analogWrite(mosfet, recieved_data[3]); // подать на мосфет ШИМ сигнал
// в соответствии с принятыми данными со 2 места массива, диапазон 0...255
}
}
Там есть функция отлова пакетов и связи. Если до завтра никто не ответит, покопаю свои старые коды с радиомодулем
Простой принцип, делается метка времени (переменная типа unsigned long), в которую в момент приёма сигнала складывается время из millis(). Потом условие, если millis минус метка больше чем некий порог, то отключать.
По такой схеме делают обнаружение отсутствия связи в DMX приёмниках.
PORTD&=B10011111; это команда? И что означает?
Это моя команда, выключает D5, D6, на неё вообще смотреть не надо. Вместо этого куска ваш код который отключает. Всё же в комментариях написано.
А, ну да... англ. Ну сорян, привычка - у меня IDE русские буквы покзывает как попало.
Я вписал ваш код со своими изменениями, и случилось вот что: я зажал кнопку и реле отключился, связь не терялась, просто отключает реле спустя 3 секунды хотя кнопка зажата. Есть подозрение, что скетч при зажатой кнопке отправляет сигнал одинажды, и ваша команда думает, что связи больше нет с пультом. Так как наш скетч при зажатой кнопке отсылает сигнал не постоянно. Знаний не хватает переделать этот не достаток.
Если есть и у других тоже идеи поделитесь пожалуйста. И еще. Этот скетч я скачал из интернета и подстроил под себя. И если я удаляю мосфет, ползунки или сервоприводы то пульт уже не работает, можно ли как-то избавиться?
Да, надо повторять.
Вот эта команда вообще царский подгон. Большое спасибо.
а с первым еще бы чуток разъяснений
byte rfdata; //payload=1
Glacion, да. rfdata это моё, вместо 7 ваше значение на откл если оно есть, и команда откл, а так же через время. Короче суть такая, что приёмник постоянно пытается выключиться, а передатчик ему мешает. Поэтому и получается что надо периодически повторять.
Glacion, да. rfdata это моё, вместо 7 ваше значение на откл если оно есть, и команда откл, а так же через время. Короче суть такая, что приёмник постоянно пытается выключиться, а передатчик ему мешает. Поэтому и получается что надо периодически повторять.
Не получается у мкня повторить, ничего не происходит какие только изменения не вносил, мне необходимо что бы на D6-D8 в случаее потери сигнала стал 0. Как я ваш код только не переделывал, ничего не получается, можете тыкнуть меня носом как это должно работать?