Prototype Arduino Code

Since there seem to be quite a few questions about the controller I thought I’d share some early code that went into the first prototype.

Important note: The code running in the first production versions has been completely rewritten. We will share that when those are shipping.

There are few main features I’m going to highlight:

  • Throttle Arming
  • Throttle Smoothing
  • Battery Voltage Display

Throttle Arming
One of the first safety features we worked on was making sure when turning on the unit there was no way the motors would instantly spin up.

Gas systems have attempted to tackle this issue with devices like Scouts safe-start module but they are slow to react and damage may already have been done after a few seconds.

The checkArmRange function is called on boot up and before the ESCs are initialized. (Most ESCs also have high throttle on boot protection built in as well). The function simply loops and checks roughly once a second to make sure the throttle/potentiometer is at zero (or within the margin of error)

Throttle Smoothing

As @Pdwhite talked about in his video throttle smoothing is important because of how responsive electric motors are compared to (one big) gas one. Also because we are reading the throttle position from a simple analog potentiometer noise interference is a small factor.

Luckily the hard part was already done and with the help of the ResponsiveAnalogRead library. I simply had to initialize it to read from the throttle input, tweak a few things, and it was ready to go.

Battery Voltage Display

This was a fun one. We wanted a simple way to tell how much “fuel” was left. Without going into too much detail the most accurate way to do this is to measure amperage flow but voltage gives the pilot a good idea.
Since the Arduino only accepts the max of 5.0V input a voltage divider was needed to step down the 50V batteries.

The handleBattery function takes care of converting everything between “empty” and “full” voltage reading to increments of 10% - since there are 10 LEDs. When the voltage gets down to 30% and 20% the lights change from green to yellow and red respectively.

Bonus
Check out the main loop function. This is what is run after everything is booted up. You’ll notice that it handles the throttle each time through but only checks the battery every once in a while. This is important because many simple embedded systems only run in one thread so they can only do one thing at a time. Reading the battery etc. is less important than controlling the throttle so that’s why it is done less often.
As you might guess reading and writing to multiple inputs and outputs in a time-sensitive manner gets pretty complicated. That’s where a real-time operating system comes (RTOS) in such as FreeRTOS

As stated before this code was primarily created for testing and getting a few prototypes off the ground and flying. You’re welcome to use it in your own builds but I were you I’d wait for the official production code to be released :slight_smile:
Let me know if you have any questions!

4 Likes

@zjwhitehead Thank you for sharing the code.
Can you upload other sources files like
Servo.h
FastLED.h
ResponsiveAnalogRead.h

I could not find the millis() function in the listing.

It looks like with RTOS-based systems it’s quite a challenge to develop responsive and reliable software. Slow chips, low memory, few threads, etc. But then, it is truly real-time, which is critical for airborne setups.

Has anyone looked into the idea of using a cheap single-board microcomputer. Those are available and cost less than $50. Will such option provide more flexibility in configuring and controlling the flight system?

Im very familiar with aviation grade software / compute setups. As the guy who will be strapped to this, it’s way easier to prove software reliability without an RTOS in the mix.

If someone wants more functionally (like wifi support or whatever) I’d strongly suggest that’s done with a second computer. It means that whole second computer can crash (like OSes do from time to time) and the micro controller running the flight computer keeps going.

As mentioned in the post ResponsiveAnalogRead.h is from library I linked.

Also Servo.h is part of the default Arduino suite (https://www.arduino.cc/en/Reference/Servo)

FastLED.h can be found on Github under the same name (GitHub - FastLED/FastLED: The FastLED library for colored LED animation on Arduino. Please direct questions/requests for help to the FastLED Reddit community: http://fastled.io/r We'd like to use github "issues" just for tracking library bugs / enhancements.) and is useful for managing SPI based LED strips etc.

All of these can be found and managed through the standard Arduino Library manager - guide


Also I agree that RTOS can complicate things a lot, especially for beginners without much programming experience. While it is fairly straightforward to get FreeRTOS running on standard Arduino boards (same power), adding fancier features is best handled on a separate and less mission critical system.

For the first kits we will be focusing on safety and reliability only. We’re already going to have many more features than current PPGs so I’m not worried about that.

Which micro are you running this code on? For a small embedded micro, it may help to avoid using types that are non processor native, and also other types that are processor time consuming.
As an example, it is unlikely that the micro has double as a native type (even if it has a FPU), and it is usually advisable to avoid float types unless you need them (processors lose optimisations on use of FPUs, and pretty much all processors rely on manual push/pop of FPU context for ISRs)
In the code, items like battery voltage are scaled into a float. This is okay, but the code would be a lot faster if you use a scaled integer (so 5.000 volts is 5000 as an unsigned short as a simple example). If you then go further to use a binary scaling, the compiler will use the micro’s ALU to use shifts instead of divides/multiplies.
Simple RTOS (a time based interrupt) are essential for safety critical systems to be able to watch for code that has got stuck.
I’m very happy to help if anyone needs advice, I have over 20 years experience of SIL3 code.
The starting point for all of these systems is a decent risk analysis (essentially, sit down and ask ‘what if’ for each failure). Again, as an example, what if the single throttle potentiometer goes open circuit in flight? You may decide ‘detection of out of range voltage’ is enough (If there is a pull up resistor at the micro), or you might decide that a sporadic value controlling 76kg of thrust is enough to warrant a twin track potentiometer (plausibility checks).
All the best with it, looks like a great project.

Is there anyway to implement redundant/backup throttle potentiometers or a way to quickly cutoff the system should the potentiometer malfunction (Ie getting stuck in the full throttle position or another dangerous position?).
Would it be better to have all of the esc’s on 1 PWM line or to have each opposite pair on there own PWM line (redundancy and more flexibility with advanced features.).
Also would it be a good idea to monitor the voltage of all (or more than one battery say 2 or 4, depending on the separated vs parallel battery wiring) of the batteries using an Arduino with more analogue inputs such as the Leonardo?
Looks really good and all.

There will definitely be multiple ways to quickly shut off the motors.
Currently it is:

  1. Hold the arm/disarm button on the throttle
  2. Reach down and turn off the main power switch