GoFly - skärmflygning/hangliding/glidförmåga altimeter-variometer från din bil navigationen (5 / 8 steg)
Steg 5: Programmering din Arduino...
Hur man ställer in programmeringsmiljö?
Du kan hitta allt på denna sida.
http://Arduino.cc/en/guide/Windows
Programmet notering.
Du behöver Arduino 1.0 miljö att kompilera programmet. Du behöver också några extra bibliotek.
http://code.Google.com/p/bmp085driver/
http://code.Google.com/p/Rogue-Code/
Jag gjorde några programmering länge sedan (över 10 år sedan) så detta program inte är perfekt. Baserat på vad jag hittade på internet, vissa lärande, försöker och referenser webbplatser.
Det finns en hel del kommentarer att du förstå hur detta program fungerar.
/* Arduino ombord skapar NMEA som protokollet med variometer utgång och beping ljud. $LK8EX1, tryck, höjd, vario, temperatur, batteri, * kontrollsumma Område 0, rå trycket i hPascal:hPA * 100 (exempel för 1013.25 blir 101325) #include < Wire.h > //i2c bibliotek
Arduino Vario av Jaros, 2012 (tillägnad atmega328 baserade arduinos)
Del i projektet "GoFly"
https://sites.Google.com/site/jarosrwebsite/para-nav
Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
det enligt villkoren i GNU General Public License som offentliggjorts av
Free Software Foundation; antingen version 2 av licensen, eller
(på ditt alternativ) någon senare version.
Detta program är distribuerat i hopp om att det kommer att vara användbar,
men utan garantier; utan att ens underförstådd garanti om
SÄLJBARHET eller lämplighet för ett visst ändamål. Se den
GNU General Public License för mer detaljer.
Du bör ha fått en kopia av GNU General Public License
tillsammans med detta program; om inte, skriv till fri programvara
Foundation, Inc., 51 Franklin St, femte våningen, Boston, MA 02110-1301 USA
LK8000 EXTERNA INSTRUMENT SERIE 1 - NMEA MENINGEN: LK8EX1
VERSION A, 110217
ingen stoppning (987.25 blir 98725, inte 098725)
Om inget tryck tillgängligt, skicka 999999 (6 gånger 9)
Om trycket är tillgängliga, ignoreras fält 1 höjd
Fält 1, höjd i meter, i förhållande till QNH 1013.25
Om rå trycket finns, detta värde IGNORERAS (du kan ställa in den till 99999
men inte verkligen behövs)! (om du vill använda det här värdet, inställd på raw tryck 999999)
Detta värde är i förhållande till havsytan (QNE). Vi utgår som för närvarande på 0m
höjd trycket är standard 1013.25.If du inte kan skicka raw höjd och sedan skicka
vad du har men då måste du inte justera det från grundinställningen i LK.
Höjd kan vara negativ. Om höjden inte tillgänglig, och pressar inte tillgängliga, ange höjd
till 99999. LK kommer att säga "Baro höjd tillgänglig" om ett fält 0 och 1 är tillgänglig.
Fält 2, vario i cm/s
Om vario inte tillgänglig, skicka 9999. Värdet kan också vara negativt.
Fält 3, temperatur i C, kan också vara negativt. Om sådana inte finns, skicka 99
Fält 4, batteriets spänning eller avgift procent. Kan inte vara negativt. Om sådana inte finns, skicka 999.
Spänning skickas som flytvärdet som: 0.1 1.4 2.3 11.2. För att skicka procentandel, lägga till 1000.
Exempel 0% = 1000. 14% = 1014. Skicka inte flyta värden för procenttal.
Procentsatsen bör 0 till 100, med inga decimaler, lagts till av 1000!
Poäng:
(1) http://code.google.com/p/bmp085driver/ //bmp085 bibliotek
(2) http://mbed.org/users/tkreyche/notebook/bmp085-pressure-sensor/ //more om bmp085 och den genomsnittliga filter
(3) http://code.google.com/p/rogue-code/ //helpfull tonar bibliotek för att göra fina pipa utan dröjsmål
(4) http://www.daqq.eu/index.php?show=prj_sanity_nullifier //how att göra högt piezo speaker
(5) http://lk8000.it //everything på grund av att
(6) http://taturno.com/2011/10/30/variometro-la-rivincita/ //huge tack för Vario algoritm
(7) http://code.google.com/p/tinkerit/wiki/SecretVoltmeter //how att mäta batterinivå med AVR ucontroller
*/
#include < BMP085.h > //bmp085 bibliotek, nedladdning från url-länk (1)
#include < Tone.h > //tone bibliotek, nedladdning från url-länk (3)
#include < stdlib.h > //we behöver det för att använda dtostrf() och konvertera flyttal till sträng
/////////////////////////////////////////
variabler som du kan testa och prova
kort speaker_pin1 = 8; Arduino speaker output-
kort speaker_pin2 = 9; Arduino högtalare +
flyta vario_climb_rate_start = 0,4; minsta klättra pipa värde (ex. start klättring pipa vid 0,4 m/s)
flyta vario_sink_rate_start = -1,1; maximal diskbänk pipa värde (ex. start diskbänk pip vid - 1,1 m/s)
#define SAMPLES_ARR 6 //define rörliga genomsnittliga filter array storlek (2 -> 30), mer betyder vario är mindre känsliga och långsammare
#define UART_SPEED 9600 //define seriell överföring hastighet (9600,19200, etc...)
/////////////////////////////////////////
/////////////////////////////////////////
BMP085 bmp085 = BMP085(); ställa in bmp085 sensor
Tone tone_out1;
Tone tone_out2;
långa temperatur = 0;
långa tryck = 101325;
float höjd;
int Battery_Vcc = 0; variabel att hålla värdet av Vcc från batteri
CONST float p0 = 101325; Trycket vid havsytan (Pa)
osignerade långa get_time1 = millis();
osignerade långa get_time2 = millis();
osignerade långa get_time3 = millis();
booleska thermalling = false;
int my_temperature = 1;
char altitude_arr [6]. Wee behöver denna matris att översätta float till sträng
char vario_arr [5]. Wee behöver denna matris att översätta float till sträng
int prover = 40;
int maxsamples = 50;
float alt [51].
flyta tim [51].
float pip;
float Beep_period;
statiska lång Karlsson [SAMPLES_ARR];
statiska lång Averaging_Filter (länge ingång);
statiska lång Averaging_Filter (länge ingång) / / flytta genomsnittliga filterfunktion
{
länge summan = 0;
för (int jag = 0; jag < SAMPLES_ARR; i ++) {
k [i] = k [jag + 1];
}
k [SAMPLES_ARR - 1] = ingång;
för (int jag = 0; jag < SAMPLES_ARR; i ++) {
summa += k [i];
}
tillbaka (summan / SAMPLES_ARR);
}
void play_welcome_beep() //play endast en gång Välkommen pip när du slår på arduino vario
{
för (int aa = 300; aa < = 1500; aa = aa + 100)
{
tone_out1.Play(AA,200); spela upp pip på stift 8 (Obs, längd)
tone_out2.Play(AA+3,200); spela upp pip på stift 9 (Obs, längd), det är starkare om vi flyttar aplitude fas
Delay(100);
}
för (int aa = 1500; aa > = 100; aa = aa-100)
{
tone_out1.Play(AA,200); spela upp pip på stift 8 (Obs, längd)
tone_out2.Play(AA+3,200); spela upp pip på stift 8 (Obs, längd)
Delay(100);
}
}
lång readVcc() / / funktion för att läsa batteri värde - fortfarande i utveckla fasen
{
långa resultatet;
Läs 1.1v referens mot AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
Delay(2); Vänta på Vref sedimentera
ADCSRA | = _BV(ADSC); Konvertera
samtidigt (bit_is_set(ADCSRA,ADSC));
resultat = ADCL;
resultatet | = ADCH << 8;
resultat = 1126400L / leda; Back-beräkna AVcc i mV
returnera resultat;
}
void setup() / / setup() funktion för att ställa alla nödvändiga parametrar innan vi går till ändlösa loop() funktion
{
Serial.BEGIN(UART_SPEED); Ställ in arduino seriell port
Wire.BEGIN(); låter init i2c-protokollet
tone_out1.BEGIN(speaker_pin1); piezo speaker output pin8-
tone_out2.BEGIN(speaker_pin2); piezo speaker output pin9 +
bmp085.init (MODE_ULTRA_HIGHRES, p0, false);
BMP085 ultra-res läge, 101325Pa = 1013.25hPa, false = Pa enheter
denna initiering är användbart för att normalisera trycket till specifika datum.
ELLER ställa in aktuell lokal hPa information från en väderstation och lokala flygplats (QNH).
play_welcome_beep(); allt är klart, spela "Välkommen" ljud
}
void loop(void)
{
float tempo=millis();
flyta vario = 0;
flyta N1 = 0;
flyta N2 = 0;
flyta N3 = 0;
flyta D1 = 0;
flyta D2 = 0;
bmp085.calcTruePressure(&Pressure); få ett prov från BMP085 i varje slinga
lång average_pressure = Averaging_Filter(Pressure); Lägg den i filter och ta genomsnittliga
Höjd = (float) 44330 * (1 - pow(((float)Pressure/p0), 0.190295)); ta ny höjd i meter
Serial.println(Battery_Vcc);
för (int cc = 1; cc < = maxsamples; cc ++) {//samples genomsnitt och vario algoritm
Alt[(CC-1)] = alt [cc];
Tim[(CC-1)] = tim [cc];
};
Alt [maxsamples] = höjd;
Tim [maxsamples] = tempo;
flyta stime = tim [maxsamples-proverna].
för (int cc =(maxsamples-samples), cc < maxsamples; cc ++) {
N1 += (tim [cc]-stime) * alt [cc];
N2 += (tim[cc]-stime);
N3 += (alt[cc]);
D1 + = (tim[cc]-stime)*(tim[cc]-stime);
D2 += (tim[cc]-stime);
};
Vario=1000*((samples*N1)-N2*N3)/(samples*D1-D2*D2);
om ((tempo-beep) > Beep_period) / / göra några pip
{
beep = tempo;
om (vario > vario_climb_rate_start & & vario < 15)
{
Beep_period=350-(Vario*5);
tone_out1.Play((1000+(100*Vario)),300-(Vario*5)); När klättring göra snabbare och kortare Piper
tone_out2.Play((1003+(100*Vario)),300-(Vario*5));
thermalling = sant; OK, har vi thermall i våra händer
} else om ((vario < 0) & & (thermalling == true)) //looks som vi hoppa ut thermall
{
Beep_period = 200.
play_siren(); oO, vi förlorade thermall spela larm
thermalling = false;
} else om (vario < vario_sink_rate_start) {//if du har high performace glidflygplan kan du ändra sjunka pip till - 0,95 m/s ;)
Beep_period = 200.
tone_out1.Play(300,340);
tone_out2.Play(303,340);
thermalling = false;
}
}
om (millis() > = (get_time2 + 1000)) //every andra få temperatur och batterinivå
{
bmp085.getTemperature(&temperature); få temperatur i celsius från tid till annan, vi måste dela upp som av 10 att få XY. Z
my_temperature = temperatur/10;
Battery_Vcc = (readVcc () / 42) + 1000; få spänning och förbereda i procent
get_time2 = millis();
}
om (millis() > = (get_time3 + 333)) //every 1/3 andra skicka NMEA utdata via seriell port
{
String str_out = //combine alla värden och skapa del av NMEA data sträng ut
String("LK8EX1"+String(",")+String(average_pressure,dec) + String(",")+String(dtostrf(Altitude,0,0,altitude_arr))+String(",") +
String(dtostrf((Vario*100),0,0,vario_arr))+String(",")+String(my_temperature,dec)+String(",")+String(Battery_Vcc,dec)+String(","));
unsigned int checksum_end, ai, bi; Beräkna checksumma för sträng
för (checksum_end = 0, ai = 0; ai < str_out.length(); ai ++)
{
bi = (unsigned char) str_out [ai];
checksum_end ^ = bi;
}
Skapa nu NMEA följetong ut för LK8000. LK8EX1 protokoll format:
$LK8EX1, tryck, höjd, vario, temperatur, batteri, * kontrollsumma
Serial.Print("$"); skriva ut första tecken på NMEA-protokollet
Serial.Print(str_out); utskriftsdata sträng
Serial.Print("*"); slutet av protokollet sträng
Serial.println(checksum_end,hex); skriva ut beräknade kontrollsumma på slutet av strängen i HEX
get_time3 = millis();
}
}
Slutet