nRF24L01, ардуино и проблемы

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем Freimor, 14 ноя 2018.

  1. Freimor

    Freimor Нуб

    Добрый день. Решил собрать робота с передачей данных по nRF24L01.
    [​IMG] Трансмиттер данные шлёт, шумов на канале быть не должно, конденсаторы по питанию припаял
    Вот код ресивера
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include <Servo.h>


    RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно

    byte recieved_data[4]; // массив принятых данных //0 - Button 1 - X 2 - Y

    // Pin assignment and servo declarations
    Servo leftServo;
    Servo rightServo;
    int leftServoPin = 8;
    int rightServoPin = 7;

    unsigned long currentTime = 0;
    unsigned long timeSinceLastInput = 0;
    int reset = 0;

    byte Connect;

    // LED pin assignments
    int ledEyeRight = 2;  // LED eye (right)
    int ledEyeLeft = 3;   // LED eye (left)
    int ledRedBack = 4; // LED Red (back)
    int ledGabLeft = 5;  // LED gabarity (left)
    int ledGabRight = 6;  // LED gabatity (right)

    void setup() {
      Serial.begin(9600);         // Used to debug when plugged into computer via USB
      //Initializing components
      leftServo.attach(leftServoPin);
      rightServo.attach(rightServoPin);

      pinMode(ledEyeRight, OUTPUT);
      pinMode(ledEyeLeft, OUTPUT);
      pinMode(ledRedBack, OUTPUT);
      pinMode(ledGabLeft, OUTPUT);
      pinMode(ledGabRight, OUTPUT);

      radio.begin(); //активировать модуль
      delay(2000);
      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openReadingPipe(1, 123);     //хотим слушать трубу 0
      radio.setChannel(0x7f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      //должна быть одинакова на приёмнике и передатчике!
      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!
      radio.powerUp(); //начать работу
     

      radio.printDetails();  // Вот эта строка напечатает нам что-то, если все правильно соединили.
    }

    void blinkFunc(int LED)
    {
      int ledState = LOW;
      unsigned long previousMillis = 0;
      unsigned long currentMillis = millis();
        const long interval = 100;
        if (currentMillis - previousMillis >= interval)
        {
        // save the last time you blinked the LED
        previousMillis = currentMillis;

        // if the LED is off turn it on and vice-versa:
        if (ledState == LOW)
        {
          ledState = HIGH;
        }
        else
        {
          ledState = LOW;
        }
        digitalWrite(LED, ledState);
      }
    }
    void loop() {
      int Xaxis;
      int Yaxis;
      int button;

      radio.startListening();
      if ( radio.available()) {  // слушаем эфир со всех труб
        radio.read( &recieved_data, sizeof(recieved_data) );
        delayMicroseconds(128);
        radio.stopListening();// чиатем входящий сигнал
        if (recieved_data[3] = 6666939){
        Serial.println(recieved_data[1]);
        Serial.println(recieved_data[2]);
        Serial.println(recieved_data[0]);
        Xaxis = recieved_data[1];
        Yaxis = recieved_data[2];
        button = recieved_data[0];

      if(Xaxis < 90){
          rightServo.write(Yaxis - (90 - Xaxis));
          leftServo.write(Yaxis);
          blinkFunc(ledGabRight);
        }

        if(Xaxis > 90){
          rightServo.write(Yaxis);
          leftServo.write(Yaxis - (Xaxis - 90));
          blinkFunc(ledGabLeft);
        }
        else {
          rightServo.write(Yaxis);
          leftServo.write(Yaxis);
        }

        if(Yaxis < 90){
          digitalWrite(ledRedBack, HIGH);
        }
        else {
          digitalWrite(ledRedBack, LOW);
        }
        //Serial.println(Xaxis);
        //Serial.println(Yaxis);
        _delay_ms(100);
      }
      } else {
        rightServo.write(90);
        leftServo.write(90);
      }
    }
    Вот код трансмитера
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"

    RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
    //RF24 radio(9,53); // для Меги

    int button = 8;  // кнопка на 3 цифровом
    int Yaxis = A0; // потенциометр на 0 аналоговом
    int Xaxis = A1; // движковый потенциометр на 1 аналоговом пине

    byte transmit_data[4]; // массив, хранящий передаваемые данные
    //byte latest_data[3]; // массив, хранящий последние переданные данные
    //boolean flag; // флажок отправки данных

    void setup() {
      Serial.begin(9600); //открываем порт для связи с ПК

      pinMode(button, INPUT);
      pinMode(Xaxis, INPUT);
      pinMode(Yaxis, INPUT);

      radio.begin(); //активировать модуль
      delay(2000);
      radio.setAutoAck(1);         //режим подтверждения приёма, 1 вкл 0 выкл
      radio.setRetries(0, 15);    //(время между попыткой достучаться, число попыток)
      radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
      radio.setPayloadSize(32);     //размер пакета, в байтах

      radio.openWritingPipe(123);   //мы - труба 0, открываем канал для передачи данных
      radio.setChannel(0x7f);  //выбираем канал (в котором нет шумов!)

      radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
      radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
      //должна быть одинакова на приёмнике и передатчике!
      //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

      radio.powerUp(); //начать работу
      radio.stopListening();  //не слушаем радиоэфир, мы передатчик
    }

    void loop() {
      Serial.println(button);
      Serial.println(map(analogRead(Xaxis), 0, 1023, 0, 180));
      Serial.println(map(analogRead(Yaxis), 0, 1023, 0, 180));
     
      transmit_data[0] = !digitalRead(button); // инвертированный (!) сигнал с кнопки
      transmit_data[1] = map(analogRead(Xaxis), 0, 1023, 0, 180); // получить значение
      // в диапазоне 0..1023, перевести в 0..180, и записать на 1 место в массиве
      transmit_data[2] = map(analogRead(Yaxis), 0, 1023, 0, 180);
      transmit_data[3] = 6666939;
      radio.write(&transmit_data, sizeof(transmit_data)); // отправить по радио
      _delay_ms(100);
    }
    При включении самого робота сразу начинает двигать сервами, хотя передатчик ещё не включён. Попытался хоть какой то ключ по данным сделать, не помогает.
    Не программист а олух несчастный, помогите(
     
  2. Daniil

    Daniil Гуру

    У вас тут если Xaxis<90, то выполняется и первое условие, и блок else второго.
    Правильно ли отрабатывают сервы постоянную отправку неизменяющихся данных?
    Как он ими двигает?
     
  3. Freimor

    Freimor Нуб

    Хотел написать что
    if(Xaxis <90){
    rightServo.write(Yaxis -(90- Xaxis));
    leftServo.write(Yaxis);
    --это поворот в сторону
    else{
    rightServo.write(90);
    leftServo.write(90);
    }
    --это если данные не пришли
    Пока что на при включении сервы начинают вращаться (сервы постоянного вращения) зависимости от данных передатчика. На порту появляются значения 18 18.
     
  4. Freimor

    Freimor Нуб

     
  5. Daniil

    Daniil Гуру

    На каком?
    У передатчика тут:
    и тут:
    Данные могут быть разные, да и само напряжение может шуметь (преобразование в более узкий диапазон своего рода фильтрация).
    У приёмника странный приём. Он всасывает всё, а хотелось бы, чтобы передатчик после отправки данных ждал от приёмника команду, что "я готов принимать данные".
    delay(100) - совсем не синхронизация.
    Если сделать так, чтобы приёмник не обрабатывал данные (поставить && 0 в условие), то лишние повороты останутся?