nodemcu-firmware/lua_examples/touch/touchjog_jog.lua

256 lines
6.2 KiB
Lua

-- 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