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

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

  1. parovoZZ

    parovoZZ Гуру

    там фуфло все. При иниицилизации необходимо прописывать абсолютно все регистры.
     
  2. Ivanii

    Ivanii Нуб

    А либа этого по умолчанию не делает???
     
  3. А либо рассчитана на настоящий nrf24, а не китайский.
     
    parovoZZ нравится это.
  4. parovoZZ

    parovoZZ Гуру

    мы говорили про примеры, не? Либа сюда как приросла?
     
  5. Ivanii

    Ivanii Нуб

    Пример без либ работает? Нормальная библиотека должна не заданные параметры инициализировать значениями по умолчанию иначе при реинициализации в регистрах останутся неизвестные значения.
     
  6. parovoZZ

    parovoZZ Гуру

    ничего она не должна
    кто такое сказал?
    поэтому их и надо вручную инициализировать. Китайские клоны nRF не содержат в регистрах значения по умолчанию. В этой ветке это обсуждалось. Это не то место, где надо экономить на коде. Если хочется экономить на коде, то прямой путь к отказу от всяких абдурин. У меня инициализация выглядит примерно так:
    Код (C++):

     uint8_t nRF_Dummy_Init(uint8_t channel)
     {
        uint8_t Buf[5];

        nRF_CE_DDR |= (1<<nRF_CE);// | (1<<PINB2);
        nRF_CE_PORT |= (0<<nRF_CE);// | (1<<PINB2);


        Buf[0] = (0<<nRF_PRIM_RX) | (1<<nRF_EN_CRC) | (0<<nRF_CRCO) | (0<<nRF_PWR_UP);    // Проверка CRC разрешена, 1 байт CRC, режим передачи
        SPI_WriteArray(nRF_WR_REG(nRF_CONFIG), 1, Buf);

        nRF_SELECT();                            // Инициируем общение - держим пин CSN весь сеанс общения,
                                        // иначе трансивер всегда будет возвращать регистр статуса
        SPI_WriteByte(nRF_RD_REG(nRF_CONFIG));                    // Читаем, что записали
        Buf[1] = SPI_ReadByte(nRF_NOP);

        nRF_DESELECT();


        if (!(Buf[0] == Buf[1]))                        // Если не совпадает
        {
            return 1;                            // то выходим из функции
        }

        Buf[0] = channel;
        SPI_WriteArray(nRF_WR_REG(nRF_RF_CH), 1, Buf);            // Установка частоты канала передачи

        Buf[0] = nRF_SEND_LEN;
        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P0), 1, Buf);        // Длина передаваемых данных

        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P1), 1, Buf);

        Buf[0] = 0;
        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P2), 1, Buf);
        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P3), 1, Buf);
        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P4), 1, Buf);
        SPI_WriteArray(nRF_WR_REG(nRF_RX_PW_P5), 1, Buf);

        Buf[0] = (0<<nRF_RF_DR) | ((0x03)<<nRF_RF_PWR0);            // Скорость передачи 1 Mbps, мощность: 0dbm
        SPI_WriteArray(nRF_WR_REG(nRF_RF_SETUP), 1, Buf);

        Buf[0] = (1<<nRF_ENAA_P0)|(1<<nRF_ENAA_P1)|(0<<nRF_ENAA_P2)|(0<<nRF_ENAA_P3)|(0<<nRF_ENAA_P4)|(0<<nRF_ENAA_P5);
        SPI_WriteArray(nRF_WR_REG(nRF_EN_AA), 1, Buf);          

        Buf[0] = (1<<nRF_ERX_P0)|(1<<nRF_ERX_P1)|(0<<nRF_ERX_P2)|(0<<nRF_ERX_P3)|(0<<nRF_ERX_P4)|(0<<nRF_ERX_P5);
        SPI_WriteArray(nRF_WR_REG(nRF_EN_RXADDR), 1, Buf);        // Разрешаем RX адреса

        //Buf[0] = (0x04<<nRF_ARD0)|(0x0F<<nRF_ARC0);                // Автоповтор:  15 попыток через 1000 us;
        //SPI_WriteArray(nRF_WR_REG(nRF_SETUP_RETR), 1, Buf);

        Buf[0] = (0<<nRF_DPL_P0)|(0<<nRF_DPL_P1)|(0<<nRF_DPL_P2)|(0<<nRF_DPL_P3)|(0<<nRF_DPL_P4)|(0<<nRF_DPL_P5);
        SPI_WriteArray(nRF_WR_REG(nRF_DYNPD), 1, Buf);

        Buf[0] = 0x11;                                //адрес канала
        Buf[1] = 0x11;
        Buf[2] = 0x11;
        Buf[3] = 0x11;
        Buf[4] = 0x11;
        SPI_WriteArray(nRF_WR_REG(nRF_RX_ADDR_P0), 5, Buf);//адрес канала для приема ответа

        SPI_WriteArray(nRF_WR_REG(nRF_TX_ADDR), 5, Buf);    // Адрес канала для передачи
         
        Buf[0] = nRF_REPEAT_INTERVAL | nRF_REPEAT_MAX;        //интервал автоповтора и количество попыток
        SPI_WriteArray(nRF_WR_REG(nRF_SETUP_RETR), 1, Buf);

        return 0;
    }
     
     
    Последнее редактирование: 9 дек 2018
  7. Ivanii

    Ivanii Нуб

    Спасибо, буду разбираться.
     
  8. Wolferio

    Wolferio Нерд

    Добрый вечер. Тему читал правда не всю. Есть 3 передатчика и 1 приемник (NRF24L01) (реализовал беспроводные сигнализаторы поклевки на рыбалку)- все работает данные передаются и принимаются. Но есть одно "НО" - сигнал работает в пределах 5-10 метров, дальше практически все 3 передатчика не тянут (тем более на открытой местности, где нет никаких помех). Подскажите как увеличить дистанцию сигнала, в чем может быть причина?, знаю что для таких передатчиков это ничтожно малое расстояние. Заранее благодарен.
     
    Последнее редактирование: 20 дек 2018
  9. parovoZZ

    parovoZZ Гуру

    Ну ты же купил отбраковку по дешману на али по цене оригинальной микросхемы. У оригинальной микры выходная мощность 1 мВт. Какая мощность у отбраковки - только гадать. Ну и наверняка с питанием касяки))
     
  10. ImrDuke

    ImrDuke Гик

    Конденсаторы на входе по питанию припаивали?
    Модули к МК припаяны или на разъемах?
     
  11. Wolferio

    Wolferio Нерд

    Конденсаторы на входе по питанию припаивали? - да конденсаторы припаяны.
    Модули к МК припаяны или на разъемах? - все 3 паяные, кроме приемника, приемник вместе с ардуиной на плате на разъемах.
    Питание там и там отдельное не от ардуины.
     
    Последнее редактирование: 20 дек 2018
  12. Eduard-VIII

    Eduard-VIII Нуб

    Ребят, подскажите инвалиду элементарный код. В теме нашел примерно похожий, но не получается.
    Приёмник nRF1 принимает из гаража integer от такой же nRF2-передатчика. Выводит на LCD1602 значение 0-1023, и состояние двух реле (на .nRF2). Это получается.
    Один раз в неделю нужно приёмник перевести на передачу, а передатчик на приём, изменить состояние реле и снова встать на приём первой НРФкой. Это никак не выходит. Может мозги совсем вытекли после инсульта?
     
  13. parovoZZ

    parovoZZ Гуру

    а есть что-то, что сможет отсчитать 604 800 секунд?
     
  14. Eduard-VIII

    Eduard-VIII Нуб

    Вы немного не поняли. Перевести приёмник в режим передатчтка, а передатчик в приёмник нужно вручную.
    Короче, приёмник, помимо основной задачи (приёма переменной) - это дистанционный тумблер.
    Т.е. включил тумблер на приёмнике (ON) - реле на передатчике влючилось и остаётся включенным, пока на приёмнике тумблер не выключу. Выключил в хате на приёмнике тумблер (OFF) -на передатчике реле выключилось - ждёт сигнала на включение, а приёмник переменную принимает постоянно.
     
  15. ImrDuke

    ImrDuke Гик

    Я сделал что все устройства приемники. Когда надо, один что то передает, остальные слушают и если в пакете находят свой ID, то выполняют инструкцию.
     
  16. Eduard-VIII

    Eduard-VIII Нуб

    Если НРФка умеет и принимать и передавать, неужели для моей задачи - дистанционный тумблер на приёмнике и передача переменной с передатчика - нужно 4 модуля?
    Если задача для Вас смешная - не смейтесь, подскажите, пожалуйста.
     
  17. parovoZZ

    parovoZZ Гуру

    В регистре CONFIG необходимо установить бит PRIM_RX. После поднятия ноги CE трансивер переходит в режим приемника. О полученном пакете можно узнать по выставленному биту RX_DR в регистре STATUS. Вычитывается полученный пакет командой R_RX_PAYLOAD.
     
  18. Eduard-VIII

    Eduard-VIII Нуб

    Сформулирую понятнее. С ардуиной недавно, в программировании слаб.
    Хлопнул инсульт. В гараж ходить тяжело. Делаю дистанционный тумблер, включающий-выключающий 2 контактора в гараже. Приёмник дома. На него приходит переменная. Этот же приёмник должен на мгновение переключится в режим передачи, а передатчик превратить в приёмник, назначить состояние пинов и вернуться в режим приёма
    Нужен кусочек кода, который при условии на приёмнике
    if(digitalRead(aPin) == LOW)
    выполнит условии на передатчике
    digitalWrite(Relay1, LOW);
    а потом вернуть приёмник на приём, а передатчик на передачу.
    Одной рукой и оставшейся после ОНМК частью мозгов сделал себе на ардуине такой электрокар без посторонней помощи


    а такую фигню никак...
    Подскажите, пожалуйста.
     
  19. ImrDuke

    ImrDuke Гик

    У меня так.

    Устройство с реле.
    Код (C++):
    #include <nRF24L01.h>
    #include <RF24.h>

    //--------------------- НАСТРОЙКИ -------------------------------
    #define DeviceID  2             // Номер устройства
    #define btnAlarm  2             // Вход датчика охраны (геркон)
    #define ctrPIN    5             // Управление вентилятором
    #define CH_NUM    0x44          // Номер канала (должен совпадать с приёмником)
    #define SIG_POWER RF24_PA_MAX   // УРОВЕНЬ МОЩНОСТИ RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
    #define SIG_SPEED RF24_1MBPS    // СКОРОСТЬ ОБМЕНА RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
    //--------------------- НАСТРОЙКИ -------------------------------
    //CE   PIN9
    //CSN  PIN10
    //SCK  PIN13
    //MOSI PIN11
    //MISO PIN12

    RF24 radio(9, 10);         // "Создать" модуль на пинах 9 и 10
    uint32_t Transmit_Data[6]; // Массив, хранящий передаваемые данные;
    uint32_t Received_Data[6]; // Массив, хранящий принимаемые данные;
    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

    byte DevID;          // Номер устройства

    void setup() {
      //Serial.begin(9600); //Инициируем порт отладки
      RadioSetup();
      byte pin;
      switch (btnAlarm) {
        case 2: pin = 0;
          break;
        case 3: pin = 1;
          break;
      }
      pinMode(btnAlarm, INPUT);     // Пин D2/D3 подтянут к Vcc
      attachInterrupt(pin, Alarm, FALLING); // Arduino Uno цифровые пины 2 (int 0) и 3 (int 1)
      pinMode(ctrPIN, OUTPUT); //Инициируем выход управления
      digitalWrite(ctrPIN, HIGH);
    }

    void loop () {
      byte  pipeNo;
      while (radio.available(&pipeNo)) {  // Слушаем эфир со всех труб
        radio.read(&Received_Data, sizeof(Received_Data)); // Чиатем входящий сигнал
        DevID = Received_Data[0];
        if (DevID == 0) {
          Flag_Btn = Received_Data[1];
        }
      }
      //что то делается
    }//end loop()

    void Transmit(boolean _Flag) {
      noInterrupts();
      radio.openWritingPipe(address[0]); // мы - труба 0, открываем канал для передачи данных
      radio.stopListening();  //не слушаем радиоэфир, мы передатчик
      Transmit_Data[0] = DeviceID;                              // Номер устройства
      Transmit_Data[1] = ;
      Transmit_Data[2] = ;
      Transmit_Data[3] = ;
      Transmit_Data[4] = _Flag;                                 // Геркон
      Transmit_Data[5] = Flag_Btn;                              // Реле
      radio.write(&Transmit_Data, sizeof(Transmit_Data));       // Отправить по радио
      radio.openReadingPipe(1, address[0]);                     // хотим слушать трубу 0
      radio.startListening();                                   // начинаем слушать эфир, мы приёмный модуль
      interrupts();
    }

    void RadioSetup() {
      radio.begin();                        // активировать модуль
      radio.setAutoAck(1);                  // режим подтверждения приёма, 1 вкл 0 выкл
      radio.setRetries(0, 15);              // (время между попыткой достучаться, число попыток)
      radio.enableAckPayload();             // разрешить отсылку данных в ответ на входящий сигнал
      radio.setPayloadSize(32);             // размер пакета, в байтах
      radio.openReadingPipe(1, address[0]); // хотим слушать трубу 0
      radio.setChannel(CH_NUM);             // выбираем канал (в котором нет шумов!)
      radio.setPALevel(SIG_POWER);          // УРОВЕНЬ МОЩНОСТИ RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate(SIG_SPEED);         // СКОРОСТЬ ОБМЕНА RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      radio.powerUp();                      // начать работу
      radio.startListening();               // начинаем слушать эфир, мы приёмный модуль
    }

    void Alarm() {
      Transmit(1);
    }
     
    Eduard-VIII нравится это.
  20. Eduard-VIII

    Eduard-VIII Нуб

    Спасибо, попробую под себя подрихтовать...