component sstep "control spindle speed from an MPG"; pin in float rpm "commanded spindle RPM (float)"; pin in signed mpg "mpg current counts (s32)"; pin in bit axis4 "axis4 is selected (bit)"; pin in bit x1 "x1 multiplier selected (bit)"; pin in bit x10 "x10 multiplier selected (bit)"; pin in bit x100 "x100 multiplier selected (bit)"; pin out float rpm_out "MPG requested rpm"; pin out bit fwd "signal to start spindle CW"; pin out bit rev "signal to start spindle CCW"; pin out bit stop "signal to stop spindle"; pin out bit subvert "MPG has taken control (wired to MPG light)"; param rw signed max_rpm = 1500 "max limit RPM (int)"; param rw signed hold_time =10 "time to hold the button without movng the dial to drop out"; variable signed latched_mpg; variable signed latched_rpm; variable signed desired_rpm; variable float time = 0.0; function _; license "GPL"; // indicates GPL v2 or later ;; inline int abs(int x){ if(x<0) return -x; return x; } FUNCTION(_){ int irpm = (int)rpm; // we work in int32 here if(!axis4 && !subvert){ // if the button is not pressed and we are not already subverting save state latched_mpg = mpg; latched_rpm = irpm; desired_rpm = irpm; fwd = rev = stop = 0; time = 0; } // axis 4 selected and button pressed (and held) else{ // has the mpg changed? if(mpg!=latched_mpg){ subvert = 1; // time to take over time = 0; int scale=0; if(x1) scale = 1; else if(x10) scale = 10; else if(x100) scale = 100; desired_rpm += (mpg - latched_mpg)*scale; latched_mpg = mpg; // limit to the range if(desired_rpm > max_rpm) desired_rpm = max_rpm; else if(desired_rpm < -max_rpm) desired_rpm = -max_rpm; } else if(axis4){ // just riding the button time += fperiod; if((int)time > hold_time) subvert = 0; } } rpm_out = desired_rpm; }