Указатель воздушной скорости "Своими руками" АРДУИНО

Когда я вижу некую фигню с незакрепленными соплями (проводами), то мне становится очень грустно.

Меня на военных предприятиях научили все провода надежно крепить дабы они не поотлетали при тряске.
 

Вложения

  • Figna_s_provodami.jpg
    Figna_s_provodami.jpg
    52,5 КБ · Просмотры: 189
незакрепленными соплями (проводами)
Может это выставочный экземпляр? Точность, говорят, 0.1 гр/час и ниже. О цене ничего не скажу.

А тут собрались на коленке собрать целиком прибор за 3 т.р.
Думаю, что не получится.

Стоила такая штуковина два года назад 27,5 тысяч рублей.
Вряд-ли что-либо сильно изменилось. Например и иже с ним - цены только по запросу.

Казалось, что может быть проще?
Включил тот прибор на 4 часа и посмотрел на уход вертикали. 
Может сделает Лукич...
Только никаких выводов из этого сделать будет невозможно, я думаю, поскольку
Можно заострить внимание на стабильности нуля и дисперсии шумов, а ведь их можно победить несложными алгоритмами (усреднять во времени или с использованием избыточных измерительных блоков). Зато погрешность от вибраций, как мы увидели выше на примере CRG20-01, может оказаться трудным описать в алгоритме. Долгое время стабильность нуля является золотым стандартом выбора ММГ. Однако на практике большее влияние на точность может оказать чувствительность к ускорениям и вибрациям.

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

У меня вопрос.
На сколько градусов "уползет" вертикаль за три - четыре часа полета?
Насколько я знаю, авиагризонты на основе твердотельных гироскопов и акселерометров умеют корректировать сами себя по нулевым показаниям акселерометров и самого гироскопа   (если нет ускорений и изменений траектории, значит полет горизонтальный, как-то так). У меня дома авиамодельный автопилот не терял горизонт как его не крути и не верти в течении долгого времени.
Курс только ползет, может дом экранирует магнитометр, на улице надо пробовать.
 
#include <I2Cdev.h>
#include <MPU6050.h>
#include <Servo.h>
#include <Wire.h>
....

accelgyro.getAcceleration(&ax, &ay, &az);
  accelgyro.getRotation(&gx, &gy, &gz);
  Fay = filter_ay(ay);
  Fax = filter_ax(ax);
  Faz = filter_az(az);
  Fgx = filter_gx(gx+339);
  Fay = Fay/100;
  Fax = Fax/100;
  Faz = Faz/100;
  LD_AXYZ = sqrt((Fay*Fay)+(Fax*Fay)+(Faz*Faz));
  L_LD_AXYZ =abs(LD_AXYZ - 158) ;// 160 приведённая величина вектора ускорения статики
  Kren_a = (Fay/LD_AXYZ)*10;
  Kren_ay = 0.610*(Kren_a*Kren_a)+3*(abs (Kren_a));// аппроксимированные значения
if ( Fgx<-10 || Fgx>10)          // отсекаем сигналы ниже 10 ед
{
Kren_g = (Kren_g + Fgx/200);      // интегратор угла
};
Kren_gx = Kren_g/31;                //31 масштабный коэфициент   

if (Kren_a < 0 )
{
  Kren_ay = -Kren_ay;             //угол с нужным знаком
};

Kren = alfa* Kren_gx + (1-alfa)*Kren_ay ;
............
myservo2.write(90-Kren);   
 
за три часа ничего не произойдёт( хотя я сейчас залил скетч и поставил), т.к.  показания угловых ускорений загрубленны до нельзя.
    Код оставил в таком виде, хоть что то осмысленное стало происходить со стрелкой.
   Если брать угол только от акселерометра( самое простое)  через проекцию ускорения свободного падения то мне кажется в то индикатор будет повторять указатель "шарик"
 
попытки математикой выделить нужный вектор от акселерометра не увенчались успехом. Функции корни и арксинусы отвратительно работали. Я не программист и дня болавства с гироскопом хватило, испытываю насыщение.
 
ветка про указатель воздушной скорости кстати,гироскоп просто под руку попался.
     Код для указателя воздушной скорости и высоты, немножко подделал и считаю что для пользования на дельте вполне пойдёт.
     Ведь что получили : бюджетный , автономный( пвд в комплекте) весом пол кг указатель. Которого вполне хватить что бы не лететь слишком медленно или слишком быстро и не вылезать из эшелона в 300м.
    Возвращаясь к гироскопу то код можно использовать таким макаром: в облако входим в горизонте(можно кнопкой ноль дать по крену) а затем следить за стрелкой, что бы была вертикально , минут 5-10ть на облако хватит?
    Потеплеет, зацеплю на подкос ,кино сниму.
 
