Simulation of elecric motor and controller in behavioural VHDL. * Power from a wall socket. Vmains live 0 SIN 0 250 50 * Behavioral power-line zero-crossing detector, Bcross cross 0 V=(V(live) > -2 && V(live) < 2) ? 5 : 0 * Motor and its rotor Xmotor live mt1 tacho 0 motor * A triac to control the motor is replaced by a voltage-controlled switch * to avoid including a manufacurer's triac library. *Xtriac mt1 gate 0 BTA16-600B Striac mt1 0 drive 0 triac off .model triac sw vt=1.5 vh=1 roff=1meg * The controller is implemented as VHDL code. The argument "-gTarget=5000" * in the model line overrides the default target motor speed in the VHDL file. * Tuning parameters Full_Band and Dead_band may also be set. Ademo [ cross tacho ] [ drive ] controller .model controller d_cosim simulation="./mc" + sim_args=["./mc.so" "-gTarget=4500"] * Motor electrical circuit - inductance, resistance and back-EMF * Loosley based on: * https://www.precisionmicrodrives.com/content/ab-025-using-spice-to-model-dc-motors/ * No resemblance is claimed to any actual motor, living or dead. .subckt motor live neutral tacho1 tacho2 + Lm=0.3 Rm=30 BackC=20 // Electrical + TorqueC=30 Linertia=20 Rdrag=20 Load={50} // Mechanical * Electrical inductance and resistance of the motor. Lm live internal {Lm} Rm internal back_emf {Rm} * Back EMF: here I(Bmech) is proportional to speed, I(Bback) is motor current. Bback back_emf neutral V=-I(Bmech)*I(Bback)*{BackC} * Mechanical simulation: torque (V), speed (I), inertia (L) and * friction/load (R). * Series (Universal) motor so torque proportional to current squared. Bmech torque 0 V=I(Bback)*I(Bback)*{TorqueC} // Motor torque Lmech torque inertia {Linertia} Rmech inertia load {Rdrag} * In addition to friction (Rdrag) there is a varying load. * Delay * | Rise time * | | Fall time * | | | Pulse width * | | | | Period * | | | | | * V V V V V Vload load 0 PULSE 0 {Load} 1.2 10m 10m 200m 400m * Tachometer: integrate speed for position and pulse. Bpos i1 0 I=I(Bmech) Cpos i1 0 0.01 .ic v(i1)=0 Btach tacho1 tacho2 V=((V(i1) - floor(V(i1)) > 0.5) ? 5 : 0) .ends .control save drive @b.xmotor.bback[i] @b.xmotor.bmech[i] xmotor.load tran 50u 3 plot @b.xmotor.bback[i] @b.xmotor.bmech[i]*-10 drive xmotor.load/10 .endc .end