Skip to main content
Firmware Stable

Motor identification: set a controller up for its motor

Applies to

Every siliXcon motor controller (hwid starts with esc), whatever application runs on it. It is the first setup step: the getting-started wizards include it as their identification step, and every application's setup assumes it is done. Repeat it after changing the motor or its sensor. It assumes the controller communicates with emGUI and the motor and its sensor are connected.

Before you start

  • emGUI version: this playbook needs an emGUI whose tool list has wait. An older one describes the identification commands as unsuitable for its MCP server and does not refuse save without -y: ask the user to update SWTools before starting.
  • This playbook changes the device and turns the motor. Propose each such step to the user, say what it does, and run it only after a clear yes. Writes that do not spin the motor (steps 2, 4 and 5) may share one yes. In step 6 one yes covers stop, identlin and the repeated identrun runs while the user stays at the motor; ask again after anything else happens - an error, a timeout, a power cycle, a phase swap, the user leaving or touching the motor. Propose each save -y before running it. Otherwise the rules of the general method apply.
  • Permission levels (emGUI's MCP menu): restore, reinit, stop, save and the parameter writes need Allow writes; identlin and identrun need Allow dangerous commands. Only the operator can set them (MCP → Stop server, choose the level, Start server). Ask when a step needs it, not earlier.
  • Before the first identlin or identrun, tell the user: while one runs, emGUI does not respond (Windows may show "Not responding" - do not close it) and nothing reaches the device, a stop included, until it finishes. The only way to abort a run is to cut the power.
  • Call identlin and identrun with execute_command timeout_ms 30000. If a call returns without emGUI's answer (the assistant's own timeout) or with timed out, never issue it again while it may still run: ask whether the motor has stopped, then read /driver/error - 65534 means the run is still going (wait 5000 ms and read again). Once it reads something else and the motor stands still, the run has ended but its printed result is lost: /driver/error must be 0, and after the user's yes the command runs once more to show its result (for identrun that counts as one of the runs in step 6). If that call times out too, end the procedure: the user runs the command in emGUI's own terminal and pastes its output for you to check.
  • Check every call: the result's ok is true, the command's own success below holds, and /driver/error is 0 afterwards.
CommandSuccess
restore -y <paths>prints <n> entries done. and returns that number: 2 for the two paths of step 2
reinit <prest>returns 0 (an unsupported sensor: 65535). May print configuring motor sensor mode <n>: <sensor>; <n> is the sensor mode, not always the prest given
stop, identlinreturn 0
identrunreturns exactly 0. 1: the motor was identified but its sensor was not (step 6)
save -yprints <n> bytes, #<hash> hash: that line is the success, the return value is the hash. Without -y emGUI refuses it (it would save nothing)

Other identification results are listed under return values. Some applications (usually ESC3 builds and LYNX) have their debug output disabled to save flash: reinit and stop then print nothing, and the return value and /driver/error are the answer. The suggested ... result lines of identlin and identrun always print.

Steps

Wherever a step says to end the procedure: do not save, go to step 8 (a power cycle brings back the saved settings and releases stop), then report (9) and escalate (10).

1. The device and its driver

list_devices: name, serial number, hwid, swid. The swid starts with VECTOR_ or BLDC_: the driver type, which changes steps 4 and 6. list_commands must list identlin, identrun, reinit, stop, save and restore; a build without identlin and identrun cannot be identified this way - tell the user. /driver/error must be 0; an undervoltage error right after power-up usually means USB was connected before the battery (trivial values). Some applications need a service login in Launchpad before parameters can be written (LYNX: credentials).

2. Default state

