Telemetrie via Audiokanal - Programmierer und Tester gesucht

Status
Nicht offen für weitere Antworten.

cesco1

Erfahrener Benutzer
#61
Ich hab bei rcgroups gefunden was mit einem digitalsignal passiert das durch einen audiokanal geht.
Gesendet wird das:



Ankommen tut das:



Deshalb brauchts einen audioträger, sprich Afsk.
 

QuadMax

Erfahrener Benutzer
#62
Deshalb brauchts einen audioträger, sprich Afsk.
Dann sind wir ja hier auf dem richtigem Weg.

~solved , Danke Metzelmaennchen~

Versuch 01:
Code:
//Sample using LiquidCrystal library
#include <TelemetryKit.h>
#include <TinyGPS.h>
#include <SoftwareSerial.h>


#define RXPIN 12
#define TXPIN 13

long lon, lat;
unsigned long fix_age;

TinyGPS gps;
SoftwareSerial nss(RXPIN, TXPIN);


void telemetryKitCallback(char *packet, size_t length) { }

void setup()
{
  nss.begin(9600);
  
  Serial.begin(9600);
    TelemetryKitInit();

}



void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (nss.available())
    {
      char c = nss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }
 if (newData)
  {
    long lat, lon;
    unsigned long age;
    gps.get_position(&lat, &lon, &age);
    
/*
länge der int's herausfinden
Das GPS gibt eine Zhal bis 8 stellen hinter dem Komma an, als int haben die Koordinaten natürlich kein Komma
*/
    int latlen = 0;

    if(lat > 10000*10000)
       latlen = 10;
    else if(lat > 100000*10000)
     latlen = 11;
    else
     latlen = 9;
  
 
    int lonlen = 0;

    if(lon > 10000*10000)
       lonlen = 10;
    else if(lat > 100000*10000)
     lonlen = 11;
    else if(lat > 100000*100000)
     lonlen = 12;
    else
     lonlen = 9;
 
    int msglen;
     
     char msg[] = lonlen,latlen,lon,lat;
      TelemetryKitTransmit(msg, sizeof(msg));
  }  
}
Löte gleich mal zwei ardus und dann schau ich mal wie gut es funktioniert.
Wenn jemand Fehler im Code findet, fände ich es super wenn er sich kurz meldet :).

char msg[] = lonlen,latlen,lon,lat;
TelemetryKitTransmit(msg, sizeof(msg));

Hat hierfür jemand eine Löung?

Gruss Max
 
Zuletzt bearbeitet:

dd8ed

Erfahrener Benutzer
#63
Ich hab bei rcgroups gefunden was mit einem digitalsignal passiert das durch einen audiokanal geht.
Gesendet wird das:



Ankommen tut das:



Deshalb brauchts einen audioträger, sprich Afsk.
Irgendwie ist der Inhalt des Eigangssignals aber vollständig erhalten geblieben. Das Signal wurde ledigilich von dem in der Übertragungsstrecke enthaltenen Differenzierer von einem NRZ- in ein RZ-Signal umgewandelt. Zur Rückgewinnung des NRZ-Signals würde ein Flip-Flop gute Dienste leisten.
Es gibt übrigens PSK-Modems, die direkt RZ senden.

Gruss
Frank
 

dd8ed

Erfahrener Benutzer
#64
Hallo,
nur mal so als Beispiel was mit FSK geht:

Das Bild oben ist das Signal am Ausgang des Demodulators des RX ohne Rauschen. Annahme ist die, das der Übertragungskanal die Standardbandbreite von 30 Hz - 15 kHz hat und einigermassen linear ist. Der Übertragungskanal wird mitsimuliert. Das Signal ist gaussgefiltert mit BT=2 (also nur ein Bisschen).

Da man ja schon mal Rauschen in der Übertragung hat, hab ich mal ordentlich Noise zugemischt. Die Amplituden von Noise und Signal sind gleich. Das ist das Bild in der Mitte.

Nach Filterung und Behandlung durch einen gescheiten Dataslicer, sieht man das, was im unteren Bild dargestellt ist. Da trifft man alte Bekannte wieder. Die Plots sind durch die Filterlaufzeiten zeitlich etwas gegeneinander verschoben.

