Prototype of PPM<>RS485 converter finished

Just first photos of my new invention, PPM<>RS485 bidirectional converter. Both units are same, direction is set by jumper. My goal is obvious, permanent installation of OpenLRS TX module on the roof and UTP cabling. Theoretical distance of transmission if over 1km. First test on 3m UTP works even power is coming through. More info later.

PA120076PA120078PA120080

Antenna tracker

 

IMG_0273

I always wanted antenna tracker. There are many commercial ones integrated to their OSD’s and transmitting location info back by audio channel or sometimes video. Not the way I wanted and pretty expensive.

After switching to my version of OpenLRS I searched for antenna tracker project (source code) suitable for use with OpenLRSng’s transparent telemetry. Then I found Ghettostation by KipK. It is running on arduino, has display and buttons and is open source. I havent had Arduino Mega nor Teensy, so I modified source code to run on atmega328. For now I am running it on OpenLRS receiver without RF module. When my Teensy arrive, I will switch it.

Author’s website

Source code on GitHub

Simplified schematic:

ltmencoder

Ghettostation understands several protocols natively, like Mavlink or UAVtalk. This is great, but in some of my planes, there is no autopilot. Just GPS and OSD. Also, using Mavlink directly needs to have full featured serial telemetry to plane with XBEE or 3DR modems. To address this, GS has it’s own protocol called LightTelemetry (LTM). It is optimized for very low baudrate and one way communication only. This was meant to be used with FSK audio modems. But it is great for OpenLRSng as well! Kipk included support for LTM in TauLabs and Multiwii, so if you have one of these, load modified firmware and connect it with receiver and you are done.  But if you have other flight control or none, I made simple arduino program for parsing NMEA crap and encoding it in LTM packets. I used TinyGPS++ library for parsing NMEA and few lines from TauLabs code.

Antenna tracker hardware is still under development, I had to find a good way to do panning. I used what I had around and recycled most of the stuff. Pan servo is modified to 360 degreed by replacing potentiometer with external one geared from servo output.  Tilt servo is direct drive.

Today I made first field test, walking around with big breadboard and great wire mess. Whole setup worked, tracker was pointing at me all the time! There is still issue with pan servo precision and ancient Garmin GPS is not very accurate, but still big success for me.

Can’t wait to finish this and fly with tracker on regular basis.

As a future feature, my plan is to add piece of code into GS to reconstruct NMEA sentences from LTM to use Oziexplorer (or any other desktop map software – no google maps) on PC to see my plane on map.

IMG_0284IMG_0276

IMG_0282IMG_0288IMG_20140315_162743

Code for protocol translating Arduino:


/**
*****************************************************************************
* NMEA to LightTelemetry protocol translator, for use in UAV
* to be used with ghettostation  https://code.google.com/p/ghettostation/
* requires TinyGPS++ library
*
* using only one serial port: GPS output to RX pin, TX pin to datalink input.
* GPS > LTM encoder > wireless datalink in air >>> wireless datalink on earth > ghettostation
* (c) kolin 2014
*****************************************************************************
*
* #################################################################################################################
* LightTelemetry protocol (LTM)
*
* Ghettostation one way telemetry protocol for really low bitrates (1200/2400 bauds).
*                        
* Protocol details: 3 different frames, little endian.
*   G Frame (GPS position) (2hz @ 1200 bauds , 5hz >= 2400 bauds): 18BYTES
*    0x24 0x54 0x47 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF  0xFF   0xC0  
*     $     T    G  --------LAT-------- -------LON---------  SPD --------ALT-------- SAT/FIX  CRC
*
*   A Frame (Attitude) (5hz @ 1200bauds , 10hz >= 2400bauds): 10BYTES
*     0x24 0x54 0x41 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xC0  
*      $     T   A   --PITCH-- --ROLL--- -HEADING-  CRC
*
*   S Frame (Sensors) (2hz @ 1200bauds, 5hz >= 2400bauds): 11BYTES
*     0x24 0x54 0x53 0xFF 0xFF  0xFF 0xFF    0xFF    0xFF      0xFF       0xC0    
*      $     T   S   VBAT(mv)  Current(ma)   RSSI  AIRSPEED  ARM/FS/FMOD   CRC
* #################################################################################################################
*/

#include <TinyGPS++.h>
#define BAUDRATE 4800
#define LTM_GFRAME_SIZE 18

TinyGPSPlus gps; //define TinyGPS++ object
TinyGPSCustom fixtype(gps, "GPGSA",2); //extract for fix type (no,2D,3D..) $GPGSA sentence, 2nd element

