Arduino Vario

I3uLL3t

User
Guten Morgen Leute,
angetrieben von der Idee eines Vereinskollegen, der es auch schon ziemlich gut am Laufen hat, werde ich mich einem kleinen Projekt widmen.
Das Projekt ist für alle etwas die wenig bzw. nur extrem teure Telemetry Möglichkeiten für ihre Fernsteuerungen haben.

Warum denn nur?
Warum mache ich das?! Zum einen weil ich mich sehr für die Arduinos interessiere und Ziele brauche um dem Umgang mit den Dingern zu Lernen. Außerdem sind mir vorhandene Lösungen einfach zu Teuer und wo ist der Spaß wenn man etwas einbaut und es dann Funktioniert. Ich Handel eher nach dem Motto Modellbau statt Modellflug. Zumal meine Modelle nach dem ersten Flug meistens wieder in den Bau gehen ;):D
Meine Kenntnisse im Bereich Arduino? Schwer zu sagen, Ich kann den Code verstehen und verändern...kleinere Codes kann ich auch selber Schreiben..Bei Größeren Brauche ich länger und die Syntax ist oft umständlicher als ein Profi es machen würde. Aber genau deswegen mache ich sowas. Um zu Lernen!
Ich werde nach Möglichkeit alles Dokumentieren und Freue mich drauf wenn der ein oder andere mir zur Seite steht mit Tipps und Ratschläge!! Konstruktive Kritik ist immer erwünscht.

Ziel des Ersten Schrittes:
Das Ziel ist es im ersten schritt ein Funktionstüchtiges Vario mit Hilfe vom Arduino Nano, eines MS5611 Barometers, zwei NRF24L01 PA LNA für die Datenübertragung und eines kleinen Oled Displays zur Anzeige der Messwerte.
Die Empfangseinheit soll so klein wie möglich gehalten werden damit sie an der Funke befestigt werden kann. Dort kann über eine Klinkenbuchse ein Handelsübliches Smartphone Headset angeschlossen werden. Der Vorteil ist das die Tasten des Headsets dafür genutzt werden sollen die Anzeigen durchzuschalten und die Höhen Werte zu nullen. Die üblichen Vario Töne werden dann über das Headset ausgegeben.

Kosten:
Die Kosten richten sich nach der Bezugsquelle und sind ziemlich unterschiedlich. Ich habe das gesamte Material für ca. 20 Euro in der Bucht ergattern können.
Möglich wäre es auch für Knapp 10-15Euro dann allerdings mit langen Lieferzeiten.
Kleinmaterial wie Widerstände oder Kondensatoren sind nicht mit eingerechnet.

Aktueller Stand:
-Warten auf das Material


Ziele der nächsten Schritte?
Das ganze soll später erweitert werden und immer weiter an Funktionen Wachsen. In wie weit es mit dem Nano funktionieren wird, wird sich dann herausstellen.
-GPS Modul zum Abgleich der höhe und zur Geschwindigkeitsanzeige.
-Logging per SD Karte und Auswertung der Daten über irgendeine Software
-Was mir sonst noch einfällt.


So ich bin gespannt auf die ersten Tests!
Wenn sich mir jemand anschließen möchte der auch Bock auf das Projekt hat soll er sich einfach bei mir Melden.

Und nu ein Schönes Wochenende.
 
Super nice! Ich mach gerade das selbe xD
Ne Frage zu deiner Datenübertragung: sind die Dinger in DE legal? Egal obs jemand merken würde oder nicht: würde mich nur interessieren. Bei mir scheitert es hauptsächlich gerade an der Übertragung. Was haben die Module für ne Reichweite? Schon getestet? Haste evtl nen kauflink von denen? Wobei, Bild würde mir schon reichen ;)
 

Bernd Langner

Moderator
Teammitglied
Hallo

Ein Vario das auf 2,4GHZ sendet in einem Modell was mit 2,4GHZ gesteuert wird
kann nicht optimal sein. Denn es besteht die Gefahr das dieses 2,4GHZ Signal den
Empfänger zustopft. Ich würde dann eher auf 433MHZ ausweichen das gibt keine
Probleme.

Gruß Bernd
 

I3uLL3t

User
Guten Morgen,
zunächst mal
@Bernd da gebe ich dir Grundsätzlich recht!! Aber da du die Frequenz der RF24 Module selber festlegen kannst und diese kein "Frequenz Hopping" machen. Kannst du diese im "Grenzbereich" Festlegen und dann sollte es eigentlich keine Probleme geben. Ich bin kein Profi was dieses Thema angeht aber ein Kollege testet es seid geraumer zeit mit diesen Modulen und hat keinerlei Verbindungseinschränkungen geloggt. Im Heimischen Wlan ist es z.B. eher so das die Module eher Sende/Empfangs Probleme haben, als das das Wlan Verbindungsprobleme hat. Ich will mich darauf nicht Festlegen und nicht behaupten das es alles richtig ist. Ich lasse mich gerne eines besseren belehren.
Ich wollte Ursprünglich auch 433MHz Module verwenden, die Sind bei mir allerdings wegen der "Langen" Antennen und Ihrer Baugröße raus gefallen. Das passt dann leider nicht mehr in meine Segler rein.
Vl. gibt es ja 433Mhz Tranciever in kleiner Bauweise von denen ich nichts weiß.