Das ganzen zeigt einen Datenstrom mit geschmeidigen 26400 Chips/Sekunde. Die "krumme" Datenrate kommt daher, dass auf der Senderseite jedes Bit mit einer 11 Bit langen Chipsequenz codiert wird. (2400 x 11 = 26400).

Die Dekodierung ist in den Plots noch nicht enthalten. Da arbeite ich noch dran. Von den 11 Chips/Bit können 5 falsch sein und es geht immer noch.
Die Ursprungsdatenrate ist 2400 Bit/Sekunde.

Eine vergleichende Simulation mit AFSK ist nicht möglich, da 26400 CPS in AFSK nicht über einen 15 kHz breiten Kanal gehen.



http://fpv-community.de/attachment.php?attachmentid=97801&stc=1&d=1404055488

Ein Vorteil wäre, das man keinen AD-Wandler zum Empfang braucht, wenn man ein externes Filter und einen externen Datasclicer verwendet. Das sind 2 OPs, 2 Dioden und ein bisschen Hühnerfutter. Mit AD-Wandler ginge das auch in Software.
Ferner hat man natürlich einiges an Processing Gain.
Auf der Sendeseite ist ein DA-Wandler vorgesehen, da man die Filterung sendeseitig besser digital machen kann. Ist aber keine Rechnerei. Die Signalform kommt aus einer Lookup-Table.

Gruss
Frank
 

Anhänge

QuadMax

Erfahrener Benutzer
#65
Wenn du das auf Arduino basis hinbekommst, oder mit vergleichbaren preislichen Mitteln, dann Hut ab ;).
Es wäre schon das Nonplusultra, mit dem Durchsatz sind die Möglichkeiten ja grenzenlos.


Es scheint immer unmöglich, bis es jemand macht.

Gruss QuadMax
 

dd8ed

Erfahrener Benutzer
#66
Hallo,
Wenn du das auf Arduino basis hinbekommst, oder mit vergleichbaren preislichen Mitteln, dann Hut ab ;).
Es wäre schon das Nonplusultra, mit dem Durchsatz sind die Möglichkeiten ja grenzenlos.


Es scheint immer unmöglich, bis es jemand macht.

Gruss QuadMax
selber umsetzen kann ich das leider nicht, da die mir zur Verfügung stehen Programmiersprachen dafür denkbar ungeeignet sind.
Ich zähle da eher zu denen, die wissen wo am Lötkolben das heisse Ende ist oder wie man Systemdesign macht.

Gemacht haben das schon viele. Das ist eine der etwas höherwertigen Standardtechniken zur Datenübertragung per Funk.
 

cesco1

Erfahrener Benutzer
#67
@QuadMax

Einen nmea gps parser findest du in der MultiWii source. Das kann dank opensource 1:1 abgekupfert werden. Das parsen hat den vorteil dass die datenmenge sehr stark reduziert werden kann.

Ein anderes projekt ist "ghettostation" wo sicher auch wesentliche teile übermommen werden könnten. Ich denk mir auch der ghettostation author wäre sehr interessiert an dem unsignedmark modem. Insbesondere wenn der bereits zur servokontrolle gebrauchte arduino parallel auch als modem verwendet wird. Das dürfte mittels hardware-pwm zur servosteuerung kein probelm sein.

Die hardware-pwm servosteuerung kann von der mwii source genommen werden. Ein 328 kann (leider) nur 2 pwm kanäle (50hz, 1000-2000us), aber das reicht ja. Hardware-pwm hat den vorteil dass der prozessor damit zu 0% belastet wird, also genügend zeit für anderes.
 
Zuletzt bearbeitet:

QuadMax

Erfahrener Benutzer
#68
Für den Sendearduino habe ich jetzt folgendes mit Unterstützung von Metzelmaennchen geschrieben:
Code:
/*
TelemtryKit can be found here: https://github.com/markqvist/TelemetryKit
*/


// configurable part:

#define RXPIN 12    //pin on  wich Arduino recieve stuff from GPS
#define TXPIN 13    //pin on wich the Arduino transmit stuff to the GPS

