Дружба nRF24L01+ и nRF24LE1!

Тема в разделе "Проводная и беспроводная связь", создана пользователем Сергей Валериевич, 21 ноя 2018.

Метки:
  1. Задача соединить nRF24L01+МК+усилитель и антенна, с nRF24LE1, 24 пина, керамическая антенна!
    Ну и конечно же с ответом о получении команды

    Выдержка из кода передатчика, ATmega168(328) Arduino Pro Mini + nRF24L01+
    Код (C++):
    //Инициализация:
      radio.begin();                              // начало работы с NRF24l01
      radio.setDataRate(RF24_250KBPS);            // скорость передачи
      radio.setChannel(CHANNEL);                  // номер канала от 0 до 125
      radio.setPALevel(RF24_PA_HIGH);             // мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
      radio.setAutoAck(false);                    // автоподтверждение выключено
      radio.setCRCLength(RF24_CRC_16);            // crc 16 бит
      radio.setPayloadSize(1);                    // размер данных 1 байт
      radio.openWritingPipe(pipes[1]);            // открываем канал передачи
      radio.openReadingPipe(1, pipes[0]);         // открываем один из 6-ти каналов приема

    //ну а так же сама передача и проверка ошибки, если таковая была:
    // передача нажатой кнопки приёмнику с проверкой
    bool sendCommand(void){
        unsigned char cheakCommand = 0;         // проверочная команда
        radio.flush_tx();                       // очистка буфера передачи
        radio.stopListening();                  // переходим на передачу данных
        radio.write(&command, sizeof(command)); // отправляем команду
        radio.startListening();                 // начинаем слушать эфир
        if(radio.available()){                  // проверяем не пришло ли чего в буфер
          radio.read(&cheakCommand, sizeof(cheakCommand));  // принимаем команду
        }
      if(command == cheakCommand) return true;  // передача завершилась удачей
      else return false;                        // иначе нет
    }
    Для приёмника писал всё в CodeBlocks+SDCC:
    Код (C++):
    //Инициализация:
        rf_configure_debug_lite(true, 1); /// инициализация приёмника в режиме приёма одного байта с выключенной проверкой
        setRetries(); /// установка количества попыток приёма-передач сигнала, и промежутка между ними
        setCRCLength(2);
        setChannel(CHANNEL); /// установка канала приёма-передачи сигнала
        setDataRate(DATA_RATE); /// установка скорости приёма-передачи сигнала
        setPALevel(PA_LEVEL); /// установка мощности приёма-передачи сигнала (PA_MAX)/

    /// Приём/передача ответа:
    /// получение команды и отправка её в ответ
    unsigned char getCommand(void){
        unsigned int counter; /// счётчик попыток чтения
        for(counter = 0; counter < 15000; counter++){ /// устраиваем цикл для приёма команды
            if(rf_irq_pin_active() && rf_irq_rx_dr_active()){ /// если есть что-то в канале для чтения, то читаем
                rf_read_rx_payload(&command, 1); /// чтение команды от передатчика
                break; /// выход из цикла
            }
        }
        rf_irq_clear_all(); /// сбрасываем все значения прерываний в rf
        rf_set_as_tx(); /// перевод rf в режим TX для передачи
        rf_write_tx_payload(&command, 1, true); /// передача команды передатчику
        while(!(rf_irq_pin_active() && rf_irq_tx_ds_active())); /// ожидаем, пока пакет будет отправлен или достигнуто максимальное число попыток передачи
        rf_irq_clear_all(); /// сбрасываем все значения прерываний в rf опять
        rf_set_as_rx(true); /// перевод rf в режим RX для чтения
        return command; /// возвращаем полученную команду
    }
    Вот и вопрос, как сделать обратную связь между Л01 и ЛЕ1 нормально, с помощью ACK?
    И ещё, если кто знает, как будить ЛЕ1 по прерыванию, к примеру, в эфире появилось что-то для неё, она просыпается из сна, делает своё дело, и засыпает?
    Заранее спасибо!

    P.S.
    Если есть и по дальности работы предположения - очень буду рад!
    А так же подтверждение получения команды....


    Добавлю к своему посту, там номер канала сами понимаете одинаков между приёмником и передатчиком.
    Индикаторы труб используются заводские, как помню 0xE7E7E7E7E7, что для приёма, что для передачи.
    Мощности разные, Л01 у меня с усилителем и антенной, и более чем HIGH уже она не работает, а вот приёмник (LE1), имеет лишь керамическую антенну, (тут мне важен размер и энергопотребление) вполне восприимчив и на MAX.
     
    Последнее редактирование: 21 ноя 2018
  2. Отвечу сразу, с этими настройками и и функциями отправки и получения команд, а так же подтверждение, работает, но необходимо клиент(nRF24LE1) сделать сонным пока ему лично ничего не поступит что-либо в эфир, вот тут я и подумал о прерывании, изначально у меня всё "просыпалось" 2 раза в секунду, проверяло эфир, и если получало, то отвечало, но это на данный момент не устраивает. Проще бы как есть в эфире, то будить радиомодуль, и он делает свою работу, потом снова сон. Ну а так же исходя что клиент просыпается лишь 2 раза в секунду, я получаю неудобства с подтверждением получения команды, отсюда и вопрос об ACK.
    Ну какое-то расстояние малое, да и подтверждение приходит плохо.
     
    Последнее редактирование: 21 ноя 2018
  3. parovoZZ

    parovoZZ Гуру

    не получится. Необходимо просыпаться и самостоятельно запрашивать у хоста информацию для себя.
     
  4. Но для nRF24L01 это я смог сделать.
    Код (C++):
    void loop(){
      attachInterrupt(0, wakeUp, LOW);            // уснуть пока IRQ NRF24 не изменит свои показания
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  // указываем как уснуть
      detachInterrupt(0);                         // выключаем прерывание
      NRF();                                      // выполняем поставленные задачи
    }
    Вот что-то такое же и хочу для nRF24LE1.
     
  5. parovoZZ

    parovoZZ Гуру

    nRF в режиме приемника 13 мА жрет.
     
  6. Собственно для этого и нужен сон, спит пока нет приёма или передачи, просыпается как есть что в эфире, быстро всё делает, и спит дальше, амперметр даже толком не успевает среагировать. Но нужно это провернуть в nRF24LE1.
     
  7. parovoZZ

    parovoZZ Гуру

    ты не понял - чтобы что-то уловить из эфира, приемник всегда должен быть включен. И жрет он 13 мА. Ну или в этом диапазоне (на LE1 не помню - давно смотрел). Поэтому все "полусонные" устройства, которые работают от батарей, работают как я писал выше.
     
  8. Нет, нет... Я всё понял, всё верно говоришь.
    Вот смотри как я делал сон в nRF24LE1:
    Код (C++):
    // основной цикл
            rf_power_up(true); /// включаем RF в режиме RX
            delay_ms(6); /// небольшая задержка после включения
    ..тут разные команды, которые надо быстро выполнить, в том числе чтение эфира..
    ...после работы с радио выполняем:
            rf_power_down(); /// выключаем RF
            if(count == 5){ /// дабы засыпать каждый пятый раз в цикле
                pwr_clk_mgmt_enter_pwr_mode_register_ret(); /// энергосбережение до ~450 mkA
                count = 1;
            }
    //
    А вот как в nRF24L01:
    Код (C++):
    void loop(){
      attachInterrupt(0, wakeUp, LOW);            // уснуть пока IRQ NRF24 не изменит свои показания
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  // указываем как уснуть
      detachInterrupt(0);                         // выключаем прерывание
      NRF();                                      // выполняем поставленные задачи
    }
    Оба работают, но мне надо сделать nRF24LE1 так же как nRF24L01 по прерыванию
     
  9. И сон по прерыванию в nRF24LE1 это не единственное что мне нужно там сделать, так же я хочу как комплект передатчик(nRF24L01)+приёмник(nRF24LE1), сделать подтверждение через ACK(автоподтверждение получение сигнала), а не получил и отправил обратно что получил.
     
  10. Для справки, L01 и LE1 идентичны в этом плане, я про прожёрливость :о)
     
  11. Ещё для справки, если используете сон, пользуйтесь ещё и "сторожевым псом". Просто у меня было такое, что я пренебрег этим, и поплатился...
     
  12. b707

    b707 Гуру

    Ты ошибаешься. Код, который у тебя приведен как сон для nRF24L01 - это сон - но сон не NRF.а твоего контроллера, например ардуины. Она засыпает и просыпается. когда NRF дергает прерывание.
    А NRF нифига не спит, он остается в режиме приемника и продолжает жрать свои 13ма

    посмотри внимательно на свой же код
    Код (C++):
    void loop(){
      attachInterrupt(0, wakeUp, LOW);            // уснуть пока IRQ NRF24 не изменит свои показания
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  // указываем как уснуть
      detachInterrupt(0);                         // выключаем прерывание
      NRF();                                      // выполняем поставленные задачи
    }
    где тут отправка nRF24L01 в сон??? - Строка 2 - прерывание ты устанавливаешь в ардуине, сон настраиваешь в строке 3 тоже ей - посмотри в код - видишь отключение ADC и BOD ?- а какие нафиг ADC в NRF? - конечно же, это отправка в сон контроллера ардуины

    Так что не надо спорить, Паровоз прав - если хочешь, чтобы приемник что-то ловил из эфира - он спать не может.
     
    Последнее редактирование: 21 ноя 2018
  13. parovoZZ

    parovoZZ Гуру

    это бесполезная инструкция.
     
  14. Стоит перепроверить амперметром...