@Simon
Zur Legalität möchte ich nicht wirklich was sagen guck dir die Datenblätter der dinger an und bilde dir selbst dein Urteil. :)
Eine Reichweite sollen die dinger von ca 1000m haben, dieses konnte mein Kollege auch ungefähr bestätigen. 500m konnte ich bis jetzt selber Testen die Schaffen sie sehr gut auf mittlerer Leistung.
Die Volle Leistung kann ich mit der Spannungversorgung des normalen Arduino Nanos nicht austesten. Mit den Angeschlossenen Teilen bricht er dort zusammen.
Bilder habe ich grade keine aber wenn du "NRF24L01 PA LNA" bei Google eingibst bekommst du einiges.


Hier sind ein Paar Bilder meines Aktuellen Standes
Ein Bericht dazu folgt.

Auf dem Bild sind die Messwerte in Meter zu sehen. Die Libary rechnet sehr gut den Druck in Meter um unter Berücksichtigung der Temperatur.
Bei diesen Messwerten war lediglich das baro abgedeckt und noch nicht eingeschrumpft. Die Messwerte sind hier aber stark gefiltert was die Messung sehr träge macht.
IMG_20170415_175148_resized_20170419_073053757.jpg

Alles Relativ zusammen gestopft damit es so klein wird wie möglich. Zwischen den einzelnen Elementen befindet sich jeweils eine Schicht "dickes" Isolierband um keine Kurzschlüsse zu verursachen.
IMG_20170415_133113_resized_20170419_073054511.jpg
IMG_20170415_131209_resized_20170419_073055053.jpg

Das Bild ist von den ersten sende und empfangs Tests. Die Höhenwerte des Baros schwanken ungefilterten um ca. 50cm also für eine 100% Höhenangabe schwer zu gebrauchen.
Durch Filtern und Mittelwerte versuche ich es so genau wie möglich zu bekommen aber das führt halt immer zu verlängerten Abtastzeiten, was mir aktuell hinterher bei der akustischen steigen/sinken Signalisierung Probleme bereitet.
IMG_20170414_203953_resized_20170419_073055737.jpg
 
Schaut ja gut aus!
Antenne ist Marke Eigenbau oder was gekauftes?
Falls du Inspiration brauchst was den code angeht:
meins löst im stillstand inzwischen sehr gut auf. +-0.2 m/s bei <1s Aktualisierungsrate (und diese Differenzen sind wahrscheinlich meiner Atmung geschuldet;)
Erster Testflug ist am Freitag
 

SPOM

User
Hallo zusammen, bitte weiter berichten. Ich verfolge dieses und ähnl. Themen mit großem Interesse.
Zwar beabsichtige ich nicht "extern" zu übertragen sonder die Jeti Telemetrie zu nutzen, aber mir gehts um das Vario.

Spannung, Strom, Einzelzellenspannung funktioniert ja schon, aber ein Vario wäre ev. noch interessant.
In den jetzigen Fliegern (Hubi, Wasserflieger) eher nicht, aber man weis ja nie.

Würdet ihr eure Sketche ev. zu Verfügung stellen?

MfG
Reinhard
 

I3uLL3t

User
Hallo,

@SPOM Ich werde dich Weiterhin auf dem Laufenden halten. Die Sketch gibt es zu gegebener Zeit wenn ich damit vorerst zufrieden bin und dieser bereinigt ist.

@Simon Die Antenne ist einfach die Standard schwarze Stabantenne, bei der ich einfach nur das Kunststoffgehäuse entfernt habe um sie kleiner zu bekommen.


Aktueller Stand
Der Aktuelle Stand ist das mein VarioModul welches sich im Flugzeg befindet Hardwaretechnisch fertig ist.
Angeschlossen wird dieses an den Balanceranschluss eines Akkus.
Es mist zuverlässig Werte und sendet die auch zuverlässig an die Empfangseinheit welche zur zeit noch auf einem Bredboard gesteckt ist. Die Messwertaufnahme und Filterung läuft komplett auf diesem Modul. Die Werte Temp, Höhe, Druck, relativeHöhe, werden in einem Struckt gespeichert und über die RF24 Module übertragen.
Die Empfangseinheit bekommt diese Daten und vergleicht den Druck der vorherigen Übertragung mit der aktuellen und gibt dann je nach steigen oder sinken ein PWM Signal über die "tone()" Funktion an einen Arduino Pin der Empfangseinheit aus. Dieser Ton verändert sich je nach Größe der Druck differenz. An diesen Pin habe ich über einen Vorwiderstand eine 4polige Klinkenbuchse (3,5mm) angeschlossen und kann somit über Standard Kopfhörer den Ton ausgeben lassen. Das Funktioniert sogar erstaunlich gut. Wichtig ist dabei der Vorwiederstand, da mir sonst bei längeren Tonfolgen, der Arduino eingefroren ist. Ich vermute das der Strom dann zu hoch ist. :confused:

