BLDC(9)
π BLDC(9) β HAL Component π
okay so bestie, this is the manual for the bldc component, and it's giving main character energy. let's get into it, no cap.
β¨ NAME β¨
bldc β BLDC and AC-servo control component. periodt.
πΈ SYNOPSIS πΈ
loadrt bldc cfg=qi6,aH
π¦ DESCRIPTION π¦
so this component is designed as an interface between the most common forms of three-phase motor feedback devices and the corresponding types of drive. but here's the tea: there is no requirement that the motor and drive should necessarily be of inherently compatible types. fr fr, you can mix and match.
each instance of the component is defined by a group of letters describing the input and output types. a comma separates individual instances of the component. for example loadrt bldc cfg=qi6,aH. yep, that's the vibe.
π·οΈ Tags π·οΈ
input type definitions are all lower-case, bestie. let's break them down:
nβ No motor feedback. this mode could be used to drive AC induction motors, but is also potentially useful for creating free-running motor simulators for drive testing. it's giving "simulation slay".hβ Hall sensor input. Brushless DC motors (electronically commutated permanent magnet 3-phase motors) typically use a set of three Hall sensors to measure the angular position of the rotor. a lower-casehin thecfgstring indicates that these should be used. so if you see anh, that's what's up.aβ Absolute encoder input. (Also possibly used by some forms of Resolver conversion hardware). the presence of this tag over-rides all other inputs. note that the component still requires to be be connected to therawcountsencoder pin to prevent loss of commutation on index-reset. do not skip that, bestie, it's important. (and yes, the original says "be be", we're keeping that energy.)qβ Incremental (quadrature) encoder input. if this input is used then the rotor will need to be homed before the motor can be run. so don't forget to home it, okay?iβ Use the index of an incremental encoder as a home reference. it's the little reference point that could.fβ Use a 4-bit Gray-scale patttern to determine rotor alignment. this scheme is only used on the Fanuc "Red Cap" motors. this mode could be used to control one of these motors using a non-Fanuc drive. (yes, "patttern" β we don't make the rules, we just report them.)
output type descriptions are all upper-case. and here's the defaults tea:
Defaults β The component will always calculate rotor angle, phase angle and the absolute value of the input value for interfacing with drives such as the Mesa 8I20. It will also default to three individual, bipolar phase output values if no other output type modifiers are used. so that's the baseline, bestie.
now the output modifiers:
Bβ Bit level outputs. Either 3 or 6 logic-level outputs indicating which high or low gate drivers on an external drive should be used. it's giving "gatekeeping, but literally".6β Create 6 rather than the default 3 outputs. In the case of numeric value outputs these are separate positive and negative drive amplitudes. Both have positive magnitude. double the outputs, double the fun.Hβ Emulated Hall sensor output. This mode can be used to control a drive which expects 3x Hall signals, or to convert between a motor with one hall pattern and a drive which expects a different one. it's the translator of the motor world.Fβ Emulated Fanuc Red Cap Gray-code encoder output. This mode might be used to drive a non-Fanuc motor using a Fanuc drive intended for the "Red-Cap" motors. cross-compatibility? we love to see it.Tβ Force Trapezoidal mode. sometimes you just gotta force it, iykyk.
π₯ OPERATING MODES π₯
the component can control a drive in either Trapezoidal or Sinusoidal mode, but will always default to sinusoidal if the input and output modes allow it. this can be over-ridden by the T tag. Sinusoidal commutation is significantly smoother (trapezoidal commutation induces 13% torque ripple). so like, sinusoidal is the smooth operator, and trapezoidal has that 13% torque ripple. choose wisely.
π ROTOR HOMING. π
to use an encoder for commutation a reference 0-degrees point must be found. the component uses the convention that motor zero is the point that an unloaded motor aligns to with a positive voltage on the A (or U) terminal and the B & C (or V and W) terminals connected together and to -ve voltage. there will be two such positions on a 4-pole motor, 3 on a 6-pole and so on. they are all functionally equivalent as far as driving the motor is concerned. so don't stress about which one, bestie.
if the motor has Hall sensors then the motor can be started in trapezoidal commutation mode, and will switch to sinusoidal commutation when an alignment is found. if the mode is qh then the first Hall state-transition will be used. if the mode is qhi then the encoder index will be used. this gives a more accurate homing position if the distance in encoder counts between motor zero and encoder index is known. to force homing to the Hall edges instead simply omit the i. so qh vs qhi is the vibe check here.
motors without Hall sensors may be homed in synchronous/direct mode. the better of these options is to home to the encoder zero using the iq config parameter. when the init pin goes high the motor will rotate (in a direction determined by the rev pin) until the encoder indicates an index-latch (the servo thread runs too slowly to rely on detecting an encoder index directly). if there is no encoder index or its location relative to motor zero can not be found, then an alternative is to use magnetic homing using the q config. in this mode the motor will go through an alignment sequence ending at motor zero when the init pin goes high It will then set the final position as motor zero. unfortunately the motor is rather springy in this mode and so alignment is likely to be fairly sensitive to load. so like, it's a little extra, but it works.
π FUNCTIONS π
bldc.N (requires a floating-point thread)
bestie this is only part 1, part 2 is coming π
π PINS π
okay bestie, strap in, because this is the whole pin list and honestly it's giving encyclopedia energy π but we do NOT skip pins in this house, every single one is getting its moment, periodt. β¨
π¨ heads up before you plug ANYTHING in: a whole bunch of these pins only exist if the personality bitmask test in the brackets passes. If the [if ...] thing is false, that pin literally does not exist β not quiet, not hidden, just gone. Read the bracket first, wire second. iykyk π
bldc.N.hall1βbit in[if personality & 0x01]β Hall sensor signal 1 π (that's the first one, bestie)bldc.N.hall2βbit in[if personality & 0x01]β Hall sensor signal 2 πbldc.N.hall3βbit in[if personality & 0x01]β Hall sensor signal 3 πbldc.N.hall-errorβbit out[if personality & 0x01]β screaming (politely) that the hall pattern you picked is giving inconsistent rotor position data π this can happen because the pattern is just wrong for that motor, or because one or more of the sensors is unconnected / broken. and here's the tea: a consistent pattern isn't necessarily a valid one, but an inconsistent one can never be valid. so like, consistency is necessary not sufficient, okurrr πbldc.N.C1βbit in[if ( personality & 0x10 )]β Fanuc Gray-code bit 0 input π§bldc.N.C2βbit in[if ( personality & 0x10 )]β Fanuc Gray-code bit 1 input π§bldc.N.C4βbit in[if ( personality & 0x10 )]β Fanuc Gray-code bit 2 input π§bldc.N.C8βbit in[if ( personality & 0x10 )]β Fanuc Gray-code bit 3 input π§bldc.N.valueβfloat inβ the PWM master amplitude input π the big boss amplitude, no capbldc.N.lead-angleβfloat in[if personality & 0x06](default: 90) β the phase lead between the electrical vector and the rotor position, measured in degrees πbldc.N.revβbit inβ set this bad boytrueand the motor spins backwards π and lowkey there's more than one way to do it: negative PWM amplitudes will also reverse the motor, and generally there'll be a Hall pattern that runs the motor in each direction too. options, bestie β¨bldc.N.frequencyβfloat in[if ( personality & 0x0F ) == 0]β frequency input for motors with no feedback at all, or the ones that only have an index (which, btw, gets ignored) πbldc.N.initvalueβfloat in[if personality & 0x04](default: 0.2) β the current used for the homing sequence, for when you've got an incremental encoder and zero hall-sensor feedback β‘bldc.N.rawcountsβs32 in[if personality & 0x06](default: 0) β encoder counts input. and this is a must: it has to be linked to the encoderrawcountspin, otherwise encoder index resets will make the motor commutation just. fail. π no cap, link itbldc.N.index-enableβbit io[if personality & 0x08]β hook this up to the matching encoderindex-enablepin so the encoder gets zeroed when it passes index π― its only job here is letting the bldc control component know an index has been seen, that's it, that's the whole assignmentbldc.N.initβbit in[if ( personality & 0x05 ) == 4]β a rising edge on this pin kicks off the motor alignment sequence π₯ and it should be wired up in a way that makes the motor re-align anytime encoder monitoring has been interrupted β typically that only happens at machine power-off. the alignment process involves powering the motor phases such that the motor ends up in a known position. the encoder counts then get stored in theoffsetparameter. β οΈ big warning though: the alignment process will tend to cause a following error if it gets triggered while the axis is enabled, so set it before the matchingaxis.N.enablepin. the complementaryinit-donepin exists to handle the sequencing you need. π«Ά
and good news: both of these pins can be ignored entirely if the encoder offset is already known explicitly β like with an absolute encoder π in that case you just set the offset parameter directly in the HAL file and move on with your life. slay.
bldc.N.init-doneβbit out[if ( personality & 0x05 ) == 4](default: 0) β indicates the homing sequence is complete β the little green checkmark of the pin worldbldc.N.A-valueβfloat out[if ( personality & 0xF00 ) == 0]β output amplitude for phase A πbldc.N.B-valueβfloat out[if ( personality & 0xF00 ) == 0]β output amplitude for phase B πbldc.N.C-valueβfloat out[if ( personality & 0xF00 ) == 0]β output amplitude for phase C πbldc.N.A-onβbit out[if ( personality & 0xF00 ) == 0x100]β output bit for phase A π‘bldc.N.B-onβbit out[if ( personality & 0xF00 ) == 0x100]β output bit for phase B π‘bldc.N.C-onβbit out[if ( personality & 0xF00 ) == 0x100]β output bit for phase C π‘bldc.N.A-highβfloat out[if ( personality & 0xF00 ) == 0x200]β high-side driver for phase A β¬οΈbldc.N.B-highβfloat out[if ( personality & 0xF00 ) == 0x200]β high-side driver for phase B β¬οΈbldc.N.C-highβfloat out[if ( personality & 0xF00 ) == 0x200]β high-side driver for phase C β¬οΈbldc.N.A-lowβfloat out[if ( personality & 0xF00 ) == 0x200]β low-side driver for phase A β¬οΈbldc.N.B-lowβfloat out[if ( personality & 0xF00 ) == 0x200]β low-side driver for phase B β¬οΈbldc.N.C-lowβfloat out[if ( personality & 0xF00 ) == 0x200]β low-side driver for phase C β¬οΈbldc.N.A-high-onβbit out[if ( personality & 0xF00 ) == 0x300]β high-side driver for phase A β¬οΈ (the bit version this time)bldc.N.B-high-onβbit out[if ( personality & 0xF00 ) == 0x300]β high-side driver for phase B β¬οΈbldc.N.C-high-onβbit out[if ( personality & 0xF00 ) == 0x300]β high-side driver for phase C β¬οΈbldc.N.A-low-onβbit out[if ( personality & 0xF00 ) == 0x300]β low-side driver for phase A β¬οΈbldc.N.B-low-onβbit out[if ( personality & 0xF00 ) == 0x300]β low-side driver for phase B β¬οΈbldc.N.C-low-onβbit out[if ( personality & 0xF00 ) == 0x300]β low-side driver for phase C β¬οΈbldc.N.hall1-outβbit out[if ( personality & 0x400 )]β Hall 1 output πbldc.N.hall2-outβbit out[if ( personality & 0x400 )]β Hall 2 output πbldc.N.hall3-outβbit out[if ( personality & 0x400 )]β Hall 3 output πbldc.N.C1-outβbit out[if ( personality & 0x800 )]β Fanuc Gray-code bit 0 output π§bldc.N.C2-outβbit out[if ( personality & 0x800 )]β Fanuc Gray-code bit 1 output π§bldc.N.C4-outβbit out[if ( personality & 0x800 )]β Fanuc Gray-code bit 2 output π§bldc.N.C8-outβbit out[if ( personality & 0x800 )]β Fanuc Gray-code bit 3 output π§bldc.N.phase-angleβfloat out(default: 0) β the phase angle, including the lead/lag angle, after encoder zeroing etc. super useful for angle/current drives π value ranges0to1and it measures electrical revolutions. so for a 4 pole motor you get two zeros, a 6-pole gives you three, and so on πbldc.N.rotor-angleβfloat out(default: 0) β rotor angle after encoder zeroing etc. this one's the moment for angle/current drives that add their own phase offset β the8I20says hi π range is0to1, measured in electrical revolutions, and again: two zeros for a 4 pole motor, three for a 6-pole, etc. etc. π«bldc.N.outβfloat outβ current output, and yes it includes the effect of thedirpin and the alignment sequence π¬ the whole ensemble, togetherbldc.N.out-dirβbit outβ direction output, and it goes high if value is negative XOR rev is true π exclusive or sweetie, it's exclusive orbldc.N.out-absβfloat outβ absolute value of the input value β¨ (what it says on the tin, bestie, no plot twist)
π PARAMETERS π
okay bestie, this is the big one β every knob, dial and secret setting on your drive lives here. take notes π
bldc.N.in-types32 r (default:-1) β state machine output, and ngl it will probably get hidden once the debug era ends πbldc.N.out-types32 r (default:-1) β also state machine output, and also probably getting hidden after debug. twins πbldc.N.scales32 rw [ifpersonality & 0x06] (default:512) β how many encoder counts fit in one full rotor revolution. the math girlies know π₯bldc.N.poless32 rw [ifpersonality & 0x06] (default:4) β how many poles your motor has. here's the tea: the encoder scale gets divided by this number, and that tells you how many encoder counts there are per electrical revolution β‘bldc.N.encoder-offsets32 rw [ifpersonality & 0x0A] (default:0) β the offset, in encoder counts, between the motor electrical zero and the encoder zero, modulo the number of counts per electrical revolution π―bldc.N.offset-measureds32 r [ifpersonality & 0x04] (default:0) β the encoder offset that the homing sequence actually measured (in certain modes). it did the work itself, iconic πbldc.N.drive-offsetfloat rw (default:0) β the angle, in degrees, that the drive applies to the commanded angle, in degrees. this one is only used during the homing sequence of drives with incremental encoder feedback, where it back-calculates from commanded angle to actual phase angle. it only matters for drives that want rotor-angle input instead of phase-angle demand. should be0for most drives, fr fr.bldc.N.output-patternu32 rw [ifpersonality & 0x400] (default:25) β the commutation pattern to output when you're in Hall Signal translation mode. see the description ofpatternfor the whole saga πbldc.N.patternu32 rw [ifpersonality & 0x01] (default:25) β the commutation pattern to actually use, from0to47. default is type25. they included every plausible combination, no cap. the table has the excitation pattern along the top and the pattern code down the left side, and each entry is the hall patterns inH1,H2,H3order. the common ones, bestie:0β 30 degree commutation26β its reverse17β 120 degree18β alternate 60 degree21β 300 degree, Bodine22β 240 degree25β 60 degree commutation
β οΈ lowkey important: a bunch of incorrect commutations will still have non-zero net torque, so they can look like they're working when they absolutely are not. it's giving fake bestie energy π
and if your motor came with zero documentation? honestly just try every single pattern. vibe check the whole table π
βββββββββββββββββββββββββββββββββββββββββββ
β Phases, Source - Sink β
βββββββ¬ββββββββββββββββββββββββββββββββββββ€
β pat β B-A C-A C-B A-B A-C B-C β
βββββββΌββββββββββββββββββββββββββββββββββββ€
β 0 β 000 001 011 111 110 100 β
β 1 β 001 000 010 110 111 101 β
β 2 β 000 010 011 111 101 100 β
β 3 β 001 011 010 110 100 101 β
β 4 β 010 011 001 101 100 110 β
β 5 β 011 010 000 100 101 111 β
β 6 β 010 000 001 101 111 110 β
β 7 β 011 001 000 100 110 111 β
β 8 β 000 001 101 111 110 010 β
β 9 β 001 000 100 110 111 011 β
β 10 β 000 010 110 111 101 001 β
β 11 β 001 011 111 110 100 000 β
β 12 β 010 011 111 101 100 000 β
β 13 β 011 010 110 100 101 001 β
β 14 β 010 000 100 101 111 011 β
β 15 β 011 001 101 100 110 010 β
β 16 β 000 100 101 111 011 010 β
β 17 β 001 101 100 110 010 011 β
β 18 β 000 100 110 111 011 001 β
β 19 β 001 101 111 110 010 000 β
β 20 β 010 110 111 101 001 000 β
β 21 β 011 111 110 100 000 001 β
β 22 β 010 110 100 101 001 011 β
β 23 β 011 111 101 100 000 010 β
β 24 β 100 101 111 011 010 000 β
β 25 β 101 100 110 010 011 001 β
β 26 β 100 110 111 011 001 000 β
β 27 β 101 111 110 010 000 001 β
β 28 β 110 111 101 001 000 010 β
β 29 β 111 110 100 000 001 011 β
β 30 β 110 100 101 001 011 010 β
β 31 β 111 101 100 000 010 011 β
β 32 β 100 101 001 011 010 110 β
β 33 β 101 100 000 010 011 111 β
β 34 β 100 110 010 011 001 101 β
β 35 β 101 111 011 010 000 100 β
β 36 β 110 111 011 001 000 100 β
β 37 β 111 110 010 000 001 101 β
β 38 β 110 100 000 001 011 111 β
β 39 β 111 101 001 000 010 110 β
β 40 β 100 000 001 011 111 110 β
β 41 β 101 001 000 010 110 111 β
β 42 β 100 000 010 011 111 101 β
β 43 β 101 001 011 010 110 100 β
β 44 β 110 010 011 001 101 100 β
β 45 β 111 011 010 000 100 101 β
β 46 β 110 010 000 001 101 111 β
β 47 β 111 011 001 000 100 110 β
βββββββ΄ββββββββββββββββββββββββββββββββββββ
π AUTHOR π
Andy Pugh β the legend, the moment, the main character β¨
π LICENSE π
GPL β free as in freedom, bestie, go forth and slay π
and that's the whole page, babe!! πΈ this is from the LinuxCNC Documentation, dated 2026-03-17, and the page is BLDC(9). mwah, go wire a motor, you got this π«Άπ
π¦ where this page comes from
- ubuntu resolute: linuxcnc-uspace 1:2.9.4-2ubuntu4 Β· GFDL-1.1-or-later
- ubuntu stonking: linuxcnc-uspace 1:2.9.4-2ubuntu4 Β· GFDL-1.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms