SkyNomad
http://forum.skynomad.net/

Домашно Варио
http://forum.skynomad.net/viewtopic.php?f=14&t=8333
Страница 1 от 3

Автор:  andrew [ Нед Ное 01, 2015 8:03 pm ]
Заглавие:  Домашно Варио

Здравейте на всички летящи.

Казвам се Андрей Манолов и това е първият ми пост тук.
Летя с спиид крила и от време на време с парапланер.

Щом има домашна ракия и домашни вариота трябва да има ;)

В тази тема ще се опитам да опиша как правя моите домашни варио-та, за да може всеки с малко умения,поялник и компютър да си направи.

Вариото което аз си правя е:

- Евтино :) ( аз поръчах по 10 броя от всяка част за проби и грешки ).
При мен за 10 броя цената на едно варио стана 15лева бройката ( горе долу, билет на сопот и 2 бири ).
- Прецизно, сензорът който използваме е Bosh ( bmp180 ) с доста добра чувствителност ( приблизително 20см ).
- Бързо ( кодът прави малко и бързо филтриране на данните от сензора давайки много бърза реакция )
- Малко ( наистина е много малко :)
- Звуково ( няма дисплей но може да бъде добавен срещу още 10-15 лева и малко код :)
- Гъвкаво ( може да си променяте кода както си искате )
- Зарежда се от USB с литиево полимерна батерия.

Списък с частите.
Аз ги поръчах от e-bay от китай наи евтините възможни няма как да сгрешите :)

$2.00 - Mini ATMEAG328 3.3V 8Mhz Replace ATmega128 For Arduino Pro Mini Compatible
$1.30 - BMP180 Replace BMP085 Digital Barometric Pressure Sensor Module For Arduino
$0.99 - 5V Mini USB 1A Lithium Battery Charging Lipo Charger Module for Arduino New
$2.00 - One 602030 3.7V 300mAh LiPo Battery MP3 MP4 Model toys High Power New
$1.65 - 10 x 2 Pin 14 x 7mm Passive Electronic Piezoelectric Piezo Buzzer DC 1-30V Black

Програматор FTDI/USB:
$2.63 - FT232RL FT232 USB to Serial adapter module USB TO 232 For Arduino pro mini new

Програматора ви трябва за да качите софтуера на вариото :)

Частите:

Изображение


Схемата:

Изображение

За да спестя място директно запоявам пин SDA и SCL na сензора към a4 и a5 на Arduino pro mini board-a.

Изображение

Така изглежда монтиран баро сензора на гърба на контролера:

Изображение


Същото погледнато отпред. Високоговорителя звързан към пин 9 и GND
Изображение


Така изглежда събрано и украсено малко.
Изображение


Ето и видео на вариото в движение:
https://www.youtube.com/watch?v=3IU2lgVRdj4


За да го програмирате ще ви трябва Arduino софтуер-а който може да свалите от официалния сайт на:
https://www.arduino.cc/en/Main/Software

Ето го и кода по долу.

Наздраве :)

Код:
//**********************************
//*   BMP085 and BMP180 version    *
//**********************************
// This is the Poor Mans Vario code for the cheaper BMP085 and the BMP180 sensor by BOSCH Sensortec
// Arduino <> Sensor: Connect VCC to VCC and GND to GND, SCL goes to analogue pin 5, SDA to analogue pin4.
// Servo signal input, connect to Arduino pin D3
// Audio output to transmitter on pin D2
// Started from code by Rolf R Bakke, Oct 2012
// Modified by Hans Meijdam, June 2013: added altitude feature
// Modified by Hans Meijdam, November 2013: Sensor routine for BMP085 and BMP180
// Modified by Andrey Manolov September 2015: positive beeping only. Tweaking average filtering.
//

#include "Wire.h"

const byte led = 13;
unsigned long time = 0;
float toneFreq, toneFreqLowpass, flpressure, lowpassFast, lowpassSlow ;
float p0; // this will be used to store the airfield elevation pressure
int altitude;
int ch1; // Here's where we'll keep our channel values
int ddsAcc;
#define I2C_ADDRESS 0x77
const unsigned char oversampling_setting = 3; //oversamplig for measurement
const unsigned char pressure_waittime[4] = {
  5, 8, 14, 26 };