list_variables (kind: param, path: /driver, recurse: true, include_defaults: false) lists the driver parameters that differ from their defaults. Values an earlier identification wrote need no question, because identification writes them again: the motor model under /driver/motor (not pp), rangle, hvar, rpole and ppr under /driver/rest, and the current-loop gains under /driver/pid_iq and /driver/pid_id. The exception is a /driver/motor/psi of 0 or below: it declares a motor without magnets, identification keeps it, so ask. Show the others to the user and ask whether each is intended: identification expects them at their defaults. Change only what the user confirms; a negative /driver/ipeak, for example, deliberately reverses the direction. A parameter marked volatile (for example /driver/limiter/ppos set by a LYNX map) is set by the application at run time and is not saved: mention it, do not restore it.

Always restore /driver/rest/roff1 and /driver/rest/roff2 to their defaults on a VECTOR build, otherwise the identification may fail: restore -y /driver/rest/roff1 /driver/rest/roff2. BLDC builds do not have them.

3. Supply

Ask whether the controller is powered from a battery or from a 4-quadrant power supply. Only those two are used for this setup. Most other power supplies cannot take the current the motor sends back during identification and braking, and the controller or the supply can be destroyed (why). Do not continue until the answer is a battery or a 4-quadrant supply. Its voltage must be within the controller's working range, from the controller's specification page (see the general method's ground rules).

4. Motor sensor

Ask which sensor the motor has: Hall sensors, Sin-Cos, resolver, a digital sensor (SSI, BiSS), an encoder, or none (sensorless). Users often call any motor sensor an "encoder": when they say encoder, ask what exactly it is and how it is connected (how many wires, to which controller inputs) before choosing prest. An incremental encoder is meant for asynchronous motors, not for permanent-magnet motors (prest).

  1. Hardware: decode_hwid with the device address - motor_sensors must include that sensor. Sensorless needs no sensor input: skip this check.
  2. Firmware: the build in the swid must support it - see the application's Mods page (search_docs for the application name and "mods", or the motor driver playbook step 6).
  3. Tell the user the motor may move from here on and must be free, then stop, then reinit <prest> with the sensor's number from the prest table (BLDC builds: BLDC prest; there Hall sensors work with 0 (auto) and 2, so keep the present one unless the user wants the other).
  4. Read its result. Return 0 and /driver/error 0: the sensor is supported. unsupported in the output, or a return of 65535: this firmware build does not contain the sensor - stop here; the user needs another build or another sensor. motor is disconnected: connect the motor first. BLDC builds, and builds without debug output, print no sensor line: the return value is the check.
  5. Hall sensors: /driver/rest/hall must read 1-6. 0 (all sensors off) and 7 (all on) are error values (hall): check the sensor supply and wiring. Hall sensors at 60° spacing also need /driver/rest/hinv set by hand (hinv); identification does not set it.

The new prest stays in RAM until save (step 6).

5. Current

Ask for the starting phase current and set /driver/iref. Start with the nominal battery current; it can be raised later. siliXcon uses peak (amplitude) values everywhere, not RMS (amplitude, not RMS, iref). Leave /driver/ipeak as it is; step 7 says when to lower it. If the user knows the motor's pole pairs, set /driver/motor/pp too (speed readings); the identification does not need it.

6. Identification

Ask first: can the motor spin freely - no load, nothing on the shaft that can be thrown or caught, a vehicle lifted with its wheel off the ground - and may you spin it now? Only a clear yes continues, and it covers this step only while nothing else happens (see Before you start). Repeat the warning that emGUI freezes during a run and only a power cut stops it.

  1. stop - takes the drive away from the throttle, the application and the CAN inputs.
  2. The MCP wait tool (not a device command), ms 1000.
  3. /driver/limit: its limiter bits 0-11 (the value AND 4095) must be 0 (limiter word); bits 12-15 do not block. A set bit is an active limiter, usually the battery voltage limiter: value 4 is ubmin (voltage below it), 8 is ubmax (voltage above it); for any other bit see the limiter word page. Suggest disabling it for now (0 disables ubmin or ubmax) or bringing the supply voltage inside ubmin-ubmax, never above the controller's maximum working voltage from its specification page. Note the value you disable: step 7 sets the real limits, and if the user does not continue to step 7, write the old value back and save -y before handing back. /driver/stat must be 0 too; its bits clear once every cause has been gone for a second, and a bit that stays needs its cause fixed (protection state).
  4. identlin. The rotor jerks into several positions; it takes some tens of seconds.
  5. identrun. The motor spins up for a few seconds and then coasts to a stop. Check its output:
    • Sensorless (prest 1 or 128): run it once; there is no correction to check.
    • Any other sensor, VECTOR build: the line suggested rangle: <x> rad (<y>% correction). The correction must be below 1 % (its absolute value; a value near ±200 % is a wrap-around and counts as 200 minus that). Otherwise run identrun again - it continues from its own result - up to 5 runs in total; then end the procedure and report every correction (sensor wiring or mounting; the motor driver playbook step 6). The roff1/roff2 correction lines are not the criterion. An encoder or resolver with a reference input: also run again whenever the output says ppr changed.
    • Hall sensors: also the line suggested hvar: <n> (<m> before) - <n> must be the same on two runs in a row in this session, which shows as <n> equal to <m> on the second, for example suggested hvar: 2 (2 before). The before value of the first run is left from an earlier setup and does not count.
    • BLDC build: the rangle correction does not settle there; only hvar must be the same on two runs in a row, within 5 runs; otherwise end the procedure as above.
    • identrun returns 1 (the output names a sensor problem): the sensor was not identified. Do not repeat and do not save; end the procedure and report the sensor, its wiring and prest (the motor driver playbook step 6).
    • The output says psi was kept because a motor without magnets is declared (/driver/motor/psi 0 or below): if the motor has magnets, restore -y /driver/motor/psi and repeat from step 6.
    • identrun refused with -105 right after the previous run: the motor is still coasting. Wait a few seconds and try again; that attempt does not count as a run.
    • Ask whether the motor turned in the wanted forward direction. If not, the user switches the controller off completely (as in step 8), swaps two motor phases and switches it on again. Nothing is saved yet, so repeat from step 2 (reverse the direction).
  6. save -y.

7. Battery limits

Ask for the battery's minimum and maximum voltage and set /driver/limiter/ubmin and /driver/limiter/ubmax. When the user gives only the cell count of a Li-ion pack, propose count × 4.2 V for ubmax and count × 3.0 V for ubmin and ask them to confirm against the cell datasheet; then the maximum discharge and charge current, /driver/limiter/ibpos (positive) and /driver/limiter/ibneg (negative) (battery limiter). The voltages must be inside the controller's working range from its specification page.

Tell the user plainly: ibneg 0 does not stop current flowing into the battery - 0 switches that limit off - and no ibneg value makes a power supply that cannot take current back usable. The battery must accept the iref current for at least 10 ms and the ipeak current for at least 2 µs, in both directions (protections, limiter reaction).

ipeak defaults to the controller's maximum and does not need lowering. Only if the battery's BMS cannot deliver that current and trips: lower ipeak below the BMS short-circuit protection level, keeping its sign (a negative value reverses the direction), and keep iref at least 10 % below ipeak (ipeak, iref and ipeak).

Then save -y again.

8. Hand back

Ask the user to switch the controller off completely - the battery off and USB unplugged, since USB can keep the controller's logic running - and on again, battery first, then USB. That releases stop - until then the throttle and the application cannot drive the motor - and starts from the saved parameters. Then read /driver/error (0) and read back what was saved - /driver/prest, /driver/iref, /driver/motor/pp, /driver/motor/Rt (no longer 0) and the four battery limits - to prove it loaded. Then continue with the application's own setup.

9. Report

  1. Device: name, serial number, hwid, swid.
  2. Sensor, prest and what reinit printed; iref.
  3. identlin and each identrun result, the final correction and hvar.
  4. What was saved; the battery limits.
  5. What the user still has to do; URLs used.

10. Escalate

The identification fails repeatedly, or a driver error returns after a power cycle: the motor driver playbook, then a diagnostic report.