Nächste Erweiterungen
-Der Knopf an den Standard Kopfhörern wird über die Klinkenbuchse an den Arduino angeschlossen um die Relative Höhe zu nullen und die Anzeigemenus des Display durch zu schalten.
-Display Anbindung und Layouting
-Glätten der Messwerte für genauere Höhenangabe


Es geht voran und ich bin für jeden Vorschlag, jede Kritik oder Lob dankbar und offen :)
 

I3uLL3t

User
Hallo Ruvy,
danke für deine Info!!!! Um es genauer zu verstehen habe ich natürlich noch Fragen.
Aus welchem Grund würdest du das so machen?
Bei einem Lautsprecher kann ich das nachvollziehen weil man den ja eventuell auch "Lauter" haben möchte bzgl. der Umgebungsgeräusche aber das Headset hat so ja eine recht gute Lautstärke und gibt die Töne sauber wieder.
Was Lautsprecher angeht habe ich kaum Ahnung und bin deswegen Froh das es bei mir überhaupt funktioniert :D .

LG Marcel
 
Keine Ahnung welche Leistungsaufnahme so ein kleiner Ohrhöhrer hat.
ABER unbedingt die Aus & Eingänge schützen. Beim Ein & Ausstecken dieser Klinkenstecker entstehen Kurzschlüsse zwischen den Leitungen.
 

ruvy

User
Hallo Marcel,

eine Antwort hast Du dir schon selbst gegeben: "Ich vermute das der Strom dann zu hoch ist."

Die Ausgänge vom Arduino können viel, aber keine hohen Strom.
Daher würde ich den Transistor dazwischenschalten, an die gleiche Betriebsspannung wo auch das Arduino dranhängt.

Kostet nur ein paar Cent, gibt es auch in Mini-SMD und Du bist auf der sicheren Seite.
Abgesehen davon das Du deinen Kopfhörer hast, weißt Du nicht was jemand anderer anschliessen möchte/wird ;)

lg
Rudi
 
Zuletzt bearbeitet:

I3uLL3t

User
Danke Matze das ist ein guter Tipp!!!

@ruvy
danke dann waren meine Gedanken doch richtig. Was andere anschließen ist mir ja egal xD :P
Aber ich werde es warscheinlich so umsetzen zumal ich nicht genau weiß wie sich das ganze mit Kopfhörern anderer Hersteller verhält.


Super das sich so viele an meinem kleinen Projekt beteiligen!!!
 
Kopfhörer und Widersände

Kopfhörer und Widersände

Also ich musste bei meinen Ohrmuscheln (bei der KLM "geklaute") insg. 30KILO-Ohm in reihe schalten, damits mir nicht die Ohren raus bläst.
Ich höre schon nen Ton, wenn ich den einen Pin vom Kopfhörer am Digitalpin hab und den anderen pin nur berühre (ich fungiere als gnd...)
Keine Ahnung warum das geht, aber scheint so zu sein, dass solche Ohrmuscheln mit extrem niedrigen Innenwiderstand daher kommen. nen 150Ohm widerstand zur Strombegrenzung am Kofhörerausgang des Arduino ist aber unbedingt pflicht, egal wie oder was. (Das macht auch die Kurzschlüsse beim aus und einstecken nichtig)
 

I3uLL3t

User
SOO es geht natürlich weiter!

Aktuell läuft das Baro relativ gut, die Messwerte sind im Rahmen und die Schwingungen durch die Sensor genauigkeit von 0,5m sind soweit gefiltert und im Rahmen.
Mein erster Ansatz war, dass ich die Höhe auslese und die Tonerzeugung aufgrund einer relativen Höhe zum Refferenzpunkt mache. Dieser Versuch hat sich als zu ungenau und nicht zuverlässig ergeben.
Durch Simon_123 seine Hilfe und die Einsicht in seinen Code, habe ich mich jetzt für seine Variante entschieden, die Werte in m/s bzw. dm/s umzurechen und dadurch den Ton zu erzeugen.
Da ich einfach die tone Funktion benutze lasse ich einen Wert x zb. 900mhz mal die dm/s errechnen und den dann als Frequenz über die tone Funktion ausgeben. in m/s waren mir die Schritte zu groß und man hat geringeres steigen nicht angezeigt bekommen. Deswegen habe ich dann die dm/s benutzt.

Mein Sender im Flugzeug schließe ich einfach an den Balancer Anschluss des Akkus an und lasse mir dann auf der Empfangseinheit die Spannung der ersten Zelle anzeigen. Dort habe ich drei Warnstufen hinterlegt die alle 3sec. abgefragt werden.

Ich werde die Tage auch den Code dazu einstellen damit man es besser versteh und ihr mir eventuell Tipps geben könnt.


