赞
踩
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接三极管,提供对外设的驱动
引脚A4为SDA,引脚A5为SCL
PA1 SCL PA0 SDA
使用softiic库,使用arduino的 Adafruit_PWMServoDriver驱动库 进行修改
若要封装,需将Adafruit_PWMServoDriver.c文件内容复制到Adafruit_PWMServoDriver.h头文件中
- PCA9685代码
- 使用asrpro自带的asr_softiic.h 和 arduino Adafruit_PWMServoDriver驱动库
- 修改处
- softiic.start(_i2caddr<<1|0); // 写 0 ,读 1 (地址要左移一位
- 注释requestfrom ; return 0
- #include "asr.h"
- extern "C"{ void * __dso_handle = 0 ;}
- #include "setup.h"
- #include "HardwareSerial.h"
- #include "asr_softiic.h"
- uint32_t snid;
- void hardware_init();
- void LED();
- void ASR_CODE();
- #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 0xFD
- class 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);
- };
- // class MySoftIIC
- // {
- // public:
- // void begin(){softiic.begin(0,1);}
- // void stop(){softiic.stop();}
- // void write(uint8_t d){softiic.write(d);}
- // uint8_t read(bool b ){softiic.read(b);}
- // void requestFrom(uint8_t addr,uint8_t d){};
- // int start(uint8_t addr){return softiic.start(addr<<1|0);}
- // void beginTransmission(uint8_t addr){start(addr);}
- // void stop(){softiic.stop();}
- // };
- // MySoftIIC WIRE;
- // Set to true to print some debug messages, or false to disable them.
- #define ENABLE_DEBUG_OUTPUT false
- Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t addr) {
- _i2caddr = addr;
- }
- void Adafruit_PWMServoDriver::begin(void) {
- softiic.begin(0,1);
- reset();
- }
- void Adafruit_PWMServoDriver::reset(void) {
- write8(PCA9685_MODE1, 0x0);
- }
- void Adafruit_PWMServoDriver::setPWMFreq(float freq) {
- //Serial.print("Attempting to set freq ");
- //Serial.println(freq);
- freq *= 0.9; // Correct for overshoot in the frequency setting (see issue #11).
- float prescaleval = 25000000;
- prescaleval /= 4096;
- prescaleval /= freq;
- prescaleval -= 1;
- if (ENABLE_DEBUG_OUTPUT) {
- Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
- }
- uint8_t prescale = floor(prescaleval + 0.5);
- if (ENABLE_DEBUG_OUTPUT) {
- Serial.print("Final pre-scale: "); Serial.println(prescale);
- }
- uint8_t oldmode = read8(PCA9685_MODE1);
- uint8_t newmode = (oldmode&0x7F) | 0x10; // sleep
- write8(PCA9685_MODE1, newmode); // go to sleep
- write8(PCA9685_PRESCALE, prescale); // set the prescaler
- write8(PCA9685_MODE1, oldmode);
- delay(5);
- write8(PCA9685_MODE1, oldmode | 0xa1); // This sets the MODE1 register to turn on auto increment.
- // This is why the beginTransmission below was not working.
- // Serial.print("Mode now 0x"); Serial.println(read8(PCA9685_MODE1), HEX);
- }
- void Adafruit_PWMServoDriver::setPWM(uint8_t num, uint16_t on, uint16_t off) {
- //Serial.print("Setting PWM "); Serial.print(num); Serial.print(": "); Serial.print(on); Serial.print("->"); Serial.println(off);
- softiic.start(_i2caddr<<1|0);
- softiic.write(LED0_ON_L+4*num);
- softiic.write(on);
- softiic.write(on>>8);
- softiic.write(off);
- softiic.write(off>>8);
- softiic.stop();
- }
- // Sets pin without having to deal with on/off tick placement and properly handles
- // a zero value as completely off. Optional invert parameter supports inverting
- // the pulse for sinking to ground. Val should be a value from 0 to 4095 inclusive.
- void Adafruit_PWMServoDriver::setPin(uint8_t num, uint16_t val, bool invert)
- {
- // Clamp value between 0 and 4095 inclusive.
- if(val > 4095)
- val = 4095;
- if (invert) {
- if (val == 0) {
- // Special value for signal fully on.
- setPWM(num, 4096, 0);
- }
- else if (val == 4095) {
- // Special value for signal fully off.
- setPWM(num, 0, 4096);
- }
- else {
- setPWM(num, 0, 4095-val);
- }
- }
- else {
- if (val == 4095) {
- // Special value for signal fully on.
- setPWM(num, 4096, 0);
- }
- else if (val == 0) {
- // Special value for signal fully off.
- setPWM(num, 0, 4096);
- }
- else {
- setPWM(num, 0, val);
- }
- }
- }
- uint8_t Adafruit_PWMServoDriver::read8(uint8_t addr) {
- softiic.start(_i2caddr<<1|0);
- softiic.write(addr);
- softiic.stop();
- //softiic.requestFrom((uint8_t)_i2caddr, (uint8_t)1);
- //return softiic.read();
- return 0;
- }
- void Adafruit_PWMServoDriver::write8(uint8_t addr, uint8_t d) {
- softiic.start(_i2caddr<<1|0);
- softiic.write(addr);
- softiic.write(d);
- softiic.stop();
- }
- Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
- //--------------------------------------------------------
- ///**************************************************************
- bool bl = 0;
- int i=0;
- void LED(){
- while (1) {
-
- //扫描设备
- for(int i = 1;i<0x7f;i++)
- {
- // int val = softiic.start(i<<1 | 0);
- // softiic.stop();
- // Serial.print(i,HEX);
- // Serial.print("ox ");
- // Serial.println(val,HEX);
- pwm.begin();
- pwm.setPWMFreq(1600);
- pwm.setPin(4,i*46,0);
- delay(100);
-
- }
-
- }
- vTaskDelete(NULL);
- }
- //------------------------------------------------
- void setup()
- {
- Serial.begin(9600);
- delay(100);
- //softiic.begin(0,1);
- pinMode(4,output);
- setPinFun(4,FIRST_FUNCTION);
- digitalWrite(4,0);
- //{speak:小蝶-清新女声,vol:10,speed:10,platform:haohaodada}
- //{playid:10001,voice:欢迎使用语音助手,用天问五幺唤醒我。}
- //{playid:10002,voice:我退下了,用天问五幺唤醒我}
- //{ID:0,keyword:"唤醒词",ASR:"天问五幺",ASRTO:"我在"}
- //{ID:1,keyword:"命令词",ASR:"打开灯光",ASRTO:"好的,马上打开灯光"}
- //{ID:2,keyword:"命令词",ASR:"关闭灯光",ASRTO:"好的,马上关闭灯光"}
- xTaskCreate(hardware_init,"hardware_init",256,NULL,100,NULL);
- }
- //--------------------------------------------------------
- //{ID:250,keyword:"命令词",ASR:"最大音量",ASRTO:"音量调整到最大"}
- //{ID:251,keyword:"命令词",ASR:"中等音量",ASRTO:"音量调整到中等"}
- //{ID:252,keyword:"命令词",ASR:"最小音量",ASRTO:"音量调整到最小"}
- void hardware_init(){
- xTaskCreate(LED,"LED",256,NULL,4,NULL);
- vTaskDelete(NULL);
- }
- /*描述该功能...
- */
- void ASR_CODE(){
- switch (snid) {
- case 1:
- //digitalWrite(4,0);
- break;
- case 2:
- //digitalWrite(4,1);
- break;
- }
- }
asrpro softiic requestfrom // 使用SOFTI2C修改
arduino softi2c 与softwire 不同read wirte实现不同
asrpro中.c文件中的定义需放入.h中,否则错误
- //arduino soft_I2c quantity 读取数量,
-
- uint8_t rxbuff[10];
-
- uint8_t requestFrom(uint8_t address, uint8_t quantity,uint8_t sendStop)
- {
- uint8_t rd ;
- uint8_t error = softiic.restart(address <<1 | 1); //*repeat start start
- Serial.print("error");
- Serial.println(error);
- for(int i = 0;i<quantity;i++)
- {
- rd = softiic.read( i == (quantity- 1));
- rxbuff[i] = rd;
- //delay(10);
- //if(error == 0)
- Serial.println(rd);
-
- }
- Serial.println("");
-
- // if(sendStop )
- softiic.stop();
-
- uint8_t rlt = (error ?1:0);
-
- return rlt;
-
- }
-
-
- //test
- uint8_t requestFrom(uint8_t address)
- {
- softiic.start(address <<1 | 1);
- uint8_t rd = softiic.read(1);
- softiic.stop();
- return rd;
-
- }
打开树莓派I2C接口
2.安装I2C工具
- # sudo apt-get install i2c-tools
- # sudo i2cdetect 1
3.查看IIC设备
4.安装PCA9865库
- sudo apt-get install git build-essential python-dev
- cd ~
- git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
- cd Adafruit_Python_PCA9685
- 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博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。