Eigenbau Tracker mit Downlink über den Audiokanal

Status
Nicht offen für weitere Antworten.

QuadMax

Erfahrener Benutzer
#81
Die Git ist nicht mehr aktuell, auch wenn aktuell draufsteht.
Aktuell ist die Version vom Post 65.
Allerdings fehlt noch die Skalierung von lat und long.
Ich komme gerade von einer Klassenfahrt und kam daher noch nicht dazu.
Kompass und Display kommen danach, dann aber auf den zweiten Arduino.

Wenn du nicht so lange warten möchtest, kann ich dir gerne Informationen zusammenstellen, damit du das Menü und den Kompass programieren kannst.
 

Poettie

Erfahrener Benutzer
#85
Huhu!
Gibt es Erfahrungen, ob man das GPS vom Ardupilot direkt abzwacken kann? Kann man ggf. die Baudrate dem Apm GPS anpassen?
Mag jetzt nicht unbedingt noch ein GPS auf den Flieger bappen :)
 

QuadMax

Erfahrener Benutzer
#86
Wie viel Hz macht denn dein GPS vom APM?
5Hz funktioniert auf jeden Fall, 2Hz könnte auch noch gehen; aber nicht getestet.
Bei der Baudrate kann sich der Arduino an das APM GPS anpassen. hier in Zeile 6.
 

Poettie

Erfahrener Benutzer
#87
Ich glaube 5Hz aber muss mal die Tage gucken. Jedenfalls mag ich ein Audiomodem für die Datenübertragung an den open360tracker von rangid benutzen.
 

Wedge

Neuer Benutzer
#88
also ich hab das hier im Thread verlinkte GPS von Banggood sowohl am APM als auch am TX Arduino angeschlossen.
Vom APM gehen alle leitungen (also + ,masse, TX und RX) ans GPS und vom Arduino ist nur der RX Pin mit dem TX Pin des GPS verbunden.

Die Baudrate im Arduino ist auf 9600 eingestellt, damit bekommt bei mir sowohl das APM als auch das Arduino lesbare Daten.
(sprich ich sehe LAT, LON und ALT im MinimOSD und kann gleichzeitig sämtliche GPS Daten übers Arduino am PC ausgeben)

klappt also Problemlos :)
 

Poettie

Erfahrener Benutzer
#90
Ah, genau so hab ich mir das vorgestellt Danke. Dann hab ich ja demnächst mal wieder was zu basteln .. Sofern die Post mal kommen sollte
 

QuadMax

Erfahrener Benutzer
#91
Das verlinkte GPS macht glaube ich nur 1Hz, kann man aber hochstellen.
Das ist kein großer Aufwand. Dafür gibt es von u-blox extra eine Software;).
 

eve-msw