Aktuell gibt es ein Problem.
:confused:
Mein Headset (ursprünglich von einem Smartphone) hat einen Knopf drauf. Der vierte Ring des Klinkensteckers ist mit diesem Knopf verbunden. Ground Ring ----- Knopf ---- vierter Ring. Diesen Vierten Ring habe ich mit einem Digital Eingang verbunden und den Internen Pullup_Widerstand im Arduino aktiviert. Theoretisch würde das so auch Funktionieren aaaaaaaber der Knopf am Headset trennt nicht komplett. Im unbetätigten Zustand habe ich einen Widerstand von 400ohm. Im Betätigten 0ohm. Dadurch bekomme ich keinen klaren Zustand am Eingangspin.
Hat jemand eine Idee wie ich trotzdem einen klaren Zustand bekomme?

Ich hoffe ihr versteht mein Gesabbel xD
 

I3uLL3t

User
DER CODE IST DAAA

DER CODE IST DAAA

Hallo Leute,
es hat ein wenig länger gedauert und ich hatte/habe arge Epfangsprobleme, die ich solangsam aber in den Griff bekomme.
Nun will euch aber mal den Code zeigen der aktuell steht und relativ gut funktioniert...Im Grunde gibt es mit dem Auslesen der Daten keine Probleme mehr lediglich die Töne will ich noch Optimieren, da das stumpf Piepen in verschiedenen Frequenzen ok ist aber mit der zeit einfach nur nervt xD

Einmal der Code der Sende Einheit im Flieger.
Code:
//--------------------------------------------------------
// EINFACHES ARDUINO VARIO V1.0
// von I3ull3t (RC-NETWROK.DE)
// CODE AUSSCHNITTE UND TIPPS VON SIMON_123 RC-NETWORK.DE
//--------------------------------------------------------
// Funktionen: STEIGEN UND SINKEN SIGNALISIEREN ÜBER HANDELSÜBLICHE KOPFHÖRER
//              MESSWERTE DES GY-63 BOARDS ANZEIGEN
//              HÖHE,TEMPERATUR,DRUCK,VERTIKALE GESCHWINDIGKEIT,SPANNUNG ZELLE1
//              AKKUWARNUNG DURCH MESSEN DER ERSTEN ZELLE AM BALANCER ANSCHLUSS
//
//
//
#include <Wire.h>
#include <MS5611.h>
#include <SPI.h>
#include "RF24.h"
bool radioNumber = 1;         // Damit die Module miteinander kommunizieren muss eines als 1 und das andere als 0 deklariert werden.
RF24 radio(6,7);              // Pins an denen das Modul angeschlossen wird. 
byte addresses[][6] = {"1Node","2Node"};
MS5611 ms5611;

boolean referenceOK = false; //wurde ein refferenz Höhenwert ausgelesen.
double pressure;
float relativeAlt;
float voltage;

const int updateATemp=100;
const int updateAlt=100;
const int updateVario=100;
const int updateVoltage=100;

float filtered = 0; //Variable um den Höhenwert zu glätten.
long lastATempMeasurement;//zeit (millis) bei der letzten temperatur-messung: if((millis()-lastATempMeasurement)>updateATemp){lastATempMeasurement=millis(); wert der temperatur wird upgedatet;}
float ambientTemprature; // wert 173 entspricht 17,3 °C //Speicher für die derzeitige temperatur
long lastAltMeasurement; //zeit (millis) bei der letzten Altitude-messung: if((millis()-lastATempMeasurement)>updateAlt){lastATempMeasurement=millis(); wert der Höhe wird upgedatet;}
float refHeight; //Variable für die Ref Höhe 
int alt; //in Metern (Speicher für die relative Höhe zum einschaltpubnkt)
long lastVarioMeasurement;
//variablen für die delta-meter und delta-sekunden der variomessung
long varioTime;
float varioPreviousAlt;
float varioRefaltTrash;
float varioLastValue; //wert für den lastValue-filter: vorheriger vario wert
int vario; //Speicher für den Variowert: 8 entspricht 0,8 Meter/sekunde steigen
float takeoffAlt;


//-------------Zu Übertragende Struktur---------
struct dat{
  float temp;
  double pres;
  float height;
  float refheight;
  int vspeed;
  float Voltage;
  unsigned long _micros;
  boolean resKey = false;
  boolean menKey = false;
}daten;
//----------------------------------------------

void setup() 
{
  Serial.begin(9600);
  radioSettings();
  baroSettings();
  checkSettings();
  
  varioLastValue=0.0F;
  lastATempMeasurement=-updateATemp;
  lastAltMeasurement=-updateAlt;
  lastVarioMeasurement=-updateVario;
  varioTime = micros();

  firstRefAlt();
}



