Ультрачувствительный акустический вариометр: точный барометр для пилотов
Компоненты и материалы
- Arduino Pro Mini 3.3V 8 MHz (MCU)
- GY-63 (MS5611) барометрический датчик давления 3.3V
- DIP-переключатель 8-позиционный
- Пьезоизлучатель (активный, со встроенным генератором)
- Мультиплексор 8×1 4051 3.3V
- LiPo аккумулятор 1s 3.7V 350mAh + провода 10 см с разъёмами
- Повышающий преобразователь напряжения + USB зарядка LiPo (TP5400 от AZDelivery)
- Резисторы: сеть 8×4.7 кОм, 220 Ом, 2×10 кОм; конденсаторы 47 мкФ, 470 мкФ
- Самовосстанавливающийся предохранитель 0.5A
- Пластиковый корпус ABS 78×39×22 мм
- Тумблер вкл/выкл
- 6-пинный разъём (female) для FTDI
- Пинхेडеры male: 2×2, 2×2, 2×2, 2×2, 2×2, 4×1, 1×1, 1×1
- 4-пинный male 90° для датчика давления
- 30 см жёсткого провода в изоляции для перемычек
- Зелёный шнур для крепления
О проекте
Введение
Это прибор, используемый пилотами во время полётов (планер, параплан, дельтаплан, воздушный шар и др.) для поиска центра термиков и эффективного набора высоты.
Краткое описание
Это высокочувствительный барометр, издающий звуковые сигналы при наборе высоты и при снижении. Звуки — простые пики: раз в секунду, два в секунду или чаще при подъёме (чем выше скорость подъёма, тем выше частота пиков). Прибор настолько чувствителен, что начинает пикать уже при вертикальной скорости всего несколько сантиметров в секунду — достаточно медленно поднять руку с вариометром, чтобы услышать сигнал. При снижении со скоростью 1 м/с и более издаётся длинный непрерывный писк.
Список компонентов
Полный список приведён выше в таблице. На схеме Fritzing показана вся необходимая обвязка. Обратите внимание: коричневый «керамический конденсатор» под тумблером на самом деле является самовосстанавливающимся предохранителем (в библиотеке не нашлось подходящего символа). Вместо восьми отдельных резисторов использована одна резисторная сборка — чёрный компонент сверху синего DIP-переключателя, с девятью выводами (один общий и восемь для резисторов). Файл схемы Fritzing доступен для скачивания.
Назначение DIP-переключателя
Синий 8-позиционный DIP-переключатель служит для выбора параметров работы вариометра. Ниже таблица настроек:
- 1 — не используется
- 2 — громкость: низкая / высокая
- 3 и 4 — порог сигнала снижения (м/с): -999 (выкл), -1, -2, -3
- 5 и 6 — частота пиков при подъёме (Гц): +1, +1.5, +2, +3
- 7 и 8 — чувствительность (м/с): +0.0, +0.1, +0.2, +0.5
Пин 1 не задействован. Пин 2 меняет громкость путём замыкания резистора в цепи пиезоизлучателя. Пины 3 и 4 задают порог снижения в двоичном коде: 00 = -999 (никогда не пищит), 01 = -1, 10 = -2, 11 = -3 м/с. Для теста можно использовать лифт — спуск с 3 этажа. Пины 5 и 6 аналогично задают частоту пиков: при одинаковой скорости подъёма настройка +2 Гц даст более частые пики, чем +1 Гц. Пины 7 и 8 устанавливают чувствительность: +0.0 — максимум (реагирует на <10 см/с, может ловить микроскопические изменения давления, например, закрытие двери); +0.5 — низкая чувствительность, требует значительной скорости подъёма. Тест: подъём на лифте с 1 на 3 этаж.
С точки зрения схемы, пины 1 и 3–8 считываются аналогово через мультиплексор 4051, затем программа определяет их состояние (значение >512 = вкл). Для выбора входа MCU выставляет 3 бита на выходах (000–111). См. функцию readDIPswitch() в коде.
Важно: батарея
Два резистора 10 кОм и конденсатор 47 мкФ образуют делитель напряжения для контроля заряда LiPo. LiPo критичны при разряде ниже 3.3В, поэтому каждые 10 секунд (BATTinterval) вызывается checkBATT(): при низком напряжении пиезоизлучатель выдаёт 6 коротких пиков в секунду. Не задерживайте выключение и заряжайте сразу!
Обязательно сделайте хотя бы одно отверстие в корпусе для доступа воздуха к датчику давления. На фото видно два отверстия: одно для звука, второе — для индикатора зарядки (и ещё одно для micro USB). С отверстиями прибор не водонепроницаем. Зелёный шнур служит для страховки — не потеряйте прибор в полёте!
Печатная плата
Использована односторонняя плата, поэтому потребовались проводные перемычки (пунктирные линии на схеме). Файлы для ЛУТ (верхний и нижний слои, зеркальные) доступны для скачивания. Печатайте на «жёлтой» или «синей» матовой бумаге для лазерного принтера при 1200 dpi без экономии тонера. Непайку ножек Arduino Pro Mini не требуется — оставьте их свободными для возможного будущего подключения FTDI (6-пинный female разъём установите на верхней стороне платы). Блок питания (step-up + зарядка) монтируется вверх тормашками, фиксируется двумя пинами без пластиковых оснований рядом с USB разъёмом. Три провода соединяют GND, BAT+ и OUT+ с этим блоком.
Барометрический датчик
GY-63 (MS5611) общается по I2C. Программа вызывает readPSensor() — ядро прошивки. Нужно относительное изменение высоты: функция многократно в секунду считывает давление, накаппливает в PrexTotal; каждые 500 мс (PrexInterval) вычисляется среднее изменение высоты и в зависимости от настроек DIP-переключателя генерируются пики или длинный сигнал. Простое усреднение оказалось достаточным; фильтры Калмана, Маджвика и Махони не дали существенного прироста.
Обновления и советы
Всё. Проект принес много удовольствия — повторяйте! :-)
Marco Zonca
Код
Acoustic Variometer code (Arduino)
/* This sketch act as Variometer for paragliding, by Marco Zonca, 2020
Arduino MiniPro 3.3 as CPU, GY-63 (MS5611) barometric pressure sensor,
8 x dipswitch, buzzer, Mux 4051, lipo 1s 3.7v 350mA, 3.7v -> 5v voltage stepup + lipo usb charger;
DipSwitch: 1= not used 2= hw low/high buzzer volume 3= \ sink alarm: OFF -1.0 -2.0 -3.0 m/sec 4= /
5= \ frequency beeps: +1.0 +1.5 +2.0 +3.0 Hz 6= / 7= \ sensibility: +0.0 +0.1 +0.2 +0.5 m/sec 8= / */
#include <MS5611.h>
#include <NewTone.h>
const int muxIOpin = 15;
const int vbattPin = 14;
const int muxbit0 = 4;
const int muxbit1 = 5;
const int muxbit2 = 6;
const int buzzerPin = 7;
const int DIPSWinterval = 5000;
const int BATTinterval = 10000;
const int PrexInterval = 500;
const boolean isDebug = false;
float sensibility[5];
float frequency[5];
float sinkalarm[5];
long n=0;
boolean dipswitch[9];
String dips;
unsigned long prevDIPSWmillis = 0;
unsigned long prevBATTmillis = 0;
float n1=0;
float n2=0;
float SensorVBatt=0;
double referencePressure = 0;
unsigned long prevPrexMillis = 0;
unsigned long currPrexMillis = 0;
double realPressure = 0;
float absoluteAltitude = 0;
float relativeAltitude = 0;
float avgAltitude = 0;
float avgPrevAltitude = 0;
long PrexCounter = 0;
float PrexTotal = 0;
float PrexVario = 0;
boolean isFirstCalc = true;
MS5611 psensor; // pressure sensor
void setup() {
Serial.begin(9600);
pinMode(muxbit0, OUTPUT);
pinMode(muxbit1, OUTPUT);
pinMode(muxbit2, OUTPUT);
pinMode(buzzerPin, OUTPUT);
sensibility[4]=0; sensibility[3]=0.5; sensibility[2]=0.2; sensibility[1]=0.1; sensibility[0]=0.0;
frequency[4]=0; frequency[3]=3.0; frequency[2]=2.0; frequency[1]=1.5; frequency[0]=1.0;
sinkalarm[4]=0; sinkalarm[3]=-3.0; sinkalarm[2]=-2.0; sinkalarm[1]=-1.0; sinkalarm[0]=-999.9;
readDIPswitch();
psensor.begin();
referencePressure = psensor.readPressure();
if (isDebug == true) Serial.println("Vario is on");
NewTone (buzzerPin,4); delay(750); noNewTone();
}
void loop() {
readPSensor();
if ((prevDIPSWmillis+DIPSWinterval) < millis()) { readDIPswitch(); prevDIPSWmillis=millis(); }
if ((prevBATTmillis+BATTinterval) < millis()) { checkBATT(); prevBATTmillis=millis(); }
}
void readPSensor() {
realPressure = psensor.readPressure();
absoluteAltitude = psensor.getAltitude(realPressure);
relativeAltitude = psensor.getAltitude(realPressure, referencePressure);
PrexCounter = PrexCounter + 1;
PrexTotal = PrexTotal + relativeAltitude;
currPrexMillis = millis();
if (currPrexMillis - prevPrexMillis >= PrexInterval) {
avgAltitude = PrexTotal / PrexCounter;
if (isFirstCalc == true) { avgPrevAltitude=avgAltitude; isFirstCalc=false; }
PrexVario=(avgAltitude-avgPrevAltitude) * (1000/PrexInterval);
if ((PrexVario <= sensibility[4]) && (PrexVario >= sinkalarm[4])) { noNewTone(); }
if ((PrexVario > sensibility[4])) { NewTone (buzzerPin,((int)(PrexVario+frequency[4]))); }
if ((PrexVario < sinkalarm[4])) { NewTone (buzzerPin,0.1); }
avgPrevAltitude=avgAltitude;
prevPrexMillis = currPrexMillis;
PrexTotal=0; PrexCounter=0;
if (isDebug == true) { Serial.print("Vario="); Serial.println(PrexVario); }
}
}
void readDIPswitch() {
int s=0;
for (n=1; n<9; n++) {
dips="0000"+String(n-1, BIN);
dips=(dips.substring(dips.length()-3,dips.length()));
if (dips.substring(2,3) == "0") digitalWrite(muxbit0, LOW); else digitalWrite(muxbit0, HIGH);
if (dips.substring(1,2) == "0") digitalWrite(muxbit1, LOW); else digitalWrite(muxbit1, HIGH);
if (dips.substring(0,1) == "0") digitalWrite(muxbit2, LOW); else digitalWrite(muxbit2, HIGH);
if (analogRead(muxIOpin) > 512) dipswitch[n]=false; else dipswitch[n]=true;
if (isDebug == true) { if (dipswitch[n]==false) Serial.print("0"); else Serial.print("1"); }
}
if (isDebug == true) Serial.println("");
s=0;
if (dipswitch[7]==true) s = s + 2;
if (dipswitch[8]==true) s = s + 1;
sensibility[4]=sensibility[s];
if (isDebug == true) { Serial.print("Sensibility="); Serial.println(sensibility[4]); }
s=0;
if (dipswitch[5]==true) s = s + 2;
if (dipswitch[6]==true) s = s + 1;
frequency[4]=frequency[s];
if (isDebug == true) { Serial.print("Frequency="); Serial.println(frequency[4]); }
s=0;
if (dipswitch[3]==true) s = s + 2;
if (dipswitch[4]==true) s = s + 1;
sinkalarm[4]=sinkalarm[s];
if (isDebug == true) { Serial.print("SinkAlarm="); Serial.println(sinkalarm[4]); }
}
void checkBATT() {
n1 = analogRead(vbattPin);
n2=(((6.60 * n1) / 1023.00));
SensorVBatt=(n2 + ((n2 * 0.0) /100));
if (SensorVBatt <= 3.4) { NewTone (buzzerPin,6,1000); }
if (isDebug == true) { Serial.print("VBatt="); Serial.println(SensorVBatt); }
}
Корпус и детали для 3D печати
Файлы доступны в разделе Custom parts and enclosures.
Схемы
Файл схемы Fritzing: vario_R1XzPifiX4.fzz
Производственный процесс
- Безопасное хранение и управление чувствительными данными с Google Cloud Secret Manager
- Анероидный барометр: конструкция, история и будущее измерения давления
- Продвинутая техника обнаружения выявляет дефекты транзисторов с беспрецедентной чувствительностью
- Революционные ультратонкие MXene сенсоры деформации повышают точность и безопасность роботизированных манипу…
- Продвинутые оптические приемники для космических коммуникаций
- Amstrong® Ultra 650MC – Высокопрочный низкоуглеродистый сталь с отличной свариваемостью
- Amstrong® Ultra 650MCT – Высокопрочная низкоуглеродистая сталь с повышенной вязкостью при низких температурах
- Amstrong® Ultra 700MC — Высокопрочный мелкозернистый сталь с отличной сварностью
- Amstrong® Ultra 700MCT — Высокопрочная сталь с повышенной вязкостью при низких температурах
- Ультрачистый хром (UHP Cr) — 99,95%+ для критических применений