Neuer Benutzer
#92
hi, habe mal das 20x4 lcd und den voltage monitor hinzu gefügt, kompass bekomme ich nicht hin :(:confused:
v input ist die auf dem schaltplan beschrieben, time geht auch nicht vielleicht weis einer rat (einfacher zähler min:sec )

ardu_modem_rx.ino
#define RX // TX or RX firmware
//#define INTVREF // use internal 1.1V ref for AD
#define LED 13
#define BAUDRATE 115200
#include <Wire.h> // comes with Arduino IDE
#include <LiquidCrystal_I2C.h> //LCD
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//I2C device found at address 0x3F lcd!

//voltage
int analogInput = 2;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000.0; // resistance of R1 (100K) -see text!
float R2 = 44950.0; // resistance of R2 (10K) - see text!
int value = 0;
//voltage ende
// PWM out is pin 9 and 10
// AFSK out is pin 11
// AFSK in is pin A3
//Voltagepin is A2

unsigned long time,lasttime;


void setup()
{
//display
lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines
lcd.setCursor(8,0);
lcd.print("Tracker");
lcd.setCursor(6,1);
lcd.print("platzhalter");
lcd.setCursor(6,2);
lcd.print(time);
//displayende

pinMode (LED, OUTPUT);
SerialOpen(BAUDRATE);
initOutput();
initFsk();
digitalWrite(LED, 1);
time = millis();
lasttime = time;
}

#define lat 0
#define lon 1

int32_t GPS_coord[2] = { 0, 0 };
uint8_t GPS_numSat;
uint16_t GPS_altitude;
uint16_t GPS_speed;

int32_t GPS_home[2] = { 0, 0 };
int32_t home_alt = 0;
boolean home_set = false;
extern uint16_t servo[2];

float angaz,angel;

float new_lat = 0.0;
float new_lon = 0.0;
float new_alt = 0.0;
float old_lat = 0.0;
float old_lon = 0.0;
float old_alt = 0.0;

float act_lat = 0.0;
float act_lon = 0.0;
float act_alt = 0.0;

float LonScale = 1.0;

void calc_lon_scale(int32_t lati)
{
float rads = (abs((float)lati) / 10000000.0) * 0.0174532925;
LonScale = cos(rads);
}

void updatepos()
{
old_lat = new_lat;
old_lon = new_lon;
old_alt = new_alt;

new_lat = (float)(GPS_coord[lat] - GPS_home[lat]);
new_lon = (float)(GPS_coord[lon] - GPS_home[lon]) * LonScale;
new_alt = (float)(GPS_altitude - home_alt);
}

float dist;

void calcangles()
{
if(new_alt < 0.5) new_alt = 0.5;
if(new_lat <= 0) new_lat = 0.1;

float angleaz,angleel;
dist = sqrt(act_lat*act_lat + act_alt*act_alt);
angleel = atan(act_lat/act_alt);
angleaz = atan(act_lon/dist);

angaz = angleaz * 57.296;
angel = angleel * 57.296;
}

#define az_fact 5.5
#define el_fact 5.5

void angletoservo()
{
servo[0] = 1500 + (int)(angaz * az_fact);
servo[1] = 1500 + (int)(angel * el_fact);
}

uint8_t missedframes = 0;
uint8_t goodframes = 0;

//volatile uint8_t ad_byte;
//volatile uint8_t ad_byte_rdy;

void loop()
{

uint8_t c,i,d;

time = millis();

/*
if (ad_byte_rdy)
{
ad_byte_rdy = 0;
SerialWrite(ad_byte);
}
*/

if (receiveLTM())
{
digitalWrite(LED, 1);
if (!home_set)
{
if (GPS_numSat >= 6)
{
home_set = true;
goodframes = 0;
missedframes = 0;
GPS_home[lat] = GPS_coord[lat];
GPS_home[lon] = GPS_coord[lon];
home_alt = GPS_altitude;
calc_lon_scale(GPS_coord[lat]);
}
}

// do gps calculations
updatepos();

act_lat = new_lat;
act_lon = new_lon;
act_alt = new_alt;

// calculate angles
calcangles();

// output to pan / tilt servo
angletoservo();
writeServos();

lasttime = time;

goodframes++;
serialize8(goodframes);
serialize8(missedframes);
SerialWrite(13);
//SerialWrite((int)(angaz*0.1));
}

if (time - lasttime >= 1050)
{
digitalWrite(LED, 0);
lasttime = time;
missedframes++;
serialize8(goodframes);
serialize8(missedframes);
SerialWrite(13);
}
// VOLTAGE !!! read the value at analog input

value = analogRead(analogInput);
vout = (value * 5.0) / 1023.0; // see text
vin = vout / (R2/(R1+R2));
if (vin<0.09) {
vin=0.0;//statement to quash undesired reading !
}

lcd.setCursor(0, 3);
lcd.print("Power Input V=");
lcd.print(vin);
delay(200);
}
 

QuadMax

Erfahrener Benutzer
#93
Wegen der Stoppuhr:

Code:
void menu()
{
//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// flight time display      
//++++++++++++++++++++++++++++++++++++++++++++++++++

sekunde = ((millis()-TimeSetZero)/1000-60*crt);
  if (sekunde < 10)
  {
    if (counter == 0) {
      lcd.setCursor(13,2);  
      lcd.print((sekunde));
      lcd.setCursor(7,3);
      lcd.print(voltage+'V');
      lcd.setCursor(12,2);
      lcd.print("0");
      }
  }
  else
  {
    if (counter == 0) {
      lcd.setCursor(12,2);
      lcd.print((sekunde));
      lcd.setCursor(7,3);
      lcd.print(voltage+'V');
    }  
  }
  
  if ( sekunde > 59)
 {
   crt = crt + 1;
   minute = minute + 1;
   }
   if (minute < 10)
   {
     if (counter == 0) {
       lcd.setCursor(10,2);
       lcd.print(minute);  
     }
   }
   else
   {
     if (counter == 0) {
       lcd.setCursor(9,2);
       lcd.print(minute);
     }
   }
 
 
 if (minute > 59){
   stunde = stunde +1;
   minute = 0;
   lcd.setCursor(9,2);
   lcd.print('00');
   if ((stunde/60) < 10)
   {
     if (counter == 0) {
       lcd.setCursor(7,2);
       lcd.print((stunde/60));     
     }
   }
  else
  {
    if (counter == 0) {
      lcd.setCursor(4,1);
      lcd.print((stunde/60));
    }
 }
 } 
//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// voltage reading    
//++++++++++++++++++++++++++++++++++++++++++++++++++
  
  if (counter == 0){
    sensorValue = analogRead(A2);

     voltage = sensorValue * (5.0 / 1023.0) * divider;    //220kOhm and 100kOhm voltage divider
  }
  
//++++++++++++++++++++++++++++++++++++++++++++++++++ 
// menu
//++++++++++++++++++++++++++++++++++++++++++++++++++

  // 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
  
  // if the input just went from LOW to HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  K1read = digitalRead(K1);
  
  if (K1read == HIGH && millis() - time > debounce) {
  
      TimeSetZero = millis();
      crt = 0;
      minute = 0;
      stunde = 0;
      lcd.setCursor(6,2);
      lcd.print("00:00:00");
  }
  
  K2read = digitalRead(K2);
  
  if (K2read == HIGH && millis() - time > debounce) {
      
      lcd.clear();
      lcd.print("Position:");
      lcd.setCursor(0,1);
      lcd.print(GPS_coord[lon]);
      lcd.setCursor(0,2);
      lcd.print(GPS_coord[lat]);
      lcd.setCursor(0,3);
      lcd.print(GPS_altitude);
      
      if (counter == 1){
        counter = 0;
        lcd.clear();
        lcd.setCursor(4,0);
        lcd.print("DIY-Tracker");
        lcd.setCursor(5,1);
        lcd.print("AudioArdu");
        lcd.setCursor(6,2);
        lcd.print("00:00:00");
      }
      else {
        counter = 1;
      }
  }
}
Und zum Kompass, bzw der Drehmatrix zum berechnen der Winkel für die Servos:
Code:
void calcangles()
{
  
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
   heading = atan2(event.magnetic.y, event.magnetic.x); 
 
  heading += declinationAngle;  
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
    
    heading = 0.017;
    
 //it is gonna really complex now, if wish to understand it, see additional file. - not done
 
 //calculating pseudo coordinates:
 float pseudoposx = -sin(heading)*(new_lat*cos(heading)-new_lon*sin(heading));
 float pseudoposy = cos(heading)*(new_lat*cos(heading)-new_lon*sin(heading));
 
 // z value is the same as the target ones, so i leaf it at new_alt 
 
 // calculating distance from pseudopoint to target and to ground station
 float pseudobottomtobase = sqrt(pseudoposx*pseudoposx+pseudoposy*pseudoposy);
 float pseudotobase = sqrt(pseudobottomtobase*pseudobottomtobase+new_alt*new_alt);
 float pseudototarget = sqrt((pseudoposx-new_lon)*(pseudoposx-new_lon)+(pseudoposy-new_lat)*(pseudoposy-new_lat));

 // calculating angels for servos now
 float angleaz,anglel;
 angleaz = 90 - atan(new_alt/(pseudobottomtobase))* 57.296;
 anglel = atan(pseudototarget/pseudotobase) * 57.296;
 
 // checking if the servos turn the right way
 if (new_lat > (tan(heading)*new_lon)) {
   }
   else {
     anglel = anglel * (-1);
   }
 if (new_lat > (-1/tan(heading)*new_lon)) {
   }
   else {
     angleaz = angleaz * (-1);
   }
  }
Bei mir hat die Einbindung der Wire.h nicht funktioniert. Das hat sich mit dem Empfangen der Daten gestört.
 

eve-msw

Neuer Benutzer
#94
muss leider gestehen habe nicht viel ahnung :) status : lcd geht, timer läuft (und reset), menu geht (anzeige gps), voltage geht, kompass geht habe aber keine anzeige ... (grad°) evtl. wäre es ja möglich das man die bodenstation halt drehen muss bis man sie "eingenordet" hat dafür wäre die anzeite mit ° halt schön :ding:, servos stehen auf 90°, buttons gehen (reset, menu), muss am sendermodem nochn groundkabel anlöten was mit dem sender verbunden wird dann könnte ich mal testen.... schönes schwitzen noch ^^
 