void loop()
{
  int voltageValue = analogRead(A1);
  voltage = voltageValue * (3.94 / 1023.0);
  readDatafromBaro();
  daten.temp = ambientTemprature;
  daten.pres = pressure;
  daten.height = relativeAlt;
  daten.refheight = takeoffAlt;
  daten.vspeed = vario;
  daten.Voltage = voltage;

  //ANZEIGEN DER MESSWERTE IM SERIAL MONITOR  DEBUGGING
  if(takeoffAlt > 0){
  Serial.println("--");
  Serial.print("Temperatur = ");
  Serial.print(ambientTemprature);
  Serial.println(" *C");
  Serial.print("Luftdruck = ");
  Serial.print(pressure);
  Serial.println(" Pa");
  Serial.print("Absolute Höhe = ");
  Serial.print(varioPreviousAlt);
  Serial.print("   refferenz Höhe = ");
  Serial.print(takeoffAlt);
  Serial.print(" m, relative Höhe = ");
  Serial.print(relativeAlt);    
  Serial.print(" m     ");
  Serial.print(vario);    
  Serial.println(" dm/s");
 }
////------------------------------------------------------------------------------------------------------------
////SENDEN
////------------------------------------------------------------------------------------------------------------
  if(takeoffAlt > 0){
    radio.stopListening();                                    // Zuerst Tranciever dazu bringen das er Sendet und nicht mehr auf Daten wartet. 
    Serial.println(F("SENDEN....."));
    daten._micros = micros();
     if (!radio.write(&daten, sizeof(daten) )){
     }
//    radio.startListening();                                    // Wieder in den Empfangsmodus wechseln um eine Antwort zu empfangen
    unsigned long sendDelay = micros();                        // Zeit messen bis die Antwort kommt, nur um die Sendegeschwindigkeit zu debuggen
    boolean timeout = false;                                   // Eine Variable um anzeigen zu lassen ob empfangen wurde oder nicht.
//    while ( !radio.available() ){                             // Wenn nix empfangen wird
//      if (micros() - sendDelay > 2000000 ){                     // Wenn zu lange gewartet wird empfangsvorgang abbrechen und weiter gehen im Loop
//          timeout = true;
//          break;
//      }      
//    } 
    //------------------------DEBUGGEN DER ÜBERTRAGUNG----------------------
//    if ( timeout ){                                             // Senden/Empfangsergebniss verarbeiten
//        Serial.println(F("Fehlgeschlagen, Übertragung Timed out!"));
//    }else{
//        radio.read( &daten, sizeof(daten) );
//        // Empfangene Antwort anzeigen lassen.
//        Serial.print(F("Sent "));
//        Serial.print(F(", Got response "));
//    }
  }

    
}//LOOP END

//REFFERENZ HÖHE BESTIMMEN BEIM INITIALISIEREN DER SETUP FUNKTION
//____________________________________________________________________________________________________________________________________________________
void firstRefAlt(){
  varioRefaltTrash=ms5611.getAltitude(ms5611.readPressure());       //MÜLL, DAMIT VOR DER REFFERENZ HÖHE EIN PAAR MESSUNGEN GEMACHT WURDEN
  varioRefaltTrash=ms5611.getAltitude(ms5611.readPressure());       //MÜLL, DAMIT VOR DER REFFERENZ HÖHE EIN PAAR MESSUNGEN GEMACHT WURDEN
  varioRefaltTrash=ms5611.getAltitude(ms5611.readPressure());       //MÜLL, DAMIT VOR DER REFFERENZ HÖHE EIN PAAR MESSUNGEN GEMACHT WURDEN
  varioRefaltTrash=ms5611.getAltitude(ms5611.readPressure());       //MÜLL, DAMIT VOR DER REFFERENZ HÖHE EIN PAAR MESSUNGEN GEMACHT WURDEN
  takeoffAlt=(                                                      //DIE EIGENTLICHE REFFERENZHÖHE BEIM EINSCHALTEN
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure()) +
    ms5611.getAltitude(ms5611.readPressure())
    )/10.0F;
    Serial.println(takeoffAlt);
}
//____________________________________________________________________________________________________________________________________________________
//DATEN AUS DEM BARO AUSLESEN UND FILTERN
//____________________________________________________________________________________________________________________________________________________
void readDatafromBaro(){
//damit ich nicht jedes mal millis() aufrufen muss
long mill=millis();
  if((mill-lastATempMeasurement)>updateATemp){
    ambientTemprature=ms5611.readTemperature();
    lastATempMeasurement=mill;
  }
  
  boolean updateAltduringVario=false;
  if((mill-lastAltMeasurement)>updateAlt){
    updateAltduringVario=true;
  }
  if((mill-lastVarioMeasurement)>updateVario){
    float absoluteAltitude = ms5611.getAltitude(ms5611.readPressure());
    absoluteAltitude += ms5611.getAltitude(ms5611.readPressure());
    absoluteAltitude += ms5611.getAltitude(ms5611.readPressure());
    absoluteAltitude += ms5611.getAltitude(ms5611.readPressure());
    absoluteAltitude += ms5611.getAltitude(ms5611.readPressure());
    absoluteAltitude = absoluteAltitude/5.0F;
    pressure = ms5611.readPressure();

    if(filtered != 0){ 
      filtered = filtered + 0.7*(absoluteAltitude-filtered);    //FILTERUNG UM FAKTOR 0.7 HIERMIT KANN GESPIELT WERDEN. JE WEITER ZUR 1 DESTO WENIGER SMOOTH LÄUFT DER FILTER
    } else { 
      filtered = absoluteAltitude;          // GEFILTERTE WERTE, UM EINEN SAUBEREN ÜBERGANG ZU BEKOMMEN UND NICHT SO STARKE SPRÜNGE 
    }
    absoluteAltitude = filtered;
    //berechnung in m/s und weitersenden in neue funktion, die die weitere filterung übernimmt
    passVario(1000*(absoluteAltitude-varioPreviousAlt)/(mill-varioTime));

   // für die nächste vario-messung alles abspeichern
    varioPreviousAlt=absoluteAltitude;
    relativeAlt= varioPreviousAlt - takeoffAlt;
    varioTime=mill;
    lastVarioMeasurement=mill;
    //falls ein höhenupdate ansteht wird das gleich mit gemacht
    if(updateAltduringVario){
      alt=varioPreviousAlt-takeoffAlt+0.5F;
      lastAltMeasurement=mill;
    }
  }
}
//____________________________________________________________________________________________________________________________________________________