//Sensor parameters taken from the BMP085 datasheet
int ac1, ac2, ac3;
unsigned int ac4, ac5, ac6;
int b1, b2, mb, mc, md;
int temperature;
long pressure;

void setup()
{
  Serial.begin(9600); // start serial for output
  Serial.println("Setting up BMP085");
  Wire.begin();
  bmp085_get_cal_data();
  bmp085_read_temperature_and_pressure(&temperature,&pressure);
  flpressure=pressure;// move long type pressure into float type flpressure
  p0 = lowpassFast = lowpassSlow = flpressure;
  Serial.print(" p0 = ");
  Serial.println(p0);
  pinMode(3, INPUT); // Set our input pins as such for altitude command input from receiver via pin D3
}

void loop()
{
  bmp085_read_temperature_and_pressure(&temperature,&pressure);
   Serial.print(temperature,DEC);
   Serial.print(" ");
   Serial.print(pressure,DEC);
   Serial.print(" ");
  flpressure = pressure;// move long type pressure into float type flpressure
  altitude = (float)44330 * (1 - pow(((float) flpressure/p0), 0.190295));
   Serial.print(" ");
   Serial.println(altitude);
  lowpassFast = lowpassFast + (flpressure - lowpassFast) * 0.3; // Andrew mod better values for bmp180 boards
  lowpassSlow = lowpassSlow + (flpressure - lowpassSlow) * 0.15; // Andrew mod better values for bmp180 boards
  toneFreq = (lowpassSlow - lowpassFast) * 50;
  toneFreqLowpass = toneFreqLowpass + (toneFreq - toneFreqLowpass) * 0.1;
  toneFreq = constrain(toneFreqLowpass, -500, 500); // Andrew mod better values for bmp180 boards and my speaker
  ddsAcc += toneFreq * 50 + 3000; // better values for bmp180 //andrew mod

//  if (toneFreq < 0 || ddsAcc > 0)
if ((toneFreq > 5 && ddsAcc > 0) ) // only sound on positive climb #andrew mod

  {
    tone(9, toneFreq + 700); 
    ledOn();  // the Arduino led will blink if the Vario plays a tone, so you can test without having audio connected
  }
  else
  {
    noTone(9);
    ledOff();
  }
  while (millis() < time);        //loop frequency timer
  time += 20;



 
}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
  int ut= bmp085_read_ut();
  long up = bmp085_read_up();
  long x1, x2, x3, b3, b5, b6, p;
  unsigned long b4, b7;

  //calculate the temperature
  x1 = ((long)ut - ac6) * ac5 >> 15;
  x2 = ((long) mc << 11) / (x1 + md);
  b5 = x1 + x2;
  *temperature = (b5 + 8) >> 4;

  //calculate the pressure
  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  x2 = ac2 * b6 >> 11;
  x3 = x1 + x2;

  if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1;
  if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
  if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1;
  if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2;

  x1 = ac3 * b6 >> 13;
  x2 = (b1 * (b6 * b6 >> 12)) >> 16;
  x3 = ((x1 + x2) + 2) >> 2;
  b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
  b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
  p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;

  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  *pressure = p + ((x1 + x2 + 3791) >> 4);
}

unsigned int bmp085_read_ut() {
  write_register(0xf4,0x2e);
  delay(5); //longer than 4.5 ms
  return read_int_register(0xf6);
}