QuadMax

Erfahrener Benutzer
#95
Der Tracker muss nicht "eingenordet" werden, die Kompensation macht meine Drehmatrix :p
(Codebeispiel aus meinem letzten Post).

Würde auch gerne weiter testen, aber der Chinese kommt mit den Uno Shields nicht bei ... .
 
#96
hallo, ich habe gesehen ihr habt ein paar Tool zum die zwei Baugruppen testen zu konnen.

leider steige ich nicht so ganz durch was für was ist.

wie kann ich den erst mal testen ob das gps geht.
dann will ich testen ob das senden geht
dann will ich testen ob das empfangen geht
und erst dann will ich die servos dran hängen und alles testen

bis jetzt hab ich nur den Empfänger und Sender nach Schaltbild aufgebaut noch ohne weitere Komponenten wie servos Display usw.
 
#98
hallo,

also mein GPS geht und mein Sender und empfänger scheint auch zu gehen, aber die Ampitude ist viel zu klein denke ich, wenn ich die ganzen posts richtig verstanden habe. Was muss ich da jetzt machen.

Unbenannt.JPG
 

QuadMax

Erfahrener Benutzer
#99
Man kann die Skalierung ändern. Es gibt einmal 1.1V und einmal 5V. Wenn dein Signal < 1.1V ist, dann kannst du dies im sketch umstellen. Irgendwo in den ersten paar Zeilen. Aber dann muss dein Spannungsteiler am Empfänger auch an AREF angeschlossen werden.

*Wenn der DisplayAD_PC allerdings auf 5V eingestellt ist, wird das Signal, wenn es nur bis 1.1V geht, nur so klein angezeigt.
 
Zuletzt bearbeitet:

QuadMax

Erfahrener Benutzer
Tolle Neuigkeiten. Meine Platinen sind endlich da:

IMG_20150722_142833.jpg


groundstation.jpg
[size=-2](anklicken für große Ansicht)[/size]

Jetzt werde ich Stück für Stück den neuen Code durchtesten, sowie die Github Wiki aktualisieren.
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.
FPV1

Banggood

Oben Unten