Readers of my blog will know that I have a weakness for modifying things to serve a purpose they never have been designed for. And admittedly, this project is one of the most stupid/nicest projects I’ve done recently. Why stupid? Well, I transformed a soldering iron into an oscilloscope… see for yourself:

As you can see in the video, you can use the soldering tip as your measurement probe. Coincidentally, a soldering iron has already a pretty good form factor for an oscilloscope. Here is a still picture of a UART waveform:

Right now, the user interface is very minimalistic. The vertical axis can be scaled simply by pressing and holding one of the buttons and then turning the iron around its axis. In the same manner the horizontal axis can be scaled by tilting the iron up and down. Using this as the main interface makes the oscilloscope surprisingly usable.

Of course, the iron can be used as a normal iron or as an oscilloscope without any changes to the hardware. The oscilloscope is simply a new menu option.

What and how

Even without any changes the TS100 is a very nice portable soldering iron. I use it as my main soldering tool. But what makes it special is that it contains a powerful 32 bit ARM processor, a graphical OLED display, open source firmware and a schematic that is available. And this makes it a very good target for this project.

The oscilloscope function requires a little change of the irons hardware. A single wire needs to be connected from the earth connection of the tip to one of the buttons. This “forwards” the voltage of the tip into an analog input of the ARM. The modification can be seen in the following image:

Using this direct connection is rather dangerous because every voltage on the tip directly reaches the ADC input pin of the ARM. For a real-world use-case I would recommend to add a resistor in series and a TVS protection diode before the ADC pin.

Limitations

Since I’ve added no front end analog circuit to the soldering iron, it is limited to what the ADC of the ARM is able to measure: 0 to +3.3V. This is of course very poor for an oscilloscope. A cheap modification would be to add also a resistor divider in front of the ADC for being able to measure higher voltages. A 10:1 divider should be a good compromise. It allows you to measure up to 33V. Also, since the ADC has a resolution of 12 bit you should still have a sufficient resolution of 8mV/LSB.

Also, the software is still not in a usable shape. I’ve just hacked some stuff into the existing firmware. For reference, you can find the code here:

Do NOT use it on your production soldering iron. Currently, it does not let you use the soldering iron and the oscilloscope code is nothing but horribly wrong. Why did I start with such a crappy implementation? Well, it was thought of as a demonstrator to check if the idea is viable. Unfortunately, the original firmware would require rewrites of large portions of it to support high frequency ADC sampling and I am not really in the mood of investing so much effort in a code basis of questionable quality.

Instead, I will start a clean room implementation of the firmware. This will then also use the new UI interactions that I have demoed for the oscilloscope. For example, all the values like target temperature will be simply settable by pressing and holding a button while turning the iron. Turning in one direction will increase the temperature, turning it to the other direction will decrease it.

Also, forwarding the oscilloscope data over USB is an option. This would allow to display the measurements on your Android device for example.

A simple multimeter will of course also be added.

At the end, what specs could you expect from it? Roughly:

0 to 30V input range

2MSPS

>30Hz display update rate

Summary

In this post I’ve shown you a demonstrator of a soldering iron turned into an oscilloscope. The obvious question for this project is of course: Why??

Well, it probably won’t replace your bench oscilloscope. But having even the simplest kind of oscilloscope at hand while you are away from the bench can be a real lifesaver. Some examples of questions to which the soldering iron oscilloscope can give you an answer:

Is there a signal at all?

Does the timing of the look sensible?

Does the voltage look sensible?

And I would say that (at least in the digital domain) 80% of problems can be eliminated by having the answer to these questions. Things like:

I did configure the UART transmitter wrong. It outputs its data on a different pin

I see a valid UART signal so the problem must be at the receiving end

Normally, the 3.3V I2C bus shouldn’t idle at 1.2V!? Did I forget to enable the pullup resistors?

Why is there no ACK bit from the I2C device? Am I sending data to the correct address?

…

