Передача трех переменных по NRF24l01

Megawollt
Offline
Зарегистрирован: 06.12.2015

Задача такая. Нужно передать три переменные для управления мотором. То есть bool вперед, назад и byte скорость.

Вот фрагмент кода. Что я делаю не так?

Передатчик

 msg[0] = fwd;
  msg[1] = bwd;
  msg[2] = spd;
  radio.write(&msg, sizeof(msg) );

Приемник

if(radio.available()){
radio.read(&msg, sizeof(msg));
msg[0]= fwd;
msg[1]=bwd;
msg[2]=spd;
}

Связь между модулями налажена. Одна переменная скорости без массива передается

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

наверно нужно обьявить массив

int msg [3];

 

Megawollt
Offline
Зарегистрирован: 06.12.2015

Все не так просто. Само собой и массив объявлен и переменные имеют значения, но нет.

Этот модуль только массивы передает?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

Megawollt пишет:

Все не так просто. Само собой и массив объявлен и переменные имеют значения, но нет.

Этот модуль только массивы передает?

ему без разницы что в трубе передавать

и перед msg уберите указатель "&"

выложите скетч полностью

Megawollt
Offline
Зарегистрирован: 06.12.2015

Указатель убирал. Не помогает. Скетч длинный, так как много строк для дисплея и прочего ненужного кода

Вот код приемника. Работает. Передает переменную скорости, но массив из трех не передает и не принимает

#include <SPI.h>
#include <RF24.h>

RF24 radio(9, 10);

byte spd;



void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);                  // Скорость передачи
  radio.setChannel(100);                           // Номер канала от 0 до 127
  radio.setRetries(25, 15);                       // Кол-во попыток и время между попытками
  radio.openWritingPipe(0xF0F0F0F000LL);         // Передача
  radio.openReadingPipe(1, 0xF0F0F0F0FFLL);     // Прием
  radio.startListening();                  

}

void loop() {
 
  radio.startListening();
 while (radio.available()) {
    radio.read(&spd, 1);
  
    
  }
 
    Serial.print("spd =");
    Serial.print(spd);
    Serial.println();
}

И еще важный вопрос. При обрыве связи остается последнее значение переменной, а надо, чтобы все обнулялось. Как поступить?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

я брал код отсюда, все прекрасно работает

http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

и сделал для себя функции приема и передачи

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10);

const uint64_t pipe = 0xE8E8F0F0E1LL;
byte pass = 0;
inе data1 = 0;
int data2 = 0;
int h = 0;
int t = 0;
boolean flag_sw = false;
byte password = 0;
unsigned long previousMillis = 0;

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.startListening();
}
void loop() {
  recv(90);
  Serial.print("Array in [1]: ");
  Serial.print(data1);
  Serial.print(" Array in [2]: ");
  Serial.print(data2);
  Serial.print(" Temperature: ");
  Serial.print(t);
  Serial.print(" Humidity: ");
  Serial.print(h);
  Serial.print(" Pass: ");
  Serial.print(pass);
  Serial.print(" Flag: ");
  Serial.println(flag_sw);

  if (millis() - previousMillis > 3000) {
    previousMillis = millis();
    password = B00000001;
    trmt(90);
    password = B00000000;
    }
  if (pass == 1 && flag_sw == true) {
    t = data1;
    h = data2;
    data1 = 0;
    data2 = 0;
    pass = 0;
    flag_sw = false;
  }
}
void trmt (uint8_t ch) {
  int arr_out[1];
  radio.setChannel(ch);
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(pipe);
  radio.stopListening();
  arr_out[0] = password;
  radio.write( arr_out, sizeof(arr_out) );
  radio.startListening();
}
void recv (uint8_t ch) {
  int arr_in[3];
  radio.setChannel(ch);
  radio.setDataRate(RF24_1MBPS);
  radio.openReadingPipe(1, pipe);
  //radio.setRetries(1, 1);
  if ( radio.available() ) {
    bool done = false;
    while (!done) {
      done = radio.read( arr_in, sizeof(arr_in) );
      pass = arr_in[0];
      data1 = arr_in[1];
      data2 = arr_in[2];
      flag_sw = true;
    }
  }
}

 