long previousMillis = 0;
long interval = 200; //5Hz telemetry send rate
bool newdata = false;

void setup()
{
	Serial.begin(BAUDRATE);
}
void loop()
{
	unsigned long currentMillis = millis();
	if (Serial.available() > 0)		//check serial line for new data
	{
		if (gps.encode(Serial.read())) //while feeding tinyGPS with new data, check if it has new sentence parsed
		{ 
			newdata=true;
		}
	}


	if(currentMillis - previousMillis > interval && newdata == true) //do this part only in interval
	{
		previousMillis = currentMillis;       // save the last time you passed
		newdata=false;
		uint8_t* LTM_Packet = encode_LTM_Packet(); //prepare the packet
		Serial.write(LTM_Packet, LTM_GFRAME_SIZE);  //send the packet
	}



}

static uint8_t* encode_LTM_Packet()
{              
	int32_t lt_latitude = 10000000 * gps.location.lat();  //Latitude in degrees (double)
	int32_t lt_longitude = 10000000 * gps.location.lng();  // Longitude in degrees (double)
	uint8_t lt_groundspeed = (uint8_t) round(gps.speed.mps());  //Speed in meters per second (double)
	int32_t lt_altitude = gps.altitude.value();  // Raw altitude in centimeters (i32)
	uint8_t lt_gpssats  = (uint8_t) round(gps.satellites.value());  // Number of satellites in use (u32)
	uint8_t lt_gpsfix = atoi(fixtype.value());  //type of GPS fix, returns string, so the conversion

	//code copied from TauLabs with LTM support
	uint8_t LTBuff[LTM_GFRAME_SIZE];
	//G Frame: $T(2 bytes)G(1byte)LAT(cm,4 bytes)LON(cm,4bytes)SPEED(m/s,1bytes)ALT(cm,4bytes)SATS(6bits)FIX(2bits)CRC(xor,1byte)
	//START
	LTBuff[0]=0x24; //$
	LTBuff[1]=0x54; //T
	//FRAMEID
	LTBuff[2]=0x47; //G
	//PAYLOAD
	LTBuff[3]=(lt_latitude >> 8*0) & 0xFF;
	LTBuff[4]=(lt_latitude >> 8*1) & 0xFF;
	LTBuff[5]=(lt_latitude >> 8*2) & 0xFF;
	LTBuff[6]=(lt_latitude >> 8*3) & 0xFF;
	LTBuff[7]=(lt_longitude >> 8*0) & 0xFF;
	LTBuff[8]=(lt_longitude >> 8*1) & 0xFF;
	LTBuff[9]=(lt_longitude >> 8*2) & 0xFF;
	LTBuff[10]=(lt_longitude >> 8*3) & 0xFF;  
	LTBuff[11]=(lt_groundspeed >> 8*0) & 0xFF;
	LTBuff[12]=(lt_altitude >> 8*0) & 0xFF;
	LTBuff[13]=(lt_altitude >> 8*1) & 0xFF;
	LTBuff[14]=(lt_altitude >> 8*2) & 0xFF;
	LTBuff[15]=(lt_altitude >> 8*3) & 0xFF;
	LTBuff[16]= ((lt_gpssats << 2)& 0xFF ) | (lt_gpsfix & 0b00000011) ; // last 6 bits: sats number, first 2:fix type (0,1,2,3)
	uint8_t LTCrc = 0x00;
	for (int i = 3; i < LTM_GFRAME_SIZE-1; i++) {
		LTCrc ^= LTBuff[i];
	}              
	LTBuff[LTM_GFRAME_SIZE-1]=LTCrc;

	return LTBuff;
}    



 

My FPV history, first steps

February 2010

I started with famous Twinstar II by Multiplex. Then first steps with Lawmate 2.4GHz/500mW, B/W CCD camera and laptop with USB digitzer. My first ever FPV flight ended really quick, my camera can not stand freezing temperatures and stopped working after few seconds.  FPV was put off for a while.

Old TS2 Old TS2 Old TS2 Old TS2

 

 July 2010

I crashed original TS2 too many times during LOS flying, I decided to buy Eaystar. I got new 480TVL camera, new 7″ portable TV, reused old Lawmate, RC on 35MHz.

ezstar1_2 ezstar1_3 ezstar1_6 ezstar1_8

With this setup I finally made some real FPV flights.  Max range was about 800m, then RC start to drop. This plane died in nose dive after failure of my transmitter (Hitec optic 6 sport). Luckily FPV pod was not there and only flying LOS.