当前位置:   article > 正文

PCA9685 模块使用_pca9865

pca9865

Overview | Adafruit PCA9685 16-Channel Servo Driver | Adafruit Learning System

https://cdn-learn.adafruit.com/downloads/pdf/16-channel-pwm-servo-driver.pdf

无法用于ws2812的控制 

setpwm 

setpin(内部还是用setpwm实现)

channel ,通道号0-15

on:从低电平跳到高电平的时候 (0-4095)

off:从高电平跳到高电平的时间(0-4095)

例:第15引脚 25%——75%高电平 pwm.setPWM(15,1024,3072) 

4095*25% = 1024 ; 4095*75%

setPWM(channel, on, off) Description This function sets the start (on) and end (off) of the high segment of the PWM pulse on a specific channel.  You specify the 'tick' value between 0..4095 when the signal will turn on, and when it will turn off.  Channel indicates which of the 16 PWM outputs should be updated with the new values. Arguments channel: The channel that should be updated with the new values (0..15) on: The tick (between 0..4095) when the signal should transition from low to high off:the tick (between 0..4095) when the signal should transition from high to low Example The following example will cause channel 15 to start low, go high around 25% into the pulse (tick 1024 out of 4096), transition back to low 75% into the pulse (tick 3072), and remain low for the last 25% of the pulse: pwm.setPWM(15, 1024, 3072)

Using as GPIO There's also some special settings for turning the pins fully on or fully off

You can set the pin to be fully on with

pwm.setPWM(pin, 4096, 0); 当gpio用 ,输出

You can set the pin to be fully off with

pwm.setPWM(pin, 0, 4096) ;当gpio用 ,关闭

本来是用来控制灯的,若用来控制舵机等,需外接电源(pca提供的电流为20ma,大于此无法驱动,需接外接电源)vcc和v+可用连帽连接,构成同一供电

vcc 为pca9685供电 

vc+为 舵机,电机等外部供电,通过另外供电,可提供更大电流

通过pwm接三极管,提供对外设的驱动 

arduino  arduino stm32

引脚A4为SDA,引脚A5为SCL

asrpro

PA1 SCL PA0 SDA

使用softiic库,使用arduino的 Adafruit_PWMServoDriver驱动库 进行修改