пока нет , я этим не занимался, для этого надо посидеть немножко на морозе для снятия показаний.Если есть сырые данные АЦП с этого датчика в диапазоне -10+10, делитесь. Я в холода не летаю, поэтому это не так актуально.
    показания с "гироскопом" за ночь естественно ни куда не ушли.

    Используемые железки у меня валялись лет 6-ть. С удивлением обнаружил , что датчик MPX7002 стоит 1000 р  против BMP085 который обойдётся в 100р.
    Может попробовать адаптировать BMP085 под динамическое давление, типа трубочка к самому датчику,а  остальное в силикон.
   А то руки зачесались еще кое что  сделать, но 1000р на игрушку рубит идею на корню.
 
От 400 до 600 на АлиЭкспресс.

адаптировать BMP085 под динамическое давление
После фильтрации у меня получалось среднеквадратичное отклонение в 1 Па. Т.е. точности достаточно. Но два датчика на одну шину не повесишь из-за одного адреса, придется программно эмулировать еще одну I2C, либо переключать аппаратную.
Покажут они, разумеется, разные цифры и придется провести статистические испытания их совместной работы при различных условиях, для оценки уже совместной погрешности.
 
Если есть сырые данные АЦП с этого датчика в диапазоне -10+10, делитесь.
По моим очень грубым пркидкам, уход нуля в режиме УС более 1 км/ч на градус. Проверял выставляя устройство на балкон. Датчик аналоговый MPX 5004
 
val1 = analogRead(mpxv);               // чтение аналогового датчика скорости
  val1 = map(val1, StartADC, StartADC+180, 0, 180);   // перевод диапазона числа АЦП в диапазон углов отклонения
  dps.getAltitude(&Altitude);            //получение данных о высоте с датчика BMP085
  val2 = (Altitude - Alt_0)/ 100;        //
  val2 = map(val2, 0, 500, 0, 180);      //  перевод диапазона высот в диапазон углов отклонения
  myservo1.write(180-val1);              // инвертируем отклонение, что бы с лево на право
  myservo2.write(180-val2);              //
> А что так много жрет-то? Там что маленький кипятильник встроен? Жрёт много похоже потому ,что сервы напрямую подкинуты. Надо с резюками играть. 

>analogRead

ШИМ экономнее прямой подачи тока на движок, наверное у Вас как раз ШИМ. Также библиотека CyberLib экономит итерации, а значит и батарею, но за счёт задействования одного таймера в МК.

Кстати, по-умолчанию, этот код ставит сервы в угол 100 раз в секунду. Не слишком много? М.б. хватит и 5-10, и двигать сервы только по достижению счётчиком значения 10-20?
 
Да для серв использовано ШИМ (даже не рассматривал другой способ управления).

По поводу оптимизации кода  не спорю.
Не думаю что будет большая разница в потреблении если операции записи в регистры заменить операциями сравнения,( вы наверное от этом)
   Пока сервы неподвижны потребление 70 мА
   При движениях потребление возрастает до 200мА при одной серве и до 300мА с гаком при работе 2х серв,зависит от характера  работы моторов. Трудно заставить на  столе изменяться одновременно и скорость и высоту, дуть и втягивать воздух одновременно не получается.
    Благо приспособу придумал для фиксации давления, так хоть указатель скорости по УС нормально тарировать получилось.
 
кстати цикл программы получился порядка 100-150мс, так что около 10ти раз в секунду корректировка и проходит.
 
Можно добавить некоторую погрешность чтобы не дёргать сервы  постоянно.
Нечто вроде
If (abs(val1-val1_предыдущее)>delta) {
     myservo1.write(180-val1);
}
If (abs(val2-val2_предыдущее)>delta ) {
     myservo2.write(180-val2);
}

По-моему вот тут может теряться точность
val2 = (Altitude - Alt_0)/ 100;        //
  val2 = map(val2, 0, 500, 0, 180);      //  перевод диапазона высот в диапазон углов отклонения

Не знаю, есть ли смысл переписать в таком виде?
val2 = Altitude - Alt_0;        // здесь Alt_0 в 100 раз больше
val2 = map(val2, 0, 50000, 0, 180);      //
или
val2 = map(Altitude - Alt_0, 0, 50000, 0, 180);      // здесь Alt_0 в 100 раз больше
 
val2 = (Altitude - Alt_0)/ 100;   - это перевод в метры

Для индикации на стрелке, вполне пойдёт.

Для вычислений вариометра использовал чистый высоту в сантиметрах:

пока код такой:



  //ПОЛУЧЕНИЕ ДАННЫХ, первичная обработка
  val1 = filter_acp(analogRead(mpxv));   // чтение аналогового датчика скорости с фильтрацией
  //0 536|40 544|50 55|60 567|70 583|80 596|90 610|100 632//536-10:
  // Serial.print (val1-StartADC);Serial.print("\t");
  dps.getAltitude(&Altitude);            //получение данных о высоте с датчика BMP085 
  val2 = filter_bmp(Altitude);
 
  //ОБРАБОТКА ДАННЫХ с датчиков для индикации
    //скорость
   //val1 = 40.59*log(val1-StartADC)-87.76;// 0-180 10гр  10км/ч
   // val1 = 55.77*log(val1-StartADC)-118.6;// 0-120 15гр  10км/ч
    val1 = 129.8*log(val1-StartADC)-447.3;// 50-110 30гр  10км/ч
   //val1 = map(val1, StartADC, StartADC+180, 0, 180);

    // вариометр скорость подьёма/спуска в spid_val2
  IntVar_IN = IntVar_IN + val2;
  ivar++ ; 
  if ( ivar == 10)
     {
      ivar = 0;
      IntVar_IN = IntVar_IN/10;
      spid_val2 = (IntVar_IN - IntVar_OUT)/165;   // скорость в м/с где 183 время между обращениями к данной строке милисикунд 
      //Serial.print(millis());Serial.println("\t");
      //Serial.print(spid_val2);Serial.println("\t");         
      IntVar_OUT = IntVar_IN;
      IntVar_IN = 0;
      
      // настройка индикации
       if (spid_val2 > 0)  //определение тендендции изменения высоты
        {
          on_redD  = 0;       // выключене светодиода противопольжного направления 
          on_grinD = 1;                
         }
       else
        {
          on_grinD = 0;
        }
      if (spid_val2 <=-1)  //определение тендендции изменения высоты
        {
          on_grinD = 0;  // выключене светодиода противопольжного направления                
          on_redD  = 1;
         }      
      else
        {
          on_redD = 0;
        }      
       }
   
   //высота в м ,преобразование для угла поворота на 180 для 600м
    val2 = val2/100;
    val2 = map(val2,0,600,0,180);

  //ВЫВОД ДАННЫХ 
  //стрелочные индикаторы
     myservo1.write(180-val1);              // инвертируем отклонение, что бы с лево на право
     myservo2.write(180-val2);               //
  //порт
  // Serial.print (val1);Serial.println("\t");
 
  //светодиодная индикация 
   if (val1<30)                    //условие включения сигнализатора ОПАСНОСТЬ,скорость меньше 60км/ч   
    { on_Alarm = 1;}
   else
    { on_Alarm = 0;}                            
      
if ( timer01 == t_timer)   //таймер мигания диодов
   {
      if (on_redD)
      {
        if (Flag_redD)
         {
          digitalWrite(redD,LOW);
          Flag_redD = 0;
         }
        else
         {
          digitalWrite(redD,HIGH);
          Flag_redD = 1;
         }
       } 
      else  digitalWrite(redD,LOW);
     if (on_grinD)
      {
        if (Flag_grinD)
         {
          digitalWrite(grinD,LOW);
          Flag_grinD = 0;
          }
        else
         {
          digitalWrite(grinD, HIGH);
          Flag_grinD = 1;
          }
      }         
      else  digitalWrite(grinD,LOW);
      
      if (on_Alarm)
      {
        if (Flag_Alarm)
         {
          digitalWrite(Alarm,LOW);
          Flag_Alarm = 0;
          }
        else
         {
          digitalWrite(Alarm, HIGH);
          Flag_Alarm = 1;
          }
      }         
      else  digitalWrite(Alarm,LOW);
      
      timer01 = 0;
   }
 
  timer01++;
   

  // КНОПКА
   if (digitalRead(knop) == HIGH) // кнопка нуля высоты
   {
   uroven0(); 
   delay(500);
   }

}
 
...сервы самые дешманские и лёгкие какие видел (9G). Если известны другие в широком доступе то в студию пожалуйста
 
Вырисовывается УС-160.
Arduino Nano, MPXV7002DP и спидометр от хантера.
У спидометра частотное управление. Если правильно понял подобранные коэффициенты, то 10 гц соответствует 100км/ч. Управление по напряжению, прощает прямое подключение к ноге МК. Читаемость сильно лучше цифровых и самодельных индикаторов.
Плюс, бонусом, подсчет воздушного пробега самолета 🙂
 

Вложения

  • IMG_20180710_014959-min.jpg
    IMG_20180710_014959-min.jpg
    218,3 КБ · Просмотры: 172
Назад
Вверх