// Get Debug information
void bmp085_get_cal_data() {
  Serial.println("Reading Calibration Data");
  ac1 = read_int_register(0xAA);
  Serial.print("AC1: ");
  Serial.println(ac1,DEC);
  ac2 = read_int_register(0xAC);
  Serial.print("AC2: ");
  Serial.println(ac2,DEC);
  ac3 = read_int_register(0xAE);
  Serial.print("AC3: ");
  Serial.println(ac3,DEC);
  ac4 = read_int_register(0xB0);
  Serial.print("AC4: ");
  Serial.println(ac4,DEC);
  ac5 = read_int_register(0xB2);
  Serial.print("AC5: ");
  Serial.println(ac5,DEC);
  ac6 = read_int_register(0xB4);
  Serial.print("AC6: ");
  Serial.println(ac6,DEC);
  b1 = read_int_register(0xB6);
  Serial.print("B1: ");
  Serial.println(b1,DEC);
  b2 = read_int_register(0xB8);
  Serial.print("B2: ");
  Serial.println(b2,DEC);
  mb = read_int_register(0xBA);
  Serial.print("MB: ");
  Serial.println(mb,DEC);
  mc = read_int_register(0xBC);
  Serial.print("MC: ");
  Serial.println(mc,DEC);
  md = read_int_register(0xBE);
  Serial.print("MD: ");
  Serial.println(md,DEC);
}

long bmp085_read_up() {
  write_register(0xf4,0x34+(oversampling_setting<<6));
  delay(pressure_waittime[oversampling_setting]);

  unsigned char msb, lsb, xlsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(0xf6); // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // waiting
  }
  lsb |= Wire.read();
  while(!Wire.available()) {
    // waiting
  }
  xlsb |= Wire.read();
  return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

void write_register(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r);
  Wire.write(v);
  Wire.endTransmission();
}

char read_register(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r); // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  v = Wire.read();
  return v;
}

int read_int_register(unsigned char r)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.write(r); // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  msb = Wire.read();
  while(!Wire.available()) {
    // waiting
  }
  lsb = Wire.read();
  return (((int)msb<<8) | ((int)lsb));
}


void ledOn()
{
  digitalWrite(led,1);
}


void ledOff()
{
  digitalWrite(led,0);
}


Автор:  Александър [ Нед Ное 01, 2015 8:08 pm ]
Заглавие:  Re: Домашно Варио

БРАВО.
Аз поръчвам първото... :)

Автор:  andrew [ Пон Ное 02, 2015 11:09 am ]
Заглавие:  Re: Домашно Варио

Сега видях че не съм обяснил както трябва в първия пост.
Идеята ми беше просто да споделя как може всеки да го направи.
Който има желание и малко да може да запоява може да го направи, ако не почти всеки има приятел който може да запоява малко :)

Затова дадох плановете и кода тук.

Аз направих 1-2 за приятели и 1 за мен, но за жалост нямам време да ги правя или продавам.

Автор:  Lord Ruthven [ Пон Ное 02, 2015 11:26 am ]
Заглавие:  Re: Домашно Варио

То хубаво, ама доколкото виждам според голямата схема го захранваш директно от батерията. Полимерките, когато са заредени докрай са на 4.2 V което е доста над 3.6-те максимално допустими за сензора според дейташийта му, т.е. можеш да очакваш скъсен живот. Като се има предвид, че изтощена батерия пък е на 3.0 V ми е интересно мерил ли си точността как се изменя с изтощаване на батерията?

Автор:  andrew [ Пон Ное 02, 2015 12:03 pm ]
Заглавие:  Re: Домашно Варио

Ардуино про мини както и bmp180 сензор платката има регулатор на волтажа. не е проблем можеби схемата трябва да показва червената линия кам RAW пин-а който е вързан към регулатора на волтажа ще го променя на схемата :)

Автор:  Х А Р И [ Вто Ное 03, 2015 11:37 pm ]
Заглавие:  Re: Домашно Варио

Няколко плюса от мен +++.

Автор:  Marv [ Сря Ное 04, 2015 7:34 pm ]
Заглавие:  Re: Домашно Варио

Това е голяма занимавка за изпълнение, Andrey Manolov ще зарадвате доста хора, ако цялото това нещо го затворите в една добре изглеждаща кутийка и го продавате по 30-40лв примерно. :)

Автор:  andrew [ Чет Ное 05, 2015 2:36 pm ]
Заглавие:  Re: Домашно Варио

