All posts by stewart@skyscratch.com

Using FrSky Telemetry with Naze32 and Cleanflight using softserial

I love the strong open source current in the RC community. Some of the best stuff comes out of it, and the power and economy of much of it is truly great.

That said, the documentation is often minimal if not cryptic, and chronically out of date. I also have a fondness for underdog platforms (in this case the 9XR Pro and Cleanflight). This combination has meant some things have taken me months to figure out. So: here is a recipe for FrSky telemetry with a Naze32 or Naze clone board running Cleanflight.

Recipe

A lot of the Naze32/Baseflight tutorials you’ll find out there will instruct you how to use the FrSky telemetry pins that are on the Naze32 board. There is a better way – softserial. The pins on the Naze32 board for FrSky telemetry are shared with the USB port, so you’ll only get telemetry once armed, and you can run into conflicts if you want to use an OSD as well as telemetry. There’s really no good reason to run the board this way – the pins predate the improved softserial code.

So, first, here’s how to wire a Naze32 board for softserial FrSky telemetry. Solder the green Rx pin from your FrSky telemetry-equiped receiver to pin 6 on the underside of your Naze32 board. Here’s what that looks like:

Diagram2

Diagram3

Now here’s how to do the same wiring on a Naze32 clone (such as Flip32, Dragonfly32, etc.):

Diagram4

Diagram5

These two examples look different, but they’ve accomplished the same thing – connect input pin 6 to the green FrSky telemetry receiver RX pin. All the other pins on the FrSky telemetry input on your receiver are optional. (In one case I wired in the ground, in another I did not. I did say I struggled with this for a while, remember?)

So that should cover the hardware end, for whatever board type you have.

Now here’s how to set up the software end in Cleanflight. Enter the following commands in the CLI:

feature telemetry
feature softserial
set telemetry_provider=0
set serial_port_3_scenario = 4
set serial_port_1_scenario = 5
set telemetry_provider=0
set telemetry_inversion=1
save

At this point, FrSky telemetry should be available to your radio.

A number of the above commands are exactly how you’ll find the defaults set, but it won’t take you long to enter them all anyhow.

Here’s the original documentation for the serial port modes above listed above: https://github.com/cleanflight/cleanflight/blob/master/docs/Serial.md. I honestly found it pretty confusing, but hopefully it will improve.

Next I hope to cover how to set up a 9XR Pro to receive this telemetry.

Rats Ate The Washing Machine -or- A Nagios NRPE Environmental Monitor for Netduino

Rats Will Eat Anything

A few years ago I made the mistake of storing food in my basement in a way that was less than safe from rodents. A small population boom in rats occurred before we understood what was happening. When we removed all access to the food in the dead of winter, we introduced a starvation whose panic we later read in the gnawed plastics on everything enclosing nourishment.

Rat-vs

All of this was bad. Rat poop and pee are nasty. But the worst thing was the desperate rats eating the rubber tubing and gaskets inside our washing machine. One frosty morning I came down to find soapy cold water hemorrhaging out of the washing machine and covering the floor of our basement. I suddenly understood why someone would want a flood monitor.

I started out with a nine-volt battery powered deal with an audible alarm.

IMG_5217

This is better than nothing, but it wasn’t going to be able to tell me about problems when I was out of town, or, for that matter, when I was at work. I wanted more. Specifically, I wanted it to plug into Nagios, which started out monitoring a few hard drives for me but has grown over the years into something a mid-sized business with its shit together might be using to monitor their network. Nagios had become the way I kept track of problems in the house. It already paged and emailed me, and it would keep metrics and historical data.

The first thing I did was look for a commercial product that did this — surely someone else needed the same thing. And, indeed, it has been done:

SensorMetrix_225Pound

As I type, that’s about $425 US, which still seems ridiculous to me, no matter how industrial and bullet proof the device surely is. I found another company doing this as well, but they charged a similar if not higher price for the same functionality.

Couldn’t I do all this with an Arduino? And the Internets of Stuff?

Why Netduino

I looked at Arduino, but a less popular alternative appealed to me: Netduino.

* I already use .NET for work. I don’t love Microsoft, but I’ve always had to admit that C# is a truly excellent environment.
* Threads, events, timers
And, probably best of all:
* In circuit debugging