若要封装,需将Adafruit_PWMServoDriver.c文件内容复制到Adafruit_PWMServoDriver.h头文件中

  1. PCA9685代码
  2. 使用asrpro自带的asr_softiic.h 和 arduino Adafruit_PWMServoDriver驱动库
  3. 修改处
  4. softiic.start(_i2caddr<<1|0); //0 ,读 1 (地址要左移一位
  5. 注释requestfrom ; return 0
  6. #include "asr.h"
  7. extern "C"{ void * __dso_handle = 0 ;}
  8. #include "setup.h"
  9. #include "HardwareSerial.h"
  10. #include "asr_softiic.h"
  11. uint32_t snid;
  12. void hardware_init();
  13. void LED();
  14. void ASR_CODE();
  15. #define PCA9685_SUBADR1 0x2
  16. #define PCA9685_SUBADR2 0x3
  17. #define PCA9685_SUBADR3 0x4
  18. #define PCA9685_MODE1 0x0
  19. #define PCA9685_PRESCALE 0xFE
  20. #define LED0_ON_L 0x6
  21. #define LED0_ON_H 0x7
  22. #define LED0_OFF_L 0x8
  23. #define LED0_OFF_H 0x9
  24. #define ALLLED_ON_L 0xFA
  25. #define ALLLED_ON_H 0xFB
  26. #define ALLLED_OFF_L 0xFC
  27. #define ALLLED_OFF_H 0xFD
  28. class Adafruit_PWMServoDriver {
  29. public:
  30. Adafruit_PWMServoDriver(uint8_t addr = 0x40);
  31. void begin(void);
  32. void reset(void);
  33. void setPWMFreq(float freq);
  34. void setPWM(uint8_t num, uint16_t on, uint16_t off);
  35. void setPin(uint8_t num, uint16_t val, bool invert=false);
  36. private:
  37. uint8_t _i2caddr;
  38. uint8_t read8(uint8_t addr);
  39. void write8(uint8_t addr, uint8_t d);
  40. };
  41. // class MySoftIIC
  42. // {
  43. // public:
  44. // void begin(){softiic.begin(0,1);}
  45. // void stop(){softiic.stop();}
  46. // void write(uint8_t d){softiic.write(d);}
  47. // uint8_t read(bool b ){softiic.read(b);}
  48. // void requestFrom(uint8_t addr,uint8_t d){};
  49. // int start(uint8_t addr){return softiic.start(addr<<1|0);}
  50. // void beginTransmission(uint8_t addr){start(addr);}
  51. // void stop(){softiic.stop();}
  52. // };
  53. // MySoftIIC WIRE;
  54. // Set to true to print some debug messages, or false to disable them.
  55. #define ENABLE_DEBUG_OUTPUT false
  56. Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t addr) {
  57. _i2caddr = addr;
  58. }
  59. void Adafruit_PWMServoDriver::begin(void) {
  60. softiic.begin(0,1);
  61. reset();
  62. }
  63. void Adafruit_PWMServoDriver::reset(void) {
  64. write8(PCA9685_MODE1, 0x0);
  65. }
  66. void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
  67. //Serial.print("Attempting to set freq ");
  68. //Serial.println(freq);
  69. freq *= 0.9; // Correct for overshoot in the frequency setting (see issue #11).
  70. float prescaleval = 25000000;
  71. prescaleval /= 4096;
  72. prescaleval /= freq;
  73. prescaleval -= 1;
  74. if (ENABLE_DEBUG_OUTPUT) {
  75. Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
  76. }
  77. uint8_t prescale = floor(prescaleval + 0.5);
  78. if (ENABLE_DEBUG_OUTPUT) {
  79. Serial.print("Final pre-scale: "); Serial.println(prescale);
  80. }
  81. uint8_t oldmode = read8(PCA9685_MODE1);
  82. uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
  83. write8(PCA9685_MODE1, newmode); // go to sleep
  84. write8(PCA9685_PRESCALE, prescale); // set the prescaler
  85. write8(PCA9685_MODE1, oldmode);
  86. delay(5);
  87. write8(PCA9685_MODE1, oldmode | 0xa1); // This sets the MODE1 register to turn on auto increment.
  88. // This is why the beginTransmission below was not working.
  89. // Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
  90. }
  91. void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
  92. //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);
  93. softiic.start(_i2caddr<<1|0);
  94. softiic.write(LED0_ON_L+4*num);
  95. softiic.write(on);
  96. softiic.write(on>>8);
  97. softiic.write(off);
  98. softiic.write(off>>8);
  99. softiic.stop();
  100. }
  101. // Sets pin without having to deal with on/off tick placement and properly handles
  102. // a zero value as completely off. Optional invert parameter supports inverting
  103. // the pulse for sinking to ground. Val should be a value from 0 to 4095 inclusive.
  104. void Adafruit_PWMServoDriver::setPin(uint8_t num, uint16_t val, bool invert)
  105. {
  106. // Clamp value between 0 and 4095 inclusive.
  107. if(val > 4095)
  108. val = 4095;
  109. if (invert) {
  110. if (val == 0) {
  111. // Special value for signal fully on.
  112. setPWM(num, 4096, 0);
  113. }
  114. else if (val == 4095) {
  115. // Special value for signal fully off.
  116. setPWM(num, 0, 4096);
  117. }
  118. else {
  119. setPWM(num, 0, 4095-val);
  120. }
  121. }
  122. else {
  123. if (val == 4095) {
  124. // Special value for signal fully on.
  125. setPWM(num, 4096, 0);
  126. }
  127. else if (val == 0) {
  128. // Special value for signal fully off.
  129. setPWM(num, 0, 4096);
  130. }
  131. else {
  132. setPWM(num, 0, val);
  133. }
  134. }
  135. }
  136. uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
  137. softiic.start(_i2caddr<<1|0);
  138. softiic.write(addr);
  139. softiic.stop();
  140. //softiic.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
  141. //return softiic.read();
  142. return 0;
  143. }
  144. void Adafruit_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
  145. softiic.start(_i2caddr<<1|0);
  146. softiic.write(addr);
  147. softiic.write(d);
  148. softiic.stop();
  149. }
  150. Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
  151. //--------------------------------------------------------
  152. ///**************************************************************
  153. bool bl = 0;
  154. int i=0;
  155. void LED(){
  156. while (1) {
  157. //扫描设备
  158. for(int i = 1;i<0x7f;i++)
  159. {
  160. // int val = softiic.start(i<<1 | 0);
  161. // softiic.stop();
  162. // Serial.print(i,HEX);
  163. // Serial.print("ox ");
  164. // Serial.println(val,HEX);
  165. pwm.begin();
  166. pwm.setPWMFreq(1600);
  167. pwm.setPin(4,i*46,0);
  168. delay(100);
  169. }
  170. }
  171. vTaskDelete(NULL);
  172. }
  173. //------------------------------------------------
  174. void setup()
  175. {
  176. Serial.begin(9600);
  177. delay(100);
  178. //softiic.begin(0,1);
  179. pinMode(4,output);
  180. setPinFun(4,FIRST_FUNCTION);
  181. digitalWrite(4,0);
  182. //{speak:小蝶-清新女声,vol:10,speed:10,platform:haohaodada}
  183. //{playid:10001,voice:欢迎使用语音助手,用天问五幺唤醒我。}
  184. //{playid:10002,voice:我退下了,用天问五幺唤醒我}
  185. //{ID:0,keyword:"唤醒词",ASR:"天问五幺",ASRTO:"我在"}
  186. //{ID:1,keyword:"命令词",ASR:"打开灯光",ASRTO:"好的,马上打开灯光"}
  187. //{ID:2,keyword:"命令词",ASR:"关闭灯光",ASRTO:"好的,马上关闭灯光"}
  188. xTaskCreate(hardware_init,"hardware_init",256,NULL,100,NULL);
  189. }
  190. //--------------------------------------------------------
  191. //{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
  192. //{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
  193. //{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
  194. void hardware_init(){
  195. xTaskCreate(LED,"LED",256,NULL,4,NULL);
  196. vTaskDelete(NULL);
  197. }
  198. /*描述该功能...
  199. */
  200. void ASR_CODE(){
  201. switch (snid) {
  202. case 1:
  203. //digitalWrite(4,0);
  204. break;
  205. case 2:
  206. //digitalWrite(4,1);
  207. break;
  208. }
  209. }

