Wednesday, June 29, 2016

PCA9685-16Channel 12-bit PWM I²C-bus LED controller Driver


    !! UPDATE !! UPDATE !!
   Available on Tindie Store here 




   PCA9685 General Description

   If you are looking for a very simple to use 16 Channel LED controller or just for a nice 16 Channel, high resolution PWM driver then this one is for you!

   The PCA9685 is an I²C-bus controlled 16-channel LED controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications.

   Each LED output has its own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates at a programmable frequency from a typical of 24 Hz to 1526 Hz with a duty cycle that is adjustable from 0 % to 100 % to allow the LED to be set to a specific brightness value. All outputs are set to the same PWM frequency.

  Each LED output can be off or on (no PWM control), or set at its individual PWM controller value.

  The LED output driver is programmed to be either open-drain with a 25 mA current sink capability at 5 V or totem pole with a 25 mA sink, 10 mA source capability at 5 V.

  The PCA9685 operates with a supply voltage range of 2.3 V to 5.5 V and the inputs and outputs are 5.5 V tolerant. LEDs can be directly connected to the LED output (up to 25 mA, 5.5 V) or controlled with external drivers and a minimum amount of discrete components for larger current or higher voltage LEDs.



PCA9685 - Block Diagram

   

Features

  • 16 LED drivers. Each output programmable at:
    • Off
    • On
    • Programmable LED brightness
    • Programmable LED turn-on time to help reduce EMI
     
  • 1 MHz Fast-mode Plus compatible I²C-bus interface with 30 mA high drive capability on SDA output for driving high capacitive buses 
  • 4096-step (12-bit) linear programmable brightness per LED output varying from fully off (default) to maximum brightness 
  • LED output frequency (all LEDs) typically varies from 24 Hz to 1526 Hz (Default of 1Eh in PRE_SCALE register results in a 200 Hz refresh rate with oscillator clock of 25 MHz)
  • Sixteen totem pole outputs (sink 25 mA and source 10 mA at 5 V) with software programmable open-drain LED outputs selection (default at totem pole). No input function.
  • Output state change programmable on the Acknowledge or the STOP Command to update outputs byte-by-byte or all at the same time (default to ‘Change on STOP’)
  • Active LOW Output Enable (OE) input pin. LEDn outputs programmable to logic 1, logic 0 (default at power-up) or ‘high-impedance’ when OE is HIGH.
  • 6 hardware address pins allow 62 PCA9685 devices to be connected to the same I²C-bus
  • Toggling OE allows for hardware LED blinking
  • 4 software programmable I²C-bus addresses (one LED All Call address and three LED Sub Call addresses) allow groups of devices to be addressed at the same time in any combination (for example, one register used for ‘All Call’ so that all the PCA9685s on the I²C-bus can be addressed at the same time and the second register used for three different addresses so that 1⁄3 of all devices on the bus can be addressed at the same time in a group). Software enable and disable for these I²C-bus address.
  • Software Reset feature (SWRST General Call) allows the device to be reset through the I²C-bus
  • 25 MHz typical internal oscillator requires no external components
  • External 50 MHz (max.) clock input
  • Internal power-on reset
  • Noise filter on SDA/SCL inputs
  • Edge rate control on outputs
  • No output glitches on power-up
  • Supports hot insertion
  • Low standby current
  • Operating power supply voltage range of 2.3 V to 5.5 V
  • 5.5 V tolerant inputs
  • -40 °C to +85 °C operation
  • ESD protection exceeds 2000 V HBM per JESD22-A114, 200 V MM per JESD22-A115 and 1000 V CDM per JESD22-C101
  • Latch-up testing is done to JEDEC Standard JESD78 which exceeds 100 mA
  • Packages offered: TSSOP28, HVQFN28


 For more details please take a look at the PCA9685 Datasheet



What we will need:

  • ESP8266 nEXT EVO Board
  • PCA9685 Extension Board as below or similar
  • For programming and uploading the driver and the software we will continue to use the LuaUploader as before.  
    Connection with the ESP8266 nEXT EVO Board is very easy, as PCA9685 Extension Board connector is fully compatible with the nEXT connector. Depending on how to you choose you socket type, you can install it on TOP or Bottom of the ESP8266 nEXT EVO Board :