Once there is a usable alpha version of the rewritten firmware available I will publish a link to it in my blog. Please subscribe if you want to be notified about this.

]]>https://befinitiv.wordpress.com/2017/09/26/ts100-oscilloscope-hack/feed/6befinitivDSCF4042DSCF4029Wifibroadcast RPI FPV image v0.4https://befinitiv.wordpress.com/2015/12/31/wifibroadcast-rpi-fpv-image-v0-4/
https://befinitiv.wordpress.com/2015/12/31/wifibroadcast-rpi-fpv-image-v0-4/#commentsThu, 31 Dec 2015 17:45:00 +0000http://befinitiv.wordpress.com/?p=724I have a small timeslot until my new year’s eve party begins so I thought I could use it to upload the newest Wifibroadcast RPI FPV image: https://github.com/befinitiv/rpi_wifibroadcast_image_builder/releases/tag/v0.4.

The changes are:

Merged TX and RX images. You can write this image file onto the SD cards for both RX and TX Raspberries. The devices change their roles accordingly depending on whether a camera is connected or not. In short: Raspberry with camera behaves like a TX device, Raspberry without camera behaves like a RX device.

Removed message flood of TX to systemd journal to avoid growth of log files. This allows for long running TX devices.

The most important change is point 1: This means for you that you only have to download one image instead of two. Also, there is no need to mark the SD cards with TX and RX since they are all the same. This makes things much easier.

Update 12/13/2015: Some people asked for example videos. Unfortunately, I only have a single set of data that I cannot publish here. If someone would like to see results of this script and provide me with data (of course with several images per day so that there is something to select from) I would process it and present it here.

Most people that have created an outdoor time-lapse video will have encountered the problem of flashing video due to sunny images followed by cloudy images or vice versa. One common way to get around this problem is to shoot more than one image per day and then select the best fitting images. But this can be quite a lot of work. If you shoot a picture each 30m you’ll end up with close to 20,000 images per year. And that would take you a while to select the right images.

Therefore, I wrote a simple script that selects one image per day that fits “best” to the day before. The script then continues to the next day and finds the “best” compared to the “best” of the previous day.

The obvious question is now: What is the “best” image? As said before, it should contain as little change in brightness as possible. Also, the change in color should be not so big.

I used quite a hacky approach that is far from being optimal but works well enough for me. I create the sum of absolute differences (SAD) over all pixels for the reference image compared to the candidate images. The SAD just subtracts all pixels of the reference picture from the candidate pictures. This absolute value of this difference image is then summed together to end up with a single score of similarity. The picture pair with the smallest score is considered to be most similar. This SAD is created for all three color channels separately to also get some simple kind of color comparison into the process.
One important step that I have not yet mentioned is the preprocessing of the images. Taking the SAD of the raw camera images is not the best idea. The pixel values of an exact position (x,y) of the two images have usually little in common. There are several reasons for this:

Ideally, these effects should not have a big influence on the similarity scoring. Therefore, I low-pass filter the images (aka blur) before comparing them. This averaging removes noise as well as small movements. Still, the overall appearance like brightness and color is maintained.

Now the script will run through the pictures in the folder “motion” and create symbolic links to fitting images in the folder “sel”. You might want to adapt the parameters inside the script like the number of images per day and the start image of the first day.

To use them you just have to install the images onto SD cards, prepare two Raspberry PIs with camera+TPLINK TL-WN722 as TX and display+TPLINK TL-WN722 as RX and you are done.

I moved the manual installation procedure from the main Wifibroadcast page to here in case you want to install Wifibroadcast onto an existing Raspberry PI image. Making things by yourself is also a good way to get to know the system better.

The images contain the basic features you would expect. Video capture at TX and video display at RX. Also, automatic video recording onto USB sticks and support for a shutdown button is included. FrSky-OSD software is also installed but disabled by default (since it depends a lot on the hardware available).

Automatic image creation

Since creating these images is quite time consuming (and I am lazy…) I automated the whole process. This also helps me and others to understand afterwards exactly what an image contains. And of course, others can put their tweaks into the build system and benefit as well from all the points above.

The following commands are all you need to do to create the TX and RX images:

