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

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

  1. ИгорьК

    ИгорьК Гуру

    Привет, Максим!
    Что есть дуплекс?
    Модуль слушает эфир до шести каналов. Надо передать - перестаёт слушать и передаёт в один. Потом опять слушает, но переход от одного к другому - по команде.
    А так - (1) питание, (2) полная, ПОЛНАЯ инициализация всех возможных параметров для модулей, (3) скорость 1Мбит и (4) "игра" с ACK и все работает.
    Библиотеку использовать из трех самую свежую. Её дорабатывали уже похоже под поддельные модули.
    От Maniacbag библиотека хуже всего - она старая и писалась ещё под настоящие.

    И, не могу не согласиться - я этот модуль не использую больше: только ESP8266. Но первый проект работает и работает стабильно.
     
    Последнее редактирование: 13 июн 2016
    ostrov нравится это.
  2. ostrov

    ostrov Гуру

    Дуплекс нужен в том смысле, чтобы данные с пульта и на пульт передавались постоянно, а не по очереди. Наверное придется ставить по 2 модуля туда и сюда. В принципе то все работает более менее стабильно, если контакты надежные, но все равно система мне пока не очень нравится.
     
  3. ИгорьК

    ИгорьК Гуру

    Если нет особых причин для этого модуля, посмотрите в сторону RFM69. Мне он кажется куда перспективнее и надёжнее.
     
    ostrov нравится это.
  4. ostrov

    ostrov Гуру

    Надо посмотреть, а то от NRF я не в восторге что то.
     
  5. sanik

    sanik Гик

    Это хорошо когда передаем данные и ни чем более не занимаемся. Вот столкнулся с проблемой решил сделать пульт универсальный с переключением. Пока не начинаю передавать данные код работает как надо как только добавляю строку radio.write(joystick, sizeof(joystick)); Все кнопки не работают светодиоды тоже, Погрешил на давилку дребезга сделал без него, то же самое. Помогите решить проблемку. Ведь помимо трех цифровых кнопок в дальнейшем нужно задействовать и аналоговую клавиатуру . И еще несколько режимов. При добавлении строки такое ощущение складывается что что код только и делает что посылает данные остальным никак не желает заниматься. Полностью прописана только одна ось.
    Код (C++):

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

    #define CE_PIN   9
    #define CSN_PIN 10
    #define JOYSTICK_X A0 //Джойстик ось Х
    #define JOYSTICK_Y A1 //Джойстик ось Y
    #define JOYSTICK_Z A2 //Джойстик ось Z
    #define POT_X A3 //потенциометр ось X
    #define POT_Y A4 //потенциометр ось Y
    #define POT_Z A5 //потенциометр ось Z
    #define BUTON A6 // аналоговые кнопки
    const int Xbutton = 4;//цифровая кнопка грибка
    const int Ybutton = 3;//цифровая кнопка грибка
    const int Zbutton = 2;//цифровая кнопка грибка
    const int Xled = 5;//индикатор оси X
    const int Yled = 6;//индикатор оси Y
    const int Zled = 7;//индикатор оси Z
    int ledState; // сотояние свотодиодов
    boolean working = false;

    unsigned long currentTime;
    unsigned long previousMillis = 0;
    const long interval = 200;
    //________________атидребезг_____________
    long debounceDelay = 50;
    long lastDebounceTime = 0;
    int XlastButtonState = LOW;
    int XbuttonState;
    int ActionX = HIGH;// состояние кнопки
    int YlastButtonState = LOW;
    int YbuttonState;
    int ActionY = HIGH;// состояние кнопки
    int ZlastButtonState = LOW;
    int ZbuttonState;
    int ActionZ = HIGH;// состояние кнопки

    int AnalogBut; // переменная для аналоговых кнопок
    int Key0;
    int Key1;
    int Key2;
    int Key3;
    int KeyWork;
    int KeyAuto;
    int val_1;  //переменная для оси X
    int val_2;  //переменная для оси Y
    int val_3; //переменная для оси Z
    int val_4; //переменная для аналоговых кнопок
    int maxVolX; //Максимальное значение джойстика
    int maxVolY;
    int maxVolZ;
    int volumX; //переменая для сравнения максимального значения джойстика
    int volumY;
    int volumZ;
    const uint64_t pipe = 0xF0F0F8F110FL; // Define the transmit pipe
    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
    int joystick[3];  // 4 element array holding Joystick readings
    void setup()
    {
      // Serial.begin(9600);
      radio.begin();
      radio.openWritingPipe(pipe);
      pinMode(Xbutton, INPUT);
      pinMode(Xled, OUTPUT);
      digitalWrite(Xled, LOW);
      pinMode(Ybutton, INPUT);
      pinMode(Yled, OUTPUT);
      digitalWrite(Yled, LOW);
      pinMode(Zbutton, INPUT);
      pinMode(Zled, OUTPUT);
      digitalWrite(Zled, LOW);
      currentTime = millis();
    }

    void loop()
    {
      currentTime = millis();
      int Xreading = digitalRead(Xbutton);
      int Yreading = digitalRead(Ybutton);
      int Zreading = digitalRead(Zbutton);
      if (working == false)// работа
      {
        // ось X
        if (Xreading != XlastButtonState)
        {
          lastDebounceTime = millis();
        }

        if ((millis() - lastDebounceTime) > debounceDelay)
        {
          if (Xreading != XbuttonState)
          {
            XbuttonState = Xreading;
            if (XbuttonState == HIGH)
            {
              ActionX = !ActionX;
            }
          }
        }
        XlastButtonState = Xreading;
        if (ActionX == HIGH)
        {
          JoyX();
        }
        else if (ActionX == LOW)
        {
          PotX();
        }
        //ось Y
        if (Yreading != YlastButtonState)
        {
          lastDebounceTime = millis();
        }

        if ((millis() - lastDebounceTime) > debounceDelay)
        {
          if (Yreading != YbuttonState)
          {
            YbuttonState = Yreading;
            if (YbuttonState == HIGH)
            {
              ActionY = !ActionY;
            }
          }
        }
        YlastButtonState = Yreading;
        if (ActionY == HIGH)
        {
          JoyY();
        }
        else if (ActionY == LOW)
        {
          PotY();
        }
        //ось Y
        if (Zreading != ZlastButtonState)
        {
          lastDebounceTime = millis();
        }

        if ((millis() - lastDebounceTime) > debounceDelay)
        {
          if (Zreading != ZbuttonState)
          {
            ZbuttonState = Zreading;
            if (ZbuttonState == HIGH)
            {
              ActionZ = !ActionZ;
            }
          }
        }
        ZlastButtonState = Zreading;
        if (ActionZ == HIGH)
        {
          JoyZ();
        }
        else if (ActionZ == LOW)
        {
          PotZ();
        }
      }
      // запись
      // кнопки аналоговые
      val_4 = analogRead(BUTON), val_4 = map(val_4, 0, 1024, 192, 255);
      joystick[3] = val_4;
    // radio.write(joystick, sizeof(joystick)); // блокирует код

    }

    int KeyAnalog()
    {
      analogRead(BUTON);
      if (AnalogBut > 1000) return Key0;
      if (AnalogBut < 50)   return Key1;
      if (AnalogBut < 250)  return Key2;
      if (AnalogBut > 450)  return Key3;
      if (AnalogBut > 650)  return KeyWork;
      if (AnalogBut > 850)  return KeyAuto;
      return Key0;
    }
    void JoyX()
    {
      led_shine(); //Включаем светодиод X
      digitalWrite(Xled, ledState);
      val_1 = analogRead(JOYSTICK_X), val_1 = map(val_1, 0, 1024, 0, 63);
      joystick[0] = val_1;
    }
    void JoyY()
    {
      led_shine(); //Включаем светодиод X
      digitalWrite(Yled, ledState);

    }
    void JoyZ()
    {
      led_shine(); //Включаем светодиод X
      digitalWrite(Zled, ledState);
    }
    void PotX()
    {
      led_None();
      digitalWrite(Xled, ledState);
      val_1 = analogRead(POT_X), val_1 = map(val_1, 0, 1024, 0, 63);
      joystick[0] = val_1;
    }
    void PotY()
    {
      led_None();
      digitalWrite(Yled, ledState);
    }
    void PotZ()
    {
      led_None();
      digitalWrite(Zled, ledState);
    }
    void led_flash()
    {
      currentTime = millis();
      if (currentTime - previousMillis >= interval)
      {
        // save the last time you blinked the LED
        previousMillis = currentTime;
        if (ledState == LOW)
          ledState = HIGH;
        else
          ledState = LOW;
      }
    }

    void led_shine()
    {
      ledState = HIGH;
    }
    void led_None()
    {
      ledState = LOW;
    }
     
     
  6. ostrov

    ostrov Гуру

    Модуль от чего питаете? От ардуинкиной 3.3? Если так, то однозначно не хватает питания с непредсказуемым результатом. Хотя, по идее должно хватать, ибо лабораторный БП показывает потребление двух модулей в пределах 0,013А, но скорее в момент передачи и/или приема данных проскакивают пиковые нагрузки, которые превышают норматив. И вообще они к питанию сверхчуствительны, малейший неплотный контакт и ничего не работает. Я вот пока не пролудил все проводки для баспаечной макетки - глючило по страшному, теперь нет.
    [​IMG]

    И вот тут чего то явно что то напутано и чего то не хватает:
    Код (C++):
    int KeyAnalog()
    {
      analogRead(BUTON);
      if (AnalogBut > 1000) return Key0;
      if (AnalogBut < 50)   return Key1;
      if (AnalogBut < 250)  return Key2;
      if (AnalogBut > 450)  return Key3;
      if (AnalogBut > 650)  return KeyWork;
      if (AnalogBut > 850)  return KeyAuto;
      return Key0;
    }
    )
     
    Последнее редактирование: 15 июн 2016
  7. sanik

    sanik Гик

    Модуль вобще не подключен, код на стадии разработки работаю пока над цифровыми кнопками Пока прописывал оси джойстика сразу проверял состояния светодиодами. Как только вписал строку передачи контролер перестал реагировать на нажатие кнопок он зависает на этой строке radio.write(joystick, sizeof(joystick));
     
  8. ostrov

    ostrov Гуру

    Ну так потому и зависает. Ответа от модуля нет же.
     
  9. ZAZ-965

    ZAZ-965 Гуру

    sanik, по-моему вы вышли за границы массива
    Код (C++):
      joystick[3] = val_4; // 0-1-2
    // radio.write(joystick, sizeof(joystick)); // блокирует код
     
  10. ostrov

    ostrov Гуру

    Да, кстати, заявлено 3 элемента, а это четвертый. Да там есть в коде много чего, если присмотреться.
     
  11. ИгорьК

    ИгорьК Гуру

    Да ладно четвертый. Если нет такого элемента в массиве, то его чтение коду в целом (не упадет) не повредит. А вот sizeof(joystick) - это размер чего?
     
  12. ZAZ-965

    ZAZ-965 Гуру

    Применение sizeof к массиву дает количество байтов, занимаемых массивом, т.е. в данном случае 6 (2-byte * 3).
     
  13. ИгорьК

    ИгорьК Гуру

    Да это риторический вопрос к автору...
     
  14. ostrov

    ostrov Гуру

    Где гарантия что ячейка за ним следующая не используется? Нельзя так делать хотя бы ради правильной привычки.
     
    ИгорьК нравится это.
  15. ИгорьК

    ИгорьК Гуру

    Все верно. Но чтение (а не писание) ее лишь приведет к посылке странных данных, а не к падению программы.
     
  16. ostrov

    ostrov Гуру

    Так в сабже именно писание. А если завтра автор объявит новую переменную за этим массивом?
     
  17. ZAZ-965

    ZAZ-965 Гуру

    А по-моему здесь запись (присваивание). И не факт, что линкер другую переменную не разместит следом.
     
    Последнее редактирование: 15 июн 2016
  18. ИгорьК

    ИгорьК Гуру

    radio.write(joystick, sizeof(joystick)); - послать на передачу в модуль NRF24 переменную "joystick" с (неправильным) размером "sizeof(joystick)". Причем "joystick" должен быть УКАЗАТЕЛЕМ.
    С точки зрения работы с массивом - это чтение.
    ... вот я и говорю, на кой шут я писал эту тему, чтобы переписывать ее заново.
     
    ostrov нравится это.
  19. sanik

    sanik Гик

    Четвертый элемент я после добавил он еще не отработан в данный момент он закоментирован Вот к примеру предыдущий подобный код у меня работает уже год. Но в приемнике прописана цифровая кнопка он переключает состояние выхода. Когда передатчик отключен кнопка работает при включении передатчика кнопка так же блокируется.
    Передатчик
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    /*-----( Declare Constants and Pin Numbers )-----*/
    #define CE_PIN   9
    #define CSN_PIN 10
    #define JOYSTICK_X A1
    #define JOYSTICK_Y A2
    #define BUTTON A3



    int val_1; //переменная для  Переменный резистор №1
    int val_2;  //переменная для  Переменный резистор №2
    int val_3; //переменная для кнопки
    // NOTE: the "LL" at the end of the constant is "LongLong" type
    const uint64_t pipe = 0xF0F0F8F010LL; // Define the transmit pipe


    /*-----( Declare objects )-----*/
    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
    /*-----( Declare Variables )-----*/
    int joystick[3];  // 2 element array holding Joystick readings
    //int joystick[2];
    void setup()
    {
      Serial.begin(9600);
      radio.begin();
      radio.openWritingPipe(pipe);
    }


    void loop()
    {
      val_1 = analogRead(JOYSTICK_X),val_1 = map(val_1, 90, 980, 0, 85);
      joystick[0] = val_1;

      val_2 = analogRead(JOYSTICK_Y),val_2 = map(val_2, 90, 980, 86, 170);
      joystick[1] = val_2;

      val_3 = analogRead(BUTTON),val_3 = map(val_3, 0, 1023, 171, 255);
      joystick[2] = val_3;

      radio.write( joystick, sizeof(joystick) );

    }
     
    Приемник

    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include <Servo.h>

    #define CE_PIN   9
    #define CSN_PIN 10
    const uint64_t pipe = 0xF0F0F8F010LL; // Define the transmit pipe
    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
    int joystick[3];  // 2 element array holding Joystick readings
    Servo myservo;  // серва1 на пин 3
    Servo myservo2;  // серва2 на пин 5
    int FOCUSpin = 2; // оптрон фокуса
    int CAMpin = 4; // оптрон затвора
    int POWERled = 15; // A1 индикатор Низкого напряжения разряд аккумулятора
    int volt  = A0;// Измерение напряжения
    const int buttonPin = 16; // A2 вход кнопки триггера
    const int ledPin = 7; // индикатор состояния тригера
    const int outPin = 6; // выход тригера
    int ledState = HIGH;         // текущее состояние выходного контакта
    int buttonState;             // текущее состояение от входного контакта
    int lastButtonState = LOW;   // предыдущее состояение входного контакта

    long lastDebounceTime = 0;
    long debounceDelay = 50;

    int voltage;  // переменная напряжения
    int pos1;
    int pos2;
    int data1; //переменная для servo
    int data2;
    int data3; //переменая для кнопки
    int but;

    void setup()
    {
      radio.begin();
      radio.openReadingPipe(1, pipe);
      radio.startListening();
      pinMode(FOCUSpin, OUTPUT);
      pinMode(CAMpin, OUTPUT);
      myservo2.attach(5);
      pinMode(buttonPin, INPUT);
      pinMode(POWERled, OUTPUT);
      pinMode(ledPin, OUTPUT);
      pinMode(outPin, OUTPUT);
      digitalWrite(ledPin, ledState);
      digitalWrite(outPin, ledState);

    }
    void loop()
    {
      voltage = analogRead(volt);
      if (voltage < 650)
      {
        digitalWrite(POWERled, HIGH);
      }
      else
      {
        digitalWrite(POWERled, LOW);
      }
      //myservo2.write(75);
      int reading = digitalRead(buttonPin);
      if (reading != lastButtonState)
      {
        lastDebounceTime = millis();
      }
      if ((millis() - lastDebounceTime) > debounceDelay)
      {
        if (reading != buttonState)
        {
          buttonState = reading;
          if (buttonState == HIGH)
          {
            ledState = !ledState;
          }
        }
      }
      digitalWrite(ledPin, ledState);
      digitalWrite(outPin, ledState);
      // lastButtonState = reading;

      if ( radio.available() )
      {
        bool done = false;
        while (!done)
        {
          done = radio.read( joystick, sizeof(joystick) );

          //data1 = joystick[1];
          //pos1 = map(data1, 86, 170, 40, 155);
          //myservo.write(pos1);

          data2 = joystick[0];
          pos2 = map(data2, 17, 85, 40, 90);
         // myservo2.attach(5);
          myservo2.write(pos2);
         // delay(100);
         // myservo2.detach();

          data3 = joystick[2];
          if (data3 < 210)
          {
            digitalWrite(FOCUSpin, HIGH);
            delay(100);
            digitalWrite(CAMpin, HIGH);
            delay(150);
            digitalWrite(CAMpin, LOW);
            digitalWrite(FOCUSpin, LOW);
          }
          else
          {
            digitalWrite(CAMpin, LOW);
            digitalWrite(FOCUSpin, LOW);
          }
        }
      }
      lastButtonState = reading;
    }
     
     
    Последнее редактирование: 15 июн 2016
  20. sanik

    sanik Гик

    Попробую подключить модуль отпишусь.