Megawollt
Offline
Зарегистрирован: 06.12.2015

Каким образом работает 72 строка если она объявлена как Булева?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

отключает 71 , когда что-то примет

Megawollt
Offline
Зарегистрирован: 06.12.2015

Она все равно объявлена как булева. Компилятор выдает ошибку, когда видит эту строку

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

какая версия ide?

у меня 1.6.5 и 1.6.7 все нормально компилит

попробуйте заменить на boolean

Megawollt
Offline
Зарегистрирован: 06.12.2015

Да тоже 1.67. А какие библиотеки подключены?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015
Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

ага, проблема в том что обновили библиотеку до версии 1.1.5

вот переделаный скетч

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10);

const uint64_t pipe = 0xE8E8F0F0E1LL;
byte pass = 0;
int8_t data1 = 0;
int8_t data2 = 0;
int h = 0;
int t = 0;
boolean flag_sw = false;
byte password = 0;
unsigned long previousMillis = 0;

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.startListening();
}
void loop() {
  recv(90);
  Serial.print("Array in [1]: ");
  Serial.print(data1);
  Serial.print(" Array in [2]: ");
  Serial.print(data2);
  Serial.print(" Temperature: ");
  Serial.print(t);
  Serial.print(" Humidity: ");
  Serial.print(h);
  Serial.print(" Pass: ");
  Serial.print(pass);
  Serial.print(" Flag: ");
  Serial.println(flag_sw);

  /*if (millis() - previousMillis > 3000) {
    previousMillis = millis();
    password = B00000001;
    trmt();
    password = B00000000;
    }*/
  if (pass == 1 && flag_sw == true) {
    t = data1;
    h = data2;
    data1 = 0;
    data2 = 0;
    pass = 0;
    flag_sw = false;
  }
}
void trmt () {
  int arr_out[1];
  radio.setChannel(90);
  radio.setPALevel(RF24_PA_HIGH);
  radio.setDataRate(RF24_1MBPS);
  radio.openWritingPipe(pipe);
  radio.stopListening();
  arr_out[0] = password;
  radio.write( &arr_out, sizeof(arr_out) );
  radio.startListening();
}
void recv (uint8_t ch) {
  int arr_in[3];
  radio.setChannel(ch);
  radio.setDataRate(RF24_1MBPS);
  radio.openReadingPipe(1, pipe);
  //radio.setRetries(1, 1);
  if ( radio.available() ) {
    while ( radio.available() ) {
      radio.read( &arr_in, sizeof(arr_in) );
      pass = arr_in[0];
      data1 = arr_in[1];
      data2 = arr_in[2];
      flag_sw = true;
    }
  }
}

 

Megawollt
Offline
Зарегистрирован: 06.12.2015

Да я все тоже самое и делаю. Завтра приду, еще попробую. А как все таки обнулять переменную при обрыве связи?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

тут надо знать что вы хотите, если передатчик все время передает то через флаг, как у меня flag_sw, если что то другое то надо знать принцип работы

Megawollt
Offline
Зарегистрирован: 06.12.2015

Да, но если связь пропадет, флаг так и останется 1

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

у меня строки 43-49 этим занимаются

я передаю пароль pass, так как это кусок умного дома, каждый датчик имеет свой пароль, а центральная часть их опрашивает

Megawollt
Offline
Зарегистрирован: 06.12.2015

В общем ничего не понимаю. Какие бы библиотеки я не подключал и что бы не делал, строка done = radio.read( msg, sizeof(msg) );  

не работает. Пишет:

void value not ignored as it ought to be
 
Но массив передался после изменения версии библиотеки.
Теперь интересует как сбрасывать переменные при разрыве связи и сделать подтверждение соединения?
  
 
Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

я вам дал ссылку, вдумайтесь

http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

Megawollt
Offline
Зарегистрирован: 06.12.2015