#define spe 9600    //speed of your GPS 

//Do not touch anything under this line
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include <TelemetryKit.h>
#include <TinyGPS.h>
#include <SoftwareSerial.h>

int alt;
long lon, lat;
unsigned long fix_age, time, date, age, chars;


TinyGPS gps;
SoftwareSerial nss(RXPIN, TXPIN);


void telemetryKitCallback(char *packet, size_t length) { }

void setup()
{
  nss.begin(spe);
  
  Serial.begin(9600);
    TelemetryKitInit();

}



void loop()
{
  bool newData = false;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (nss.available())
    {
      char c = nss.read();
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }
 if (newData)
  {

  gps.get_position(&lat, &lon, &age);
  alt = gps.altitude();
  gps.get_datetime(&date, &time, &age);
     

  char buffer[13];
  buffer[0]  = lat >> 24;
  buffer[1]  = lat >> 16;
  buffer[2]  = lat >> 8;
  buffer[3]  = lat;
  buffer[4]  = lon >> 24;
  buffer[5]  = lon >> 16;
  buffer[6]  = lon >> 8;
  buffer[7]  = lon;
  buffer[8]  = alt >> 8;
  buffer[9] = alt;
  buffer[10] = time >> 24;
  buffer[11] = time >> 16;
  buffer[12] = time >> 8;
  buffer[13] = time;
      
  TelemetryKitTransmit(buffer, 14);
  }  
}
Es sendet Längengrad, Breitengrad, die Höhe und die Uhrzeit.


Schaue mir das mit dem Hardware PWM gleich mal genauer an.
Marks Library beißt sich nämlich mit der Servo Library .
Da steht dann folgendes:
TelemetryKit\TelemetryKit.cpp.o: In function `__vector_11':
F:\Bibliotheken\Dokumente\FPV_DiY Tracker\arduino-1.0.5-r2-windows\arduino-1.0.5-r2\libraries\TelemetryKit/TelemetryKit.cpp:457: multiple definition of `__vector_11'
Servo\Servo.cpp.o:F:\Bibliotheken\Dokumente\FPV_DiY Tracker\arduino-1.0.5-r2-windows\arduino-1.0.5-r2\libraries\Servo/Servo.cpp:103: first defined here

Was haltet ihr von dd8ed's Vorschlag? Wäre das machbar? Kann das jemand hier programmieren?

Gruss QuadMax
 

cesco1

Erfahrener Benutzer
#69
Schaue mir das mit dem Hardware PWM gleich mal genauer an.
Falls du nicht klarkommst kann ich da helfen. Braucht timer1 (16 bit) und ist eigentlich easy. Bei MWii ist das nur wegen den vielen #ifdef unleserlich.

Die "multiple definition of `__vector_11' " heisst du hast 2 interrupthandler für denselben IR definiert. Was braucht denn marcs modem an interrupts und timern? Ich glaube nur der sendeteil braucht einen timer? Empfänger hat nur den AD interrupt, oder?

hw-pwm servos, braucht timer1, out an pin9 und pin10:
Code:
/**************************************************************************************/
/***************                  Motor Pin order                  ********************/
/**************************************************************************************/

uint8_t PWM_PIN[2] = {9,10};   // arduino pins 9 + 10
uint16_t servo[2] = { 1500, 1500 }; // servo pulse in usec

/**************************************************************************************/
/***************   Writes the Servos values to the needed format   ********************/
/**************************************************************************************/
void writeServos() 
{
  OCR1A = servo[0]<<1; //  pin 9
  OCR1B = servo[1]<<1; //  pin 10
}


/**************************************************************************************/
/************        Initialize the PWM Timers and Registers         ******************/
/**************************************************************************************/

void initOutput() {

  /****************            mark all PWM pins as Output            ******************/
  for(uint8_t i=0;i<2;i++) pinMode(PWM_PIN[i],OUTPUT);
    
  /********  Specific PWM Timers & Registers for the atmega328P (Promini)   ************/  
  TCCR1A = (1<<WGM11) ; // 16 bit fast pwm
  TCCR1B = (1<<CS11) | (1<<WGM13) | (1<<WGM12); // clk/256
  ICR1 = 0x9FE0; // 20ms repetition rate
  
  TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
  TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
  
  writeServos();
}