The build_images.sh automatically downloads the needed bits such as basic raspbian images, build tools and kernel. The kernel will be patched, compiled and installed onto the base image. This is followed by chrooting with the help of qemu (because Raspberry PI is an ARM architecture) into the image and (natively) install Wifibroadcast and co. Oh and all the configurations like network card settings, enabling of the camera and HDMI mode are also automatically set.

Future plans

Currently, the image only supports 2.4GHz operation. I would like to extend the images to also support 5GHz Wifi sticks and choose the frequency automatically, depending on which sticks are connected. Unfortunately, I do not have compatible 5GHz Wifi sticks available so it is still unclear if and when this will happen.

]]>https://befinitiv.wordpress.com/2015/11/02/prebuild-wifibroadcast-raspberry-pi-fpv-images/feed/9befinitivLatency analysis of the raspberry camerahttps://befinitiv.wordpress.com/2015/09/10/latency-analysis-of-the-raspberry-camera/
https://befinitiv.wordpress.com/2015/09/10/latency-analysis-of-the-raspberry-camera/#commentsThu, 10 Sep 2015 19:11:14 +0000http://befinitiv.wordpress.com/?p=555This post presents results of an analysis looking for the cause of latency in a Raspberry wifibroadcast FPV setup

—

The last bit a wifibroadcast FPV system would need to kill analog FPV would be better latency. The robustness of the transmission using wifibroadcast is already better, the image quality for sure, just the latency is a bit higher.
This post will not present a solution and will also not measure total system delay. It concentrates on the latencies in the TX PI.

Test setup

For measuring latency easily you need something to measure that is driven by the same clock as the measurement. I decided to go with a simple LED that is driven by a GPIO of the Raspberry. The LED is observed by the camera. This setup can be seen in the following Figure:

I wrote a program that toggles the LED and outputs for each action a timestamp delivered by gettimeofday(). This allows me know the time of the LEDs actions relative to the PIs clock.

Capture-to-h264 latency

The latency between the image capture to a h264 image comprises capture and compress latency. Since this both happens hidden by raspivid, it cannot be divided easily. And this is the number we more or less “have to live with” until Broadcom opens up the GPU drivers.

I measured the latency using a modified version of raspivid. The compression engine packs the h264 data into NAL units. Think of them as h264 images that are prefixed by a header (0x00000001) and then written image after image to form the video stream. The modification I added to raspivid was that each NAL unit received a timestamp upon arrival. This timestamp was written right before the NAL header into the h264 stream.

I also wrote a program that was able to read my “timestamped” stream and convert it into single images that are attached with their corresponding timestamps.

For example, the LED toggling program gave me an output like this:

OFF 1441817299 404717
ON 1441817299 908483
OFF 1441817300 9102
ON 1441817300 509716
OFF 1441817300 610361
ON 1441817301 111039
OFF 1441817301 211695
ON 1441817301 717073
OFF 1441817301 817717
ON 1441817302 318342
OFF 1441817302 419034
ON 1441817302 919647
OFF 1441817303 20302
ON 1441817303 520965
OFF 1441817303 621692
ON 1441817304 122382
OFF 1441817304 223078
ON 1441817311 718719
OFF 1441817311 819685
ON 1441817312 320652
OFF 1441817312 421654

First column is the status of the LED, second column the seconds, third column the microseconds.

Where the first column represents the seconds and the second column represents the microseconds.

Since the LED was running at 2Hz and the camera at 48Hz I could directly relate the LED event to a specific video frame just by looking at the images (-> is the LED on or off?). This gave me two timestaps, the first of the LED event and the second of the capture of it.

The delay I got out of these was always in the range between 55ms and 75ms. The variation of 20ms makes sense since this is roughly our frame time. Depending on whether I captured the LED at the beginning (longer delay) or at the end of the exposure (shorter delay) the times vary.

Camera settings were: 48FPS, -g 24, -b 6000000, -profile high

Capture latency

I was wondering: Does the 55ms minimum latency come mostly from compression or from capturing? I looked through ways to capture directly and found some nice hack here: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=109137.
Here I did the same trick with the LED and was even a bit more lucky to capture this shot:

Notice that the LED is half-on half-off? This is due to the rolling shutter effect of the sensor. By accident I captured the LED right “in the middle” where it turned off. So the capture time of this shot is known to be exactly when the LED switched state (so here we do not have the 55-75ms jitter as in the case above). The delay between event and capture in this case was 38ms. Unfortunately, the camera runs in this hacky mode at 5Mpixel. So this is not exactly the 720p FPV scenario.

Compression latency

To validate my findings from above I also timestamped the hello_encode program included in Raspian. This gave me a compression latency of 10ms for a single 720p frame.

Conclusion

Although my different measurements are not completely comparable to each other I now have a rather clear view on the latencies:

One thing I did notice on my experiments with raspivid: It uses fwrite to output the h264 stream. Since this is usually buffered I noticed sometimes about 6KiB being stuck in the buffering. Now that size if far away from a whole frame size so it won’t cause one frame being stuck inside the pipeline. But nonetheless, it will probably cause a small delay.

Another thing I noticed is that the NALU header (0x00000001) is written by raspivid at the beginning of each new h264 frame. Since the decoder needs to wait until the next header to know the end of the frame, a latency of one frame is created (unnecessarily).
Maybe a variant of wifibroadcast that is directly integrated into raspivid would make sense. This could treat whole h264 frames as an atomic block, divide the frame into packages and transmit them. Right now the blocking is done at fixed intervals. This leads to the problem that additional data is stuck in the pipeline due to a partly filled block. I still need some time to think it over but there could be some potential here.

Introduction

Ever since the 90s I used my good old Graupner MC15 35MHz system. This worked always well, also with my first quadcopter “Mikrokopter”. But when I changed to my Naze32 system the RC started to become unreliable. This has led to at least three crashes which was quite annoying. Even with lots of ferrites and other filtering elements I could not get the system to work reliable anymore.

So it was time to look for alternatives. But… my video transmission based on wifibroadcast used 2.4Ghz technique. It is well known that 2.4GHz RC systems interfere with WIFI and and analog transmission.

One idea to overcome this issue was to trim the frequency of the TL-WN722N card below 2.4GHz. Here are the required changes to the kernel described. However, this approach has several disadvantages. First, the WIFI cards most likely do not have any calibration data if you leave the official channels. I tested my cards in my microwave oven and noticed a much higher packet loss rate. In fact is was so high that a wifibroadcast video transmission would not be possible. The second disadvantage is that this is illegal to use outside of a shielded cage. In summary: Not an option.

The second possibility would be to buy a 2.4GHz RC system and switch to 5GHz wifi equipment for wifibroadcast. The problem here is that I did not want to buy new wifi sticks. I developed everything for the TL-WN722N and I really like them. In the past I had to test a bunch of other cards until I found the TL-WN722N… Plus since they use 2.4GHz they offer a more robust transmission in case of obstacles. So again, not an option for me.

Mh, and now? There are DIY FrSky modules available. Refer to this nice project. This could have been used with an altered frequency scheme so that not the whole 2.4GHz band is used. But… RC is the most critical part of a quadcopter. And I am not really in the mood to do experiments on this part. It’s quite some work to get the RX and TX modules to run and then I don’t know anything about the reliability of the code or the range and quality of the TX modules… The answer is the same: Not an option.

But I liked the idea of using a 2.4GHz RC system that does not use the full spectrum. I looked around and found no systems that lets the user configure the spectrum. But what if we could modify a bought system in that respect? This is what this post is about.

How most 2.4GHz RC system are working

Most of the RC systems (Hott, Frsky, Hitec, …) use the TI CC2500 chip for the RF communication. The chip is used in a hopping scheme so that a narrow-band channel changes its frequency over the entire 2.4GHz spectrum at a high frequency (100 times per second in case of Hott). This is the trick why these RCs are so robust. Even if there are disturbances on some channels the chances are high that still packets on other channels come through.

