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

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

  1. parovoZZ

    parovoZZ Гуру

    А ведь можно открыть даташит или переведённый на русский язык обзор и сделать всё ручками. У меня на это ушло 3 вечера.
     
  2. Wolferio

    Wolferio Нерд

    У меня всё это заняло вечер. Вопрос "Зачем Изобретать велосипед?"
     
  3. parovoZZ

    parovoZZ Гуру

    У меня не более пару часов было на вечер. С учетом того, что и на малинке поднял связь через nRF, но у же с библиотекой и через прерывания =) Ну всё, как и должно быть. На МК весь код уложился в 1.2 кБ. Вообще, есть дикое желание перелезть на многоногую аттини - 328 камень много батареек жрет. Цель - 2-3 года от литиевой на 3 вольта 250 мА/ч с выходом в эфир раз в 5 минут. А следующий этап - солнечная батарея с ионисторами.
    Я всегда был свободным человеком. Захочу - буду программировать МК от TI, или STM, или отечественное что. То бишь я свободен и не зависим в этом плане. И никакого велосипеда в этом нет. Даташиты для того и пишутся, чтоб их читали и изучали.
     
  4. Ilyadodge

    Ilyadodge Нуб

    Всем привет. НЕ пинайте сильно. Я полный ламер в этих вопросах.
    Кто нибудь сталкивался вот с таким вот модулем. ?
    https://ru.aliexpress.com/item/New-...89caf24&transAbTest=ae803_1&priceBeautifyAB=0

    Продавался как NRF24L01+ но по факту этот модуль используя скетчи годные для NRF24L01+ не видит ничего.
    Обычный модуль NRF24L01+ на тех же скетчах работает прекрасно.
    Кондеры напаяны на оба модуля.
    Сразу оговорюсь на алиэкспрессе купил обычный модуль NRF24L01+ точнее купил два но пришел только один. ПРишлось второй в магазине докупать. А завести второй не получилось. Нашел похожий модуль на алиэкспресс и кинул ссылку сюда в надежде на то что кто либо его опознает и сможет подсказать.
    НА модуле никаких опознавательных знаков нет
     
  5. ИгорьК

    ИгорьК Гуру

    Ты первый пост видел?????????????????????????

    Первый! Ламер - это что? Халявщик, не читающий тему?
     
  6. Ilyadodge

    Ilyadodge Нуб

    А вы уверены что в теме именно этот модуль есть ? я его не обнаружил в ней. 88 страниц прочитать ради того что бы увидеть что его тут нет удовольствие сомнительное. В вашем первом сообщении где рассматриваються модули этого модуля нет.
     
  7. ИгорьК

    ИгорьК Гуру

    Первое фото в первом посте не помогло?
     
  8. Ilyadodge

    Ilyadodge Нуб

    Это не он.
     
  9. ИгорьК

    ИгорьК Гуру

    Это он.
     
  10. Ilyadodge

    Ilyadodge Нуб

    Спасибо. Можете просто сказать. В Итоге его можно с обычным NRF24L01+ подружить ? Из поста я так понял что нет. Может ошибаюсь ?
     
  11. ИгорьК

    ИгорьК Гуру

    И на кой я все это писал и собрал в начале темы?

    Нельзя его спарить с обычным.
     
    MickNich и Ilyadodge нравится это.
  12. Ilyadodge

    Ilyadodge Нуб

    Спасибо.
     
  13. Jazzy

    Jazzy Нерд

    Ищу гуру по nrf24. Нужна оптимизация быстродействия под конкретный проект с подключением irq пина. Подробно расскажу в лс.
     
  14. parovoZZ

    parovoZZ Гуру

    чиркай.
     
  15. Добрый день.
    Данный модуль начал изучать пол года назад, в ходе экспериментов удалось завести и наладить передачу данных в обе стороны, однако столкнулся со странным поведением, которое не могу исправить уже более двух недель. Прочитал все 88 страниц в надежде найти ответ, так же искал информацию на англоязычных сайтах, но пока безуспешно.

    Работаю с модулями так, передатчик передает пакет, переключается в режим прослушки и ждет ответ от приемника, приемник как получил пакет, обработал, переключается в режим передачи и возвращает ответ. (Использую ACK на обоих модулях). И все бы хорошо, если бы не одно странное поведение. Иногда необходимо передавать сразу несколько пакетов подряд (длинная посылка разбитая по 32 байта). В таком случае если пакетов 3, 6, 9 и т.д. происходит следующее, передатчик успешно отправляет 3 пакета подряд, переключается в режим прослушки, приемник принимает пакеты обрабатывает их, переключается в режим передачи, передает ответный пакет, приходит ACK о том что пакет успешно передан, но передатчик в режиме прослушки ничего не получает. Хотя иногда все же данные приходят. Причем если отправить 4 пакета подрят, то все работает отлично.
    Если не переключать режимы, прием передача, то тоже все работает отлично.
    По скольку проблеммы только на числах кратных 3м, то подозреваю что тут что то не ладное с очередью FIFO которая как раз имеет буфер на 3.

    Пробовал отключить ACK, в таком случае все хорошо работает, но мне нужно подтверждение о получении пакета, можно конечно реализовать это программным образом, и переключаться между режимами. Но в таком случае возникает следующая ситуация, при отправке нескольких пакетов подряд, когда передатчик передал пакет, приемник ответил, но его ответ не дошел, и передатчик еще раз отправляет пакет, одни и те же данные могут прийти повторно, и тут их надо сверять. Поэтому такой режим не подходит.

    Для питания использую преобразователи с 5в на 3.3в (двух типов) вот такой, пробовал модули от трех разных продавцов, с усилителями и без, дополнительно напаивал конденсаторы. Один приемник собран на плате и полностью пропаян, еще два на макете и дюпонах, да и стабильность работы не дает грешить на питание.

    Вот уже не знаю что здесь думать, подключаю модули к Arduino nano заказанных у одного продавца одной партией, может дело в них.

    Использую библиотеку nrf от tmrh20 последнюю скачанную через Arduino IDE. Здесь уже писали что она доработанная и лучше использовать ее.
    Если кто сталкивался с подобной проблемой помогите. Уже столько времени потратил на модуль, что хочется все таки запустить проект на нем. Но уже во всю смотрю на esp8266.

    Если у кого то есть возможность хочу попросить проверить данное поведение с моим скетчем. Специально для отлавливания этой проблеммы собрал два тестовых скетча, по мере чтения форума они слегка выросли в размерах, вставлял паузы, перед отправками менял режимы, для сброса очереди, менял настройки инициализации, использовал writeFast и т.д. Но к сожалению ни чего не помогает. Помогает только сброс питания модуля на передатчике, тогда он первый раз отправляет и принимает с успехом, а дальше опять сбои.

    передатчик
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24 radio(9, 10);
    int radio_retries = 5;
    int radio_delay = 10;

    const uint64_t pipes[3] = { 0xAABBCCDD44LL, 0xAABBCCDD44LL, 0xAABBCCDD55LL };
    byte data1[32] {48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48};
    byte data2[32] {49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49};
    byte data3[10] {50,50,50,50,50,50,50,50,50,50};

    void setup() {
      Serial.begin(9600);
      Serial.setTimeout(50);
      radio.begin();
      delay(100);
      radio.powerUp();
      // radio.setAutoAck(false);
      radio.setAutoAck(true);
      radio.setChannel(90);
      radio.setRetries(15,15);
      radio.setPayloadSize(32);
      radio.setCRCLength(RF24_CRC_8);
      radio.setDataRate(RF24_1MBPS);     // (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS)
      radio.setPALevel(RF24_PA_MAX);       // (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1, pipes[2]);
      radio.startListening();
    }

    void loop() {
      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[2]);
      radio.stopListening();
      delay(1000);
      send();
      radio.openWritingPipe(pipes[2]);
      radio.openReadingPipe(1,pipes[0]);
      radio.startListening();
      radio.flush_rx();
      radio.flush_tx();
      delay(1000);
      radio.stopListening();
      radio.startListening();
      recive();
      delay(3000);
    }

    void send() {
      if (!radio.write(data1, sizeof(data1))) {
        fifo();
        Serial.println("fail data1");
        return ;
      }
      fifo();
      delay(1200);
      if (!radio.write(data2, sizeof(data2))) {
        fifo();
        Serial.println("fail data2");
        return ;
      }
      fifo();
      delay(1200);
      if (!radio.writeFast(data3, sizeof(data3))) {
        fifo();
        Serial.println("fail data3");
        return ;
      }
      fifo();
      delay(1200);
    }

    void recive() {
      byte income_pipe;
      byte signal[32];
      unsigned long responce_started_at = millis();
      boolean timeout = true;

      // Wait 5 seconds for responce
      while (millis() - responce_started_at < 5000) {
        if (radio.available(&income_pipe)) {
          if (income_pipe == 1) {
            radio.read(&signal, sizeof(signal));
            timeout = false;
            break;
          }
        }
      }

      if (!timeout) {
        for (int i = 0; i < sizeof(signal); i++) {
          Serial.write(signal[i]);
        }
        Serial.write(10);
      } else {
        Serial.println("RADIO RESPONCE TIMEOUT");
      }
    }

    void fifo() {
      if(!radio.txStandBy()){
        Serial.println("fail fifo");
      }
    }
     
    приемник
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24 radio(9, 10);
    int radio_retries = 5;
    int radio_delay = 10;

    const uint64_t pipes[3] = { 0xAABBCCDD44LL, 0xAABBCCDD44LL, 0xAABBCCDD55LL };
    byte data1[32] {48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48};
    byte data2[32] {49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49};
    byte data3[10] {50,50,50,50,50,50,50,50,50,50};

    void setup() {
      Serial.begin(9600);
      Serial.setTimeout(50);
      radio.begin();
      delay(100);
      radio.powerUp();
      // radio.setAutoAck(false);
      radio.setAutoAck(true);
      radio.setChannel(90);
      radio.setRetries(15,15);
      radio.setPayloadSize(32);
      radio.setCRCLength(RF24_CRC_8);
      radio.setDataRate(RF24_1MBPS);     // (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS)
      radio.setPALevel(RF24_PA_MAX);       // (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
      radio.openWritingPipe(pipes[2]);
      radio.openReadingPipe(1, pipes[0]);
      radio.startListening();
    }

    void loop() {
      if (radio.available()) {
        listen();
      }
    }

    void listen() {
      byte code[32];
      boolean isData = false;
      unsigned long started_at = millis();

      while (millis() - started_at < 1500) {
        if (radio.available()) {
          radio.read(&code, sizeof(code));
          radio.stopListening();
          radio.startListening();

          for (int i = 0; i < sizeof(code); i++) {
            Serial.write(code[i]);
          }
          Serial.write(10);
          started_at = millis();
          isData = true;
        }
      }

      if (isData){
        radio.flush_rx();
        radio.flush_tx();
        delay(2000);
        Serial.println("try to send back");
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[2]);
        radio.stopListening();
        delay(100);
        if (!radio.write(data3, sizeof(data3))) {
          Serial.println("fail data3");
        }
        radio.openWritingPipe(pipes[2]);
        radio.openReadingPipe(1,pipes[0]);
        radio.startListening();
      }
    }
     
    PS. На форуме писали что антенны с усилителями начинают работать только при прикосновении к антенне пальцем, сталкивался с такой проблеммой, решил ее проставлением всевозможных настроек в сетапе.
     
    Последнее редактирование: 13 июн 2018
  16. parovoZZ

    parovoZZ Гуру

    Эта тема для тех, у кого трансиверы не завелись с кандачка)) Если связь между трансиверов пошла, то читать эту тему бесполезно - искусство программирования данных трансиверов здесь не приводится. Курс молодого бойца ты уже прошел.
    Читать надо не сайты с форумами, а даташит. Там всё разложено по полочкам.

    Я глубоко убежден, что библиотеки = зло. Понимания как работать с трансиверами так и не наступит.
    Порядок отправки пакета следующий.
    1. Заряжаем буфер fifo данными с помощью команды W_TX_PAYLOAD. Если подтверждение не требуется, то команда должна быть W_TX_PAYLOAD_NOACK. После чего дергаем ногу CE. Через 130 микросекунд трансивер начнет передачу. Приемник по принятию пакета и проверки его на целостность, отправляет пакет подтверждения ACK. Если есть необходимость передачи данных от приемника в сторону передатчика, то в fifo приемника их можно записать командой W_ACK_PAYLOAD. С первым же пакетом подтверждения они улетят. Переключаться между режимами для обратной передачи пользователю не надо - трансивер делает все сам автоматически.
    2. Факт успешной доставки пакета устанавливается прерыванием на ноге IRQ. Как только получили прерывание, читаем регистр статуса. В нем содержится три флага:
    TX_DS - флаг поднимается после успешной доставки пакета (получен пакет подтверждения ACK). Значит, можно заряжать fifo новой порцией данных и отправить её.

    MAX_RT - флаг поднимается тогда, когда лимит повторной отправки пакета исчерпан, а пакет подтверждения так и не получен. В этом случае есть два пути - стереть пакет из буфера или пытаться его отправить повторно командой REUSE_TX_PL до получения подтверждения. В любом случае этот флаг надо сбросить вручную, иначе блокируется дальнейшая работа (либо выключить трансивер pwr_up = 0).

    RX_DR - это, собственно, флаг успешного приема пакета. Если в пакете пришли данные, которые ждем, то читаем их длину, в какой трубе и лезем в fifo их считывать. По окончании чтения данные уз fifo удаляются автоматически. Если не ждем - стираем их.

    Ну вот как-то так.)))
     
  17. parovoZZ

    parovoZZ Гуру

    Ещё что заметил - скорость 1 мбит, а какой таймаут между повторными отправками пакетов? Передатчик банально может не успевать принимать пакет подтверждения, т.к. стреляет как из пулемета.
     
  18. Спасибо за ответ.

    В скетче ставил паузы по 1с, 3с. Нет передач подряд без задержек. Тоже думал что в этом может быть проблема. Поэтому стал отправлять, ждать секунду и ещё раз отправлять, после переключений тоже задержки.

    Самое интересное что подтверждение об успешной отправке приходит, а вот передатчик в режиме прослушки не обнаруживает данных в буфере.
    Делал костыль, что если число пакетов кратное трем, добавлять ещё один пакет.

    К слову IRQ у меня не подключен, только 7 из 8 подключены.
    Тут читал что у кого-то завелось с подключением всех 8. Стоит попробовать.

    Буду дальше изучать проблему, если удастся решить, напишу.

    Ещё раз спасибо за ответ.
     
    Последнее редактирование: 14 июн 2018
  19. parovoZZ

    parovoZZ Гуру

    Да хоть час. Как только получил флаг об успешной отправке пакета - смело передавай следующий. Буфер фифо можешь сразу зарядить данными, но надо следить за флагом переполнения, иначе данные бесследно исчезнут.

    А зачем переключаешься в режим приема? Данные можешь переслать в пакете подтверждения. В любом случае, после переключения режимов необходимо подождать 130 микросекунд - время стабилизации петли ФАПЧ.

    Работать надо по прерываниям от ноги irq. Получил прерывание - прочитал регистр статуса - порешил дела.

    У меня влёгкую передаются 300 пакетов в секунду по 11 байт в каждом. Можно и гораздо быстрее - в целях отладки частота тактирование всего мегагерц, отравляю один и тот же пакет 15 раз через 250 микросекунд. Место для разгона есть - как минимум, в 100 раз))
     
  20. parovoZZ

    parovoZZ Гуру

    По паузе повтора так и не сказал.