void setup() 
{
  initOutput();
}

void loop () 
{
  //whatever ...
  writeServos();
}
 
Zuletzt bearbeitet:
#70
Ein 328 kann (leider) nur 2 pwm kanäle (50hz, 1000-2000us), aber das reicht ja.
Nicht ganz korrekt, an Pin 3,5,6,11 sind auch noch mal PWMs, nur leider mit 8bit...

Die "multiple definition of `__vector_11' " heisst du hast 2 interrupthandler für denselben IR definiert.
vector 11 ist beim Atmega328 der Comparison Match vom ocra1/Timer1

Quote aus der Source
// We need a timer to control how often our sampling functions
// should run. To do this we will need to change some registers.
// First we do some configuration on the Timer/Counter Control
// Register 1, aka Timer1.
Timer1 ist also belegt :( Soweit ich aber sehen konnte ist das nur fuer den Empfaenger... also genau da wo er ja interessant waere.
Beim Sender waere Timer1 eventuell wohl nutzbar aber da wollt ihr ja keine Servos anschliessen oder ;)

Man kann das aber auch einfach als Modem betrachten und die Daten ueber rs232 in einen zweiten Arduino schaufeln wo der Timer dann frei waere. Just my 2 cents ;) Soll nur als Hilfestellung dienen!
 
Zuletzt bearbeitet:

cesco1

Erfahrener Benutzer
#71
Wir brauchen 16 bit timer bei 50hz servos.

Bei 500hz reichen 8 bit. Aber wird denn jeder 500hz taugliche digitalservos verwenden? Also doch nur 2 brauchbare pwm kanäle. Die auflösung bei 50hz und 8 bit pwm wird so richtig mies. Und auch da hat der 328 nur 2 mal 8 bit pwm von timer2, weil timer0 wird arduino intern genutzt ...

Ich denke das mit timer1 ist genau anders rum, der sender braucht timer1, der empfänger nicht. Bitte prüfen.

Den sender könnte man auf den ad-wandler IR umleiten, so wie das im empfänger auch ist. Der AD würde zwar leer laufen, aber das schadet nicht, und macht code einfacher, also win-win.

Der Marc braucht den timer eh nur um 9600hz zu generieren, und das kann 8 bit timer2 wahrscheinlich genau so gut. Das ist die 2. lösung.
 
Zuletzt bearbeitet:

cesco1

Erfahrener Benutzer
#72
Ich habe die modem lib mal angeschaut, und leider verwendet sie timer1 bei senden und bei empfang.

Beim senden macht timer1 die 9600hz samplingfrequenz für den DA. Beim empfang war das früher der freilaufende AD wandler der die 9600hz macht. Keine ahnung ob das bei der arduino lib geändert hat, oder ob timer1 einfach zwecklos mitläuft?

Jedenfallls ist es möglich sowohl sender wie auch empfänger mit dem AD timer zu steuern, d.h. timer1 immer freizulassen. Wer fragt den unsignedmark?
 

cesco1

Erfahrener Benutzer
#74
Ich hab anhand der source vom unsignedmark mein eigenes dings gebastelt. Der sender läuft mit timer2 PWM und braucht als externe beschaltung nur ein RC glied um die 64khz pmw glattzuschleifen (also keine R leiter als DA wandler). Am empfänger verwende ich anstatt des IIR filters eine summierung. Samplerate ist 8000hz, töne sind 1000 / 2000 hz, baudrate = 1000. Das sytem is asynchron, nicht wie mark seins synchron. Das läuft zwar, aber ist noch lange nicht fertig / optimal.

https://github.com/Cesco1/ArduModem

Das "#define TX" macht code für den sender, "#define RX" macht code für empfänger. Timer1 ist bei beiden frei. Das ganze auf 2000 baud zu schrauben sollte kein problem sein.

Ein wort noch .. der unsignedmark empfänger ist empfindlich auf die richtige bias. D.h. der empfängereingang sollte ziemlich genau 2.5V haben bei 5V spannung.

