Пошел по первому пути с идентификатором. Все заработало, но теперь появились обрывы в приеме. При постоянном нажатии на кнопку пульта, индикаторы на приемниках стали мигать вместо постоянного свечения
Откуда я знаю, что у вас там передается, что за индикаторы мигают и почему - вы же продолжаете постить какие=то огрызки вместо кода. Думаете, кто-то похитит вашу гениальную программу?
Миллис так и не исправили, хотя утверждали, что вам все понятно.
Нет, не думаю, просто в коде много ненужного, не относящегося к проблеме.
Миллис исправлю, как заработает все остальное. Сейчас я добился нормальной работы, но принцип приема-передачи без использования ackpayload я так и не понял
Если на приемнике и передатчике использовать просто "старт-прием/передача- стоп", то связи нет. Есть какая то хитрость?
Я решил его все таки использовать и добился более-менее стабильных результатов. Часовой тест оно прошло без проблем.
Миллис не стал поправлять, так как нет времени, аппарат надо сдавать. Переполнение миллис происходит через месяц, а схема работает не больше часа. Тему Евгения про переполнение я прочитал, учту это в обновлении
Вот код пульта
#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
#include <U8glib.h>
#define potPin A0 //Вывод резистора скорости
#define uPin A3 //Вывод напряжения батареи
#define fwdPin 0 //Вывод кнопки "Вперед"
#define bwdPin 2 //Вывод кнопки "Назад"
#define LED 1 //Пин диода
//Контакты от радиомодуля NRF24L01 подключаем к пинамнам:
//SCK -> 13//MISO -> 12//MOSI -> 11//CSN -> 10//CE -> 9
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI
RF24 radio(9, 10); //Подключения радиоблока
long previousMillis1 = 0;
long previousMillis2 = 0;
const int interval = 2000; //Интервал ожидания обратного пакета
double ubat = 0.0; //Напряжение батареи
byte spd_d = 0; //Скорость для отображения на дисплее //Комманда "Назад"
int msg[4];
int ack[2];
int u1;
int u2;
float vout1 = 0.0;
float vin1 = 0.0;
float vout2 = 0.0;
float vin2 = 0.0;
float R1 = 100000.0;
float R2 = 10000.0;
unsigned long timer1;
unsigned long timer2;
unsigned long timer3;
void setup(){
pinMode(fwdPin, INPUT); //Режимы пинов
pinMode(bwdPin, INPUT);
pinMode(LED, OUTPUT);
digitalWrite(bwdPin, HIGH);
digitalWrite(fwdPin, HIGH);
digitalWrite(LED, LOW);
ubat = (analogRead(uPin) * 5.35) / 1023.0;
radio.begin();
radio.setDataRate(RF24_250KBPS); // Скорость передачи
radio.setChannel(112); // Номер канала от 0 до 127
radio.setPALevel(RF24_PA_MAX); // Мощность передатчика
radio.setRetries(15, 15); // Кол-во попыток и время между попытками
radio.enableDynamicPayloads();
radio.enableAckPayload();
radio.setAutoAck(1);
radio.openWritingPipe(0xF0F0F0F0FFLL); // Открываем канал передачи
radio.openReadingPipe(1,0xAABBCCDD11LL); // Открываем один из 6-ти каналов приема // Начинаем слушать эфир
msg[0] = 1;
u8g.setRot180();
u8g.setFont(u8g_font_6x12);
} //end setup
void loop(){ //Начало цикла
u8g.firstPage();
do {
u8g.drawRFrame(1, 1, 127, 31, 1);
unsigned long currentMillis1 = millis();
unsigned long currentMillis2 = millis();
if (millis()> timer1 + 10000){
ubat = (analogRead(uPin) * 5.35) / 1023.0; //Замер напряжения батареи
timer1 = millis();
}
msg[3] = map(analogRead(potPin), 1023, 0, 255, 50); //Маппинг 10 бит в 8 бит
spd_d = map(msg[3], 50, 255, 20,100); //Маппинг скорости для дисплея из 255 в 100
vout1 = (u1 * 5.0) / 1024.0;
vin1 = vout1 / (R2/(R1+R2));
if (vin1<0.09) {
vin1=0.0;
}
vout2 = (u2 * 5.0) / 1024.0;
vin2 = vout2 / (R2/(R1+R2));
if (vin2<0.09) {
vin2=0.0;
}
if (radio.isAckPayloadAvailable()) {
radio.read(&ack,sizeof(ack));
if(ack[0] == 1){
previousMillis1 = currentMillis1 +interval;
u1 = ack[1];
}
if(ack[0] == 2){
previousMillis2 = currentMillis2 +interval;
u2 = ack[1];
}
}
// Строка напряжения батареи
u8g.setPrintPos(70, 10);
u8g.print("Bat");
u8g.setPrintPos(95, 10);
u8g.print(ubat);
u8g.print("V");
if(msg[1] == 111 || msg[2] == 222){
digitalWrite(LED, HIGH);
}
else{
digitalWrite(LED, LOW);
}
//Строка скорости
u8g.setPrintPos(5, 10);
u8g.print("Speed ");
u8g.print(spd_d);
u8g.print("%");
//Строка соединения
if (currentMillis1 < previousMillis1) {
u8g.setPrintPos(5, 20);
u8g.print("Connected ");
u8g.print("Acc ");
u8g.setPrintPos(90, 20);
u8g.print(vin1);
u8g.print("V");
}
else {
u8g.setPrintPos(25, 20);
u8g.print("Not connected");
u1 = 0;
}
if (currentMillis2 < previousMillis2) {
u8g.setPrintPos(5, 30);
u8g.print("Connected ");
u8g.print("Acc ");
u8g.setPrintPos(90, 30);
u8g.print(vin2);
u8g.print("V");
}
else {
u8g.setPrintPos(25, 30);
u8g.print("Not connected");
u2 = 0;
}
//если кнопка "Вперед" нажата ...
if (digitalRead(fwdPin) == LOW && !digitalRead(bwdPin) == LOW){
timer2 = millis();
}
//если кнопка "Назад" нажата ...
if (digitalRead(bwdPin) == LOW && !digitalRead(fwdPin) == LOW){
timer3 = millis();
}
if (millis() < timer2 + 300){
msg[2] = 0;
msg[1] = 111;
}
//если кнопка "Назад" нажата ...
else if (millis() < timer3 + 300){
msg[2] = 222;
msg[1] = 0;
}
else {
msg[1] = 0;
msg[2] = 0;
}
if(msg[0] == 1){
radio.write(&msg,sizeof(msg));
msg[0] = 2;
}
if(msg[0] == 2){
radio.write(&msg,sizeof(msg));
msg[0] = 1;
}
} while(u8g.nextPage());
} //Конец цикла
Код приемника
#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
#define voltmeter A3 //Вывод вольтметра
#define directPin1 7
#define directPin2 8 //Вывод управления направлением
#define conLed 0 //Вывод светодиода соединения
#define movLed 1 //Вывод светодиода движения
#define motPin1 5
#define motPin2 6 //Вывод управления мотором
#define brake1 A1
#define brake2 A0
class Timer {
public:
unsigned long previous;
unsigned long interval;
boolean s;
boolean tick;
Timer() {
previous = millis();
s = 0;
tick = 0;
}
void stop() {s = 0; }
void start() {s = 1; }
void read(unsigned long _interval) {
interval = _interval;
unsigned long current = millis(); tick = 0;
if (s == 0) {previous = current; }
if (current - previous > interval) {previous = current; tick = 1;}
}
};
RF24 radio(9, 10); // Выводы трансивера
Timer timer2;
long previousMillis = 0; // Переменная внутреннего таймера
int interv = 1500;
int interv2 = 350;
int msg[4]; // Массив переменных приема
byte val; //Значение ШИМ
int ack[2];
int u;
unsigned long timer1;
unsigned long timer3;
unsigned long timer4;
unsigned long timer5;
byte fwd;
byte bwd;
byte spd;
bool flag1;
bool flag2;
void setup() { //Установки
pinMode(conLed , OUTPUT); // Вывод индикатора соединения
pinMode(movLed, OUTPUT); // Режим индикатора движения
pinMode(directPin1, OUTPUT); // Режим вывода управления
pinMode(directPin2, OUTPUT);
pinMode(motPin1, OUTPUT);
pinMode(motPin2, OUTPUT);
pinMode(brake1, OUTPUT);
pinMode(brake2, OUTPUT);
digitalWrite(conLed , HIGH);
digitalWrite(movLed, HIGH);
digitalWrite(directPin1, LOW);
digitalWrite(directPin2, LOW);
digitalWrite(motPin1, LOW);
digitalWrite(motPin2, LOW);
digitalWrite(brake1, HIGH);
digitalWrite(brake2, HIGH);
delay(1500);
digitalWrite(brake1, LOW);
digitalWrite(brake2, LOW);
digitalWrite(conLed , LOW);
digitalWrite(movLed, LOW);
radio.begin(); // Включение радиосвязи
radio.setDataRate(RF24_250KBPS); // Скорость передачи
radio.setChannel(112); // Номер канала от 0 до 127
radio.setPALevel(RF24_PA_MAX); // Мощность передатчика
radio.setRetries(15, 15); // Кол-во попыток и время между попытками
radio.enableAckPayload();
radio.enableDynamicPayloads();
radio.setAutoAck(1); // Автоотправка обратного пакета
radio.openWritingPipe(0xAABBCCDD11LL); // Открываем канал передачи
radio.openReadingPipe(1, 0xF0F0F0F0FFLL); // Открываем один из 6-ти каналов приема
radio.startListening(); // Начинаем слушать эфир
u = analogRead(voltmeter); //Блок вольтметра
timer2.start();
}//Конец установок
void loop() { // Начало цикла
unsigned long currentMillis = millis(); // Вспомогательная переменная таймера
if (millis()> timer1 + 10000){
u = analogRead(voltmeter); //Блок вольтметра
timer1 = millis();
}
if(val > spd){
val = spd;
analogWrite(motPin1, val);
analogWrite(motPin2, val);
}
timer2.read(10);
if(msg[0] == 2){
if(msg[1] == 111){
timer4 = millis();
}
if(msg[2] == 222){
timer5 = millis();
}
if(millis() < timer4 + interv2){
fwd = 111;
}
else{
fwd = 0;
}
if(millis() < timer5 + interv2){
bwd = 222;
}
else{
bwd = 0;
}
if(msg[3] >= 50){
spd = msg[3];
}
}
if (radio.available()) { // Запуск приема
radio.read(&msg, sizeof(msg) );
ack[0] = 2;
ack[1] = u;
radio.writeAckPayload( 1, &ack, sizeof(ack));
previousMillis = currentMillis + interv;
}
if (fwd == 111 || bwd == 222) { // Зажигает светодиод при приеме сигнала движения
digitalWrite(movLed, HIGH);
digitalWrite(brake1, HIGH);
digitalWrite(brake2, HIGH);
}
else {
digitalWrite(movLed, LOW);
}
if (fwd != 111 && bwd != 222 && val == 0) {
timer3 = millis();
}
if (currentMillis > previousMillis) { // Сброс переменных при разрыве связи
if(val == 0) {digitalWrite(brake1, LOW); digitalWrite(brake2, LOW);}
digitalWrite(conLed, LOW); // Выключение индикатора связи
fwd = 0;
bwd = 0;
}
else { // Включение индикатора при соединении
digitalWrite(conLed, HIGH);
}
if(fwd == 111 && flag2 !=1 && (millis() > timer3 + 200)){
digitalWrite(directPin1, HIGH);
digitalWrite(directPin2, HIGH);
flag1 = 1;
if(timer2.tick && val < spd){
val++;
analogWrite(motPin1, val);
analogWrite(motPin2, val);
}
}
else if(bwd == 222 && flag1 != 1 && (millis() > timer3 + 200)){
digitalWrite(directPin1, LOW);
digitalWrite(directPin2, LOW);
flag2 = 1;
if(timer2.tick && val < spd){
val++;
analogWrite(motPin1, val);
analogWrite(motPin2, val);
}
}
else{
if(val == 0){
flag1 = 0; flag2=0;
digitalWrite(brake1, LOW);
digitalWrite(brake2, LOW);
}
if(timer2.tick && val > 0){
val--;
analogWrite(motPin1, val);
analogWrite(motPin2, val);
}
}
}//Конец цикла
Всем спасибо за помощь, правда как работает режим приемо-передачи без автоответа я пока так и не понял. В ближайшее время начну пробовать дальше
С китайскими модулями с антенкой получается примерно 30 метров через две стены в старом здании.
Так как это театр, а аппарат на ардуине - часть декорации, то нет возможности уйти на такое расстояние, чтобы оно было по прямой видимости, так что по прямой ловит очень далеко.
Так же могу добавить, что качественные и дорогие модули работают гораздо лучше и удобнее в эксплуатации
Не знаю, у меня вот такой (вроде такой же, да?) на открытой местности над водой уверено работает на 800 метров (если верить вот этому GNSS).
Планирую провести экстремальный тест - гнать вперёд до потери связи и посмотреть на расстояние, на котором потеряет, но это только когда лёд сойдёт и когда будет отлажена и испытана подсистема автоматического возвращения домой при потере связи, пока она написана, но ни разу не проверялась.
Не знаю, у меня вот такой (вроде такой же, да?) на открытой местности над водой уверено работает на 800 метров (если верить вот этому GNSS).
Евгений, спасибо за отклик - а без усилителя заведомо качественные не посоветуете? Мне 800м не надо, мне метров 15-20 через пару стен. С усилителем брать не хотелось бы - они большие и много потребляют.
Парни, я тут случайно наткнулся, в общем, я прошлом посте ссылался на отличный GPS-GLONASS. Он даже у меня дома в 5 метрах от окна (крыша железная) всё отлично ловит. Так вот, я тут увидел забавный девайс на его базе. И хочу предупредить -не верьте описанной в статье распиновке, а именно фразе: "The I2C lines are for factory programming of the module. No register data is available in the device’s datasheet. All communication with the device in this guide occurs over serial".
I2C там нужен ни для какой ни заводской установки - это просто интерфейс имеющегося на борту модуля чипа компаса (QMC5883). К нему вполне походят библиотеки для QMC5883, но впрочем там и без библиотек интерфейс проще пареной репы. Компас отлично работает. I2C выводы на модуле НЕ притянуты к питанию. И
Кстати, в статье показывают скетч чтения координат, а про компас как будто забыли - похоже, не знали как подключить, а статью написать надо было :))))
Спасибо, буду пробовать. Я ничего не писал про грамотное программирование. Я разработчик схем, а скетчи я второй раз в жизни вижу :)
Пошел по первому пути с идентификатором. Все заработало, но теперь появились обрывы в приеме. При постоянном нажатии на кнопку пульта, индикаторы на приемниках стали мигать вместо постоянного свечения
код передатчика
код приемника
Откуда я знаю, что у вас там передается, что за индикаторы мигают и почему - вы же продолжаете постить какие=то огрызки вместо кода. Думаете, кто-то похитит вашу гениальную программу?
Миллис так и не исправили, хотя утверждали, что вам все понятно.
Нет, не думаю, просто в коде много ненужного, не относящегося к проблеме.
Миллис исправлю, как заработает все остальное. Сейчас я добился нормальной работы, но принцип приема-передачи без использования ackpayload я так и не понял
Если на приемнике и передатчике использовать просто "старт-прием/передача- стоп", то связи нет. Есть какая то хитрость?
Если на приемнике и передатчике использовать просто "старт-прием/передача- стоп", то связи нет. Есть какая то хитрость?
АвтоАск везде выключили? Если автоответ не используется, на всех приемниках и передатчиках должно быть
radio.setAutoAck(false);
Я решил его все таки использовать и добился более-менее стабильных результатов. Часовой тест оно прошло без проблем.
Миллис не стал поправлять, так как нет времени, аппарат надо сдавать. Переполнение миллис происходит через месяц, а схема работает не больше часа. Тему Евгения про переполнение я прочитал, учту это в обновлении
Вот код пульта
Код приемника
Всем спасибо за помощь, правда как работает режим приемо-передачи без автоответа я пока так и не понял. В ближайшее время начну пробовать дальше
Megawollt. вопрос не по сути ветки - какая дальность у вас получается с NRF24 ?
С китайскими модулями с антенкой получается примерно 30 метров через две стены в старом здании.
Так как это театр, а аппарат на ардуине - часть декорации, то нет возможности уйти на такое расстояние, чтобы оно было по прямой видимости, так что по прямой ловит очень далеко.
Так же могу добавить, что качественные и дорогие модули работают гораздо лучше и удобнее в эксплуатации
"модули с антенной" - это с усилителем, типа таких
:
даже эти всего 30м? - да, негусто...
Так же могу добавить, что качественные и дорогие модули работают гораздо лучше и удобнее в эксплуатации
как их отличить-то, "качественные" от некачественных? Брать самые дорогие? :) - как-то глупо...
Не знаю, у меня вот такой (вроде такой же, да?) на открытой местности над водой уверено работает на 800 метров (если верить вот этому GNSS).
Планирую провести экстремальный тест - гнать вперёд до потери связи и посмотреть на расстояние, на котором потеряет, но это только когда лёд сойдёт и когда будет отлажена и испытана подсистема автоматического возвращения домой при потере связи, пока она написана, но ни разу не проверялась.
Не знаю, у меня вот такой (вроде такой же, да?) на открытой местности над водой уверено работает на 800 метров (если верить вот этому GNSS).
Евгений, спасибо за отклик - а без усилителя заведомо качественные не посоветуете? Мне 800м не надо, мне метров 15-20 через пару стен. С усилителем брать не хотелось бы - они большие и много потребляют.
К сожалению, не знаю.
Парни, я тут случайно наткнулся, в общем, я прошлом посте ссылался на отличный GPS-GLONASS. Он даже у меня дома в 5 метрах от окна (крыша железная) всё отлично ловит. Так вот, я тут увидел забавный девайс на его базе. И хочу предупредить -не верьте описанной в статье распиновке, а именно фразе: "The I2C lines are for factory programming of the module. No register data is available in the device’s datasheet. All communication with the device in this guide occurs over serial".
I2C там нужен ни для какой ни заводской установки - это просто интерфейс имеющегося на борту модуля чипа компаса (QMC5883). К нему вполне походят библиотеки для QMC5883, но впрочем там и без библиотек интерфейс проще пареной репы. Компас отлично работает. I2C выводы на модуле НЕ притянуты к питанию. И
Кстати, в статье показывают скетч чтения координат, а про компас как будто забыли - похоже, не знали как подключить, а статью написать надо было :))))
Да, да. Эти самые НРФки, которые я когда то купил по 100р 20 штук. Сейчас я от них ухожу.
30 метров это реальные данные через две стены в помещении, где больше 100 вайфай точек.
В деревне по прямой говорят, что бьет и на километр, но стоит свернуть не туда и всё.
Сейчас я покупаю вот такие модули.
https://ru.aliexpress.com/item/2-4GHz-rf-Wireless-uhf-Module-Power-Ampli...
Они намного меньше, работают увереннее и антенна более удобная. Хвостом можно вывести на корпус