热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PCA9685在nodeMCU开发板的驱动移植

背景最近尝试做六足机器人,遇到了需要用pwm控制板控制舵机的问题。淘了快PCA9685的16路舵机控制板,卖家给的参考程序是在Arduinouno的驱动

背景

最近尝试做六足机器人,遇到了需要用pwm控制板控制舵机的问题。淘了快PCA9685的16路舵机控制板,卖家给的参考程序是在Arduino uno的驱动,想着移植到nodeMCU上,用lua能省不少开发时间。

clipboard.png

c版驱动

/*************************************************** This is a library for our Adafruit 16-channel PWM & Servo driverPick one up today in the adafruit shop!------> http://www.adafruit.com/products/815These displays use I2C to communicate, 2 pins are required to interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution****************************************************/#ifndef _ADAFRUIT_PWMServoDriver_H
#define _ADAFRUIT_PWMServoDriver_H#if ARDUINO >= 100#include "Arduino.h"
#else#include "WProgram.h"
#endif#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
#define PCA9685_SUBADR3 0x4#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xFE#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9#define ALLLED_ON_L 0xFA
#define ALLLED_ON_H 0xFB
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFDclass Adafruit_PWMServoDriver {public:Adafruit_PWMServoDriver(uint8_t addr = 0x40);void begin(void);void reset(void);void setPWMFreq(float freq);void setPWM(uint8_t num, uint16_t on, uint16_t off);void setPin(uint8_t num, uint16_t val, bool invert=false);private:uint8_t _i2caddr;uint8_t read8(uint8_t addr);void write8(uint8_t addr, uint8_t d);
};#endif

/*************************************************** This is a library for our Adafruit 16-channel PWM & Servo driverPick one up today in the adafruit shop!------> http://www.adafruit.com/products/815These displays use I2C to communicate, 2 pins are required to interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution****************************************************/#ifndef _ADAFRUIT_PWMServoDriver_H
#define _ADAFRUIT_PWMServoDriver_H#if ARDUINO >= 100#include "Arduino.h"
#else#include "WProgram.h"
#endif#define PCA9685_SUBADR1 0x2
#define PCA9685_SUBADR2 0x3
#define PCA9685_SUBADR3 0x4#define PCA9685_MODE1 0x0
#define PCA9685_PRESCALE 0xFE#define LED0_ON_L 0x6
#define LED0_ON_H 0x7
#define LED0_OFF_L 0x8
#define LED0_OFF_H 0x9#define ALLLED_ON_L 0xFA
#define ALLLED_ON_H 0xFB
#define ALLLED_OFF_L 0xFC
#define ALLLED_OFF_H 0xFDclass Adafruit_PWMServoDriver {public:Adafruit_PWMServoDriver(uint8_t addr = 0x40);void begin(void);void reset(void);void setPWMFreq(float freq);void setPWM(uint8_t num, uint16_t on, uint16_t off);void setPin(uint8_t num, uint16_t val, bool invert=false);private:uint8_t _i2caddr;uint8_t read8(uint8_t addr);void write8(uint8_t addr, uint8_t d);
};#endif

c版测试

/*************************************************** This is an example for our Adafruit 16-channel PWM & Servo driverPWM test - this will drive 16 PWMs in a 'wave'Pick one up today in the adafruit shop!------> http://www.adafruit.com/products/815These displays use I2C to communicate, 2 pins are required to interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution****************************************************/#include
#include // called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm &#61; Adafruit_PWMServoDriver(0x41);void setup() {Serial.begin(9600);Serial.println("16 channel PWM test!");// if you want to really speed stuff up, you can go into &#39;fast 400khz I2C&#39; mode// some i2c devices dont like this so much so if you&#39;re sharing the bus, watch// out for this!pwm.begin();pwm.setPWMFreq(1600); // This is the maximum PWM frequency// save I2C bitrateuint8_t twbrbackup &#61; TWBR;// must be changed after calling Wire.begin() (inside pwm.begin())TWBR &#61; 12; // upgrade to 400KHz!}void loop() {// Drive each PWM in a &#39;wave&#39;for (uint16_t i&#61;0; i<4096; i &#43;&#61; 8) {for (uint8_t pwmnum&#61;0; pwmnum <16; pwmnum&#43;&#43;) {pwm.setPWM(pwmnum, 0, (i &#43; (4096/16)*pwmnum) % 4096 );}}
}

