-- Stepper Jog for DRV8825 -- This library lets you jog your DRV8825 stepper using variable -- frequency PWM, but it keeps track of your step counter so you -- know your final position local m = {} -- m = {} m.motor = require("touchjog_jog_drv8825") -- These pins are set in touchjog_jog_drv8825.lua now -- m.pinStep = 2 -- GPIO22, pin36 on esp32-wroom-32d, Orig 2 -- m.pinDir = 14 -- pin33 on esp32-wroom-32d, Orig 14 -- m.pinSleep = 0 -- ENN pin28 GPIO17 on esp32-wroom-32d, Orig 15 or 0 -- m.pinPulseIn = 36 --2 -- 36 STEP Pulse In (Sens_VP), Pin 24 (Touch2) m.bits = 9 m.dutyStart = 0 m.dutyAtRun = 256 -- Since using 9bits 2^9=512, so 256 is 50% duty m.freqStart = 100 m._freq = 100 m._isOn = false m.isDebug = false -- You can pass in override settings to init including -- stepper_ctrl_jog.init({IRUN=4}) function m.init(tbl) print("initting...") -- if tbl ~= nil and tbl.IRUN ~= nil then m.IRUN = tbl.IRUN end m.motor.init({ initStepDirEnPins=true, -- pinStep = m.pinStep, -- pinDir = m.pinDir, -- pinEn = m.pinSleep, isDebug = false }) m.pinDir = m.motor.pinDir m.pinStep = m.motor.pinStep print("initted pins for drv8825") -- -- Start counting pulses before turning on pwm -- m.initPulseCtr() -- print("initted pulse ctr") -- After you init the pulsecnt library, you need to override -- the gpio settings that it applies to the ctrl_gpio_num to -- make it not just be an output pin gpio.config( { gpio=m.pinDir, dir=gpio.IN_OUT, pull=gpio.PULL_UP } ) -- Start the PWM module, but at duty 0 so like it's off m.start() -- Pause it like what we do on joystick at center pos m.pause() print("Initted drv8825_jog") end function m.round(num, numDecimalPlaces) local mult = 10^(numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult end m._lastFreq = 0 m._maxDelta = 20 function m.setfreq(fr, isOverrideAccel) if fr < 1 then print("Err on freq:", fr) return end -- Check last freq and don't let them change too fast if isOverrideAccel ~= true then if fr > m._lastFreq then -- they want faster if fr - m._lastFreq > m._maxDelta then local askedFr = fr fr = m._lastFreq + m._maxDelta print("Dampened accel from fr:",askedFr,"to fr:",fr) end elseif fr < m._lastFreq then -- they want slower if m._lastFreq - fr > m._maxDelta then local askedFr = fr fr = m._lastFreq - m._maxDelta print("Dampened decel from fr:",askedFr,"to fr:",fr) end end end print("Setting freq to:", fr) pcall(m._channel:setfreq(fr)) m._lastFreq = fr end function m.setduty(duty) m._channel:setduty(duty) -- print("Set duty:", duty) end function m.getFreq() return m._channel:getfreq() end function m.getSteps() local steps = m.motor.pcnt:getCnt() print("Steps: "..steps) return steps end function m.start() m._channel = ledc.newChannel({ gpio=m.pinStep, bits=m.bits, mode=ledc.HIGH_SPEED, timer=ledc.TIMER_1, channel=ledc.CHANNEL_1, frequency=m.freqStart, -- Hz -- 2^11 = 2048 -- 2^9 = 512 duty=m.dutyStart --512 -- 2**10 = 1024, so 50% duty is 512 }); m._isOn = true print("Start... freq:", m.freqStart, "duty", m.dutyStart) end function m.stop() m._channel:stop(ledc.IDLE_LOW) -- m.setfreq(m.freqStart) -- m.setduty(0) m._isOn = false print("Stopped") end m._isPaused = false function m.pause() -- m.setfreq(10, true) --override dampening m.setduty(0) m._isPaused = true print("Paused") end function m.resume() if m._isOn == false then return end if m._isPaused == false then return end m.setduty(m.dutyAtRun) m._isPaused = false print("Resumed") end function m.jogStart(freq) print("jogStart. freq:", freq) -- m.motor.dirFwd() m.motor.enable() m.setfreq(freq, true) --override dampen m.resume() -- m.motor.readDRV_STATUS() end function m.jogStop() m.pause() m.motor.disable() m.getSteps() -- m.motor.readDRV_STATUS() end m.testState = 0 -- 0 is run fwd, 1 is rev, 2 is pause m.testLastState = nil m.testFreq = 200 m.testLenMs = 1000 m.testPauseMs = 2000 -- Pass in tbl lenMs, pauseMs, freq function m.testStart(tbl) if tbl.freq ~= nil then m.testFreq = tbl.freq end if tbl.lenMs ~= nil then m.testLenMs = tbl.lenMs end if tbl.pauseMs ~= nil then m.testPauseMs = tbl.pauseMs end -- Start test where we jog fwd for 1 second -- Then we jog rev for 1 second m.jogStart(m.testFreq) m._testTmr = tmr.create() print("Starting out test at lenMs:", m.testLenMs, "pauseMs:", m.testPauseMs, "freq:", m.testFreq) m._testTmr:alarm(m.testLenMs, tmr.ALARM_SEMI, function() -- print("Got tmr. testState:", m.testState, "testLastState:", m.testLastState) -- check state if m.testState == 0 then -- we were just going fwd -- we are going to a pause state print("We are going to pause for ms:", m.testPauseMs) m.testLastState = 0 m.testState = 2 m.jogStop() m._testTmr:interval(m.testPauseMs) elseif m.testState == 2 then -- we were just on a pause -- jog again m.motor.dirToggle() if m.testLastState == 0 then m.testState = 1 print("We are going to jog reverse at freq:", m.testFreq, "for ms:", m.testLenMs) elseif m.testLastState == 1 then m.testState = 0 print("We are going to jog forward at freq:", m.testFreq, "for ms:", m.testLenMs) end m.jogStart(m.testFreq) m._testTmr:interval(m.testLenMs) elseif m.testState == 1 then -- we were just in rev -- we are going to a pause state print("We are going to pause for ms:", m.testPauseMs) m.testLastState = 1 m.testState = 2 m.jogStop() m._testTmr:interval(m.testPauseMs) end -- restart timer m._testTmr:start() end) end function m.testStop() m.jogStop() if m._testTmr then local running, mode = m._testTmr:state() if running then m._testTmr:unregister() end end end -- m.init() -- m.jogStart(100) -- m.testStart() -- localTime = time.getlocal() -- print(string.format("%02d:%02d:%02d", localTime["hour"], localTime["min"], localTime["sec"])) return m