Помогите с контролем напряжения на приемнике

Тема в разделе "Проводная и беспроводная связь", создана пользователем saanger, 30 май 2020.

Метки:
  1. saanger

    saanger Нуб

    Добрый день! Очень хочется видеть на дисплее пульта радиоуправления кораблем уровень напряжения на аккумуляторе приемника. Поиски чего то конкретного с примером не могу найти. Я не очень силен в программировании. На экране появляются четырехзначные числа, а сервы сильно тормозят. Подскажите как это можно сделать.
    Код (C++):
    /*Основной 4-канальный передатчик с использованием модуля nRF24L01.*/
    /*http://www.youtube/c/electronoobs */

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

    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #define OLED_RESET 7
    Adafruit_SSD1306 display(OLED_RESET);
    /*Создайте уникальную трубу. Приемник должен
       носить тот же уникальный код*/


    const uint64_t pipeOut = 0xE8E8F0F0E1LL; //ВАЖНО: так же, как в приемнике

    RF24 radio(9, 10); // select  CSN  pin
    byte yaw;//рыскание
    // Размер этой структуры не должен превышать 32 байта
    // Это дает нам до 32 8 бит канала
    struct MyData {
      byte throttle;     //газ
      byte yaw;          //рыскание
      byte pitch;        //тангаж
      byte roll;         //крен
      byte AUX1;
      byte AUX2;
    //byte LED1;
    //byte LED2;
    };
    MyData data;
    int telemetry[1];
    float vbat;

    void resetData()
    {
      //Это начальные значения каждого канала
      // Газ 0 для остановки двигателей
      //127 - среднее значение
      data.throttle = 0;
      data.yaw = 127;
      data.pitch = 127;
      data.roll = 127;
      data.AUX1 = 0;
      data.AUX2 = 0;
    //data.LED1 = 0;
    //data.LED2 = 0;
    }
    void setup()
    {
    Serial.begin(9600);
    D3_In;D4_In;D5_In;D6_In;D7_In;D8_In;
    D3_High;D4_High;D5_High;D6_High;D7_High;D8_High;
      radio.begin();
      //radio.setAutoAck(false);
      radio.setDataRate(RF24_1MBPS);
      radio.enableAckPayload();
      radio.openWritingPipe(pipeOut);
      resetData();
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // инициализация дисплея по интерфейсу I2C, адрес 0x3C
    }
    /**************************************************/
    //Мы отображаем значения от 0-1024 до 0-255,
    //потому что у нас есть 8-битные каналы и 8 бит = 254,
    //как только мы получим значения в приемнике, мы можем отобразить значения еще раз, так что не волнуйтесь
    // Возвращает исправленное значение для положения джойстика, которое учитывает
    // значения внешних экстентов и середины диапазона джойстика.
    int mapJoystickValues(int val, int lower, int middle, int upper, bool reverse)//ниже,среднее,верхнее,обратный
    {
      val = constrain(val, lower, upper);
      if ( val < middle )
        val = map(val, lower, middle, 0, 128);
      else
        val = map(val, middle, upper, 128, 255);
      return ( reverse ? 255 - val : val );
    }
    void loop(){
    int Right_trim = map(A6_Read, 0, 1023, 64, 191); //правый триммер
    //правый джойстик вправо-влево
    if(A1_Read < 512)
    yaw = constrain(map(A1_Read, 17, 511, 0, Right_trim), 0, 255);
    else
    yaw = constrain(map(A1_Read, 512, 940, Right_trim, 255), 0, 255);
    if (D3_Read == 0)
       {data.yaw = map(yaw, 0, 255, 64, 191);}
    if (D4_Read == 1 && D3_Read == 1)
       {data.yaw = map(yaw, 0, 255, 32, 223);}
    if (D4_Read == 0)
       {data.yaw = yaw;}

    int Left_trim = map(A7_Read, 0, 1023, 64, 191); //левый триммер
    //правый джойстик вперед-назад
    if(A0_Read < 512)
        data.pitch = constrain(map(A0_Read, 0, 511, 0, Left_trim), 0, 255);    //0, 511 - половина диапазона хода оси (свое значение ставим вместо цифры 0)
    else
        data.pitch = constrain(map(A0_Read, 512, 1023, Left_trim, 255), 0, 255);           //512, 1023 - вторая половина диапазона (свое значение ставим вместо цифры 1023)

    //Диапазон газа*/
    if (D8_Read == 0)
        {data.throttle = constrain(map(A3_Read, 0, 1023, 0, 128), 0, 128);}
    if (D7_Read == 1 && D8_Read== 1)
        {data.throttle = constrain(map(A3_Read, 0, 1023, 0, 191), 0, 191);}     //0, 1023 - тут тоже
    if (D7_Read == 0)
         {data.throttle = constrain(map(A3_Read, 0, 1023, 0, 255), 0, 255);}

    /*Читаем значения аналогового входа
    При значении true оно будет инвертировать значение
    При значении false будут использоваться значения от 0 до 1024.
    Эта часть на случай, если вы подключите понтонометры, поменяв местами провода
    и настроить значения
    Используемые здесь калибровочные числа должны быть измерены
    для ваших джойстиков, пока они не отправят правильные значения.*/

      data.roll     = mapJoystickValues( analogRead(A2), 60, 575, 1015, false );    //крен
      data.AUX1     = D5_Read; //2 тумблера
      data.AUX2     = D6_Read;

      radio.write(&data, sizeof(MyData));
      if( radio.isAckPayloadAvailable() ) {                                  // если получаем пустой ответ
    // если в ответе что-то есть  читаем
      radio.read(&telemetry, sizeof(telemetry));        
    }
      display.clearDisplay(); // очистка дисплея
      display.setTextSize(4); // установка размера шрифта
      display.setTextColor(WHITE); // установка цвета текста
      display.setCursor(2, 20); // установка курсора в позицию X = 0; Y = 0
      display.print (telemetry[1]); // записываем в буфер дисплея нашу фразу
      display.display(); // и её выводим на экран
      display.print ("      "); // пробел между цифрами
      delay(100);
    Serial.println(telemetry[1]);
    }
    Код (C++):
    /*
    Этот код получает 6 каналов и создает ШИМ-выход
    Пожалуйста, поделитесь и подпишитесь: https://www.youtube.com/c/ELECTRONOOBS
    */

    //#include "printf.h"
    #include <CyberLib.h>
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include <Servo.h>
    #define MIN 60
    //Определить ширину
    int pwm_width_4 = 0;
    int pwm_width_5 = 0;
    int pwm_width_6 = 0;
    int pwm_width_7 = 0;
    int pwm_width_8 = 0;
    int pwm_width_9 = 0;
    /***************Телеметрия***************/
    int telemetry[1];
    int value = 0;
    float vout = 0.0;
    float vbat = 0.0;
    float kpop = 0.1;
    /**************Телеметрия***************/
    Servo PWM4;
    Servo PWM5;
    Servo PWM6;
    Servo PWM7;
    Servo PWM8;
    Servo PWM9;                
    struct MyData {
    byte throttle;                            
    byte yaw;
    byte pitch;
    byte roll;
    byte AUX1;
    byte AUX2;
    };
    MyData data;

    const uint64_t pipeIn = 0xE8E8F0F0E1LL;  
    RF24 radio(2, 10);

    void resetData()
    {
    //Мы определяем начальное значение каждого ввода данных
    //3 потенциометра будут в среднем положении, так что 127 - это середина из 254
    data.throttle = 0;//газ
    data.yaw = 127;//рыскание
    data.pitch = 127;//тангаж
    data.roll = 127;//крен
    data.AUX1 = 1;
    data.AUX2 = 1;
    }
    /**************************************************/
    void setup()
    {
    /***************Телеметрия***************/
        analogReference(DEFAULT);
        pinMode(A3, INPUT);
    /***************Телеметрия***************/
    Serial.begin(250000);
    //Установите контакты для каждого сигнала ШИМ
      PWM4.attach(4);
      PWM5.attach(5);
      PWM6.attach(6);
      PWM7.attach(7);
              D14_Out;D15_Out;
                                               
      resetData();
      radio.begin();
      radio.enableAckPayload();                 // разрешить отсылку данных в ответ на входящий сигнал                                            //!!!и не работает на скорости 250!!!
      radio.setDataRate(RF24_1MBPS);
      radio.openReadingPipe(1,pipeIn);
    //мы начинаем радиосвязь
      radio.startListening();
    }
    /**************************************************/
    unsigned long lastRecvTime = 0;
    void recvData()
    {
    while ( radio.available() ) {
    radio.read(&data, sizeof(MyData));
    lastRecvTime = millis();  //здесь мы получаем данные
    }
    }
    /**************************************************/
    void loop()
    {
    recvData();
    unsigned long now = millis();
    //Здесь мы проверяем, не потеряли ли мы сигнал, сбросили ли мы значения
    if ( now - lastRecvTime > 1000 ) {
    // Сигнал потерян?
    resetData();
    }
    /********************telemetr***********************************/
    // формируем пакет данных телеметрии
        value = analogRead(A3);
        vout = (value) / 1024.0;
        vbat = vout* 4.19;
        telemetry[1] = vbat;
        radio.writeAckPayload(pipeIn, &telemetry, sizeof(telemetry));    // отправляем пакет телеметрии
    /********************telemetr**********************************/

    if (data.AUX1==1){D14_Low;}else{D14_High;}
    if (data.AUX2==1){D15_Low;}else{D15_High;}

    //Теперь мы записываем сигнал ШИМ с помощью функции сервопривода
    PWM4.writeMicroseconds(map(data.throttle, 0, 255, 1000, 2000));
    PWM5.writeMicroseconds(map(data.yaw,  0, 255, 700, 2300));
    PWM6.writeMicroseconds(map(data.pitch,  0, 255, 1000, 2000));
    PWM7.writeMicroseconds(map(data.roll,   0, 255, 1000, 2000));
    Serial.print("vbat:");      Serial.print(vbat);           Serial.print("    ");
    Serial.print("Throttle: "); Serial.print(data.throttle);  Serial.print("    ");
    Serial.print("Yaw: ");      Serial.print(data.yaw);       Serial.print("    ");
    Serial.print("Pitch: ");    Serial.print(data.pitch);     Serial.print("    ");
    Serial.print("Roll: ");     Serial.print(data.roll);      Serial.print("    ");
    Serial.print("Aux1: ");     Serial.print(data.AUX1);      Serial.print("    ");
    Serial.print("Aux2: ");     Serial.print(data.AUX2);      Serial.print("\n");
    }//Loop end
    /*
    Канал - data.yaw         (право / лево )   порт -  D5
    Канал - data.pitch       (вперёд / назад)  порт -  D6
    Канал - data.throttle    (газ)             порт -  D4
    Канал - data.roll        Рудер (Rudder)    порт -  D7
    Канал - msg[4]           (доп канал)       порт - A0 (Значения сигнала 0/1)
    Канал - msg[5]           (доп канал)       порт - A1 (Значения сигнала 0/1)
    */

    /**************************************************/
     
    Последнее редактирование: 30 май 2020
  2. parovoZZ

    parovoZZ Гуру

    Что за МК на корабле? Сервы тормозят - это как?
     
  3. saanger

    saanger Нуб

    Ардуино нано. На пульте джойстик двигаешь, а серва двигается с задержкой.