| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- --[[
- @module pca9685
- @summary pca9685 16路PWM驱动舵机
- @version 1.0
- @date 2023.12.26
- @author xwtx
- @usage
- --注意:因使用了sys.wait()所有api需要在协程中使用
- -- 用法实例
- PROJECT = "pca9685"
- VERSION = "1.0.0"
- sys = require("sys")
- pca9685=require("pca9685")
- local i2c_id = 1
- sys.taskInit(
- function()
- i2c.setup(i2c_id,i2c.SLOW)
- sys.wait(1000)
- pca9685.init(i2c_id,60)
- sys.wait(1000)
- local i=0
- while true do
- pca9685.setpwm(i2c_id,0,i)
- if i >= 100 then
- i=0
- end
- i=i+10
- sys.wait(2000)
- end
- end
- )
- sys.run()
- ]]
- local pca9685={}
- local PCA_Addr = 0x40 --pwm通道地址
- local PCA_Model =0x00 --工作模式:读1/写0
- local LED0_ON_L =0x06
- local LED0_ON_H =0x07
- local LED0_OFF_L= 0x08
- local LED0_OFF_H =0x09
- local PCA_Pre = 0xFE
- local function pca9685_write(i2cId,addr, data)
- local ret
- ret=i2c.send(i2cId, PCA_Addr, { addr, data })
- sys.wait(15)
- if ret then
- return true
- else
- return
- end
- end
- local function pca9685_read(i2cId,addr)
- i2c.send(i2cId, PCA_Addr, addr)
- sys.wait(5)
- local data = i2c.recv(i2cId,0x40, 1)
- if #data==0 then
- return
- else
- return data
- end
- end
- --[[
- pca9685 初始化
- @api pca9685.init(i2cId,hz)
- @int i2cid 使用的i2c id, 或者是软件i2c的实例
- @int hz pca9685的输出频率
- @return 成功返回true 失败返回nil
- ]]
- function pca9685.init(i2cId,hz)
- local ret=0
- ret=pca9685_write(i2cId,PCA_Model,0x00)
- if not ret then
- return
- end
- ret=pca9685.setfreq(i2cId,hz)
- if not ret then
- return
- end
- pca9685.setpwm(i2cId,0,0);
- pca9685.setpwm(i2cId,1,0);
- pca9685.setpwm(i2cId,2,0);
- pca9685.setpwm(i2cId,3,0);
- pca9685.setpwm(i2cId,4,0);
- pca9685.setpwm(i2cId,5,0);
- pca9685.setpwm(i2cId,6,0);
- pca9685.setpwm(i2cId,7,0);
- pca9685.setpwm(i2cId,8,0);
- pca9685.setpwm(i2cId,9,0);
- pca9685.setpwm(i2cId,10,0);
- pca9685.setpwm(i2cId,11,0);
- pca9685.setpwm(i2cId,12,0);
- pca9685.setpwm(i2cId,13,0);
- pca9685.setpwm(i2cId,14,0);
- pca9685.setpwm(i2cId,15,0);
- sys.wait(100)
- return true
- end
- --[[
- pca9685 设置频率
- @api pca9685.setfreq(i2cId,freq)
- @int i2cid 使用的i2c id, 或者是软件i2c的实例
- @int freq pca9685的输出频率,范围为24HZ~1526HZ
- @return 成功返回true 失败返回nil
- ]]
- function pca9685.setfreq(i2cId,freq) --PCA9685频率设置
- local prescale
- local oldmode
- local newmode
- local prescaleval
- local ret
- prescaleval = 25000000;
- prescaleval = prescaleval / 4096
- prescaleval = prescaleval / freq
- prescaleval = prescaleval - 1
- prescale = math.floor(prescaleval + 0.5)
- oldmode = string.toHex(pca9685_read(i2cId,PCA_Model))
- newmode = (oldmode & 0x7F)|0x10
- ret=pca9685_write(i2cId,PCA_Model, newmode)
- if not ret then
- return
- end
- ret=pca9685_write(i2cId,PCA_Pre, prescale)
- if not ret then
- return
- end
- ret=pca9685_write(i2cId,PCA_Model, oldmode)
- if not ret then
- return
- end
- sys.wait(5)
- ret=pca9685_write(i2cId,PCA_Model, oldmode|0xa1)
- if not ret then
- return
- end
- return true
- end
- --[[
- pca9685 设置PWM占空比
- @api pca9685.setpwm(i2cId,num, duty_cycle)
- @int i2cid 使用的i2c id, 或者是软件i2c的实例
- @int num 通道号
- @int duty_cycle 占空比 0~100
- @return 成功返回true 失败返回nil
- ]]
- function pca9685.setpwm(i2cId,num, duty_cycle)
- local on = 0
- if duty_cycle==50 then
- on=0
- else
- on=math.floor(4096*((100-duty_cycle)/100))
- end
- local off=on+math.floor(4096*(duty_cycle/100))
- local ret = i2c.send(i2cId, PCA_Addr, { LED0_ON_L + 4 * num, on & 0xFF, on >> 8, off & 0xFF, off >> 8 })
- sys.wait(5)
- if ret==false then
- return
- end
- return true
- end
- return pca9685
|