lua版驱动

PwmSvr&#61;{id&#61;0, PCA9685_SUBADR1&#61;0x2, LED0_ON_L&#61;0x6, ALLLED_ON_L&#61;0xFA,pinSCL&#61;1, PCA9685_SUBADR2&#61;0x3, LED0_ON_H&#61;0x7, ALLLED_ON_H&#61;0xFB,pinSDA&#61;2, PCA9685_SUBADR3&#61;0x4, LED0_OFF_L&#61;0x8, ALLLED_OFF_L&#61;0xFC,_i2caddr&#61;0x40, PCA9685_MODE1&#61;0x0, LED0_OFF_H&#61;0x9, ALLLED_OFF_H&#61;0xFD,addr&#61;nil, PCA9685_PRESCALE&#61;0xFE
}
function PwmSvr.read8(addr)i2c.start(PwmSvr.id)i2c.address(PwmSvr.id, PwmSvr._i2caddr,i2c.TRANSMITTER)i2c.write(PwmSvr.id,addr)i2c.stop(PwmSvr.id)i2c.start(PwmSvr.id)i2c.address(PwmSvr.id, PwmSvr._i2caddr,i2c.RECEIVER)local c&#61;i2c.read(PwmSvr.id,1)i2c.stop(PwmSvr.id)return string.byte(c)
end
function PwmSvr.write8(addr,d)i2c.start(PwmSvr.id)i2c.address(PwmSvr.id, PwmSvr._i2caddr ,i2c.TRANSMITTER)i2c.write(PwmSvr.id,addr,d)i2c.stop(PwmSvr.id)
end
function PwmSvr.reset()PwmSvr.write8(PwmSvr.PCA9685_MODE1,0x0)
end
function PwmSvr.begin()i2c.setup(PwmSvr.id, PwmSvr.pinSDA, PwmSvr.pinSCL, i2c.SLOW)PwmSvr.reset()
end
function PwmSvr.setPWMFreq(freq)local prescale&#61;math.ceil((25000000/4096)/(freq*0.9)&#43;0.5)local oldmode &#61; PwmSvr.read8(PwmSvr.PCA9685_MODE1)local newmode &#61;bit.bor(bit.band(oldmode,0x7F),0x10)PwmSvr.write8(PwmSvr.PCA9685_MODE1,newmode)PwmSvr.write8(PwmSvr.PCA9685_PRESCALE,prescale)PwmSvr.write8(PwmSvr.PCA9685_MODE1,oldmode)for i&#61;0,6000 do tmr.wdclr() endPwmSvr.write8(PwmSvr.PCA9685_MODE1, bit.bor(oldmode,0xa1))
end
function PwmSvr.setPWM(num,on,off)i2c.start(PwmSvr.id)i2c.address(PwmSvr.id, PwmSvr._i2caddr ,i2c.TRANSMITTER)i2c.write(PwmSvr.id,PwmSvr.LED0_ON_L&#43;4*num,bit.band(on,0xff),bit.rshift(on,8),bit.band(off,0xff),bit.rshift(off,8))i2c.stop(PwmSvr.id)
end
function PwmSvr.setPin(num,val,invert)if(val>4095) then val&#61;4095 endif(invert) thenif(val&#61;&#61;0) thenPwmSvr.setPWM(num, 4096, 0)elseif(val&#61;&#61;4095) thenPwmSvr.setPWM(num, 0, 4096)elsePwmSvr.setPWM(num, 0, 4095-val)endelseif(val&#61;&#61;4095) thenPwmSvr.setPWM(num, 4096, 0)elseif(val&#61;&#61;0) thenPwmSvr.setPWM(num, 0, 4096)elsePwmSvr.setPWM(num, 0, val)endendend

lua版测试

dofile("PwmSvr_PCA9685.lua")
PwmSvr.begin()
PwmSvr.setPWMFreq(60)
for pin&#61;0,15 dofor r&#61;150,400 doPwmSvr.setPWM(pin, 0, r)tmr.wdclr()end
end

源码地址

https://github.com/Seasonley/...



推荐阅读
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文讨论了如何在不使用SearchBar display controller的情况下,单独使用SearchBar并捕获其textChange事件。作者介绍了实际状况,即左侧SliderMenu中的SearchBar需要在主页TableView中显示搜索结果。然后,作者提供了解决方案和步骤,帮助读者实现这一功能。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
红星闪闪小肉肉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有