The CC2500 is connected to a microcontroller via SPI and transmits or receives data under control of the microcontroller. This is the case for the transmitter as well as for the receiver.
If you take a look at the CC2500s data sheet then you’ll find that this chip has a channel register. This is what’s used to implement the frequency hopping. Both microcontrollers on TX and RX write the same channel sequence into this register so they hop “together” through the spectrum.
So all there is to do is to change the sequence they use and limit its values.

Ways to modify the channel register data

The most obvious way would be to change the software on the microcontroller in the RX and TX so that only a portion of channels is used. Unfortunately, firmware updates (in case of Hott) are encrypted. So one would need to find the encryption algorithm, possibly the key and need to reverse engineer the firmware. Things get even worse because you would have to do this twice, both for RX and TX. And again for every new firmware version. And again for other models. And again for other manufacturers. What a nightmare.

Another approach would be to alter the hardware. One would need to build a device that monitors the SPI communication between the microcontroller and CC2500 and modify the writes to the channel register. While this is a bit less elegant that a software-only solution it provides one major advantage: It works for all CC2500 based systems. Regardless of the firmware version, model, manufacturer… it always works. That’s why I’ve chosen to go down that road.

SPI injector

As said above, the SPI injector should watch for SPI writes to the channel register and overwrite its value. I’ve choosen to always set the MSB of the channel value to zero. This way the spectrum is always in the lower half of 2.4GHz.

I’ve chosen a CPLD to do the work. The reason is that it would be quite tough to get the timing right with just a microcontroller. The SPI bus runs at 4MHz so a microcontroller that just runs two or three times faster might not be able to change just a single bit at the right time.

This schematic explains nicely how the CPLD integrated into the system:

Here you can see that the CPLD listens on the SPI lines. However, the original connection of the MOSI signal has been cutted and is feeded through the CPLD. Whenever the channel register is written, the CPLD zeros the MOSI signal at the right time.

This is also visible in the waveforms:

The red arrow shows the position where the CPLD has overwritten one bit (DIN is original data, DOUT is modified data).

I modified a Graupner GR-12 receiver. You can see the connections on the PIC microcontroller here:

Here is a picture of the modified receiver:

If you want to apply this hack to a different receiver, you just need to follow the traces from the CC2500. Of course, you need to patch both the receiver and the transmitter (so that both agree on the channels they choose).

Checking if things work well

I needed a way to check if my changes did work and affected the spectrum. Luckily my TX (Graupner MZ-12) provides a view on which channels it received data.
Here you see the default (unmodified system) output where all channels are more or less available:

When I integrated the SPI injector only on the receiver side, half of the channels (the upper channels) should be deactivated. The reason for this that now the TX and RX disagree on the upper half of the channels. TX still uses the original hopping scheme while RX uses the modified scheme. The TX spectrum agrees

After both devices have been modified the spectrum looks ok again (because now both devices agree on the hopping scheme):

Notice the symmetry? This is because the upper half of the channels is now remapped by the CPLD to the lower half. So it is to be expected that the spectrum diagram tells more or less the same for both halves.

How to rebuild

First, you need to clone the repository:

hg clone https://bitbucket.org/befi/cc2500_rc_freq_mod

In the repository you find the sources as well as a testbench for simulation, an UCF file for defining the pinout and prebuilt images.

As a next step you need to flash a XC9536XL CPLD from Xilinx with the prebuilt files. There are many ways to do so. You could use the official Xilinx JTAG cable, a parallel port adapter, a bus pirate and many more. You find lots of information in this Hackaday howto.

The last step is to find out the traces on your TX and RX, cut the MOSI trace and wire up the CPLD. The pinout is described in the spi_mod.ucf file.

Conclusion

In this post I presented a cheap way to modify the spectrum of a RC system. One advantage is that only the channel scheme is modified. Since all other aspects of the RC system are untouched, you still have the good range and high reliability of the original system.
Most importantly, this modification works on all RC systems that use the CC2500 chip, irregardless of brand, model or firmware version.

Introduction

