Esc-Protocol generation with a teensy 4.0 board

Hello everyone

I'm trying to build a swashlplatless helicopter, like the one by Youtuber Tom Stanton. One part to make the helicopter work is to adjust the speed of the motor several times (at least 10 times) per revolution.

In order to achieve this number of adjustments per revolution, I try to generate a sufficiently fast Esc protocol directly from the MCU (in my case a Teensy 4.0, as this can also calculate the throttel values quickly enough).

The only suitable library I could find was a dshot library (GitHub - jacqu/teensyshot: DSHOT communication with ESC using a teensy MCU), but I couldn't get it to work. Worse still, it confused my Teensy board so much that I could no longer reset or reuse it.

It wouldn't have to be dshot though, anything above about 1000Hz would probably do as well.

Now my question to you guys: Do you see a possibility how I could generate this signal? Writing my own library is out of the question for me, as this would exceed my capabilities. But maybe I have overlooked one? Or am I overlooking another type of a solution?

Tom Stanton worked with a Oneshot125 signal for his helicopter, but he didn't say in his video how he achieved this.

My components:

MCU: Teensy 4.0, Teensy® 4.0

Esc: DYS XSD 20A Mini ESC (oneshot125/42, multishot, Dshot300/600 capable), DYS XSD 20A 3-4S ESC BLHeli_S

Best regards

Simun

If you have ruled out writing a library, you've ruled out writing your own code, as there is nothing magic about a library that makes it any harder, really.

It's the algorithm and use of microprocessor features that makes writing such code a challenge.

Out of curiosity I googled

 teensy synthesize dshot

and see the library you haven't succeeded with, yet, and some other plausible looking hits. Have you poked around out there?

Does that library look like it is getting any attention lately? Perhaps someone has forked it and worked to keep it up to date.

Old or new I'm not sure how it would quasi-brick your teensy, so this is at the moment a head scratcher.

a7

Thanks a lot for your response!
I've seen the other dshot librarys, but I didn't mention them, because they either use an arduino uno or an arduino nano. Do you think it would be hard to rewrite them to use them with my teensy board? I have access to both arduinos, but I think they wouldn't be fast enough to do the throttle calculations at such a high frequency.
There were actually two people that forked the library, but they didn't change anything.

tl;dr: give up now :expressionless:

But first a question: how many channels of ESC signals do you need to synthesize? Do you also need to decode signals from a traditional flight control board, or from a receiver?

Can you draw a block diagram covering the distance from your sticks to your motors? I am curious about where and how the lifting, heavy or light, gets done.


I did some research but TBH got sidetracked srsly by trying to find out how a swashplateless hell can even work at all.

Then I looked at Tom Stanton, who I have seen before getting up to more fun than one person should be allowed to have, and bringing to it knowledge and intelligence and motivation and discipline I could only dream of possessing.

Spent the rest of the day trying to feel better about my miserable accomplishments.

Anyway, synthesis of dshot, or any of the higher speed analog ESC signaling methods, usually involves exploiting the f out of the processor.

This means using counters and timers, interrupts possibly and maybe even assembly language for the very fine timing. And DMA…

I saw evidence of this in both the teensy library and the UNO library.

Since the two processors are different at least in the details of how to work the peripherals (counters and timers) and speed, it means that translating from one to the other may be a misstep, where just starting over with the specifications would have been quicker. At least for someone with some intimate knowledge of the chip she was writing for.

If 1000 Hz update on a synthesized PWM waveform will do, it should be possible. But it will involve some hairy programming, some of which could be reversed out of example code, but really should come from the top down starting with the spec.

HTH

a7

1 Like

As I first want to develop the main drive before adding the tail rotor, I only need one channel of esc signals at the moment.
For the time being, I only want to determine the throttle values with three potentiometers (one for main throttle, one for pitch value and one for the roll value). So I will only have to use three AnalogRead pins for this (if you still want a diagram, you are of course welcome to tell me). I'll add the Fc and the rest afterwards because I have to plan my time well since this is a final project for school.

Yes, I certainly agree with what you said about Tom Stanton. Really a brilliant person. That's also why he was able to just write his own library to generate the oneshot125 signal.

Thanks also for pointing out that it is very difficult to rewrite the library for my MCU, so that I won't waste any more time on it.

Yes, I think a 1000Hz update rate will probably be enough. Could you maybe give me some hints (to which I can then inform myself on my own) on how to proceed to program the signals? For example, one question that immediately arises is how the Esc knows how to interpret the PWM signals, as these are not like a normal protocol for which the esc was made.

But before I start programming, I want to be sure that there is no 'simple' solution to generate this signal. Because I can hardly imagine that nobody has yet had to control a motor with a slightly higher frequency than a normal PWM signal and created a library for it. If you have time, could you make sure that I'm not just blind (I've spent several hours trying to find something myself)?