Я не нашел там ответов на свои вопросы :(

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

Megawollt пишет:

Я не нашел там ответов на свои вопросы :(

Serial.println("No radio available");

ни о чем не говорит?

Megawollt
Offline
Зарегистрирован: 06.12.2015

Говорит, но не работает. Эта строка не является подтверждением соединения

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

 а вы добавьте вместо нее flag_sw = false;

Megawollt
Offline
Зарегистрирован: 06.12.2015

Есть и флаг. Проблема в том, что подтверждение работает только в момент приема сообщения. То есть на дисплее надписи моргают.

Я в замешательстве. И по поводу обнуления переменных при пропадании связи я тоже ничего не могу выяснить.

Не хочу кидать весь код по причине его длинны

Есть еще вот такая команда  radio.writeAckPayload, но и с ней ничего не получается

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

можно сделать задержку через millis, т.е. пока есть 1 сбрасывать значения, если нет 1 например 100 мс дать 0

Megawollt
Offline
Зарегистрирован: 06.12.2015

Наверное это вариант. А нет случаем готового кода?

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

blink without delay из примеров IDE

Radjah
Offline
Зарегистрирован: 06.08.2014

Я бы сделал структуру и дал полям осмысленные названия.

Megawollt
Offline
Зарегистрирован: 06.12.2015

Поподробнее...

Что такое осмысленные названия?

 

После всех эксперементов обмена массивами не получилось. Только прием и передача в одну сторону. Вот коды

Передатчик

radio.stopListening();
msg[0] = spd;
msg[1] = fwd;
msg[2] = bwd;
radio.write(msg,sizeof(msg));
radio.startListening();
if (radio.available()) {
radio.read(param, sizeof(param));
param[0]= stat;
param[1]= r_lim;
param[2]= l_lim;
param[3]= u_acc;
}

Приемник

radio.startListening();
if (radio.available()) {
radio.read(msg, sizeof(msg));
spd = msg[0];
fwd = msg[1];
bwd = msg[2];
radio.stopListening();
param[0]= stat;
param[1]= r_lim;
param[2]= l_lim;
param[3]= u_acc;
radio.write(param, sizeof(param));
radio.startListening();
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Не используй sizeof(msg), sizeof(param). msg и param указатели. sizeof возвращает размер этих указателей, а это 2 или 4, в зависимости от контроллера.

Megawollt
Offline
Зарегистрирован: 06.12.2015

а что использовать вместо них? Почему во всех примерах так?

Radjah
Offline
Зарегистрирован: 06.08.2014

Ну вот так например:

struct sendtemp {
  uint32_t dt;       // Время unixtime
  float    outtemp;  // Температура на улице
  float    intemp;   // Температура внутри
  float    pres;     // Давление
  float    humin;    // Влажность относительная внутри
  float    humout;   // Влажность относительная на улице
};

И как-то так писать:

  sendtemp st;
...
  st.outtemp = sensors.getTempC(dsaddr1);
  st.humin = SHT2x.GetHumidity();
  st.pres = bmp.readPressure() / 133.32;
  st.humout = dht.readHumidity();

Ну и sizeof вернет размер структуры, а не указателя.

Megawollt
Offline
Зарегистрирован: 06.12.2015

Интересное предложение, но вряд ли это поможет.

Проблема в отсутствии приемопередачи, а не в структуре

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

если проблему еще не решили, честно сказать не понял

https://yadi.sk/d/CXjuENmaEEwun

там либа и примеры, либу надо ставить "мою"

архив RF24

 

Megawollt
Offline
Зарегистрирован: 06.12.2015

А где там пример его как приемопередатчика?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

у тебя же вроде передатчик и приемник? или двухсторонняя связь нужна?

пример rx_test и tx_test

Megawollt
Offline
Зарегистрирован: 06.12.2015

Именно двухсторонняя. Проблема в том, что они работают как приемник и передатчик, а вот в обратную сторону не хотят

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

тогда я тебе не помогу. не разбирался особо с этим вопросом

Megawollt
Offline
Зарегистрирован: 06.12.2015

Да вот я и пытаюсь.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

я знаю про автоответ, но там всего 1 байт можно вроде отправить. хотя смотря что отправлять обратно. по идее и в 1 байте можно уместить управление впред назад и управление скоростью

Radjah
Offline
Зарегистрирован: 06.08.2014

payload вроде любую можно сделать в пределах rx-буфера.

Megawollt
Offline
Зарегистрирован: 06.12.2015

В принципе одного байта хватит. Мне надо отправить единицу состояния соединения и две единицы предела(левый, правый).

Можно еще float из трех знаков.

Только вот логику работы оправки обратно я так и не понял

Даня
Offline
Зарегистрирован: 05.03.2021

Получилось запустить, но только удалось загрузить скетч "передатчик" на ардуино nano, а на "приемник" выдает ошибка (выделил жир. шрифтом). Подскажите пожалуйста как исправить? 

Код передатчика "приемник"

#include <Servo.h>    //the library which helps us to control the servo motor

#include <SPI.h>      //the communication interface with the modem
#include "RF24.h"     //the library which helps us to control the radio modem
 
//define the servo name
Servo myServo1;
Servo myServo3;
Servo myServo4;
Servo myServo2;
Servo myServo5;
Servo myServo6;
 
RF24 radio(9,10);     /*This object represents a modem connected to the Arduino. 
                      Arguments 9 and 10 are a digital pin numbers to which signals 
                      CE and CSN are connected.*/
 
const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem,that will receive data from the Arduino.
 
int msg[6];
 
void setup(){
 
  //define the servo input pins
  myServo1.attach(14); //A0
  myServo2.attach(15); //A1
  myServo3.attach(16); //A2
  myServo4.attach(17); //A3
  myServo5.attach(18); //A4
  myServo6.attach(19); //A5
  
  radio.begin();                    //it activates the modem.
  radio.openReadingPipe(1, pipe);   //determines the address of our modem which receive data.
  radio.startListening();           //enable receiving data via modem
  }
 
 
void loop(){
  if(radio.available()){
    bool done = false;
    while (!done){
    done = radio.read(msg, sizeof(msg));
 
    myServo1.write(msg[2]); //A0
    myServo2.write(msg[4]); //A1
    myServo3.write(msg[3]); //A2
    myServo4.write(msg[1]); //A3
    myServo5.write(msg[0]); //A4
    myServo6.write(msg[5]); //A5
    }
  }
}
 
Код приемника "передатчик"
#include <SPI.h>                      //the communication interface with the modem
#include "RF24.h"                     //the library which helps us to control the radio modem
 
int msg[6]; //Total number of data to be sent (data package)
 
//define the flex sensor input pins
int flex_6 = A5;
int flex_5 = A4;
int flex_4 = A3;
int flex_3 = A2;
int flex_2 = A1;
int flex_1 = A0;
 
//define variables for flex sensor values
int flex_6_val;
int flex_5_val;
int flex_4_val;
int flex_3_val;
int flex_2_val;
int flex_1_val;
 
RF24 radio(9,10);                     //9 and 10 are a digital pin numbers to which signals CE and CSN are connected.
                                      
const uint64_t pipe = 0xE8E8F0F0E1LL; //the address of the modem, that will receive data from Arduino.
 
 
void setup(void){
  Serial.begin(9600);
  radio.begin();                      //it activates the modem.
  radio.openWritingPipe(pipe);        //sets the address of the receiver to which the program will send data.
}
 
void loop(void){
  flex_6_val = analogRead(flex_6); 
  flex_6_val = map(flex_6_val, 550, 1000, 180, 0);
  
  flex_5_val = analogRead(flex_5); 
  flex_5_val = map(flex_5_val, 550, 1000, 0, 180);
  
  flex_4_val = analogRead(flex_4);
  flex_4_val = map(flex_4_val, 550, 1000, 0, 180);
 
  flex_3_val = analogRead(flex_3);
  flex_3_val = map(flex_3_val, 550, 1000, 0, 180);
 
  flex_2_val = analogRead(flex_2);
  flex_2_val = map(flex_2_val, 550, 1000, 0, 180);
  
  flex_1_val = analogRead(flex_1);
  flex_1_val = map(flex_1_val, 550, 900, 150, 30);
  
  msg[0] = flex_6_val;
  msg[1] = flex_5_val;
  msg[2] = flex_4_val;
  msg[3] = flex_3_val;
  msg[4] = flex_2_val;
  msg[5] = flex_1_val;
  radio.write(&msg, sizeof(msg));
}

 

b707
Offline
Зарегистрирован: 26.05.2017

вставьте код по правилам форума и выложите сообщение об ошибке