Early after I published wifibroadcast there were suggestions on improving the forward error correction (FEC) mechanism. While I agreed on these suggestions, my primary goal was to first create something that is usable to see if the idea behind wifibroadcast is worth following. After some months of testing and dozens of other people having also great experiences with wifibroadcast I was confident enough to start to “improve” things.

Initially I implemented a simple retransmission. Each packet got sent several times, increasing the chance that at least one packet got through. This worked sufficiently well but had some issues:

Bandwidth: The only parameter to increase the reliability was the retransmission rate. And this rate basically multiplied the net bandwidth. This is quite obvious: If you transmit each packet three times, you need three times the bandwidth.

Relieability: Although it seems unlikely that all N retransmissions of the same packet are lost that phenomenon existed. The explanation is quite simple: If you roll a dice often enough, the likelihood of some strange combinations happening needs to be considered. For example, if you roll a million times, you could expect to see the sequence “1”-“2”-“3”-“4” nearly a thousandth times. The same is true for wifibroadcast. We are sending a lot of packets so unlikely things can easily happen.

FEC method

Some commentators suggested to take a look at udpcast, a tool that is able to transfer data over a lossy unidirectional link. And well, that is exactly what wifibroadcast does! The FEC code there was well written and easy to adopt for my use case. In addition, the code is fast enough to run on a Raspberry PI A+. In the code Vandermonde matrices are used to perform the FEC.
The idea behind the code is very simple. Your data has to be divided into packets and a fixed number of them are grouped together to form a block. Lets assume we have a block size of 8 packets. The FEC code now allows you to calculate an arbitrary number of FEC packets (that have the same size as the DATA packets). Lets assume we use 4 FEC packets. If now a DATA packet gets lost, it can be replaced by any of the 4 FEC packets. So we might be able to repair up to 4 DATA packets, regardless which ones of the 8 are affected. This leads to two important advantages:

Bandwidth: Since we used in the example above 4 FEC packets per 8 DATA packets, the bandwidth requirements are +50%. This could not have been archived with retransmission. There the “smallest” bandwidth with redundancy would be +100%

Reliability: Since any DATA packet can be repair with any FEC packet, the chances of corruptions drop significantly. It is no more important which packets are corrupted, only how many.

Usage

The new FEC feature has been merged into the default branch of wifibroadcast (together with the new fifo interface introduced here)
To update (both on tx and rx!):

hg pull
hg update
make clean && make

The basic usage of wifibroadcast has not changed. Only some parameters have now a different meaning:

-b This parameter describes the number of DATA packets per block. So this parameter has more or less the same meaning as with the retransmission version

-r This parameter has changed from number of retransmissions to number of FEC packets. Each block will be appended with -r FEC packets.

-f Packet size. This parameter is identical to the retransmission version in that it defines the size of a packet. The only difference is that packets now cannot be smaller than -f.

It is also important to note that both tx and rx need to agree on -b, -r and -f. Otherwise the transmission does not work anymore.

How to set the parameters

The values of the parameters depend on your application. There are two things to consider: The coding rate and the block length. The coding rate is defined by the ratio between DATA and FEC packets. The block length is simply given by the -b parameter.

Changing the coding rate while keeping block size constant: Increasing the number of FEC packets increases the reliability of the link at the expense of higher bandwidth. A FEC ratio of 50% is roughly(!) comparable (in terms of reliability) to a retransmission rate of 2. If your block size is 8 DATA packets then this would result in 4 FEC packets.

Changing the block lengths while keeping the coding rate constant: An increased block length can increase the reliability of a link without increasing the bandwidth. However, this increases the latency since it needs to be waited until a full block of data has been received before the transmission can begin. Why does this increase reliability? Very often, blocks are only mildly corrupted so that not all FEC packets will be needed. However, these unused FEC packets are useless for the following block. By increasing the block size you are also increasing the “range” where the FECs can be applied.