Your previous answers have certainly helped me so far. Many thanks again.

simun

ps: What do you mean by "should come from the top down starting with the spec"?

Well it isn't clear what I meant. Just start with the exact specifications for the signal you want to synthesize, and your intimate knowledge of the processor you are using to do it.

No borrowing or translating.

1000 Hz is 20x the typical cheap hobby servo refresh rate, that's enough to make some solutions for 50 Hz unworkable at 1000 Hz.

What ESC are you using? I think ESCs can auto-detect and get happy with, say Oneshot125, a very faster PWM signal.

I run BLHeli on ESCs, choose the protocol with the Betaflight Configurator and it requires no changes to the ESC firmware.

I just googled

Oscar Oneshot125

which will support my thinking, and introduce you to Oscar Liang, a very good source of information not buried the critical 20 seconds in the middle of a 17 minute video.

a7

2 Likes

Thank you. I'll try, although i think it is a bit difficult for me to write the actual code afterwards.

Okay, but I mean this is also just a regular protocol, while a 1000 Hz PWM wouldn't be one. But maybe it still wouldn't make any difference, because what probably counts is the duty cycle.
I'm using the following esc: DYS XSD 20A 3-4S ESC BLHeli_S

I have already read many articles of Oscar Liang. Indeed often very helpful.

best
simun

What is critical in the analog protocols is the pulse width.

A bit of reading and I find

  • Oneshot125 (pulse width 125-250 μs, maximum frequency 4 kHz);

So what would be easy to do (or to say is not possible) is to use the microprocessor timer/counter hoping for good control over a pulse of width 125 to 250 microseconds happening at least 1000 times a second.

The 4 kHz upper limit is where such pulses would start overlapping.

I think this would be like cutting butter with a blowtorch on the teensy, and I think probably within the reach of a slower processor board.

I have some bookmarks all over these fora and the internet by now, I am perhaps imagining it but I think I see bright light at the end of the tunnel.

First though I see Nick Gammkn has a counter/timer article, I can get motivated to read that as if I know what he's talking about. :expressionless:

What do you think the resolution of the pulse width should be? I suppose the higher the better, and the fewer places that limit resolution in the entire command chain, the better.

If you are playing with combining three analog signals at 10 bit resolution, it seems like achieving that granularity in the synthesized ESC pulses would be something to aim for.

a7

What is critical in the higher speed analog protocols is the pulse width.

A bit of reading and I find

  • Oneshot125 (pulse width 125-250 μs, maximum frequency 4 kHz);

So what would be easy to do, or to say is not possible, is to use the microprocessor timer/counter hoping for good control over a pulse of width 125 to 250 microseconds happening at least 1000 times a second.

The 4 kHz upper limit is where such pulses would start overlapping.

I think this would be like cutting butter with a blowtorch in the teensy, and I think probably within the reach of a slower processor board.

Forgot to send this, meanwhile this shows up:

which is doing Oneshot125 at 3000 Hz, using delay() for the frequency and cleverness for the pulse.

Gotta love having a 72 MHz clock. The teensy 4.0 at 600 MHz looks like you could almost do the synthesis with relatively high level literal and naive code…

I have a teensy of some ilk around here, I haven't used it so far as I am mostly stuck in the 5 volt world, and most of the significant stuff I ever did was on relatively slow processors with tiny amounts of memory, so I've not been overly ambitious.

a7

Hello
I'm really sorry that it took so long to answer, but I had a lot going on this weekend.

Okay I will try that. I hope that it isn't too hard.

Before I start I have one last question:
Is there a place where things related to "how to produce an analogue signal for an esc-protocol" are explaind? Because I have to acquire a lot of knowledge, for example about timers and so on. Unfortunately I haven't found anything myself.

simun

I don't make any sense of that. The signal from the flight controller, or the Arduino, is digital.

If it is a traditional servo signal, it is a digital pulse of varying width arriving at a certain frequency.

If it is DShot type so-called digital, it is a pulse train following a protocol meant to end up delivering bits which end up representing numbers in the ESC.

a7

i don't know why they are named that way, but i think all esc signals except dshot and proshot are called analogue signals.

The most commonly used protocols include Oneshot125, Oneshot42, Multishot, and Dshot300, Dshot600 and Dshot1200. The Oneshot and Multishot protocols use analog signals like PWM, whereas Dshot (Digital shot) uses a digital signal.

source: What is an Electronic Speed Controller & How Does an ESC Work - Tyto Robotics

Yes, but not properly. It just points up the fact that a pulse is synthesized by the controller, and then measured by the ESC.

So theoretically an "analog" pulse has infinite resolution, you can make it say 1250.0001 or 1249.9999 microseconds long. So it could be thought of as analogous to something like stick angle on a throttle controller.

Practically, since they are synthesized by processes running on a microprocessor and measured n
by ESC firmware, there is no infinite resolution.

In any case, both signals when examined will either be logically high or low, or making the extremely rapid transition between those.

a7

Hello

Agreed, thanks.

Were you able to find anything?
If you didn't have time or didn't feel like searching, that's fine of course. I just wanted to make sure that you hadn't forgotten the question :slight_smile:

best regards
simon

The signal itself is simply the digital output given by writing a 1 or 0 to a bit on a port configured as an output.

The easy but somewhat slower way is with pinMode() in setup() and digitalWrite() anywhere as appropriate and needed. When precision and/or speed is an issue, "direct port manipulation" can be used, it's very simple to do and googling

 arduino direct port manipulation 

will turn up many ppl 'splaining it. You'll get a bit of a peek at the way microprocessors do it, stuff hidden nicely by pinMode and digitalWrite.

On a fast processor, you can literally generate the signal with digital writing and delay() and delayMicroseconds(). Same same as naive Arduino LED blinking.

For "real" synthesis that would be a challenge to program directly, or impossible, you needa use the timer/counters.

Nick Gammon is another name worth knowing if you haven't come across his stuff.

Nick Gammkn on timer/counters

I tell ppl to read this carefully pretending you know what he's talking about. Put you finger on the code and trace through his examples. Work them IRL or with the wokwi simulator.

I don't think he'll exactly serve up Oneshot125, but it will give you an idea of the power and flexibility that is there to exploit, and maybe either totally convince you to give up (don't) or get something working well enough to come and ask for help.

As I may have said, I was fully up to speed on timer/counters some years ago - never mind how long precisely - but that was for a different processor family. There are only a handful of things that counter/timers can do, so knowing one is a huge head start to learning another. Nothing has risen to a level where I am motivated to thoroughly learn the AVR's, although I have bluffed my way through to success on some relatively simple uses.

a7

1 Like

I had to stare at the Oscar Liang's diagram for a while before I understood what it was trying to say--Using OneShot(whatever) versus PWM makes sure that the adjustments to the PWM happen only once per pulse, (hence "oneshot") as compared to doing PWM with something like analogWrite(...) where the analogWrite() adjustments could happen out of sync with the timer's clock, potentially repeat or delay a pulse because of double-buffering OCRxn. The diagram is showing the normal 488Hz analogWrite()'s PWM setting an Uno's TCNT=0, and doing an extra cycle because OCRnx is double-buffered. (The diagram also looks a bit wrong in that in the top frame, the "S2" duty is longer than the bottom frame's "S2" duty)

Then the OneShot versus OneShot125 (versus Oneshot43) protocols set limits on cycle-widths so the ESC can determine which scheme is being used based on one pulse width--if you get a pulse width dT=1000-2000us long, interpret as a call for "duty" (dT-1000)/1000, dT=125-250us, as (dT-125)/125 duty, and dT=43-90us as (dT-43)/43 duty.

But besides going too deep into the weeds, the new thing I learned is that a free-running timer-based PWM can cause a timer-cycle's worth of delay in acting on a control loop's recalculation, while the OneShot schemes deliver a one-shot pulse ASAP each time through the control loop.

Thanks.

Thank you. That's a good "take away" summary of ESC "PWM".

I wish there were a different name for

good old PWM

where 0 to 100 percnet implies a pulse duty cycle that ultimately consumes the entire period at the frequency and

ESC/servo PWM

where 0 rom100 relates to the pulse width, but the pulse comes along when it does, regularly we hope, and 100 may come nowhere near to existing during the entirety of the gap between pulses.

An analog (WRT control electronics) servo is relatively slow compared to the pulse delivery rate, so you gotta keep them coming.

An ESC with modern firmware can literally respond to (and start heading towards obeying) a single pulse.

Dunno for sure they do, as a noise pulse might be rejected, but at worst a few good thin pulses should make the control program happy to head towards zero, for example.

Between the sticks and the props on these little aircraft is a crap-ton of amazing engineering, between the IMU (thank you, iPhone, for making those affordable), neodymium magnets, 2.4 GHz transception and of course quite a number of processors running a huge amount of code. At rates of OMG.

It all amounts to being basically impossible, and I didn't even mention the 5.8 GHz video link, OLED screens &c.

A great time to be alive.

a7

I did peek a bit at the VESC project and GitHub - vedderb/bldc: The VESC motor control firmware enough to see that in the various modes, the ESC can anticipate when the next pulse may arrive and do whatever else it would do. With "good old PWM" at 0% or 100%, the ESC wouldn't get any synchronization data.

It is interesting how much is indistinguishable from magic.

I will do some more research and then try to write a first attempt with the tips, but it will probably take me quite a long time.
Thank you for all your help!

simun

2 Likes

Here's a simple library that works with Teensy and the OneShot125 protocol: GitHub - simondlevy/TeensyOneShot125: Simple Teensy library for running brushless-motor ESCs with OneShot125 protocol