PCA9865 module usage

It is originally used to control lights. If it is used to control servos, etc., an external power supply is required.

arduino arduino stm32

Pin A4 is SDA and pin A5 is SCL

asrpro

Use softiic library and use arduino’s Adafruit_PWMServoDriver driver library to modify

To encapsulate, you need to copy the contents of the Adafruit_PWMServoDriver.c file to the Adafruit_PWMServoDriver.h header file

PCA9685 code
 Use asr_softiic.h and arduino Adafruit_PWMServoDriver driver libraries that come with asrpro
Modifications
softiic.start(_i2caddr<<1|0); // Write 0, read 1 (the address needs to be shifted one bit to the left
Comment 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 & amp;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();
//------------------------------------------------ --------
///*********************************************** ***************
boolbl = 0;
int i=0;
void LED(){
  while (1) {
   
    //Scan device
    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:Xiaodie-fresh female voice,vol:10,speed:10,platform:haohaodada}
  //{playid:10001,voice:Welcome to the voice assistant, wake me up with Tianwen Wuyao. }
  //{playid:10002,voice:I quit, wake me up with Tianwen Wuyao}
  //{ID:0,keyword:"wake word",ASR:"Tianwen Wuyao",ASRTO:"I am"}
  //{ID:1,keyword:"Command word",ASR:"Turn on the lights",ASRTO:"Okay, turn on the lights now"}
  //{ID:2,keyword:"Command word",ASR:"Turn off the lights",ASRTO:"Okay, turn off the lights now"}
  xTaskCreate(hardware_init,"hardware_init",256,NULL,100,NULL);
}
//------------------------------------------------ --------
//{ID:250,keyword:"Command word",ASR:"Maximum volume",ASRTO:"Adjust the volume to the maximum"}
//{ID:251,keyword:"Command word",ASR:"Medium volume",ASRTO:"Adjust the volume to medium"}
//{ID:252,keyword:"Command word",ASR:"Minimum volume",ASRTO:"Adjust the volume to the minimum"}
void hardware_init(){
  xTaskCreate(LED,"LED",256,NULL,4,NULL);
  vTaskDelete(NULL);
}
/*Describe this function...
*/
void ASR_CODE(){
  switch (snid) {
   case 1:
    //digitalWrite(4,0);
    break;
   case 2:
    //digitalWrite(4,1);
    break;
  }
}

asrpro softiic requestfrom // Use SOFTI2C to modify

Arduino softi2c and softwire have different read wire implementations

The definitions in the .c file in asrpro need to be placed in .h, otherwise an error will occur.

//arduino soft_I2c quantity reads the 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;
  
}

Raspberry Pi

Open the Raspberry Pi I2C interface

2. Install I2C tools

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

3. View IIC devices

4. Install PCA9865 library

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

Or go directly to GitHub – adafruit/Adafruit_Python_PCA9685: Python code to use the PCA9685 PWM servo/LED controller with a Raspberry Pi or BeagleBone black. Download and transfer to Raspberry Pi and then use pip install Adafruit_Python_PCA9685.zip to install

After the installation is complete, unzip Adaruit_Python_PCA9685 and enter the examples folder

Execute python simpletest.py

Raspberry Pi uses PCA9685 servo control board to control the servo_Raspberry Pi pca9685 controls the servo-CSDN Blog

Raspberry Pi uses Python to drive SSD1306 (IIC/SPI communication) – Teemo’s Mysterious Station

Raspberry Pi i2c communication settings and methods to view i2c communication address_Raspberry Pi reads i2c registers-CSDN Blog