asrpro softiic requestfrom // 使用SOFTI2C修改

arduino softi2c 与softwire 不同read wirte实现不同

asrpro中.c文件中的定义需放入.h中,否则错误 

  1. //arduino soft_I2c quantity 读取数量,
  2. uint8_t rxbuff[10];
  3. uint8_t requestFrom(uint8_t address, uint8_t quantity,uint8_t sendStop)
  4. {
  5. uint8_t rd ;
  6. uint8_t error = softiic.restart(address <<1 | 1); //*repeat start start
  7. Serial.print("error");
  8. Serial.println(error);
  9. for(int i = 0;i<quantity;i++)
  10. {
  11. rd = softiic.read( i == (quantity- 1));
  12. rxbuff[i] = rd;
  13. //delay(10);
  14. //if(error == 0)
  15. Serial.println(rd);
  16. }
  17. Serial.println("");
  18. // if(sendStop )
  19. softiic.stop();
  20. uint8_t rlt = (error ?1:0);
  21. return rlt;
  22. }
  23. //test
  24. uint8_t requestFrom(uint8_t address)
  25. {
  26. softiic.start(address <<1 | 1);
  27. uint8_t rd = softiic.read(1);
  28. softiic.stop();
  29. return rd;
  30. }

树莓派

打开树莓派I2C接口

2.安装I2C工具

  1. # sudo apt-get install i2c-tools
  2. # sudo i2cdetect 1

3.查看IIC设备

4.安装PCA9865库

  1. sudo apt-get install git build-essential python-dev
  2.   cd ~
  3.   git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
  4.   cd Adafruit_Python_PCA9685
  5.   sudo python3 setup.py install

或是直接进入 GitHub - adafruit/Adafruit_Python_PCA9685: Python code to use the PCA9685 PWM servo/LED controller with a Raspberry Pi or BeagleBone black. 下载后传给树莓派 然后使用 pip install Adafruit_Python_PCA9685.zip 安装

安装完成后,解压Adaruit_Python_PCA9685 进入examples文件夹

执行 python simpletest.py 

树莓派使用PCA9685舵机控制板控制舵机_树莓派pca9685控制舵机-CSDN博客

树莓派使用 Python 驱动 SSD1306(IIC/SPI 通信) - 提莫的神秘小站

树莓派i2c通讯 设置 和 查看 i2c通信地址方法_树莓派读取i2c寄存器-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/774858
推荐阅读
相关标签
  

闽ICP备14008679号