New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSHOT600 & 150 -> digital one shot motor (ESC) protocol #1282

Merged
merged 6 commits into from Oct 18, 2016

Conversation

@blckmn
Copy link
Member

blckmn commented Oct 8, 2016

A very first untested cut only for discussion - it is only tested for compilation - not on actual hardware yet. The idea was floated by Felix and also independently discussed previously within the betaflight contributors group. It is very similar to WS2812 LED strip communications. Credit goes to Felix.

updated for the DSHOT protocol. see below.

@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 8, 2016

image

Bit length is 1.67us using 40 timer ticks (24mhz).

For a bit to be 0: 625ns HI (T0H - 15 timer ticks)
For a bit to be 1: 1250ns HI (T1H - 30 timer ticks)

The bit content is 11 bits throttle, 1 bit for telemetry request (separate return channel), and a 4 bit pseudo checksum (the 4 most significant bits of the throttle repeated). Most significant bits first.

New frame (reset) 1-2us LO (at least 1 complete bit length).

DSHOT600 (600khz) and DSHOT150 (150khz) both exist. DSHOT150 is merely slowed version of the protocol where the timer tick count is the same, but the timer is running at 6mhz.

@digitalentity

This comment has been minimized.

Copy link
Contributor

digitalentity commented Oct 8, 2016

Do we have ESCs supporting this protocol?

@DieHertz

This comment has been minimized.

Copy link
Member

DieHertz commented Oct 8, 2016

@digitalentity No, but the general idea can probably be implemented in a BLHeli fork as a proof-of-concept.

src/main/drivers/pwm_output_digital.c Outdated
void pwmWriteDigital(uint8_t index, uint16_t value)
{
uint16_t outputValue = value - 1000;
motorDmaOutput_t motor = dmaMotors[index];

This comment has been minimized.

@ledvinap

ledvinap Oct 8, 2016

Contributor

this will copy whole structure.

@digitalentity

This comment has been minimized.

Copy link
Contributor

digitalentity commented Oct 8, 2016

Digital is amazing and also slightly less critical to signal line characteristics.

src/main/drivers/pwm_output_digital.c Outdated
{
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
motorDmaOutput_t motor = dmaMotors[descriptor->userParam];
motor.transferInProgress = 0;

This comment has been minimized.

@DieHertz

DieHertz Oct 8, 2016

Member

Looks like a dead assignment, the comment from @ledvinap also applies.

This comment has been minimized.

@blckmn

blckmn Oct 8, 2016

Member

fixed this one up - needs to move to some form of double buffering or the like to handle motor updates whilst a transfer is in progress

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 8, 2016

IMO this will be problematic. ESC is good at measuring time, but processing 1/M edges/s will be problematic. It would be necessary to reimplement ESC receiver code.

It may be better to use modulation that will encode multiple bits per edge/pulse. Existing infrastructure may be used, edge frequency and spacing will stay reasonable.

For example:
Encoding 5 bits (32 levels), 2us resolution + 48us base (48 - 112 us) will get ~ 50 bits/ms, 3-4 10bit updates with synchronization and checksum per ms.

Bidirectional communication may be possible - using some slots for reply.

@digitalentity

This comment has been minimized.

Copy link
Contributor

digitalentity commented Oct 8, 2016

Multiple bits per pulse is less tolerant to noise and line quality (inductance/capacitance). ESCs with hardware receiving timer (BLHeli_S) should be capable of processing 1Mbis/s stream. Still, 2 or 3 bits per pulse should be possible.

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 8, 2016

The concept has been tested and it works even more reliable than the current pwm pulses.

Though it only has been tested on stm32 as esc chip

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 8, 2016

This is just a draft to check possibilities.

This is a full working protocol with even checksum in there!
https://youtu.be/TSYQSw_zMCE

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 8, 2016

@ledvinap
This is just a concept. The actual protocol will be robust and not necessary 1mhz as thats total overkill.
You can gain much higher resolution on lower speeds which are still much higher and more accurate than current oneshot stuff

@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 8, 2016

Agreed, this code was only bashed out for discussion. I'll play with it on real hardware tomorrow. I'm sure there are a lot of updates and improvements to be had.

@Linjieqiang

This comment has been minimized.

Copy link
Contributor

Linjieqiang commented Oct 8, 2016

What esc will be supported this great idea?

@deepimpact

This comment has been minimized.

Copy link

deepimpact commented Oct 8, 2016

Here is Felix testing in recent video https://youtu.be/TSYQSw_zMCE

On Oct 8, 2016 7:17 AM, "LinJieqiang" notifications@github.com wrote:

What esc will be supported this great idea?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#1282 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ANUohABdB8g3MeU23oMMVlsfYUctl4bKks5qx4negaJpZM4KRod_
.

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 8, 2016

@deepimpactio
Its the same video I posted above ;)

Its actually his idea to do this from DMA after somr discussions. That only makes it possible to get this speed and accuracy when you go digital.

@deepimpact

This comment has been minimized.

Copy link

deepimpact commented Oct 8, 2016

@borisbstyle sorry I missed that ;)

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 8, 2016

