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

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

  1. ra0wx

    ra0wx Нерд

    К сожалению, ничего не получается. Как только программа приемника входит
    Код (C++):
     if ( radio.available()) {  }
    и нет данных с передатчика, она останавливается. И не могу пока найти ответ, как продолжить выполнение. Может быть кто то еще сталкивался с такой ситуацией?
     
  2. parovoZZ

    parovoZZ Гуру

    Это ты с помощью внутрисхемной отладки определил?
     
  3. ra0wx

    ra0wx Нерд

    Да, выполнял построчное разрешение работы программы. Вот такой простой код
    Код (C++):
     if ( radio.available()) {
              lcd.setCursor(12,0);lcd.print("RUN")
              }
    уже не выполняется при отключении передатчика.
     
  4. parovoZZ

    parovoZZ Гуру

    Есть всего два путя - работать по прерыванию и второй - вычитывать регистр статуса и проверять флаг заполнения буфера приемника. Все остальное - это рытьё ямы посреди дороги. Что и было показано выше.
     
  5. ra0wx

    ra0wx Нерд

    Вы правы. Не поможете с реализацией примера кода для ардуино, я в этом деле относительный новичок.
     
  6. b707

    b707 Гуру

    Конечно не выполняется - он и не должен.
    Но это же не означает. что "программа останавливается"
     
  7. ra0wx

    ra0wx Нерд

    Я
    Я имел ввиду, что она ждет данных из канала, и дальнейших шагов не делает. Нет смысла обсасывать этот момент, он понятен. А вот как проверять флаг заполнения буфера приемника, это более интересно.
     
  8. b707

    b707 Гуру

    приведите весь код
    С чего вы взяли, что "дальнейших шагов не делает" - не понятно. Оператор if не блокирющий
     
  9. parovoZZ

    parovoZZ Гуру

    Я вот так делаю. Если кто найдет баг или возможный баг - скажите.
    Код (C++):
    nRF_SELECT();

                    status = SPI_WriteByte(nRF_NOP);            // Отправляем команду пустышку и первым байтом транcивер отдаст статус

                    nRF_DESELECT();
                     
                    SPI_WriteArray(nRF_WR_REG(nRF_STATUS), 1, &status);    // Сбрасываем все прерывания    

                 
                    if (BitIsSet(status, nRF_MASK_RX_DR))            // Если получены данные
                    {
                        WDT_int_16mS;                // Взводим вачдог, если связь с трансивером пойдет не по плану
         
             //ниже полученные данные из автоответа...моя специфика. У вас другое либо вообще нет.
                        while (nRF_Receive(&Payload))            // Вычитываем настройки, пока не опустеет буфер
                        {
                            Value_threshold_min = (Settings.Sensivity >> 1);

                            Settings.Sensivity &= 0b1;

                            T0_Set_OCR0A(Settings.Level);
                        }
      // выше полученные данные из автоответа...моя специфика

                        WDT_off;                    // Выключаем вачдог

                        ClearBit(status, nRF_MASK_RX_DR);
                    }

                    if (BitIsSet(status, nRF_MASK_MAX_RT))            // Если прием не подтвержден
                    {
                        nRF_SELECT();

                        SPI_WriteByte(nRF_FLUSH_TX);            // Очищаем буфер передачи

                        nRF_DESELECT();

                        ClearBit(status, nRF_MASK_MAX_RT);
                    }
    Код (C++):
    uint8_t    status;                // Переменная со значением регистра статуса из трансивера
    ыыыы Форум моржопит табуляцию(((
     
  10. ra0wx

    ra0wx Нерд

    Спасибо, вечером проверю в железе. В своих изысканиях по библиотеке , наткнулся на проверку этого регистра :
    Код (C++):
    /****************************************************************************/

    void RF24::startListening(void)
    {
      write_register(CONFIG, read_register(CONFIG) | _BV(PWR_UP) | _BV(PRIM_RX));
      write_register(STATUS, _BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );

      // Restore the pipe0 adddress, if exists
      if (pipe0_reading_address)
        write_register(RX_ADDR_P0, reinterpret_cast<const uint8_t*>(&pipe0_reading_address), 5);

      // Flush buffers
      flush_rx();
      flush_tx();

      // Go!
      ce(HIGH);

      // wait for the radio to come up (130us actually only needed)
      delayMicroseconds(130);
    }

    /****************************************************************************/
    Думаю, если отследить состояние _BV(RX_DR ), (что в принципе перекликается с вашим кодом), можно получить искомое. Почему то толком нигде не описан выход линии IRQ, есть немного в описании регистра "MASK_RX_DR, MASK_TX_DS, MASK_MAX_RT - маскировка источников прерываний. При установке одного из этих бит в единицу, соответствующее событие и установка соответствующего бита в регистре STATUS не будет генерировать сигнал прерывания на линии IRQ." По сути, возможно по состоянию этого выхода можно отслеживать есть прием данных или нет.Но все нужно проверить в железе. Такого симулятора на работе нет. Плюс нужен еще один вход контроллера.
     
  11. parovoZZ

    parovoZZ Гуру

    в даташите всё прекрасно описано. Да там и описывать-то нечего.

    Не можно - а нужно. Для передатчика IRQ совсем не обязателен - данные отправил, через паузу считал статус. Если всё ок - заснул.

    Без ЛА много не на проверяешь.
     
  12. ra0wx

    ra0wx Нерд

    Мне думается вот из за чего программа не идет дальше:
    Код (C++):
    /****************************************************************************/

    bool RF24::available(void)
    {
      return available(NULL);
    }

    /****************************************************************************/
    Она тут крутиться пока не увидит изменения состояния.
    Я что то только в одном месте нашел. Ну да ладно, попробую, а там видно будет
     
  13. b707

    b707 Гуру

    послушайте, вы вроде в других вопросах адекватно рассуждаете. А вот про это уже как минимум третий раз пишете чушь Это код не стопорит программу. Ищите в другом месте.
     
  14. ra0wx

    ra0wx Нерд

    А что по вашему происходит в этих двух строках.
     
  15. b707

    b707 Гуру

    проверятся флаг наличия данных в буфере приемника.
    Если данные есть - вернется true, если нет - false

    И ВСЕ! программа пойдет дальше, на этой строчке она НЕ ТОРМОЗИТ.

    Если у вас эта конструкция вешает программу - проверяйте свой собственный код, может вы эту проверку в цикл while() засунули?
     
  16. ra0wx

    ra0wx Нерд

    Если вы читали внимательно, цель задачи вывести программу из if ( radio.available) когда передатчик (как физическое устройство) отключен. И нужно это для того, чтобы очистить знакоместо на дисплее от несуществующих на этот момент значений и записать в них 0. И на сколько я понял, проверка будет продолжаться до тех пор, пока не вернется true(грубо говоря пока передатчик не включится). А заложена эта проверка не в программе а в библиотеке, только и всего.
     
  17. b707

    b707 Гуру

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

    А что касается вашей задачки - она решается элементарно, без всяких копаний в регистрах и даташитах. Каждый раз, когда приемник что-то получил с передатчика - взводите программный таймер. Если новых данных нет, скажем. 1 секунду - очищаете экран. Что тут сложного?
     
  18. ra0wx

    ra0wx Нерд

    К сожалению, такой подход не работает, проверено.
     
  19. b707

    b707 Гуру

    простите, но это звучит как "к сожалению, таблица умножения дает неверный результат, я проверял" :)

    Этот подход НЕ МОЖЕТ НЕ РАБОТАТЬ, ибо он прост и логичен до безобразия.
    Причина может быть только одна - вы его не поняли и применяете неверно.
    Поэтому я и пишу - выкладывайте весь свой код, посмотрим, почему подход "не работает".
     
  20. ra0wx

    ra0wx Нерд

    Вот кусочек кода библиотеки :

    Может быть я действительно что то упускаю. А свой код смогу выложить только после работы
    Код (C++):
    /****************************************************************************/

    bool RF24::available(void)
    {
      return available(NULL);
    }

    /****************************************************************************/

    bool RF24::available(uint8_t* pipe_num)
    {
      uint8_t status = get_status();

      // Too noisy, enable if you really want lots o data!!
      //IF_SERIAL_DEBUG(print_status(status));

      bool result = ( status & _BV(RX_DR) );

      if (result)
      {
        // If the caller wants the pipe number, include that
        if ( pipe_num )
          *pipe_num = ( status >> RX_P_NO ) & B111;

        // Clear the status bit

        // ??? Should this REALLY be cleared now?  Or wait until we
        // actually READ the payload?

        write_register(STATUS,_BV(RX_DR) );

        // Handle ack payload receipt
        if ( status & _BV(TX_DS) )
        {
          write_register(STATUS,_BV(TX_DS));
        }
      }

      return result;
    }

    /****************************************************************************/

    bool RF24::read( void* buf, uint8_t len )
    {
      // Fetch the payload
      read_payload( buf, len );

      // was this the last of the data available?
      return read_register(FIFO_STATUS) & _BV(RX_EMPTY);
    }

    /****************************************************************************/