I’ve done enough near-embedded programming to appreciate being able to step through code in a debugger or hit pause. I was willing to pay a bit more for this, and to tolerate some compromises in the environment to avoid Resharper withdrawl.

It also meant a lot to me that, although the board was $60 instead of ~$30 for an Arduino, it came with Ethernet built in and I wouldn’t have to futz around with a shield on day one. This looked like a kinder, gentler introduction to Arduino-esque work.

Porting NRPE to C# and the Micro Framework

As pleasant as C# usually is, it takes working in a smaller version of it to remind you how much is in the libraries, and not in the language proper. Working on the Micro framework is like working in a galley kitchen on a tiny sailboat when you are used to a decent home kitchen. Templates? Nope.  String formatting? Nope. Linq? Hah – that’s rich.

Fortunately, NRPE is a very simple format:

[2 Byte int16_t] – Version number
[2 Byte int16_t] – Type (Query/Response)
[4 Byte u_int32_t] – CRC32 Checksum
[2 Byte int16_t] – result code (OK, WARNING, ERROR, UNKNOWN)
[1024 Byte char] Buffer

Even so, I struggled with byte ordering and padding for a bit of time before figuring it out. The biggest problem was getting a compatible CRC working, and finally I ended up porting this code to C#. There was other code out there that might have worked, but nearly all other C# code makes good, healthy, virile use of templates and Linq and everything else you can’t have in 192kb of memory.

How Does It Work

You can have a look at the code yourself, but those without a Nagios installation might like a preview of how things work once you’ve installed things.

Here’s how to call the various checks manually. Here we are running check_nrpe (the client to our Netduino server) from Ubuntu:

# ./check_nrpe -n -H noah.doodle.local -c check_temp

OK - Temperature = 25.6C 78.1F Relative Humidity = 33.6% | temp_celsius=25.6000004;35;38;0;100, relative_humidity=33.6000023%;70;80;0;100, temp_fahrenheit=78.080000686645519;95;100.40000000000001;32;212
# ./check_nrpe -n -H noah.doodle.local -c check_flood

OK - No water detected | water_detected=0
# ./check_nrpe -n -H noah.doodle.local -c check_uptime

OK - Uptime: 03:42:51.2740000 Free memory: 101364 | uptime_in_seconds=13371, uptime_in_hours=3, uptime_in_minutes=222, free_memory=101364

These are the three services I’ve written so far. There are three main parts visible here:

  • OK

The result code. In this case the service is considered to be in a good condition.

  • Temperature = 25.6C 78.1F Relative Humidity = 33.6%

This is human-readable status text that will appear in Nagios.

  • temp_celsius=25.6000004;35;38;0;100, relative_humidity=33.6000023%;70;80;0;100, temp_fahrenheit=78.080000686645519;95;100.40000000000001;32;212 :

The values after the pipe is performance data which is all logged, and can be retrospectively graphed using various plug-ins.

So here’s how the service appears in Nagios. Here apparently the rats are back and have found their way past the metal plates I bolted onto the bottom of the washing machine, or perhaps our first floor toilet has overflowed and poured down a heating duct into the basement again (no rats to blame for that, unless my butt can be considered to be a sinking ship.) And something has gone wrong with the temperature sensor – maybe the leads have been eaten by the rats.

NagiosStatusSlice2

Here’s what the command line output would look for these two problem cases:

WARNING - Could not read temperature. |
CRITICAL - Water detected! | water_detected=1

Here’s a screenshot of what can be done with the performance data collected over time, from a time without emergencies or failures. We can see a steadily rising uptime, and a constant memory usage (no leaks apparently):

NagiosUptimeInMinutesAndFreeMemoyDemo

Some variation in the temperature, and a nearly constant humidity:

NagiosTempAndHumidityGraphDemo

Limitations

It’s important to note that the -n here is *essential*:

./check_nrpe -n -H noah.doodle.local -c check_uptime

This disables SSL for NRPE. There’s apparently no room in the Netduino for such a large library. If this is essential to you I suppose you could wrap it inside a VPN tunnel, etc.

Here’s what you’ll see if you try to call NRPE without SSL:

# ./check_nrpe -H noah.doodle.local -c check_flood
CHECK_NRPE: Socket timeout after 10 seconds.

