Saturday, April 27, 2013

Quick and dirty data modem for video transmitter

If you use a video transmitter to transmit video from a FPV plane or a balloon it often does not make a lot of sense to transmit sound as well. You may find yourself with an unused sound channel that could be used for usefull telemetry data.
Normally you would need some sort of modem to convert data into sound and vice versa but it turnes out that the audio bandwidth of many video transmitters are actually wide enough to directly transmit low baud rate serial data.
One problem is that these transmitters/receivers have DC blocking capacitors in the signal path. Since normal 8N1 serial data has a DC component the signal gets distorted.
The simple solution uses the fact that the transmitters often have a limited dynamic range. When the amplitude of the input signal reaches a certain level the receiver starts to clamp the signal and force it to the middle of the dynamic range. We can use this to our atvantage by transmitting a constant stream of data. The transmitter constantly tries to center the signal by clamping.
On the receiving side you need to do something similar since the signal passes another set of capacitors. Here you need to insert your own clamping circuit to restore the signal ballance
There are at couple of issues with this method
A) you need to adjust the signal level into the receiver just right. Too much signal and the image transmission gets distorted, too little no clamping occur and data gets distorted.
B) The baud rate must be low enough to pass the bandwidth of the transmitter and high enough to get good clamping. 4800BAUD is usually a good compromise.
C) You need to transmit data continously without interruption.

This is what the data looks like after passing the signal chain. Bottom trace is original data and top trace is just before the 74LS14:



If you are using Arduino to transmit data there is an additional problem. The Arduino serial library offers no method for detecting when the serial output buffer is full. If you continously call Serial.write() your program will stall whenever the serial buffer is full and you will effectively be using all your program time waiting for the serial port.
This trick lets you check when it is time to send a new character:

// How to send a constant unbroken stream
// of data without stalling main loop 
// to wait for Serial
// Dzl 2013

void setup()
{
  Serial.begin(4800);
}

void loop()
{
  if(UCSR0A&(0x01<<UDRE0)) //True if tx buffer has room
  {
    char some_data=random(255);
    Serial.write(some_data);
  }

  //-Free time here to do usefull stuff
}

No comments:

Post a Comment