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

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

  1. ИгорьК

    ИгорьК Гуру

    Итак, загружаем полезной информацией оповещение передатчику о приеме сообщения.
    Начнем с приемника - информация должна быть загружена до получения сообщения от передатчика.
    Код (C):
    /* В дефайнах */
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    RF24 radio(9,10); // Определяем рабочие ножки;
    const uint64_t pipe = 0xE8E8F0F0E1LL; // Определяем адрес рабочей трубы;

    /* В сетапе */
    radio.begin(); // Старт работы;
    radio.enableAckPayload();  // Разрешение отправки нетипового ответа передатчику;
    radio.openReadingPipe(1,pipe);  // Открываем трубу и
    radio.startListening();  //начинаем слушать;

    /* В лупе */

    uint32_t message = 111;  //Вот какой потенциальной длины сообщение - uint32_t!
    //туда можно затолкать значение температуры от датчика или еще что-то полезное.
    radio.writeAckPayload( 1, &message, sizeof(message) ); // Грузим сообщение для автоотправки;
    if ( radio.available() ) { //Просто читаем и очищаем буфер - при подтверждении приема
        int dataIn;  //передатчику приемник протолкнет ему в обратку наше сообщение;
        bool done = false;
        while (!done) {
            done = radio.read( &dataIn, sizeof(dataIn)); // Значение dataIn в данном случае
            //не важно. Но его можно использовать и как управляющую команду.
        }
    }
    Все, приемник получив любое сообщение от передатчика, отправит ему обратно число 111.

    Передатчик:
    Код (C):
    /* В дефайнах */
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    RF24 radio(9,10);
    const uint64_t pipe = 0xE8E8F0F0E1LL;
    uint32_t message;  // Эта переменная для сбора обратного сообщения от приемника;
    /* В сетапе */
    radio.begin();
    radio.enableAckPayload();
    radio.openWritingPipe(pipe);
    /* В лупе */
    int command = 555;  // Не суть - приемнику надо что-то передать, но это может быть и полезная информация;
    radio.write( &command, sizeof(command) );  //Отправляем команду;
    if ( radio.isAckPayloadAvailable() ) {  // Ждем получения...
          radio.read(&message,sizeof(message));  //... и имеем переменную message с числом 111 от приемника.
    }
     
    Последнее редактирование: 25 июн 2014
    Mestniy, M.a.x и AlexVS нравится это.
  2. ИгорьК

    ИгорьК Гуру

    Последнее, слегка правим библиотеку.
    Вроде бы все что я постарался описать выше взято из официальных примеров, понятно и должно работать. Но лично у меня - работало с перебоями и нестабильно. В чем дело (глубинно) - не знаю. Если у вас все работает - не делаем. Но если что-то идет не так, то:
    1. в установленной библиотеке, в файле RF24.h делаем следующие изменения.
    В секции protected находим строку uint8_t flush_tx(void); и делаем ее такой: //uint8_t flush_tx(void);, то есть закомментируем, и повторяем эту же строку в секции public: uint8_t flush_tx(void); .
    2. теперь перед каждой передачей вставляем функцию:
    Код (C):
    int command = 555;
    radio.flush_tx();// Новая функция, которая стала доступной.
    radio.write( &command, sizeof(command) );
    Все заработало очень стабильно и надежно.

    Иногда возникают проблемы с Arduino Mega. Что можно сделать дополнительно:

    1. Проблемы питания Меги. Пробуем питать модуль от внешнего 3.3 вольта. Параллельно микрофарадному конденсатору напаиваем какую-нибудь вч керамику.

    По возможности смотрим осциллографом что там на ногах питания. Смотрите особенно в момент передачи - сделайте какой-нибудь цикл в секунду и выстреливайте пакеты на передачу.

    2. Меняем ВСЕ ноги подключения Меги, а именно:
    а) Начнем с простого - физически меняем пару ног CE и CSN и программно переопределяем их в
    RF24 radio(CE_PIN, CSN_PIN);

    б) Если это не помогает, меняем ноги SCK, MOSI, MISO - убираем их с 52, 51 и 50 на соответствующие ноги разъема ICSP, что рядом с основным процессором Мега 2560.
     
    Последнее редактирование: 4 сен 2014
    MickNich нравится это.
  3. ИгорьК

    ИгорьК Гуру

    В заключение, код из первого поста темы. Это рабочий код приемников, которые получают и отрабатывают четыре команды:
    100 - выключиться:
    101 - включить ШИМ на всю дурь (чтобы было светло) на 3,5,6 ногах и число на 4 ноге;
    102 - играть ШИМ (чтобы было прикольно) и включить 4 ногу;
    103 - включить ШИМ совсем чуть-чуть (чтобы маневрировать между мебелью ночью).
    Код без комментариев, потому что он из другого проекта.
    Код передатчика желающие напишут самостоятельно или найдут по предыдущей ссылке.
    Код (C):
    /*
    Рабочий вариант 18.06.2014
      1 - GND
      2 - VCC 3.3V !!! NOT 5V
      3 - CE to Arduino pin 9
      4 - CSN to Arduino pin 10
      5 - SCK to Arduino pin 13
      6 - MOSI to Arduino pin 11
      7 - MISO to Arduino pin 12
      8 - UNUSED
    */

    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include <stdint.h>

    #define CE_PIN  9
    #define CSN_PIN 10

    #define PIN_RED 3
    #define PIN_GREEN 5
    #define PIN_BLUE 6
    #define PIN_LIGHT 4
    #define BrightGoToilet 15

    //const uint64_t pipe = 0xE8E8F0F0E1LL; // Труба для одного приемника
    const uint64_t pipe = 0xE8E8F0F0EELL;  // Труба для второго приемника

    RF24 radio(CE_PIN, CSN_PIN);
    int command;

    unsigned long timeToStepMoodLamp = 0;
    #define delayNextStepMoodLamp 5
    #define delayToGoToilet 150

    uint8_t i = 0;                                // Всякие счетчики;
    uint8_t redOld = 0, greenOld = 0, blueOld = 0, red = 0, green = 0, blue = 0;
    int iUp = 0;
    int iDown = 25;
    enum {
        stepCheckNRF,
        stepOff,
        stepOnLight,
        stepMoodLight,
        stepGotToilet,
    } StepOfProgramNow;

    struct {
        unsigned switchOff      : 1;
        unsigned switchOn        : 1;
        unsigned moodLamp        : 1;
        unsigned gotToilet      : 1;
        unsigned lightSwitchedOn : 1;
    } flag;
    /*=================================== Setup ===================================== */
    void setup()  {
        //Serial.begin(9600);
        //delay(1500);
        //Serial.println("Nrf24L01 Receiver Starting");

        pinMode(PIN_LIGHT, OUTPUT);
        delay(2000);
        radio.begin();
        radio.setDataRate(RF24_250KBPS);
        radio.setChannel(0);
        radio.setRetries(15,15);
        radio.setAutoAck(1);
          radio.openReadingPipe(1,pipe);
        radio.startListening();

            analogWrite(PIN_RED,127); // Смотрим, все ли зажигается при включении;
            delay(1000);
            analogWrite(PIN_BLUE,127);
            delay(1000);
            analogWrite(PIN_GREEN,127);
            delay(2000);
            analogWrite(PIN_RED,0);
            delay(1000);
            analogWrite(PIN_BLUE,0);
            delay(1000);
            analogWrite(PIN_GREEN,0);
            delay(500);

        StepOfProgramNow = stepCheckNRF;
        flag.switchOn = 0;
        flag.moodLamp = 0;
        flag.gotToilet = 0;
    }

    /*=================================== Loop ===================================== */

    void loop(void) {

        switch (StepOfProgramNow) {
            case stepCheckNRF:
                if (timeToStepMoodLamp > millis()) {                // Проверим что со временем - не перешли ли через ноль?
                        timeToStepMoodLamp = millis();
                    }
                if ( radio.available() ) {                            // В случае, если есть что прочитать в буфере;
                    bool done = false;
                    while (!done)                                    // Начинаем упрямо считывать информацию;
                    {
                        done = radio.read( &command, sizeof(command) );
    //                      Serial.print(" Command = ");
    //                      Serial.println(command);
             
                        if (command == 100) {                        // Флаги для "Все выключено";
                            flag.switchOff = 1;
                            flag.switchOn = 0;
                            flag.moodLamp = 0;
                            flag.gotToilet = 0;
                        }
             
                        if (command == 101) {                        // Флаги для "Включена подсветка";
                            flag.switchOff = 0;
                            flag.switchOn = 1;
                            flag.lightSwitchedOn = 0;
                            flag.moodLamp = 0;
                            flag.gotToilet = 0;
                        }
                        if (command == 102) {                        // Флаги для "Лампа настроения";
                            flag.switchOff = 0;
                            flag.switchOn = 0;
                            flag.moodLamp = 1;
                            flag.lightSwitchedOn = 0;
                            flag.gotToilet = 0;
                        }
                        if (command == 103) {                        // Флаги для "Ночная подсветка";
                            flag.switchOff = 0;
                            flag.switchOn = 0;
                            flag.moodLamp = 0;
                            flag.gotToilet = 1;
                            flag.lightSwitchedOn = 0;
                        }
                    }
                }
            StepOfProgramNow = stepOff;
            break;

    /*=================================== Off ===================================== */
            case stepOff:
                if (flag.switchOff && flag.lightSwitchedOn) {
                      if (millis() > timeToStepMoodLamp + delayToGoToilet) {
                        iDown--;
                        analogWrite(PIN_RED,iDown);
                        analogWrite(PIN_GREEN,iDown);
                        analogWrite(PIN_BLUE,iDown);
             
                        if (0 == iDown) {
                            digitalWrite(PIN_LIGHT,0);
                            flag.lightSwitchedOn = 0;
                            //Serial.println("Write 0");
                            iDown = BrightGoToilet;
                        }
                    }
                }
            StepOfProgramNow = stepOnLight;
            break;
    /*=================================== On Light ===================================== */
            case stepOnLight:
                if (flag.switchOn && !flag.lightSwitchedOn) {
                    analogWrite(PIN_RED,255);
                    analogWrite(PIN_GREEN,255);
                    analogWrite(PIN_BLUE,255);
                    digitalWrite(PIN_LIGHT,1);
                    flag.lightSwitchedOn = 1;
                    iDown = 255;
                    //Serial.println("Write 255");
                    //delay(3000);
                }

            StepOfProgramNow = stepMoodLight;
            break;
    /*=================================== Mood Lamp ===================================== */        
            case stepMoodLight:
                if (flag.moodLamp) {
         
                    if(!flag.lightSwitchedOn) {
                        iDown = 127;
                        digitalWrite(PIN_LIGHT,1);
                        flag.lightSwitchedOn = 1;
                    }
         
                    if (millis() > timeToStepMoodLamp + delayNextStepMoodLamp)
                    {
                        if ((red == redOld) && (green == greenOld) && (blue == blueOld) ) {
                            do {
                                red  = random(255); green = random(255); blue  = random(255);
                            } while (((abs)(red - green) < 140) && ((abs)(green - blue) < 140) && ((abs)(blue - red) < 140 ) );
                 
                            i++;                                                        // Счетчик смены цветов;
                            if (10 == i) { red = 255; green = 0; blue = 0; }            // Периодически устанавливаем чистые цвета;
                            if (20 == i) { red = 0; green = 255; blue = 0; }
                            if (30 == i) { red = 0; green = 0; blue = 255; }
                            if (40 == i) { red = 255; green = 255; blue = 0; }
                            if (50 == i) { red = 0; green = 255; blue = 255; }
                            if (60 == i) { red = 255; green = 0; blue = 255; }
                            if (70 == i) { red = 255; green = 255; blue = 255; i = 0; }
                        }
             
                        analogWrite (PIN_RED, redOld);
                        analogWrite (PIN_GREEN, greenOld);
                        analogWrite (PIN_BLUE, blueOld);
                        //Serial.println("Write Mood");
             
                        if (red > redOld) redOld++;
                        if (red < redOld) redOld--;
                        if (green > greenOld) greenOld++;
                        if (green < greenOld) greenOld--;
                        if (blue > blueOld)    blueOld++;
                        if (blue < blueOld) blueOld--;
             
                        timeToStepMoodLamp = millis();
                    }
                }
            StepOfProgramNow = stepGotToilet;
            break;

    /*=================================== Go To Toilet ===================================== */
            case stepGotToilet:
                if ( flag.gotToilet && !flag.lightSwitchedOn) {
                    if (millis() > timeToStepMoodLamp + delayToGoToilet)
                    {
                        iUp++;
                        analogWrite(PIN_RED,iUp);
                        analogWrite(PIN_GREEN,iUp);
                        analogWrite(PIN_BLUE,iUp);
                        //digitalWrite(PIN_LIGHT,0);
             
                        if (iUp == BrightGoToilet) {
                            flag.lightSwitchedOn = 1;
                            iUp = 0;
                        }
                    }
                    //Serial.println("Write 25 to Toilet");
                }
            StepOfProgramNow = stepCheckNRF;
            break;
         
            default:
            break;
        }
    }
     
    Все. Ушел делать другой проект.
     
    Последнее редактирование: 4 сен 2014
    9xA59kK и AlexVS нравится это.
  4. ИгорьК

    ИгорьК Гуру

    А вот так присоединим модуль к Arduino Yun:
    NrfYun.jpg
    И инициализируем командой
    nrf24(8, 10);
     
  5. k0rwin

    k0rwin Нуб

    Всем доброго...
    Мучаю эти модули. Arduino Uno, две штуки. На одной приемник, на другой передатчик. Конденсаторы впаяны. Библиотека исправлена. Незашумленный канал выбран. Но...
    Данные передаются, только если перегрузить ардуинку с передатчиком (или просто заново открыть монитор порта). При этом приемник получает последнюю команду, которая была до перезагрузки и первую сразу после. И опять тишина.
    На даже этот "финт ушами" не всегда помогает. Где-то 1 раз из трех.
    Куда копать еще можно, подскажите пожалуйста.
     
  6. k0rwin

    k0rwin Нуб

    Да, еще момент. Если команда доходит - то обязательно доходит именно пара, как описал.
     
  7. k0rwin

    k0rwin Нуб

    Еще один факт обнаружился. Если нажать кнопку перезагрузки и подержать ее пару секунд - даже ответ приходит. Но опять же, раз на раз не приходится.
    Замерил напряжение: 3.33, стабильно. При перегрузке тоже.
     
  8. ИгорьК

    ИгорьК Гуру

    Ваш случай серьезнее.
    1. Общая мысль. Модуль ОЧЕНЬ капризен по наводкам. Наличие на приемном модуле 3,3 в, измеренное вольтметром, ни о чем не говорит. Если есть возможность - посмотрите осциллографом что там.
    Я сделал два совершенно аналогичных приемных исполнительных устройства, так вот одно отказывалось работать напрочь, а другое - работало! Менял местами модули - ничего не помогало. Пришлось полностью вынести все исполнительные транзисторы и твердотельное реле на отдельную плату:
    0002.jpg
    На фото видно, что над ардуино остался только разъем под модуль.
    Поэтому попробуйте кроме электролита припаять параллельно и керамический конденсатор.
    2. Здесь высказывалось предположение, что при инициализации модули загружаются случайными параметрами. Возможно, необходимо в сетапе определять абсолютно все параметры работы.
    3. Показывайте скетч - будем думать.
     
  9. k0rwin

    k0rwin Нуб

    ИгорьК, спасибо за ответ.
    По пунктам:
    1. Осциллографа, к сожалению нет.
    2. Задавать параметры руками пробовал. Тот же результат, за исключением, что на скорости, отличной от дефолтной вообще ответа не было. Сейчас попробую еще раз все аккуратно проинициализировать.
    3. Скетч - практически Ваш, из примера, за мелкими незначительными исключениями. Но, вот, на всякий случай:

    RF24_send:

    Код (Text):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"


    RF24 radio(9,10);
    const uint64_t pipe = 0xE8E8F0F0E1LL;
    uint32_t message;
    int counter = 0;

    void setup(void)
    {
      Serial.begin(57600);
      printf_begin();
      radio.begin();
      //radio.setChannel(0x40);
      //radio.setPALevel(RF24_PA_MAX);
      //radio.setDataRate(RF24_250KBPS);
      //radio.setRetries(15, 15);
      radio.setDataRate(RF24_2MBPS);
     
      radio.enableAckPayload();
      radio.openWritingPipe(pipe);
    }


    void loop(void)
    {
      int command = random(1,4);
      Serial.print("Send: ");
      Serial.println(command);
     
      radio.flush_tx();
      radio.write( &command, sizeof(command) );
     
      if ( radio.isAckPayloadAvailable() ) {
            radio.read(&message,sizeof(message));
            Serial.print("Receive: ");
            Serial.println(message);
      }
     
      delay(1000);
    }
    int serial_putc( char c, FILE * ) {
      Serial.write( c );
      return c;
    }

    void printf_begin(void) {
      fdevopen( &serial_putc, 0 );
    }
    RF24_receive:

    Код (Text):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"


    RF24 radio(9,10);
    const uint64_t pipe = 0xE8E8F0F0E1LL;


    void setup(void)
    {
      Serial.begin(57600);
      printf_begin();
      radio.begin();
      //radio.setChannel(0x40);
      //radio.setPALevel(RF24_PA_MAX);
      //radio.setDataRate(RF24_250KBPS);
      radio.setDataRate(RF24_2MBPS);
     
      radio.enableAckPayload();
      radio.openReadingPipe(1,pipe);
      radio.startListening();
      radio.setAutoAck(1);
     
      radio.printDetails();

      printf("\n\r");
    }


    void loop(void)
    {
      uint32_t message = 111;
      radio.writeAckPayload( 1, &message, sizeof(message) );
      if ( radio.available() ) {
          int dataIn;
          bool done = false;
          while (!done) {
              done = radio.read( &dataIn, sizeof(dataIn));
              Serial.println(dataIn);
          }
      }
    }
    int serial_putc( char c, FILE * ) {
      Serial.write( c );
      return c;
    }

    void printf_begin(void) {
      fdevopen( &serial_putc, 0 );
    }
    Кроме модуля к ардуинке ничего не присоединено. Питание от USB. Пробовал запитать от отдельного блока питания (в этом случае вместо серийного порта мигал диодами на прием-передачу) - результат идентичный.
     
  10. ИгорьК

    ИгорьК Гуру

    1. Вы попытались работать с самым сложным вариантом. Уберите все, что касается AckPayload и попробуйте добиться стабильной работы. Возможно: int command = random(1,4) заменить на int command = (int) random(1,4); в коде передатчика, и int dataIn на static int dataIn в коде приемника.
    2. Что касается AckPayload, попробуйте заменить uint32_t message на static uint32_t message в скетче передатчика, а также uint32_t message на static uint32_t message в скетче приемника.
     
    k0rwin нравится это.
  11. k0rwin

    k0rwin Нуб

    Так. Ура, ура, ура :). Заработало :).
    В общем, меня изначально сильно смущало, что приходит пара команд: последняя до ребута и первая после. Впечатление, что какой-то буфер не чистится (помимо того, который Вы принудительно у себя чистите через flush_tx). В итоге: добавил непосредственно перед write:

    Код (Text):
    radio.startListening();
    radio.stopListening();
    ... и все заработало.

    Теперь осталось внимательно почитать доки к классу и понять таки, что именно происходит. Ну и сделать по человечески :).

    Огромное спасибо за помощь! Благодаря Вашему описанию, таки все получилось!
     
    Последнее редактирование: 18 авг 2014
    Karabas нравится это.
  12. geher

    geher Гуру

    startListening включает режим приема (прослушивания частоты).
    stopListening, соответственно, этот режим выключает.
    write в этом режиме не работает, соответственно, режим должен быть отключен при помощи stopListening.
    Вроде так.
     
  13. ИгорьК

    ИгорьК Гуру

    И я также кричал после двух недель битвы с модулем :)

    Допишите, пожалуйста, чем закончится Ваша работа. Уверен, что с этим модулем не одни мы бьемся.
     
    Последнее редактирование: 18 авг 2014
  14. k0rwin

    k0rwin Нуб

    Вот код startListening / stopListening из самой библиотеки:

    Код (Text):
    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);
    }

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

    void RF24::stopListening(void)
    {
      ce(LOW);
      flush_tx();
      flush_rx();
    }
    Если вызвать все тоже самое из своего кода (предварительно перекинув в паблик) - работает. Комментим любую строку - потери пакетов или вообще тишина (за исключением записи в RX_ADDR регистр, это явно только для чтения нужно). По значениям, которые пишутся в CONFIG и STATUS надо копнуть даташит, прямо сейчас времени нет. Постараюсь завтра. Но, как видно из кода stopListening, flush_tx там вызывается. Это в любом случае избавляет нас от необходимости ковырять саму либу. Что интересно, если просто вызвать stopListening - не помогает. Нужно обязательно парой...

    PS: интересно, у Вас ведь работает просто с flush_tx. Это версия библиотеки отличается или сами модули?
     
  15. ИгорьК

    ИгорьК Гуру

    У меня нет очистки буфера чтения возможно потому, что нет AckPyload в скетче.
    Но... возможно наша пляска с бубнами лишена смысла по той причине, что мы проглядели в библиотеке одну важную вещь, а именно: необходимость иметь постоянный адрес переменных для отправки и приема.
    И здесь получается интересная ситуация: кто-то объявляет такие переменные глобальными, кто-то локальными, а у кого- то в передатчике и приемнике и так и так.
    И получается большое число комбинаций глюков.
    В общем, наблюдая за Вашим кодом и сравнивая его с референсным увидел лишь одно отличие - переменные примеров являются статическими.
    С точки зрения языка С конкретных примеров это не имеет особого смысла. Все должно и так работать. Но если посмотреть внимательно библиотеку, то в передающих и принимающих функциях адрес переменных указан как const. А такой адрес возникает, по-моему, если переменная объявлена или глобальной или локальной, но static.
    Предлагаю проверить эту мысль. У меня уже все работает и лежит на шкафах, а у Вас, видимо, еще на макетке. Убирайте все очистки буферов и объявляйте переменные как static. Интересно, что получится?
     
    Последнее редактирование: 19 авг 2014
  16. Игорь добрый день. Спасибо за толковые разъяснения по данным модулям, всё толково и помогло мне заюзать данный модуль. В том как передать и принять массив разобрался всё работает хорошо и без проблем, конденсаторы припаивать не пришлось. Но задача передать с 4 приемников по 4 трубам 4 массива и на модуле приемнике их принять - вот тут затык у меня. Знаю, что где то в коде затупил но не могу поянть где. Не могли бы если вас не затруднит отрывок кода приёмника принимающего два массива с двух модулей? Спасибо.
     
  17. geher

    geher Гуру

    В примерах к библиотеке RF24 есть такой на шесть труб:
    nRF24_Arduino_as_hub

    Код (Text):
    /*
    This program is the receiver for nRF24_Send_to_RPi that was originally written
    for the Raspberry Pi and ported back to UNO for completeness.

    Found out that I cannot have two startListening() statement, one in setup() and another
    inside the loop() and the radio.available() will not received anything at all.

    The receiver will accept 6 pipes and display received payload to the screen

    The receiver will return the receive payload to the sender usinbg the same pipe
    to calculate the rtt if the payload matched

    Max payload size is 32 bytes

    Forked RF24 at github :-
    https://github.com/stanleyseow/RF24

    Date : 08/05/2013

    Written by Stanley Seow
    stanleyseow@gmail.com
    */

    #include <LiquidCrystal.h>
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"

    LiquidCrystal lcd(10, 7, 3, 4, 5, 6);

    RF24 radio(8,9);

    // Radio pipe addresses for the 2 nodes to communicate.
    //const uint64_t pipes[6] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL, 0xF0F0F0F0E4LL, 0xF0F0F0F0E5LL };
    // bytes serv1 = 0x7365727631 in hex
    const uint64_t pipes[6] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0E1LL, 0xF0F0F0F0E2LL, 0xF0F0F0F0E3LL, 0xF0F0F0F0E4LL, 0xF0F0F0F0E5LL };


    void setup(void)
    {
      digitalWrite(2,HIGH);
      delay(500);
      digitalWrite(2,LOW);

        // Setup LCD
      lcd.begin(16,2);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("SensorHub V0.91");

      Serial.begin(57600);
      printf_begin();

      radio.begin();

      radio.setDataRate(RF24_1MBPS);
      radio.setPALevel(RF24_PA_MAX);
      radio.setChannel(76);
      radio.enableDynamicPayloads();
      radio.setRetries(15,15);

      radio.setCRCLength(RF24_CRC_16);

      radio.openWritingPipe(pipes[0]);
      radio.openReadingPipe(1,pipes[1]);
      radio.openReadingPipe(2,pipes[2]);
      radio.openReadingPipe(3,pipes[3]);
      radio.openReadingPipe(4,pipes[4]);
      radio.openReadingPipe(5,pipes[5]);

      radio.startListening();
      radio.printDetails();

      delay(1000);
      lcd.clear();
    }

    void loop(void)
    {
        char receivePayload[31];
        uint8_t len = 0;
        uint8_t pipe = 0;
         
         
        // Loop thru the pipes 0 to 5 and check for payloads  
        if ( radio.available( &pipe ) ) {
          bool done = false;
          while (!done)
          {
            len = radio.getDynamicPayloadSize();
            done = radio.read( &receivePayload,len );
         
            // Sending back reply to sender using the same pipe
            radio.stopListening();
            //radio.openWritingPipe(pipes[pipe]);
            radio.write(receivePayload,len);
         
            // Format string for printing ending with 0
            receivePayload[len] = 0;
            printf("Got payload: %s len:%i pipe:%i\n\r",receivePayload,len,pipe);
         
            lcd.setCursor(0,0);
            lcd.clear();
            lcd.print("L:");
            lcd.setCursor(2,0);
            lcd.print(len);
            lcd.setCursor(5,0);  
            lcd.print("P:");
            switch (pipe) {
              case 0:
                lcd.setCursor(7,0);
                lcd.print(pipe);  
                break;
              case 1:
                lcd.setCursor(8,0);
                lcd.print(pipe);  
                break;        
              case 2:
                lcd.setCursor(9,0);
                lcd.print(pipe);  
                break;      
              case 3:
                lcd.setCursor(10,0);
                lcd.print(pipe);  
                break;
              case 4:
                lcd.setCursor(11,0);
                lcd.print(pipe);  
                break;
              case 5:
                lcd.setCursor(12,0);
                lcd.print(pipe);  
                break;
              default:
                break;
            }      
         
         
            lcd.setCursor(0,1);
            lcd.print(receivePayload);
     
            radio.startListening();
         
            // Increase pipe and reset to 0 if more than 5
            pipe++;
            if ( pipe > 5 ) pipe = 0;
          }

        }

    delay(20);

    }
     
     
  18. старнно у меня такого примера нет в библиотеке. Буду разбираться, спасибо
     
  19. gonzales

    gonzales Гик

    угу. вторая неделя уже пошла.
    Проблема в Меге, не хочет скотина работать на прием. Передачу выполняет, прием нет. Уно работает в две стороны нормально.
    Конденсатор пока не припаивал, заеду на днях прикуплю, но есть подозрение, что дело не в нем, так как регистры не сбиваются при включении (printdetails выдает вот что).

    Код (Text):
    STATUS= 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
    RX_ADDR_P0-1= 0xe7e7e7e7e7 0xe8e8f0f0e1
    RX_ADDR_P2-5= 0xc3 0xc4 0xc5 0xc6
    TX_ADDR= 0xe7e7e7e7e7
    RX_PW_P0-6= 0x00 0x20 0x00 0x00 0x00 0x00
    EN_AA= 0x3f
    EN_RXADDR= 0x03
    RF_CH= 0x5c
    RF_SETUP= 0x0f
    CONFIG= 0x0f
    DYNPD/FEATURE= 0x3f 0x07
    Data Rat= 2MBPS
    Model= nRF24L01+
    CRC Lengt= 16 bits
    PA Power= PA_MAX
    Но вот в чем дело, не могу понять.

    Да, кстати, скетч scanner на меге работает
     
    Последнее редактирование: 3 сен 2014
  20. ИгорьК

    ИгорьК Гуру