Friday, November 25, 2016

ESP Basic - PCA9685-16Channel 12-bit PWM I²C-bus LED controller Driver - Part 1



PCA9685 Extension Board Module Available also on Tindie!





ESP Basic Tutorials Series: 

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

  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.



 What we will need:

    Connection with the ESP8266 nEXT EVO Board is very easy, as PCA9685 Module connector is fully compatible with the nEXT Bus connector.


 
Driver implementation

   As been a I2C compatible device you need to have a standard I2C Bus Initialisation function as usual and also to know the I2C address of the device.  
  For a more detailed hardware overview go to PCA9685 General Description Article


 Software: 

1. Main program:

 i2c.setup(4,5) 'choose your I2C bus pins

dev_addr = 64  '0x40 - I2C Address for the PCA9685

mode1 = 0    '0x00 location for Mode1 register address
mode2 = 1    '0x01 location for Mode2 reigster address
led0 = 6     '0x06 location for start of LED0 registers
rst = 1      '0x01 reset device
rval = 0     'read register value

led_on = 4096
led_off = 0

ledN = 0

dim led_stat(8)
led_stat(0)=0
led_stat(1)=0
led_stat(2)=0
led_stat(3)=0
led_stat(4)=0
led_stat(5)=0
led_stat(6)=0
led_stat(7)=0


stat = "Init.."

'reset device     write_reg(mode1, rst)
reg = mode1
data = rst
gosub [WRITE_REG]

'check if proper initialised
gosub [READ_REG]
'wprint rval
if rval == "1" then
   status = true
   stat = "PCA9685 Init OK"
else
   status = false
   stat = "PCA9685 Init Failure!"
end if

wprint " <b>PCA9685 - 16Channel 12-bit PWM I2C bus LED controller<br>driver demo</b><br><i>by tech@esp8266-projects.com</i><br><br><br>"
wprint "Initialisation Status: "
textbox stat

'set for auto-increment
let data = 160
gosub [WRITE_REG]

'Choose below the desired output mode!
'Direct LED connection
'set to output mode INVRT = 1 OUTDRV = 0
reg = mode2
data = 16
gosub [WRITE_REG]


'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
 
'choose LED_N - ON
wprint " <br>Input LED number : "
textbox ledN
wprint "<br> <br>"
button " Set LED ON ",[SetON]
button " Set LED OFF ",[SetOFF]
wprint "<br> <br> <br>"
button "LED 0",[LED0]
button "LED 1",[LED1]
button "LED 2",[LED2]
button "LED 3",[LED3]
button "LED 4",[LED4]
button "LED 5",[LED5]
button "LED 6",[LED6]
button "LED 7",[LED7]
wprint "<br> <br><br>"
button "LOOP",[loop]
wprint "<br> <br><br> <br>"
button "EXIT",[Exit]
wait


2. LOW Level subroutines


2.1 WRITE Register "reg"

[WRITE_REG]
i2c.begin(dev_addr)
i2c.write(reg)
i2c.write(data)
i2c.end()
return

2.2 READ Register "reg"


[READ_REG]
i2c.begin(dev_addr)
i2c.write(reg)
i2c.end()
i2c.begin(dev_addr)
i2c.requestfrom(dev_addr,1) 'start a transaction to read 1 byte
rval = i2c.read()           'read the byte
i2c.end()
return


2.3 WRITE LED_N Register
 

[WRITE_LED]
i2c.begin(dev_addr)
i2c.write(led0+4*ledN)
ah = led_on >> 8
al = led_on and 255
i2c.write(al)
i2c.write(ah)

ah = led_off >> 8
al = led_off and 255
i2c.write(al)
i2c.write(ah)
i2c.end()
return


 3. BUTTON Subroutines

[LED0]
ledN = 0
gosub [LED_SW]
wait

[LED1]
ledN = 1
gosub [LED_SW]
wait

[LED2]
ledN = 2
gosub [LED_SW]
wait

[LED3]
ledN = 3
gosub [LED_SW]
wait

[LED4]
ledN = 4
gosub [LED_SW]
wait

[LED5]
ledN = 5
gosub [LED_SW]
wait

[LED6]
ledN = 6
gosub [LED_SW]
wait

[LED7]
ledN = 7
gosub [LED_SW]
wait



4. LED_N Switch subroutine



[LED_SW]
if led_stat(ledN) = 0 then
   led_stat(ledN) = 1
   led_on = 4096
   led_off = 0
   gosub [WRITE_LED]
else
   led_stat(ledN) = 0
   led_on = 0
   led_off = 4096
   gosub [WRITE_LED]
end if
return


 

5. ON / OFF Subroutines

          [SetON]
led_on = 4096
led_off = 0
gosub [WRITE_LED]
wait

[SetOFF]
led_on = 0
led_off = 4096
gosub [WRITE_LED]
wait


 
6. FOR loop demo
[loop]
For x = 0 to 8
ledN = x
gosub [LED_SW]
Next x
For x = 8 to 0 step -1
ledN = x
gosub [LED_SW]
Next x
wait



7. EXIT Program subroutine

[Exit]
end


 


In the ESP Basic Web editor interface Type & Save your program as "PCA9685.bas" and Run it.  
If all OK the result should look as below:
  



No comments:

Post a Comment