//STEIGEN UND SINKEN UMRECHNEN IN VERTIKALE GESCHWINDIGKEIT dm/s
//____________________________________________________________________________________________________________________________________________________
//KOMPLETT VON SIMON GEKLAUT!!! DANKE DAFÜR!!
void passVario(float value){
  int vspeed;
  
  if(value>=0){             //UMRECHNEN IN DM/s
    vspeed=0.5F+value*10;
  }else{    
    vspeed=value*10-0.5F;
  }  

  if(((vspeed<0&&varioLastValue<0&&vspeed<varioLastValue*0.3F)||(vspeed>0&&varioLastValue>0&&vspeed>varioLastValue*0.3F))||(vspeed>3||vspeed<-3)){
    vario=vspeed;
  }else{
    vario=(vspeed+varioLastValue)/2.0F;
  }
  //achtung: last value wird gleich vspeed, nicht gleich vario gesetzt-> es kann kein messwert von vor mehr als 2 zyklen auf den neuen wert einfluss nehmen, nichtmal spurenweise.
  varioLastValue=vspeed;
}
//____________________________________________________________________________________________________________________________________________________
//SETTINGS FUNKTIONEN
//____________________________________________________________________________________________________________________________________________________
void baroSettings(){
    Serial.println("Sensor initialisieren");
  while(!ms5611.begin(MS5611_ULTRA_HIGH_RES))
  {
    Serial.println("Kein Sensor gefunden");
    delay(500);
  }
}
//____________________________________________________________________________________________________________________________________________________
void checkSettings(){
  Serial.print("Oversampling: ");
  Serial.println(ms5611.getOversampling());
}
//____________________________________________________________________________________________________________________________________________________
void radioSettings(){
  radio.begin();
  radio.setPALevel(RF24_PA_MAX );
  radio.setDataRate(RF24_250KBPS);
  radio.enableAckPayload();
  radio.setChannel(115);
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  } 
  radio.startListening();s
}
//____________________________________________________________________________________________________________________________________________________


Und nun der vom Empfänger auf dem Boden.
Code:
//--------------------------------------------------------
// EINFACHES ARDUINO VARIO V1.0
// von I3ull3t (RC-NETWROK.DE)
// CODE AUSSCHNITTE UND TIPPS VON SIMON_123 RC-NETWORK.DE
//--------------------------------------------------------
// Funktionen: STEIGEN UND SINKEN SIGNALISIEREN ÜBER HANDELSÜBLICHE KOPFHÖRER
//              MESSWERTE DES GY-63 BOARDS ANZEIGEN
//              HÖHE,TEMPERATUR,DRUCK,VERTIKALE GESCHWINDIGKEIT,SPANNUNG ZELLE1
//              AKKUWARNUNG DURCH MESSEN DER ERSTEN ZELLE AM BALANCER ANSCHLUSS
//
//
//
#include <SPI.h>
#include <Wire.h>
#include "RF24.h"
#include "U8glib.h"
#include "pitches.h"


U8GLIB_SH1106_128X64 u8g(10, 8 , 9);      //ANSCHLÜSSE UND TYP DES DISPLAYS ZUR KOMMUNIKATION MIT DER LIBARY

int menu = 0;     //noch ohne Funktion
int menbtn = 0;   //noch ohne Funktion
//Die Noten für die Startmelodie (basiert auf tone-example von arduino.cc) geklaut von SIMON XD
int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

float steigen;  //Variable für die Frequenz  des Steigen Tons 
float sinken;   //Variable für die Frequenz  des Steigen Tons 
int vspeedlast; //Speicher für die letzte Vertikale Geschwindigkeit
float maxHeight = 0.00; //Speicher für die Maximale Höhe der Session
float vWarn1 = 3.70;  //Spannungswarnung level 1
float vWarn2 = 3.50;  //Spannungswarnung level 2
float vWarn3 = 3.40;  //Spannungswarnung level 3
long vMessTime;       // Eine Variable in der millis() gespecihert wird
long lastvMessTime;   // Zeit der letzten Spannungsmessung
long lastspMessTime;  // Zeit der letzten Vertikalen Geschwindigkeits Messung
long spMessTime;      // Eine Variable in der millis() gespeichert wird
bool radioNumber = 0; // Festlegung der NRF24 Module, eines muss 1 sein das andere 0