Edit:
Inzwischen ist ein gps parser und pwm output integriert. Die wandlung gps-daten -> ltm protokoll und dann ltm-daten -> winkel für die servos fehlt.
 
Zuletzt bearbeitet:

QuadMax

Erfahrener Benutzer
#75
coole Erweiterung cesco :).

Da eine Baudrate von 1000 nicht gerade viel ist, sollte man sich gut überlegen, was man alles senden möchte, zwegs Updaterate.
Es wäre doch bestimmt möglich, den Code allgemeiner zu schreiben, ich zb bräuchte keine Anzahl der gps Satelliten, dafür aber die Uhrzeit, andere wollen vielleicht die Geschwindigkeit senden,... .

Oder willst du gleich ein all-in-one Trackingsystem?

github cesco1 hat gesagt.:
the RX gps calculations are not there, data is simply spewn out the serial line
Hier meine Errungenschaft:
Code:
  //Bestimmen der Grad zum drehen
  pangrad = atan((groundposlat-airposlat)/(groundposlong-airposlong));
  tiltgrad = atan((airposalt-groundposalt)/(sqrt((groundposlat-airposlat)*(groundposlat-airposlat)+(groundposlong-airposlong)*(groundposlong-airposlong))));
 
  // Winkelkorrektion
  //gegen den uhrzeigersinn negative winkel, mit, positiv 
  if ((airposlat < groundposlat) && (airposlong < groundposlong)) 
  {
    pangrad = (pangrad + 90);
  }
  if ((airposlat > groundposlat) && (airposlong < groundposlong)) 
  {
    pangrad = 90 - (pangrad *(-1));
  }
  if ((airposlat > groundposlat) && (airposlong > groundposlong)) 
  {
    pangrad = (90 - pangrad) *(-1);
  }
  if ((airposlat < groundposlat) && (airposlong > groundposlong)) 
  {
    pangrad = (pangrad*(-1) + 90)*(-1);
  }
 

cesco1

Erfahrener Benutzer
#76
@QuadMax Danke für die formeln!

Eigentlich wollte ich das ganze LTM G-frame implementieren. Das hier:



Das ist von ghettostation https://github.com/KipK/Ghettostation/wiki

Etwas weiteres ist die grosse signal amplitude die der empfänger braucht. Anstatt nun den AD mit 5V referenz und 2.5V mitte laufen zu lassen könnte man im AD setup auf die interne 1.1V referenz umschalten (ADMUX = 0xE3 anstatt 0x63), und den eingangs bias spannungsteiler zwischen gnd und dem AREF pin machen? Das wäre dann 0.55V bias und 5 mal empfindlicher. Wer probierts?
 
Zuletzt bearbeitet:

QuadMax

Erfahrener Benutzer
#77
5hz wären ja super, im Moment läuft er ja nur mit 1000 baud, aber du meintest, dass es kein Problem wäre das etwas hochzuschrauben.
Code sieht bis jetzt sehr gut aus, allerdings brauchst du die "Winkelkorrektur", damit hat man Werte von -180° bis 180°, ansonsten kommen nämlich nur Werte von 0 bis 180 Grad raus.
Damit meine ich, dass der Winkel von B und D sowie der von C und E im Moment noch gleich sind (siehe Anhang).
(A stellt die Bodenstation dar und die anderen Punkte mögliche Aufenthaltsorte des Flugobjektes. Die y Achse zeigt nach Norden.)

In meinem Beispiel sind lan und lon vertauscht, wie ich gerade gemerkt habe, sry.

Gruss QuadMax
 

Anhänge

cesco1

Erfahrener Benutzer
#78
das läuft sauber ohne die "Winkelkorrektur" da ich die atan2 argumente umgestellt habe.

Testproggi output:
Lat 100.0 Lon 100.0 AZang 44.999386
Lat 100.0 Lon -100.0 AZang -44.999386
Lat -100.0 Lon 100.0 AZang 134.99815
Lat -100.0 Lon -100.0 AZang -134.99815

Es braucht aber noch einen "verkürzungsfaktor" bei lon da die distanz per grad nicht konstant ist.