Digital is great idea, I would love to see it done.
My objection is about wire format:

  • pulse length transfer is implemented on both sizes, so use it as much as possible.
  • 2 edges per bit is IMO far too wasteful.
  • It should be possible to have interrupt only implementation on FC side.
@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 8, 2016

@ledvinap can you draw up your preferred wire format (perhaps something like the sequencing image I found and posted). Love to be able to visualise your ideas.

@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 8, 2016

Yes it was a first hack, interrupt driven transfer of motor value from variable to dma buffer, and subsequent enabling of dma transfer should be easy to add in.

One of the things about digital is there's no disarmed pulse needed. Disarmed the FC can simply send a 0 value for a motor, and the ESC can immediately detect bit length and understand resolution. No calibration required.

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 8, 2016

@blckmn : I have nothing concrete, but I was considering the problem some time ago.

It would be interesting to do some measurements to see how pulses are deformed.

Some random thoughts:

  • reasonable number of bits should be sent per edge/interrupt
  • minimum interrupt spacing should be guaranteed, so there is time to finish ISR handler before next edge arrives (important for ESC decoding, HW capture is not always available and will only help with single edge)
  • rising and falling edges are deformed differently. Using constant length pulse of one polarity and long enough data pulses (to fully charge all capacities) will help (optocoupler in ESC input will make it much worse)
  • it is probably not worth using both rising and falling edge - it will complicate SW and the gain will be small (+ above)
  • some mechanism to synchronize ESC clock is necessary(for multi-bit encodings). It will also help with edge arrival deformation.
    • AVR RC oscillator tolerance is quite poor/it may be calibrated from sync pulses
    • frame sync may be combined with time sync - for example short pulse
  • checksum is necessary; it should be designed to detect pulse length error
  • channel from ESC to FC would be great
    • single wire
    • protocol should allow it at least theoretically (no nasty hacks in future)
    • asymmetric speed - throttle update needs bigger bandwidth than telemetry
    • can be implemented later

(to be continued)

@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 8, 2016

@ledvinap hadn't really thought about it for low spec MCUs on ESCs - was thinking for the STM based ESCs.

@Linjieqiang

This comment has been minimized.

Copy link
Contributor

Linjieqiang commented Oct 9, 2016

"ESC32 "(http://autoquad.org/esc32/) is a great hardware and open source project for reference.I suggest we can use standard C language to rewrite it or open a new esc project.

  • digital motor protocol.Also support current traditional PWM input protocol
  • channel from ESC to FC would be great.I can't agree more.

Looking forward to see your test video.This will be a great development.

@ronlix

This comment has been minimized.

Copy link
Contributor

ronlix commented Oct 9, 2016

Hi,

the protocol we have working ATM (the one thats also on that video) includes 16-bit. one bit is 1,67µS (i use 40 24Mhz tics)
a one has a PWM value of 1.25µS (30 24Mhz tics) a zero 0.625µS (15 24Mhz tics). so 600k baud :)