Занимавка е да, но идеята на темата е в стил "направи си сам" :)
Нямам желание да е комерсиално и наистина нямам време от нормалната си работа да го развивам като продукт.

Но, пък за който има желание и време ще си е забавен хоби проект с практична полза в спорта.

Поздрави,
Андрей

Автор:  Marv [ Чет Ное 05, 2015 4:14 pm ]
Заглавие:  Re: Домашно Варио

andrew написа:
Занимавка е да, но идеята на темата е в стил "направи си сам" :)
Нямам желание да е комерсиално и наистина нямам време от нормалната си работа да го развивам като продукт.

Но, пък за който има желание и време ще си е забавен хоби проект с практична полза в спорта.

Поздрави,
Андрей

Евала така или иначе! 8)

Автор:  zgaddo [ Пет Дек 04, 2015 11:35 am ]
Заглавие:  Re: Домашно Варио

Много хубава идея Андрей!
А този код имаш ли симулатор с който да го тестваш преди да го качиш?

Автор:  andrew [ Нед Дек 06, 2015 10:53 pm ]
Заглавие:  Re: Домашно Варио

Ами не, тествам го директно на устройството той се качва за нqколко секунди през usb програматора.
Микроконтролера позволява безброи препрограмираниq и е Arduino framework-а е много лесен и забавен за учене, тестване бъзикане и подобни бързи прототипи.

Ако имаш интерес в електрониката програмирането горещо го препоръчвам. Ще се забавляваш много с бързо тестване и създаване на подобни устройства.

Автор:  Viper_Weasel [ Чет Яну 28, 2016 2:34 pm ]
Заглавие:  Re: Домашно Варио

Днес успях да го сглобя, инсталирам и тествам в полеви уловия.
Трудът по сглабянето и инсталирането е нищожен - всеки който може да допре 2 жици и горещо желязо може да си го направи.
На първи тестове е малко хаотчно и прекалено чувствително, предполагам че може да е от сензора или от самият код.
Ще го пробвам скоро в полет, ако работи добре е идеалното нещо за вграждане в каска, а заедно със едно малко соларче ще стане перфектно!

Автор:  Kaloyan Paunov [ Чет Яну 28, 2016 4:24 pm ]
Заглавие:  Re: Домашно Варио

Сглобявам и аз в момента. Надчваме че ще тръгне вече. До сега успях само на ардуино уно тъй като не можех да накарам мини-то да комуникира с компа

Автор:  JordanMK [ Пон Фев 29, 2016 9:13 pm ]
Заглавие:  Re: Домашно Варио

аз сам направил сштото варио , само сам сменил малко кода затова што првичнио код беше таков че вариото беше премногу чуствително... ( реагираше некаде на 5цм ) и сшто когато стоеше в место знаеше да свирка... след промената вариото реагира вече на промена на висината од 20-25цм и мога да кажам че вече не е толку чуствително и не дава никакве звукове при стоене в место и двизена помалки од 20цм.

едина промена којато сам направил е в този дел на кода

if ((toneFreq > 5 && ddsAcc > 0) ) // only sound on positive climb


вместо toneFreq > 5 аз исползвах toneFreq > 30 ( може и помалка вредност , ама вариото че биде по чуствително , некаде околе 15-20 реагира на 10цм ) според мен нема зашто да дава звуци на помалко од 20цм затова користам цифра > 30

исто искам да напоменам че това е само за позитива , когато висината се намалва сам исклучил звуците

Автор:  petrun [ Сря Мар 02, 2016 8:57 pm ]
Заглавие:  Re: Домашно Варио

Моето лично мнение е не да се променя прага, а да се имплементира филтър тип "плаващ прозорец" ("floating window"). Не съм преглежда кода, вероятно има някаква филтрация. На доста подобни проекти слагат Калманов филтър, който за варио е меко казано неуместен, защото тук не гоним предикативност. На плаващия прозорец може да се направят проби с различна дължина (брой семпли), с което се променя дълбочината на филтрацията или иначе казано "пъргавостта".

Страница 1 от 3 Часовете са според зоната UTC + 2 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/