I give the code for an unidirectionnal Audio telemetry, I make this because I want very smooth display on Google Map or any other app for Android, and long range with only one powerfull TX on the Drone / one powerfull TX on groundstation with sensitive receivers.
I use the DS8500 AFSK 1200 Hart modem chip, but it work perfectly with Arduino AFSK SoftModem library on each side (I can give the code for Serial -> AFSK / AFSK -> Serial).
DS8500-KIT "plug'n'play" evaluation board on MOUSER http://fr.mouser.com/ProductDetail/Maxi ... IazpdPmg==
On GroundStation my smartphone run "Bluetooth GPS" + "Google Map" (and any other GPS recorder app), Baro Altitude is used as GPS Altitude inside groundstation NMEA generator. It is easy to add more data (for the groundstation telemetry) because there is free space inside frames for 5Hz operation.
MultiWii part :
Inside CONFIG.H
Code: Select all
/********************************************************************/
/**** Pascal ****/
/********************************************************************/
#define GPSTOMODEM
#define GPSTOMODEM_SERIAL_PORT 1 // must be 0 on Pro Mini and single serial boards; Set to your choice on any Mega based board
#define GPSTOMODEM_FREQ 64 // 5Hz
Inside SERIAL.INO
Code: Select all
// Pascal
void gpsToModem(){
#if !defined(PROMINI)
CURRENTPORT=GPSTOMODEM_SERIAL_PORT;
#endif
serialize8('$');
checksum[CURRENTPORT] = 0;
serialize32(GPS_coord[LAT]);
serialize32(GPS_coord[LON]);
serialize32(EstAlt);
tailSerialReply();
}
Only for DS8500 use, inside SERIAL.INO also I add "UCSR1C |= (1<<UPM11)" because DS8500 need ODD parity serial input :
For a modem on SERIAL PORT 1 replace :
Code: Select all
case 1: UCSR1A = (1<<U2X1); UBRR1H = h; UBRR1L = l; UCSR1B |= (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1); break;
With :
Code: Select all
case 1: UCSR1A = (1<<U2X1); UBRR1H = h; UBRR1L = l; UCSR1B |= (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1); UCSR1C |= (1<<UPM11); break;
Inside MULTIWII.INO main() loop
Code: Select all
#ifdef GPSTOMODEM
static uint8_t trackerTimer = 0;
if (!(++trackerTimer % GPSTOMODEM_FREQ)) {
gpsToModem();
}
#endif
Inside your Ground station main loop, call this function (bluetooth on Serial0 and modem on Serial1), I still work on it, I use a ChipKit PIC32 Arduino like board (groundstation do any other task).
Code: Select all
void modemToGps() {
static uint8_t current;
static uint8_t n = 0;
static uint8_t sum = 0;
static uint8_t frame[FRAMESIZE];
static int32_t lat;
static int32_t lon;
static uint8_t ns;
static uint8_t ew;
static uint32_t latdeg;
static uint32_t londeg;
static uint32_t latmin;
static uint32_t lonmin;
static int32_t alt;
static uint32_t aAlt;
while(Serial1.available()) {
current = Serial1.read();
switch(n) {
case 0:
if(current == '$')
n = 1;
break;
case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8:
case 9: case 10: case 11: case 12:
frame[n++ - 1] = current;
sum ^= current;
break;
case 13:
if(current == sum) {
lat = (frame[3] << 24) + (frame[2] << 16) + (frame[1] << 8) + frame[0];
lon = (frame[7] << 24) + (frame[6] << 16) + (frame[5] << 8) + frame[4];
alt = (frame[11] << 24) + (frame[10] << 16) + (frame[9] << 8) + frame[8];
ns = lat < 0 ? 'S' : 'N';
ew = lon < 0 ? 'W' : 'E';
lat = abs(lat);
lon = abs(lon);
aAlt = abs(alt);
latdeg = lat / 10000000;
londeg = lon / 10000000;
latmin = lat % 10000000 * 6;
lonmin = lon % 10000000 * 6;
Serial.print("$GPGGA,120000,");
Serial.print(latdeg);
Serial.print(latmin / 1000000);
Serial.print('.');
Serial.print(latmin % 1000000);
Serial.print(',');
Serial.print(ns);
Serial.print(',');
Serial.print(londeg);
Serial.print(lonmin / 1000000);
Serial.print('.');
Serial.print(lonmin % 1000000);
Serial.print(',');
Serial.print(ew);
Serial.print(",1,10,1,");
if(alt < 0)
Serial.print('-');
Serial.print(aAlt / 100);
Serial.print('.');
Serial.print(aAlt % 100);
Serial.println(",M,,,,*00");
tone(SPKPIN, 500, 10);
} else
tone(SPKPIN, 400, 10);
n = 0;
sum = 0;
break;
}
}
}
Pascal