Search code examples
picpwmservomotordriverdc

Control fan speed with PCA9685 and a PIC


I would like to control the speed of various motors using a PIC and PCA9685.

This following code allow me to start the rotation, but it does not reduce the speed

void pca9685_Set_rate(int address, int rate)
{
    i2c_start();
    i2c_write(address);
    i2c_write(MODE1);
    i2c_write(Sleep);
    i2c_stop();

    i2c_start();
    i2c_write(address);
    i2c_write(PreScale);
    i2c_write(rate);
    i2c_stop();

    i2c_start();
    i2c_write(address);
    i2c_write(MODE1);
    i2c_write(PCA9685AI);  // Set MODE1 back to INT_CLK, AutoIncrement, Normal
    i2c_stop();

    __delay_us(500);       // Required for PCA oscillator startup
}

void pca9685_Set_speed(int address, int line, int speed)
{
    unsigned int on_count  = 0;
    unsigned int off_count = speed;

    i2c_start();
    i2c_write(address);
    i2c_write((line*4) + 6);
    i2c_write(on_count);        // Writing 8 LSB bits of ON count
    i2c_write(on_count >> 8);   // Writing 4 MSB bits of ON count
    i2c_write(off_count);       // Writing 8 LSB bits of OFF count
    i2c_write(off_count >> 8);  // Writing 4 MSB bits of ON count
    i2c_stop();
}

in the main():

enter code here
pca9685_Set_rate(0x80, 0x03); // 1600
ledn = 1;

pca9685_Set_speed(0x80, ledn, 4095);
DelayMs(500);
DelayMs(500);
DelayMs(500);
DelayMs(500);

pca9685_Set_speed(0x80, ledn, 3500);
DelayMs(500);
DelayMs(500);
DelayMs(500);
DelayMs(500);

pca9685_Set_speed(0x80, ledn, 3000);
DelayMs(500);
DelayMs(500);
DelayMs(500);
DelayMs(500);

pca9685_Set_speed(0x80, ledn, 2500);
DelayMs(500);
DelayMs(500);
DelayMs(500);
DelayMs(500);

pca9685_Set_speed(0x80, ledn, 2000);

I am using a single MOSFET on PCA9685 out to convert the level to 12 V.

Could be this the problem? Must I use a TB6612 or a DRV8833?


Solution

  • It was solved by adding a 2.2 kΩ resistor and a TIP120 (power transistor) on any output, so for each 12 V DC fan.

    The code is OK.