There’s also some sanity checking in the code; if the Query Type is not recognized TinyNrpeServer will not be able to respond to the query and will not try. A debug message will give a hint about SSL if you are attached to the console.

Stability

If you look through the code, you may find it quite paranoid about errors and crashes, with two separate hard reboots in the code. This is because I tested the code fairly hard and I was striving to prevent the device from ever becoming unresponsive and needing a reboot.

The device now does a hard restart in two cases:

1) When it gets an exception

There are some exceptions I discovered that occur normally, such as socket disconnection errors, which can often be recovered from without resorting to rebooting the device. Unfortunately, not ALL of them seemed to be recoverable, or at least not consistently, and rather than distinguish, I chose to restart the device. Under normal operating conditions they are quite rare.

2) When it hasn’t received a query for a configurable time interval

In testing, I tested using very abusive conditions, but these conditions could easily get the Netduino into a state where not only would my code not hear incoming network connections (which could arguably perhaps be my fault), the device’s network stack would crash, and it would become unresponsive to ping, which I felt a whole lot less responsible for.

In my code I have this timeout configured like this:

/// <summary>
/// Number of milliseconds before the board will reboot itself.
/// </summary>
public const int InactivityTimeout = 60 * UpTimeCheck.SecondsPerMinute * UpTimeCheck.MillisecondsPerSecond;

In other words, if it hasn’t had an incoming message in an hour, it’ll reboot itself. If you need to fine-tune this interval, I would set this to at least twice your minimum check interval. So if you check the device every 5 minutes, set this to at least 10 minutes.

I chose to set this much higher so I can see via the uptime graph if this ever actually happens — a hour of downtime should be unambiguously visible.

In all fairness to the Netduino platform, I seriously doubt anyone will hang this server under a typical network load. A discrete poll from a single Nagios server every minute or two is not going to seriously tax anything. Perhaps once in a blue-moon a network exception will occur and the device will quietly reboot — if it does, you should see that reflected in the uptime performance data, but still enjoy essentially uninterrupted availability. I don’t expect anyone to actually make the device unresponsive, and activate the watchdog reset. But please tell me how it goes for you.

If I were to take this any farther, I would want a proper watchdog timer in hardware.

Expansion

I didn’t really NEED anything more than a flood monitor, but I thought I’d throw in at least one other metric to get the code ready to handle multiple checks, hence the temperature check.

Here’s the least you’d need to do to implement a check:

/// <summary>
 /// An example of the least you need to do to implement a check
 /// </summary>
 public class DemoCheck : NrpeCheck
 {
     public override NrpeMessage.NrpeResultState GetStatus(out string statusString, out Hashtable performanceData)
     {
        performanceData = new Hashtable();var demoMetric = 20;
        performanceData.Add("demo_metric", demoMetric);
        statusString = "Demo Metric: " + demoMetric.ToString();
        // Always Ok.
        return NrpeMessage.NrpeResultState.Ok;
     }
 }

You’d probably want some conditional code for the ResultState, and any metrics you have would probably vary. But adding any sort of monitoring should be easy, at least from TinyNrpeServer’s standpoint.

If you come up a sensor you’d like to add, send me an email with a patch or a pull request. I’d love this NRPE server have more monitoring to offer out-of-the-box.

Cost

So, if not $425, what did I spend? Probably less than $120. It would have been a lot cheaper if I knew what I was doing — this was my first Arduino-type project and the very basics were mysterious to me. I ended up trying a bunch of things that did not work before finding things that worked passably well.

Circuit

Noah V2

Installation

Initial test of flood monitor

Protoshield wired up

Flood Sensor final check

Sensor held in place with hair bands

Between the machines

It glows quite prominently in the gloom

Getting DHT-22 Wired up

DHT-22 in place

 

Installed into Project boxIMG_5271

Bibliography & Appreciation

For invaluable, indirect assistance with the core NRPE protocol, thanks especially to Andreas Marschke and Sadris. For the DhtSensor class, Stanislav “CW” Simicek and everyone on this thread. For cluing me in about Watchdogs and hard reboots, the people on these threads. Chris Walker for the Stopwatch class (and everything else in Netduino, of course).

The Code

https://github.com/StewLG/NetduinoNrpe