nRF24L01+ : побеждаем модуль.

Тема в разделе "Проводная и беспроводная связь", создана пользователем ИгорьК, 19 июн 2014.

  1. post125

    post125 Нуб

    Добрый день! Удалось ли Вам подружить NRF c DUE? У меня никак не получается.
     
  2. cerberus

    cerberus Нуб

    Приветствую. Есть приемник и передатчик на NRF. Суть проблемы в след.
    после включения приемник принимает сигналы около 10-15 секунд после чего перестает отвечать на команды передатчика. возобновляется прием только после reset передатчик не перезагружаю.
    приемник:
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    const uint64_t pipe = 0xF0F1F2F3F4LL;
    int time;
    int rull1;
    int rull2;
    int gaz1;
    int gaz2;
    int bash;
    int fire;
    int firepin;
    int smoke;
    int flag;
    RF24 radio(9, 10);
    byte msg[8];
    void setup(){
      pinMode(7, OUTPUT); //подъем башни
      pinMode(3, OUTPUT);//~pwm //скорость поворота башни
      pinMode(8, OUTPUT); //опуск башни
      pinMode(5, OUTPUT);//~pwm //скорость гусеницы лев
      pinMode(6, OUTPUT);//~pwm //скорость гусеницы прав
      pinMode(2, OUTPUT); //привод башни влево
      pinMode(4, OUTPUT); //привод башни вправо
      pinMode(A0, OUTPUT); //привод гусениц лев вперед
      pinMode(A1, OUTPUT); //привод гусениц лев назад
      pinMode(A2, OUTPUT); //привод гусениц прав вперед
      pinMode(A3, OUTPUT); //привод гусениц прав назад
      pinMode(A4, OUTPUT); //дым
      pinMode(A5, OUTPUT); //выстрел
      pinMode(A6, OUTPUT); //концевик
      pinMode(A7, OUTPUT);  //пулемет

    radio.begin();
    radio.setChannel(9);
    radio.setPayloadSize(32);
    radio.setDataRate(RF24_1MBPS);
    radio.setPALevel(RF24_PA_MAX);
    radio.setAutoAck(1);
    radio.openReadingPipe(1,pipe);
    radio.startListening();
    Serial.begin(9600);
    delay(20);}
    void loop(){  
    if (radio.available()){time = millis();
    radio.read(&msg, sizeof(msg));}
    if (millis() - time > 1000){
      msg[0] = 130;
      msg[1] = 130;
      msg[2] = 130;
      msg[3] = 130;
      msg[4] = 0;
      msg[5] = 0;
      msg[6] = 0;// режим Fail saif
    }

    if (msg[3] > 132) //ТОРМОЗ правой гусеницы
    {
    rull2 = map(msg[3], 132, 255, 255, 0);
    }
    else
    {
    rull2 = 255;
    }

    if (msg[3] < 127) // тормоз левой гусеницы
    {
    rull1 = map(msg[3], 127, 0, 255, 0);
    }
    else
    {
      rull1 = 255;
    }
    if (msg[2] > 135) //движение назад
    {
    gaz1 = map(msg[2], 132, 255, 0, rull1);
    gaz2 = map(msg[2], 132, 255, 0, rull2);
      digitalWrite(A0, LOW);
      digitalWrite(A1, HIGH);
      digitalWrite(A2, LOW);
      digitalWrite(A3, HIGH);
      analogWrite(5, gaz1);
      analogWrite(6, gaz2);
    }
    if (msg[2] < 125)// движение вперед
    {
    gaz1 = map(msg[2], 128, 0, 0, rull1);
    gaz2 = map(msg[2], 128, 0, 0, rull2);
      digitalWrite(A0, HIGH);
      digitalWrite(A1, LOW);
      digitalWrite(A2, HIGH);
      digitalWrite(A3, LOW);
      analogWrite(5, gaz1);
      analogWrite(6, gaz2);
    }
    if(125 <= msg[2] && msg[2] < 135)
    {
      digitalWrite(A0, LOW);
      digitalWrite(A1, LOW);
      digitalWrite(A2, LOW);
      digitalWrite(A3, LOW);
      analogWrite(5, 0);
      analogWrite(6, 0);
    }

    if (msg[1] > 130) //поворот бвшни
    {
      bash = map(msg[1], 130, 255, 0, 255);
      digitalWrite(4, LOW);
      digitalWrite(2, HIGH);
      analogWrite(3, bash);
    }
    if (msg[1] < 124)
    {
      bash = map(msg[1], 124, 0, 0, 255);
      digitalWrite(4, HIGH);
      digitalWrite(2, LOW);
      analogWrite(3, bash);
    }
    if (124 < msg[1] && msg[1] < 130)
    {
       digitalWrite(2, LOW);
      digitalWrite(4, LOW);
    }
    if ( 135 < msg[0] && msg[0] < 255) {digitalWrite(8, HIGH);}
      else
      {
        digitalWrite(8, LOW);
      }

    if (0 <= msg[0] && msg[0] < 125) digitalWrite(7, HIGH);
    else
      {
        digitalWrite(7, LOW);
      }
     
    fire = msg[4]; // ВЫСТРЕЛ ПУШКИ

    if (fire == 1)
    {
      digitalWrite(A4, HIGH);
    }
    else
    {
    digitalWrite(A4, LOW);
    }

    smoke = msg[5]; // ДЫМ

    if (smoke == 1&&flag == 0)
    {
    digitalWrite(A5, !digitalRead(A5));
    flag=1;
    }
    if (smoke == 0&&flag == 1)
    {
      flag=0;
    }

    Serial.println(msg[3]);
    }
    передатчик:
    Код (C++):
    #include <SPI.h>                        
    #include <RF24.h>                        
    byte msg[8];                            
    const uint64_t pipe = 0xF0F1F2F3F4LL;
    RF24 radio(9, 10);
    const int ledPin = A4;
    int ledState = LOW;
    long previousMillis = 0;
    long interval = 1000;

    void setup()
    {
      pinMode(5, INPUT);
      pinMode(6, INPUT);
      pinMode(7, INPUT);
      pinMode(8, OUTPUT);
    Serial.begin(9600);
    radio.begin();
    delay(50);
      radio.setChannel(9);
      radio.setPayloadSize(32);
      radio.setRetries(5,15);
      radio.setDataRate(RF24_1MBPS);
      radio.setPALevel(RF24_PA_MAX);
      radio.setAutoAck(1);
      radio.openWritingPipe(pipe);
    }

    void loop()
    {
    msg[0] = map(analogRead(A0), 0, 1023, 0, 254);
    msg[1] = map(analogRead(A1), 0, 1023, 0, 254);
    msg[2] = map(analogRead(A2), 0, 1023, 0, 254);
    msg[3] = map(analogRead(A3), 0, 1023, 0, 254);
    msg[4] = !digitalRead(5);
    msg[5] = !digitalRead(6);
    msg[6] = !digitalRead(7);
    /*if (analogRead(A4) < 490)
    {
    unsigned long currentMillis = millis();
     
      //проверяем не прошел ли нужный интервал, если прошел то
      if(currentMillis - previousMillis > interval)
      {
        // сохраняем время последнего переключения
        previousMillis = currentMillis;
        // если светодиод не горит, то зажигаем, и наоборот
        if (ledState == LOW)
          ledState = HIGH;
        else
          ledState = LOW;
      }
        // устанавливаем состояния выхода, чтобы включить или выключить светодиод
        digitalWrite(ledPin, ledState);
        }
        else
        {*/

        digitalWrite(ledPin, HIGH);
      radio.write(&msg, sizeof(msg));
    Serial.println(msg[0]);
    }
     
  3. parovoZZ

    parovoZZ Гуру

    Ну...в трансивере приемника забивается приемный FIFO и трансивер ждет его очистки.
     
  4. cerberus

    cerberus Нуб

    Прошу вас подробнее описать как очистить буфер. Команды flush_rx, и flush_tx не помогли.
     
  5. Ye11ow

    Ye11ow Нерд

    Друзья, доброго дня.
    Никак не могу понять, модули то работают, то нет.
    Паял конденсатор 100 мкФ на приемник и на передатчик - результат такой же.
    Посмотрите пжлст код и подскажите, что можно попробовать исправить в нем, мне ту говорили про инициализацию, но я не понимаю что это и тем более что с этим делать:)

    Кто поможет - расцелую;)


    Код передатчика:
    Код (C++):
    //-----------Настройка диодной ленты
    #include "Adafruit_NeoPixel.h" //Подключение библиотеки для ленты
    #define ledPin 2               //Пин ленты РГБ
    #define ledCount 13             //кол-во диодов в ленте
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(ledCount, 2); // создаем переменную , где указываем кол-во диодов в ленте

    //----------Настройка цвета ленты
    #define red 255 //255
    #define green 70 //70
    #define blue 0//0

    //----Настройка микрофона
    #define micPin 1  // микрофон подключаем к первому пину аналоговому
    #define limitMicValue 100 //значение микрофона, превысив которое начинаются различные действия
    int micValue;     //Переменная для значений от микрофона

    //----Настройка сервопривода
    #include <Servo.h>//Подключаем библиотеку серво
    #define pinServo 4 //Управление сервоприводом 4 пин
    #define timeServo 500 // Время открытия сервы для скатывания шариков
    Servo myservo;//создаем серво объект для контроля сервоприводом

    //----Настройка передатчика
    #include <SPI.h>               // Подключаем библиотеку для работы с шиной SPI
    #include <nRF24L01.h>         // Подключаем файл настроек из библиотеки RF24
    #include <RF24.h>              // Подключаем библиотеку РФ24
    RF24 radio(9, 10);             // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN)
    int radioValue;
    int data[1];//создаем массив для передачи данных



    void setup() {
      Serial.begin (9600);
      pinMode (micPin, INPUT);  //Настраиваем пин под микрофон на ввод в контроллер
      strip.begin (); //инициализация ленты
      strip.setBrightness(255);//яркость светодиодов
      myservo.attach(pinServo); // наздначаем управление сервой на 3 пин
      myservo.write (145);//Начальная позиция сервопривода
      radio.begin(); //активировать модуль
      radio.setChannel(5);   // Указываем канал передачи данных (от 0 до 127), 5 - значит передача данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
      radio.setDataRate     (RF24_1MBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
      radio.setPALevel      (RF24_PA_HIGH); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
      radio.openWritingPipe (0x1234567890LL);// Открываем трубу с идентификатором 0x1234567890 для передачи данных (на одном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
    }


    void LED () {       //Создание функции для светодиодной ленты
      for (int i = 0; i <= ledCount ; i++) {
        strip.setPixelColor (i, red, green, blue);
      }
      strip.show ();
      delay(500);
      for (int i = 0; i < ledCount; i++)
      {
        strip.setPixelColor(i, strip.Color(0, 0, 0));
      }
      strip.show ();
      delay(2000);
        for (int i = 0; i <= ledCount ; i++) {
        strip.setPixelColor (i, red, green, blue);
      }
      strip.show ();
      delay(1000);
     
      for (int i = 0; i < ledCount; i++)
      {
        strip.setPixelColor(i, strip.Color(0, 0, 0));
      }
      strip.show ();
      delay(1000);


    for (int i = 0; i <= ledCount ; i++) {
        strip.setPixelColor (i, red, green, blue);
      }
      strip.show ();
     
    }

    void servo () {    //Создание функции для серворивода
      myservo.write (70);
      delay (timeServo);
      myservo.write (145);
    }

    void loop() {
      radioValue = 0;
      data[0] = radioValue;
      micValue =  analogRead(micPin);
      Serial.println (micValue);
      radio.write(&data, sizeof(data)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить. Отправить данные можно с проверкой их доставки: if( radio.write(&data, sizeof(data)) ){данные приняты приёмником;}else{данные не приняты приёмником;}

      if (micValue > limitMicValue) { //если значение с микрофона превысит лимитированное значение, то...
       radioValue = 1;
       data [0] = radioValue;
       radio.write(&data, sizeof(data)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить. Отправить данные можно с проверкой их доставки: if( radio.write(&data, sizeof(data)) ){данные приняты приёмником;}else{данные не приняты приёмником;}
       LED ();
        delay (10000); //время задержки пока булькает ЛИНКОКО
        servo();
       for (int i = 0; i <= ledCount ; i++) {
        strip.setPixelColor (i, 0, 0, 0);
      }
      strip.show ();
      }
      Serial.println (micValue);
    }
    Код приемника:
    Код (C++):
    //-----------Настройка диодной ленты
    #include "Adafruit_NeoPixel.h" //Подключение библиотеки для ленты
    #define ledPin 6               //Пин ленты РГБ
    #define ledCount 10             //кол-во диодов в ленте
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(ledCount, ledPin); // создаем переменную , где указываем кол-во диодов в ленте


    //-----------Настройка приёмника
    #include <SPI.h>      // Подключаем библиотеку  для работы с шиной SPI
    #include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24
    #include <RF24.h>     // Подключаем библиотеку  для работы с nRF24L01+
    RF24  radio (9, 10); //создаем объект radio для работы с библиотекой RF24 и указываем номера выводов
    int data[2]; //массив для приёма

    void setup() {
      Serial.begin(9600);
      pinMode (4, OUTPUT);//пин компрессора
    strip.begin (); //инициализация ленты
    strip.setBrightness (255); //настройка яркости светодиодов
    radio.begin(); //активировать модуль
    radio.setChannel(5);                                  // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков)
    radio.setDataRate     (RF24_1MBPS);                   // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
    radio.setPALevel      (RF24_PA_HIGH);                 // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
    radio.openReadingPipe (1, 0x1234567890LL);            // Открываем 1 трубу с идентификатором 0x1234567890 для приема данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора)
    radio.startListening  ();                             // Включаем приемник, начинаем прослушивать открытую трубу
     
    }
    void LED () {
      for (int i = 0; i < ledCount ; i++) {
        strip.setPixelColor (i, 254,0 , 254);//настройка цветов
      }
      strip.show ();//передать на ленту

    }

    void loop() {

    if(radio.available()) {
      radio.read(&data, sizeof(data));
       Serial.println(data[0]);  
    }
    if (data[0] == 1) {
    delay(2000);
      digitalWrite(4,HIGH);
      delay(10);
       LED();
        delay(6000);
     
    } else {
      digitalWrite(4,LOW);
      for (int i = 0; i <= ledCount ; i++) {
        strip.setPixelColor (i, 0, 0, 0);//настройка цветов
       
      }
      strip.show();

    }
    }
     
  6. vvr

    vvr Инженерище

    у вас в коде столько делеев, что ожидать от него нормальной работы не приходится.
     
    DetSimen нравится это.
  7. Ye11ow

    Ye11ow Нерд

    Как можно исправить ситуацию?
    мне в любом случае нужны задержки на определенное время.
     
  8. vvr

    vvr Инженерище

    используйте milis().
     
  9. AlexAxel

    AlexAxel Нерд

    добрый день. Как-то решилась http://forum.amperka.ru/threads/nrf24l01-побеждаем-модуль.3205/page-103#post-209612
    эта проблема? Дело в том, что у меня то же самое - один пакет проходит и затыкается.

    Увидел вот что: если в монитор порта кинуть Т - оно начинает работать на передачу, потом если кинуть R - то прием. Так вот, этот единственный пакет проходит при переключении режимов. Вот пустил его в режим передачи - он один пакет закинул (на приемнике появился этот пакет), и дальше глухо. Переключаемся обратно в прием, потом снова в передачу - точно так же, один пакет прошел и снова тишина
     
  10. parovoZZ

    parovoZZ Гуру

    Скорее всего, нет ответа в виде АСК пакета от приемника. Без значения регистров статуса и прочих сложно что-то говорить.
     
  11. AlexAxel

    AlexAxel Нерд

    хм.. Что именно мне выложить?
     
  12. parovoZZ

    parovoZZ Гуру

    Для начала значение регистра статуса. Модуль всегда его отдает самым первым при начале общения с ним.
     
  13. AlexAxel

    AlexAxel Нерд

    stat.jpg
     
  14. parovoZZ

    parovoZZ Гуру

    Нет, это не интересно. Нужен после затыка.
     
  15. AlexAxel

    AlexAxel Нерд

    Опять хм... А где мне его взять то? stat2.jpg

    Если так только?
     
  16. parovoZZ

    parovoZZ Гуру

    Выложи ещё такую же картинку, но только сразу после успешной отправки пакета. По ходу, библиотека регистр статуса сбрасывает.
     
  17. AlexAxel

    AlexAxel Нерд

    вот чего заметил - при запуске RX_ADDR_P0-1 = 0x0000000106 0x0000000100, а после отправки первого пакета - RX_ADDR_P0-1 = 0x0000000100 0x0000000106

    ХЗ правда что это значит...
     

    Вложения:

    • stat3.jpg
      stat3.jpg
      Размер файла:
      105,7 КБ
      Просмотров:
      547
    Последнее редактирование: 3 апр 2019
  18. parovoZZ

    parovoZZ Гуру

    Ну смотри: при таком раскладе TX_DS должен равняться 1. То бишь надо другим способом читать. Самое простое - обратиться напрямую через SPI и загнать в трансивер 8 единиц. В ответе от трансивера мы получим статус. Собственно, все какие проблемы у меня были с ним, все решались сразу же после анализа статуса...Дерзай!
    Логический анализатор или осциллограф есть?
     
  19. parovoZZ

    parovoZZ Гуру

    Кстати, плохой адрес. Нули надо заменить.
     
  20. Incub-79

    Incub-79 Нуб

    Добрый день, можете мне помочь ?
    Собрал приемник и передатчик (Ардуино UNO), но что-то не то.
    Не происходит прием данных, передача фиксируется в "терминале".
    При нажатии кнопки резет на передатчике происходит передача последнего значения и первого значения.