Ich hab das inzwischen getestet, mit navisim als input und einem servo zur kontrolle. Eine niedrige updaterate ist wirklich ein problem. Da wackelt das servo, bewegt sich ruckartig.
Wenn man die baudrate hochzuschraubt steigt auch das notwendige SNR, also eine ziemlich schlechte lösung.

Abhilfe schafft ein extrapolator. Damit lässt sich auch bei 2 hz updaterate eine flüssige servobewegung machen, weil die 2hz intern auf 20hz hochgerechnet werden (pos = alte pos + vel * time). Ich hab ne testversion von dem, damit läuft mein servo flüssig-sauber. Die source ist auf git (sender + empfänger neu laden, da neu mit 2hz).


Anhang: processing testproggi az/al berechnung atan2
 

Anhänge

Zuletzt bearbeitet:

QuadMax

Erfahrener Benutzer
#79
ich dachte tan2 wäre gleichzusetzten mit arcustangens :).

Wenn du Tester brauchst, ich bin bereit;).


Ich habe mich mal durch deinen Code gearbeitet und jetzt wird mir auch klar, warum die die Anzhal der gps Satelliten brauchst.
Erst wenn mehr als 5 Satelliten verfügbar sind, kann die Homeposition auch gesetzt werden.
super Idee ;) das beugt Fehler vor. Helium gab mir den Tipp, dass der Tracker erst trackt, wenn das Modell sich mehr als 10 Meter von der Station entfernt, damit es nicht zu heftigen Bewegungen beim Tracker kommt.

Programmiere gerade für meinen eigenen Tracker eine gui, vielleicht kann man hier etwas verwerten.

Code:
/*-----( Import needed libraries )-----*/
#include <Wire.h>  // comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads


//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address


