Joystick Lua library and example code (#2710)
This commit is contained in:
parent
13735b7228
commit
3515876cac
|
@ -0,0 +1,256 @@
|
|||
-- ChiliPeppr Joystick controller
|
||||
-- Used to control analog joysticks that are implemented just using
|
||||
-- variable resistors where you feed in 3.3v and get out a variable voltage
|
||||
-- based on position of the joystick. Joysticks like the Playstation portable
|
||||
-- or Xbox joysticks work this way and are readily available on Amazon, Ebay,
|
||||
-- or Aliexpress.
|
||||
--
|
||||
-- Working example of using this library:
|
||||
-- https://www.youtube.com/watch?v=ITgh5epyPRk
|
||||
--
|
||||
-- Visit http://chilipeppr.com/esp32
|
||||
-- By John Lauer
|
||||
--
|
||||
-- There is no license needed to use/modify this software. It is given freely
|
||||
-- to the open source community. Modify at will.
|
||||
--
|
||||
-- To use:
|
||||
-- joystick = require("joystick")
|
||||
-- joystick.on("xy", function(x, y)
|
||||
-- print("Got xy change. x:", x, "y:", y)
|
||||
-- end)
|
||||
-- joystick.on("x", function(x)
|
||||
-- print("Got x change. x:", x)
|
||||
-- end)
|
||||
-- joystick.on("y", function(y)
|
||||
-- print("Got y change. y:", y)
|
||||
-- end)
|
||||
-- joystick.on("xcenter", function()
|
||||
-- print("Got x center")
|
||||
-- end)
|
||||
-- joystick.on("ycenter", function()
|
||||
-- print("Got y center")
|
||||
-- end)
|
||||
-- joystick.on("button", function(val)
|
||||
-- print("Got button:", val)
|
||||
-- end)
|
||||
-- joystick.init()
|
||||
|
||||
-- For test/debug
|
||||
-- if m.tmr then m.tmr:stop(); m.tmr:unregister() end
|
||||
|
||||
local m = {}
|
||||
-- m = {}
|
||||
|
||||
m.pinAdcX = 6 -- ADC 6: GPIO34
|
||||
-- m.pinAdcY = 3 -- ADC 3: GPIO39
|
||||
-- m.pinAdcY = 7 -- ADC 7: GPIO35
|
||||
m.pinAdcY = 5 -- ADC 5: GPIO33
|
||||
-- m.pinSwitch = 18
|
||||
m.pinSwitch = 32
|
||||
|
||||
-- For TTGO
|
||||
-- m.centerX = 1850
|
||||
-- m.centerXMin = 1800
|
||||
-- m.centerXMax = 1915
|
||||
-- m.centerY = 1850
|
||||
-- m.centerYMin = 1800
|
||||
-- m.centerYMax = 1915
|
||||
|
||||
-- For Wemos battery powered
|
||||
m.centerX = 1800
|
||||
m.centerXMin = 1700
|
||||
m.centerXMax = 1870
|
||||
m.centerY = 1800
|
||||
m.centerYMin = 1700
|
||||
m.centerYMax = 1870
|
||||
|
||||
|
||||
m.isInitted = false
|
||||
m.tmr = tmr.create()
|
||||
|
||||
---
|
||||
-- @name init
|
||||
-- @description Call this first to setup your ADC ports and button port. You
|
||||
-- need to connect X to ADC 6: GPIO34, Y to ADC5: GPIO33, and the button to GPIO32.
|
||||
-- If you need to use alternate ports you should change the code in joystick.lua.
|
||||
-- Also, 11db attenuation is turned on by default because it is the best
|
||||
-- performance for analog joysticks. If you are finding a broader range of voltage
|
||||
-- is coming back from your joystick, adjust the attenuation in the init() method.
|
||||
-- @returns nil
|
||||
function m.init()
|
||||
|
||||
if m.isInitted then
|
||||
return
|
||||
end
|
||||
|
||||
print("Initting joystick pins. X: " .. m.pinAdcX .. ", Y: " .. m.pinAdcY .. ", Switch: " .. m.pinSwitch)
|
||||
|
||||
-- Initialise the pins
|
||||
gpio.config( { gpio=m.pinSwitch, dir=gpio.IN, pull=gpio.PULL_UP } )
|
||||
m.startSwitchInterrupt()
|
||||
|
||||
-- adc.setwidth(adc.ADC1, 9) -- read 9 bit on ADC
|
||||
adc.setwidth(adc.ADC1, 12) -- read 12 bit on ADC
|
||||
adc.setup(adc.ADC1, m.pinAdcX, adc.ATTEN_11db )
|
||||
adc.setup(adc.ADC1, m.pinAdcY, adc.ATTEN_11db )
|
||||
|
||||
m.tmr:alarm(250, tmr.ALARM_AUTO, function()
|
||||
m.readXY()
|
||||
-- m.readY()
|
||||
-- m.readX()
|
||||
end)
|
||||
|
||||
m.isInitted = true
|
||||
|
||||
end
|
||||
|
||||
m.onX = nil
|
||||
m.onXCenter = nil
|
||||
m.onY = nil
|
||||
m.onYCenter = nil
|
||||
m.onXY = nil
|
||||
m.onButton = nil
|
||||
---
|
||||
-- @name on
|
||||
-- @description Attach to the callback events available from this joystick library
|
||||
-- @param event_name A string of the event you want a callback on. "x", "y", "xy", "xcenter", "ycenter", "button"
|
||||
-- @param func The callback to receive after the event
|
||||
-- @returns nil
|
||||
function m.on(event_name, func)
|
||||
if event_name == "x" then
|
||||
m.onX = func
|
||||
elseif event_name == "xcenter" then
|
||||
m.onXCenter = func
|
||||
elseif event_name == "y" then
|
||||
m.onY = func
|
||||
elseif event_name == "ycenter" then
|
||||
m.onYCenter = func
|
||||
elseif event_name == "xy" then
|
||||
m.onXY = func
|
||||
elseif event_name == "button" then
|
||||
m.onButton = func
|
||||
end
|
||||
end
|
||||
|
||||
m.lastX = 0
|
||||
function m.readX()
|
||||
local val = adc.read(adc.ADC1, m.pinAdcX)
|
||||
if m.lastX == val then return end
|
||||
m.lastX = val
|
||||
print("X: " .. val)
|
||||
if m.onX then m.onX(val) end
|
||||
end
|
||||
|
||||
m.lastY = 0
|
||||
function m.readY()
|
||||
local val = adc.read(adc.ADC1, m.pinAdcY)
|
||||
if m.lastY == val then return end
|
||||
m.lastY = val
|
||||
print("Y: " .. val)
|
||||
if m.onY then m.onY(val) end
|
||||
end
|
||||
|
||||
m.lastXWasCenter = true
|
||||
m.lastYWasCenter = true
|
||||
function m.readXY()
|
||||
local valX = adc.read(adc.ADC1, m.pinAdcX)
|
||||
local valY = adc.read(adc.ADC1, m.pinAdcY)
|
||||
|
||||
-- if x or y is new value then send xy update
|
||||
local isXYUpdated = false
|
||||
|
||||
-- do some level setting for center point
|
||||
if valX >= m.centerXMin and valX <= m.centerXMax then
|
||||
-- consider it a center point
|
||||
-- valX = m.centerX
|
||||
|
||||
-- see if last X was center, and if so ignore
|
||||
if m.lastXWasCenter then
|
||||
-- do nothing
|
||||
else
|
||||
|
||||
-- last x was not center, so fire off event
|
||||
m.lastXWasCenter = true
|
||||
if m.onXCenter then
|
||||
node.task.post(node.task.LOW_PRIORITY, function()
|
||||
m.onXCenter(m.centerX)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- x is not on center, so fire event
|
||||
m.lastXWasCenter = false
|
||||
isXYUpdated = true
|
||||
if m.onX then
|
||||
node.task.post(node.task.LOW_PRIORITY, function()
|
||||
m.onX(valX)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if valY >= m.centerYMin and valY <= m.centerYMax then
|
||||
-- consider it a center point
|
||||
-- valY = m.centerY
|
||||
-- see if last Y was center, and if so ignore
|
||||
if m.lastYWasCenter then
|
||||
-- do nothing
|
||||
else
|
||||
|
||||
-- last x was not center, so fire off event
|
||||
m.lastYWasCenter = true
|
||||
if m.onYCenter then
|
||||
node.task.post(node.task.LOW_PRIORITY, function()
|
||||
m.onYCenter(m.centerY)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- y is not on center, so fire event
|
||||
m.lastYWasCenter = false
|
||||
isXYUpdated = true
|
||||
if m.onY then
|
||||
node.task.post(node.task.LOW_PRIORITY, function()
|
||||
m.onY(valY)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if isXYUpdated then
|
||||
if m.onXY then
|
||||
node.task.post(node.task.LOW_PRIORITY, function()
|
||||
m.onXY(valX, valY)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- print("X: " .. valX .. ", Y: " .. valY)
|
||||
|
||||
end
|
||||
|
||||
function m.readSwitch()
|
||||
local val = gpio.read(m.pinSwitch)
|
||||
print("Switch: ", val)
|
||||
if m.onButton then m.onButton(val) end
|
||||
end
|
||||
|
||||
function m.startSwitchInterrupt()
|
||||
gpio.trig(m.pinSwitch, gpio.INTR_UP_DOWN, m.onSwitchInterrupt)
|
||||
print("Set interrupt for switch.")
|
||||
end
|
||||
|
||||
m.lastSwitchVal = 0
|
||||
function m.onSwitchInterrupt(pin, level)
|
||||
if level == m.lastSwitchVal then return end
|
||||
m.lastSwitchVal = level
|
||||
print("Got switch interrupt. pin: ", pin, ", level: ", level)
|
||||
end
|
||||
|
||||
-- m.init()
|
||||
|
||||
return m
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
-- ChiliPeppr Joystick controller
|
||||
-- Used to control analog joysticks that are implemented just using
|
||||
-- variable resistors where you feed in 3.3v and get out a variable voltage
|
||||
-- based on position of the joystick. Joysticks like the Playstation portable
|
||||
-- or Xbox joysticks work this way and are readily available on Amazon, Ebay,
|
||||
-- or Aliexpress.
|
||||
--
|
||||
-- Working example of using this library:
|
||||
-- https://www.youtube.com/watch?v=ITgh5epyPRk
|
||||
--
|
||||
-- Visit http://chilipeppr.com/esp32
|
||||
-- By John Lauer
|
||||
--
|
||||
-- There is no license needed to use/modify this software. It is given freely
|
||||
-- to the open source community. Modify at will.
|
||||
--
|
||||
joystick = require("joystick")
|
||||
|
||||
joystick.on("xy", function(x, y)
|
||||
print("Got xy change. x:", x, "y:", y)
|
||||
end)
|
||||
|
||||
-- joystick.on("x", function(x)
|
||||
-- print("Got x change. x:", x)
|
||||
-- end)
|
||||
|
||||
-- joystick.on("y", function(y)
|
||||
-- print("Got y change. y:", y)
|
||||
-- end)
|
||||
|
||||
joystick.on("xcenter", function()
|
||||
print("Got x center")
|
||||
end)
|
||||
|
||||
joystick.on("ycenter", function()
|
||||
print("Got y center")
|
||||
end)
|
||||
|
||||
joystick.on("button", function(val)
|
||||
print("Got button:", val)
|
||||
end)
|
||||
|
||||
joystick.init()
|
||||
|
Loading…
Reference in New Issue