RF24 radio(6,7);      // Pin Festlegung des NRF24 11/12/13 sind fest in der Libary vorgegeben
byte addresses[][6] = {"1Node","2Node"}; 
boolean firstrun = true; //TEST!! NOCH KEINE FUNKTION

//-------------Zu Übertragende Struktur---------
struct dat{
  float temp;
  double pres;
  float height;
  float refheight;
  int vspeed;
  float Voltage;
  unsigned long _micros;
  boolean resKey = false;
  boolean menKey = false;
}daten;
//----------------------------------------------

void setup() {
  pinMode(5, OUTPUT);         //Output pin fuer das Headset
  pinMode(4, INPUT_PULLUP);   //Input Pin fuer den Taster am Headset
  radioSettings();
  Startmelody();
  vMessTime = millis();
}
//DRAW FUNKTION FÜR DIE U8GLIB
//____________________________________________________________________________________________________________________________
//DIE ÜBERTRAGENEN DATEN AUF DEM DISPLAY ANZEIGEN
void draw(void) {
  u8g.setFont(u8g_font_10x20);
  u8g.setPrintPos(0, 17);
  u8g.print("Hoehe:");u8g.print(daten.height);
  u8g.setFont(u8g_font_6x12);
  u8g.setPrintPos(0, 30); 
  u8g.print("Temp:"); u8g.print(daten.temp);
  u8g.setPrintPos(0, 40); 
  u8g.print("vSpeed:"); u8g.print(daten.vspeed);
  u8g.setPrintPos(0, 50);  
  u8g.print("Druck:");u8g.print(daten.pres);
  u8g.setPrintPos(0, 60);  
  u8g.print("Spannung:");u8g.print(daten.Voltage);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//LOOP
void loop() {
   sendReturn();
   VoltageWarning();
   MaxHeight();   //Die Maximale Flughöhe speichern   NOCH KEINE FUNKTION
   
   u8g.firstPage();  
  do {
      draw();
  } while( u8g.nextPage() );
  
  if (vspeedlast != daten.vspeed){
    if(daten.vspeed > 0 || daten.vspeed < 0){ //wenn das Steigen größer oder kleiner 0dm/s ist dann...
      if (daten.vspeed < 2 || daten.vspeed > (-2)){ //....kontrolliere ob wir uns zwischen 2 und -2 bewegen...
        noTone(5);                                  //...wenn ja dann keinen Ton wiedergeben
      }
      if(daten.vspeed > 2){                   //....kontorllier ob steigen.....
        steigen = 900 + daten.vspeed*5;
        tone(5,steigen, 200);               //Ton für 200ms wiedergeben
      }
      if(daten.vspeed < (-2)){              //..oder sinken
        sinken = 600 + daten.vspeed*3;
        tone(5,sinken);                     //dauerton wiedergeben
      }
    }
  }else{
    // HAUPTSÄCHLICH FÜR MEINE TESTS GEDACHT, DA ICH NOCH EIN PAAR VERBINDUNGSPROBLEME HABE UND SONST NICHT UNTERSCHEIDEN KANN OB DIE VERBINDUNG ABGEBROCHEN IST ODER NICHT
   spMessTime = millis();
    if(spMessTime-lastspMessTime > 2000){         // sollte der vspeed werd 2000ms konstant bleiben (z.B. wegen verbindungsausfall) dann......
      if(daten.vspeed != 0 ){ //....kontrolliere das vspeed nicht 0 ist....
        if(daten.vspeed > 2){                   //....kontorllier ob steigen.....
          steigen = 900 + daten.vspeed*5;
          tone(5,steigen, 100);                 //...und gib den ton 100ms wieder
        }
        if(daten.vspeed < (-2)){              //..oder sinken
          sinken = 600 + daten.vspeed*3;
          tone(5,sinken,100);
        }
    
      }
     lastspMessTime = spMessTime;
    }
  }
  vspeedlast = daten.vspeed;
}
//END LOOP
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNKTION ZUM SENDEN UND EMPFANGEN DER DATEN
//____________________________________________________________________________________________________________________________
void sendReturn(){
  if( radio.available()){                                                     
      while (radio.available()) {   
        radio.read( &daten, sizeof(daten) );               // DATEN ABFRAGEN
      }
//      radio.stopListening();                               //  NICHT MEHR AUF DATEN WARTEN (DEBUG)
//      radio.write( &daten, sizeof(daten) );                 // DATEN ZURÜCK SENDEN. (DEBUG)     
//       radio.startListening();                             //  WIEDER ZUHÖREN      
  } 
}
//FUNKTION UM DIE REFFERENZ HOEHE NEU ZU SETZEN
//____________________________________________________________________________________________________________________________
//NOCH OHNE FUNKTION
void refKey(){
  
}


//SETTINGS FUNKTIONEN
//____________________________________________________________________________________________________________________________
//EINSTELLUNGEN FÜR DAS NRF24
void radioSettings(){
radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.enableAckPayload();
  radio.setChannel(115);
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.startListening();
}
//STARTMELODI ZUM FUNKTIONSTEST
//____________________________________________________________________________________________________________________________
//GEKLAUT VON SIMON
void Startmelody(){
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(5, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(5);
  }
}
//VOLTAGE CHECK AND WARNING
//____________________________________________________________________________________________________________________________
void VoltageWarning(){
  vMessTime = millis();
  if(vMessTime-lastvMessTime > 10000 || lastvMessTime == 0){          //Alle 10sec die Spannung überprüfen und ggf. Warnung raus geben
    if(daten.Voltage < vWarn3){
      tone(5,900,100);
      delay(100);
      tone(5,1800,100);
      delay(100);
      tone(5,900,100);
      delay(100);
      tone(5,1800,100);
      delay(100);
      tone(5,900,100);
    }else if(daten.Voltage < vWarn2){
      tone(5,900,100);
      delay(100);
      tone(5,1800,100);
      delay(100);
      tone(5,900,100);
    }else if(daten.Voltage < vWarn1){
      tone(5,900,100);
      delay(100);
      tone(5,1800,100);
    }
  lastvMessTime = vMessTime;
  }
}

//MAXIMALE HÖHE
//____________________________________________________________________________________________________________________________
void MaxHeight(){
  if(maxHeight == 0.00){
    maxHeight = daten.height;
  }else if (daten.height > maxHeight){
    maxHeight = daten.height;
  }
}

Die Codes sind nicht Final und mit Sicherheit kann man einiges besser schneller und einfacher schreiben aber meine Programmierkentnisse im bereich Arduino stecken noch in den Kinderschuhen.
Ich bin für jeden Tipp dankbar!!!

LG Marcel.
 

I3uLL3t

User
Sieht auch interessant aus. Mich würde die Reichweite interessieren?
Mir fehlen da allerdings die Angaben zur momentanen Höhe und dergleichen. Kann sein das ich was übersehen habe, bin der Sprache aber auch nicht wirklich mächtig :D
Die Tage wird es bei mir auch hoffentlich weiter gehen.
 

Oxymoron

User
... sieht nicht nur interessant aus, sondern ist es auch! Wenn das Vario an einen Empfängerausgang angeschlossen wird, kann mittels eines (Moment-)Schalters am Sender die Funktion zwischen Vario und Höhe über Grund umgeschaltet werden! Die entsprechende Flughöhe wird dann durch Tonsequenzen mit unterschiedlicher Frequenz übertragen. ;)
Die Reichweite mit der Spule als Antenne beträgt mindestens 300 Meter, eine höhere Reichweite kann mit einer geraden Antenne erzielt werden.
 