/*-----( Declare Variables )-----*/
int sekunde, sensorValue, counter;
int c = 0;
float voltage, voltkons;
int K1 = 2;
int K2 = 3;
int K3 = 4;
long homelon, homelat, homeald, airlon, airlat, airald, TimeSetZero;
int K1read,K2read,K3read;           // the current reading from the input pin
int K1previous = LOW;    // the previous reading from the input pin
int K2previous = LOW;
int K3previous = LOW;


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  lcd.begin(20,4);         // initialize the lcd for 20 chars 4 lines
  lcd.setCursor(4,0);
  lcd.print("DIY-Tracker");
  lcd.setCursor(5,1);
  lcd.print("AudioArdu");
  lcd.setCursor(6,2);
  lcd.print("00:00:00");

  lcd.setCursor(7,3);
  lcd.print("00,00V");

  voltkons = (5/1023);

  pinMode(K1,INPUT);
  pinMode(K2,INPUT);
  pinMode(K3,INPUT);

  counter = 0;

}
void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{

//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// flight time display      **finished
//++++++++++++++++++++++++++++++++++++++++++++++++++
sekunde = ((millis()/1000-60*c-TimeSetZero));
  if (sekunde < 10)
  {
    if (counter == 0) {
      lcd.setCursor(13,2);  
      lcd.print((sekunde));
      lcd.setCursor(12,2);
      lcd.print("0");
      }
  }
  else
  {
    if (counter == 0) {
      lcd.setCursor(12,2);
      lcd.print((sekunde));
    }  
  }
  
  switch (sekunde)
 {
 case 60:
   c = c+1;
   if (counter == 0) {
       if (c = 60) {
        c = 0;
       }
   }
   if (c < 10)
   {
     if (counter == 0) {
       lcd.setCursor(10,2);
       lcd.print(c);  
     }
   }
   else
   {
     if (counter == 0) {
       lcd.setCursor(9,2);
       lcd.print(c);
     }
   }
 break;
 }
 
 switch (c)
 {
 case 60:
   if ((c/60) < 10)
   {
     if (counter == 0) {
       lcd.setCursor(7,2);
       lcd.print((c/60));     
     }
   }
  else
  {
    if (counter == 0) {
      lcd.setCursor(4,1);
      lcd.print((c/60));
    }
  }
 break;
 }   


//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// voltage reading and displaying    **working atm
//++++++++++++++++++++++++++++++++++++++++++++++++++

  sensorValue = analogRead(A3);

  float voltage = sensorValue * (5.0 / 1023.0);

 // if (counter == 0) {
   // lcd.setCursor(7,3);
   // lcd.print(voltage);
//}


//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// menu    **testing
//++++++++++++++++++++++++++++++++++++++++++++++++++


// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers


K1read = digitalRead(K1);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (K1read == HIGH && K1previous == LOW && millis() - time > debounce) {
 
    lcd.setCursor(4,0);
    lcd.print("DIY--Tracker");
    lcd.setCursor(5,1);
    lcd.print("AudioArdu");
    
    counter = 0;
  }

K1previous = K1read;

K2read = digitalRead(K2);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (K2read == HIGH && K2previous == LOW && millis() - time > debounce) {
     
    counter++;
    if (counter > 3) {
      counter = 1;
    }
    if (counter == 1) {
      lcd.setCursor(0,1);
      lcd.print("#set Home Position");
      lcd.setCursor(1,4);
      lcd.print("F-Zeit=>0");
      lcd.setCursor(2,8);
      lcd.print("SOS");  
    }
    if (counter == 2) {
      lcd.setCursor(0,1);
      lcd.print("set Home Position");
      lcd.setCursor(1,4);
      lcd.print("#F-Zeit=>0");
      lcd.setCursor(2,8);
      lcd.print("SOS");  
    }
    if (counter == 3) {
      lcd.setCursor(0,1);
      lcd.print("set Home Position");
      lcd.setCursor(1,4);
      lcd.print("F-Zeit=>0");
      lcd.setCursor(2,7);
      lcd.print("#SOS");  
      }
    
    
    time = millis();    
  }

K2previous = K2read;

K3read = digitalRead(K3);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (K3read == HIGH && K3previous == LOW && millis() - time > debounce) {
  
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("set Home Position");
    lcd.setCursor(1,4);
    lcd.print("F-Zeit=>0");
    lcd.setCursor(2,8);
    lcd.print("SOS");
    
    time = millis();
  } 
  
  if (K3read == HIGH && K3previous == LOW && millis() - time > debounce) {
    
    if (counter == 1) {
      if (homelon != 0) {
        lcd.clear();
        lcd.setCursor(0,3);
        lcd.print("wirklich neue");
        lcd.setCursor(1,2);
        lcd.print("Position setzen?");
      
      } 
      else {
        homelon = airlon;
        homelat = airlat;
        homeald = airald;
    
      }
    }
    
    if (counter == 2) {
      TimeSetZero = millis();
      c = 0;
    counter = 0;  
    }
    
    if (counter == 3) {
      lcd.setCursor(0,0);
      lcd.print("Position:");
      lcd.setCursor(1,0);
      lcd.print(airlon);
      lcd.setCursor(2,0);
      lcd.print(airlat);
      lcd.setCursor(3,0);
      lcd.print(airald);
    }
  }        
  time = millis();      

  K3previous = K3read;

  if (K3read == HIGH && K3previous == LOW && millis() - time > debounce && (counter==1)) {
        homelon = airlon;
        homelat = airlat;
        homeald = airald;
        counter = 0;  
  }

}
Das Menu ist noch nicht getestet worden und die Spannungsmessung funktioniert noch nicht, aber ich arbeite dran ;).
Rauskommen soll dann so was wie das Bild im Anhang.

Gruss QuadMax
 

Anhänge

Zuletzt bearbeitet:

coax1337

Neuer Benutzer
#80
Moinsen,

habe mal versucht die Schaltung aufzubauen. Doku aus MicroAPRS auf einem Breadboard.
Dann aus dem TelemetryKit den Transmitter Sketch auf den Arduino Uno hochgeladen.
Hätte jetzt es erhofft das es auf anhieb ist funktioniert, aber ist bei mir nicht so ;)

Wo werden die digitalen Pins deklariert?
Und sollte die TX Led nicht leuchten? :)

Oder muss ich zuerst beide Arduinos aufbauen ?

Das PTT ist Push-To-Talk? und für uns doch uninteressant oder?
 
Status
Nicht offen für weitere Antworten.
FPV1

Banggood

Oben Unten