PCA9685 16 Channel PWM Extension Board


Driver implementation
 
 
As
PCA9685 has a I2C compatible compatible interface, building a driver for it it's a pretty straigh forward process following the standard path for a I2C compatible device:
 
 
1 . I2C Bus initialisation function
function  init_i2c(sda, scl)
          i2c.setup(id, sda, scl, i2c.SLOW)
     end


2 . PCA9685 Read register function
function read_reg(reg)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,reg)
          i2c.stop(id)
          i2c.start(0x0)
          i2c.address(0x0, dev_addr,i2c.RECEIVER)
          c = i2c.read(0x0,1)
          i2c.stop(0x0)
          rval = string.byte(c, 1)
          --print(rval)
          return rval
end

3 . PCA9685 Write register function
function write_reg(reg, data)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,reg)
          i2c.write(id,data)
          i2c.stop(id)
end


4 . Write 12bit values function
function write_12_bit(a)
         ah=bit.rshift(a,8)
         al=bit.band(a,0xff)
         --print(a,ah,al)
         return ah, al
end  

5 . PCA9685 initialisation function

-- LED_ON and LED_OFF are 12bit values (0-4095)
-- ledN is 0-15

function init_pca()
    write_reg(mode1, rst)           --reset device

    if (read_reg(mode1)==0x01) then --check status
        status = true
        print("PCA9685 Init OK")
    else
        status = false
        print("PCA9685 Init Failure!")
    end
    --print(status)

    write_reg(mode1, 0xA0) --10100000 - set for auto-increment


   -- choose here the desired output mode!

    --Direct LED connection
    write_reg(mode2, 0x10) --set to output mode INVRT = 1 OUTDRV = 0

    --External N-type driver
    --write_reg(mode2, 0x04)   -- set to output mode INVRT = 0 OUTDRV = 1

    --External P-type driver
    --write_reg(mode2, 0x14) --set to output mode INVRT = 1 OUTDRV = 1
   
    return status
end


6 . Write LEDn function
 function write_LED(ledN, LED_ON, LED_OFF)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,led0+4*ledN)
          write_12_bit(LED_ON)
          i2c.write(id,al)
          i2c.write(id,ah)
          write_12_bit(LED_OFF)
          i2c.write(id,al)
          i2c.write(id,ah)
          i2c.stop(id)
end


7 . Set LEDn ON function  

function setLED_ON(ledN)
        write_LED(ledN,0x1000,0)
end


8 . Set LEDn OFF function

function setLED_OFF(ledN)
        write_LED(ledN,0,0x1000)
end


9 . Set LEDn Dimmer function

function LED_Dimmer(ledN, dimm)
   if (dimm==0) then setLED_OFF(ledN)
   else if (dimm==100) then setLED_ON(ledN)
        else write_LED(ledN, dim, 0)
   end
   end
end


 10 . Main Program
dev_addr=0x40  --I2C Address for the PCA9685

mode1=0x00     --location for Mode1 register address
mode2=0x01     --location for Mode2 reigster address
led0=0x06      --location for start of LED0 registers
rst=0x01       --reset device

id = 0
sda=2 --GPIO4
scl=1 --GPIO5

--init I2C Bus
init_i2c(sda, scl)


--init PCA9685
init_pca()
 
--running tests
--set LED_0 ON/OFF
setLED_ON(0)
setLED_OFF(0)

--Dim LED_0 at different levels
write_LED(0,0,4095)
write_LED(0,0,2048)
write_LED(0,0,1024)
write_LED(0,0,512)
write_LED(0,0,256)
write_LED(0,0,128)
write_LED(0,0,64)
write_LED(0,0,32)
write_LED(0,0,16)
write_LED(0,0,8)
write_LED(0,0,4)

 --test Dimmer
dim=2
tmr.alarm( 1, 200, 1, function()
      if (dim>=4096) then dim=2 end
      write_LED(0,0,dim)
      dim=dim+200
      print(dim)
end)


tmr.stop(1)










1 comment:

rambler said...

Thank you for another great tutorial again TJ, you really are opening up Esp_Basic to some very useful i2c functionality.

Post a Comment