I3uLL3t

User
Der Aktuelle Stand

Der Aktuelle Stand

Es ging wieder langsam weiter, leider auch nur sehr langsam aus diversen Gründen.

Aktuell läuft das Vario recht zuverlässig und Stabil. Die Höhe wurde mit einem GPS verglichen und Passt.
Das GPS Modul ist auch eingebunden, funktioniert....aber noch nicht so wie ich das gerne Hätte. Es kommen mir noch zu wenig Daten die Sekunde an.
Es gibt Aktuell 4 Menus die durch die Taste am Headset umgeschaltet werden können. Durch 3 sekündiges betätigen des Tasters am Headset wird die Höhe auf 0 gesetzt sowohl GPS als auch Baro und die Maximal Höhe der Session wird in Menu 2 gespeichert. Dort werden die Letzten drei Maximal Höhen gespeichert.
Menu 3 gibt mir meine Daten aus dem GPS Modul wieder. In Menu 4 kann ich mir die Akkuwarnstufen anzeigen lassen. Die Funktioniert aber grade nicht da auf meinem Prototypen Arduino Promini keine Ref Spannung Messbar ist. Warscheinlich irgendwo ein defekt auf dem Board.

Die Reichweite der Übertragung konnte ich nun bis ca 450m testen, danach war das Modell ein wenig klein :)

Alles in allem geht es voran. Der Code hat sich auch nochmal Stark verändert Speziell in der akustischen Darstellung von Steigen und Sinken.

Startbildschirm
IMG_20170918_211951.jpg


Menu1 Darstellung der Messwerte des Baros
IMG_20170918_211836.jpg

Menu 2 Darstellung der letzten drei maximal Höhen
IMG_20170918_211847.jpg

Menu 3 Werte des GPS Moduls mit Relativer Höhe zum Startpunkt
IMG_20170918_211857.jpg

Menu 4 Akkuwarnstufen Anzeige
IMG_20170918_211905.jpg


Empfangseinheit
IMG_20170918_212059.jpg
 

PeGru

User
Schön, dass Zeit gefunden hast an dem Projekt weiter zu arbeiten.
Würde mich sehr für eine Audioprobe vom Variometer interessieren.
Könntest Du eine wave erzeugen und zugänglich machen?

Und halte uns weiter auf dem aktuellen Stand.



@ Holger Lambertus: kannst Du bitte die Bilder aus deinem Beitrag rausnehmen oder verkleinern.
Bin der Meinung, sie gehören nicht in den Thread von Marcel. Danke
 
Ansicht hell / dunkel umschalten
Oben Unten