i do no start or stop bit.. i simply look for a low period longer then one bit length to get in sync.

i sent first 11 bit throttle signal, one bit telemetry request and 4 bit CRC which is the 4 highest bits of the throttle signal repeated. i send the MSB first.

for stm32 mcu's its very easy to read as they can use the dma for it. for mcu's without dma it might be more complex, but i thought there you can first use the rising edge, and then read as much falling edges as you like.. as the MSB is sent first, its no problem reading just f.e. 8 bit of it.

using PWM for one bit instead of just edges has two advantages.. first it is very easy to sent with the stm32's timer DMA and second, oscillator drift really dont matters as every bit has its own start and end edge.

we are still testing and looking for a sensfull usage of the bitcount and the speed.. so im open for ideas :)

BTW. quadmovr flying it (we called it Dshot): https://m.youtube.com/watch?v=ggwHzueVRag

regards

Felix

@blckmn blckmn force-pushed the blckmn:digital_motors branch Oct 9, 2016

@blckmn

This comment has been minimized.

Copy link
Member

blckmn commented Oct 9, 2016

Thanks @ronlix - have updated to take into account your protocol.

Tested on a scope - however it is tied to PID loop for updates. Not sure if the timing is absolutely correct - but you can see the bits move in the motors tab ok :)

@ronlix

This comment has been minimized.

Copy link
Contributor

ronlix commented Oct 9, 2016