Since with this new FEC feature the bandwidth requirements of wifibroadcast can be lowered quite significantly, new WIFI modulations are now usable. I’ve added a new patched firmware under patches/AR9271/firmware/htc_9271.fw.mcs1 that if being copied to /lib/firmware/htc_9271.fw (on tx) enables the MCS1 modulation. This gives you 13mbit/s air data rate of which roughly net 10mbit/s are usable. So this modulation would be perfect to use if you have a h264 data rate of 6mbit/s with a 8/4 coding rate (resulting in a 9mbit/s bandwidth requirement).

The lower modulation rate should give you a better range if you are flying at high distance or with massive occlusions.

Since the last flyaway of my quad having a telemetry link that transmits GPS coordinates was high on my wish-list. Wifibroadcast was prepared long time ago to transfer a second data stream in parallel to the video data by defining ports. But until now I did not make use of it. You can see a video of the OSD in action here:

This post describes how to set up the OSD display. Additionally, two changes required to wifibroadcast are described before the actual OSD stuff.

Setup

My quad uses a Naze32 flight controller that is able to provide FrSky telemetry data over a serial link. The serial port of the Naze32 is connected to a USB2SERIAL converter that is plugged into the tx Raspberry. The telemetry data is then transmitted using wifibroadcast over a second port in parallel to the video. On the receiving Raspberry the telemetry data is received, parsed and drawn onto the screen.

Wifibroadcast minimum packet length

Telemetry data is very different to video data in that it consists of very small packets. For example, most of the FrSky packets are only 5 bytes long. Using the default settings of tx this would lead to a single packet being sent for each small telemetry data unit. This of cause would create a high overhead since the ratio of payload to required header data is very low. To avoid this issue I added a command line parameter -m that can be used to define a minimum payload length. If given, tx waits until it has captured the minimum number of bytes and only then sends a packet.

Several tx instances in parallel

As said above wifibroadcast had the “port” feature for quite some time. The idea was to start several instances of tx, each with a different -p parameter. I used this method for my first telemetry experiments but noticed something odd: Whenever I started a second tx instance in parallel to the video tx process, the video tx was influenced. This was even the case when the second tx did not send any data at all. Quite strange. The result of this was that the video transmission was less fluid and stuttering a bit. Quite a high price for just a bit of telemetry data…

I basically had two options: Trace the cause of this issue in the kernel or adapt tx so that a single instance is able to send several data streams. I went for the latter one because I think it required less effort.
The route I went for was that tx got a new parameter -s that describes the number of parallel streams that shall be transmitted. If this parameter is omitted then tx behaves just like before, transmitting a single stream that is read from standard input. If however two or more streams are requested, tx changes the way it works. It then creates named FIFOs under /tmp. For example, if -s 2 is given, tx creates two named FIFOs called /tmp/fifo0 and /tmp/fifo1. Everything that gets written into fifo0 will be transported over the first port and everything written into fifo1 gets transported over the second port. Quite simple. The actual port number can be influenced by the -p parameter. It serves as an offset. Assuming that -p 100 is given, then fifo0 sends on port 100 and fifo1 on port 101.

The next section will show a usage example of this new mode that should make things clearer.

This feature is still not in the master branch since I had not yet the time to test it well. But after my first successful flight I will merge it into the master.

Putting things together

These commands assume that you have already installed wifibroadcast (as described here).

Transmitting side

First, change to the “tx_fifo_input” branch in wifibroadcast:

cd
cd wifibroadcast
hg pull
hg update tx_fifo_input
make

Next, start a tx instance in the background with a retransmission block size of 4, a minimum packet size of 64 bytes and two parallel streams:

Of cause, you can also save the telemetry data using the “tee” command.

In case you just want to test the OSD without the whole wifibroadcast stuff there is a FrSky telemetry log included in the repository:

./frsky_omx_osd . < testlog.frsky

Conclusion

The OSD works well for me. But be warned: Things are still a bit hacky around here. I wouldn’t guarantee that my FrSky protocol interpretations are always right. No wonder seeing how that protocol is designed. It is a perfect example of what happens if companies outsource their coding tasks to mental institutions
It should be easy though to replace the frsky.c parser with a different one (also for a different protocol). Volunteers are welcome