cool :) if you like, and have a kiss24A to test, you can download my test FW here http://ultraesc.de/KISS24A_Dshot.zip
you will need to flash it onto the bootloader (kiss ESC fw 1.02 or later) with the kiss GUI or my little stand alone crome app (http://ultraesc.de/KISSESC_flashloader.zip)

please be carefull when using it, its not much tested!

regards

Felix

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 9, 2016

Hmm ... for stm32 based ESC, using CANbus is probably far superior ...

@blckmn blckmn changed the title Digital motor protocol D-Shot => digital one shot motor (ESC) protocol Oct 9, 2016

@rav-rav

This comment has been minimized.

Copy link
Contributor

rav-rav commented Oct 17, 2016

Data does not need to be throttle signal. There might be other information that could be useful to communicate to the ESC or request different responses like RPM, temperature, settings.

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 17, 2016

There are IMO two possibilities for extra data:

  • use command type to differentiate between throttle signal and other commands
    • command 11 bits for command + data may be a bit small
      • allow longer packets
      • split command into multiple packets
    • longer packet may cause noticeable delay before throttle update
  • implement 'side channel' for other data.
    • for example 4 bits per packet, sent together with throttle update
    • collect data until packet is complete

Similar problem will be with returning data from ESC - throttle update shall not be starved too much

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 17, 2016

@rav-rav
What temperature does the ESC needs to know from FC?
There is 1 bit for telemetry request where ESC can send data back to the FC. Thats a different data stream and not same. There you have no throttle signal and freedom to send whatever you want with any speed.

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 17, 2016

@ledvinap Yes thats the best idea indeed. There should be a "prefix" value what describes the sent value.

@ledvinap

This comment has been minimized.

Copy link
Contributor

ledvinap commented Oct 17, 2016

Limiting checksum to 2 bits will probably lead to real-world situations where incorrect packet is accepted (2 consecutive bits set to zero etc.). IMO 4 bits is minimum if you want to trust received data

@rav-rav

This comment has been minimized.

Copy link
Contributor

rav-rav commented Oct 17, 2016

I meant to request temperature from ESC, not send temperature to it. But you are right, all data from ESC could be send to the FC combined in one packet.

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 17, 2016

Anyway I think this should be kept as it is for now as there is nothing else to tell to the ESC for now. Don't forget that the ESC has to support all this! Let's keep it simple as it is and reliable for now. Once this step is achived and more ESC come up in the market what support this the other things can be discussed.

The KISS24 esc does return a telemetry data with rpm's, temperature and amperage consumption and current value. It does it through seperate wire connected to the UART RX. The FC can read the data from ESC's 1 by 1 . All escs can be connected to the same UART
Someone already did a draft implementation for receiving packet here
https://github.com/basdelfos/betaflight/tree/esc_telemetry

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 17, 2016

@rav-rav You get the full 32bit packet with all stuff within a telemetry request as described in my previous post

@kc10kevin

This comment has been minimized.

Copy link
Contributor

kc10kevin commented Oct 17, 2016

@blckmn - See PR on you digital_motors branch for the Fury DShot implementation. Thanks.

@blckmn blckmn force-pushed the blckmn:digital_motors branch Oct 17, 2016

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 17, 2016

Have been testing and was still not able to produce a single CRC error in KISS ESC

Temperature [C]:       35
Voltage [V/100]:     1588
Ampere [A/100]:         2
CRC Fails:              0
Sync Fails :           16
Auto bitrate [k]:       0
Throttle [%]:          23
Startuptime [ms]:      85

@blckmn blckmn force-pushed the blckmn:digital_motors branch 2 times, most recently Oct 18, 2016

@blckmn blckmn force-pushed the blckmn:digital_motors branch to 9f742b0 Oct 18, 2016

@basdelfos

This comment has been minimized.

Copy link
Contributor

basdelfos commented Oct 18, 2016

The KISS24 esc does return a telemetry data with rpm's, temperature and amperage consumption and current value. It does it through seperate wire connected to the UART RX. The FC can read the data from ESC's 1 by 1 . All escs can be connected to the same UART
Someone already did a draft implementation for receiving packet here
https://github.com/basdelfos/betaflight/tree/esc_telemetry

Decided with Boris to implement ESC Telemetry into the Dshot implementation. Dshot makes it easier to implement the ESC Telemetry request, because it is only one bit to set and Dshot does not require different approaches for synced/unsyced motor update.

New ESC Telemetry draft implementation with Dshot: https://github.com/basdelfos/betaflight/tree/esc_telemetry_dshot

Old PWM implementation will not be developed anymore

@borisbstyle

This comment has been minimized.

Copy link
Contributor

borisbstyle commented Oct 18, 2016

Let's merge this one. We can add other targets seperately

@borisbstyle borisbstyle merged commit f698f99 into betaflight:development Oct 18, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@AndersHoglund

This comment has been minimized.

Copy link
Contributor

AndersHoglund commented Oct 19, 2016

I think it would be wise to reserve a few more bits for commands or prefix. Now there is only one, telemetry request. I can directly see a few anothers, signed/unsigned throttle value. Or in practice rather "3D" mode. Refering to the discussion on #1350 .

Another important usage would be for protocol version negotiation. FC protocol version sent to ESC should also be regarded as a version request, ESC returning its protocol version via telemerty back channel.

Maybe to current "Telemetry request" bit rather should be a "Command bit" and the following 11 bit values should be the actual command. Cmd 0 : Version , 1: Telemetry req , 2: 3D mode (signed values) , 3; 2D mode (unsigned values), etc etc .

By having no room at all, it will be very hard for any future expansion. Closing the door already from the start would not be too wise.

@ronlix

This comment has been minimized.

Copy link
Contributor

ronlix commented Oct 19, 2016

@AndersHoglund we have the throttle values of 1-47 reserved for settings. with it we can set or request a lot of things.. the telemetry is different as it gets requested as long as the motor runs..

@peabody124 peabody124 referenced this pull request Nov 12, 2016

Open

DShot support #2253

@blckmn blckmn deleted the blckmn:digital_motors branch Jan 1, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment