#!/usr/bin/python
# -*- encoding: utf-8 -*-

# Priklad ovladani obvodu PCA9685: 
#  Postupné rozsvecovani a zhasinani LED pri zmene stridy

import time
import smbus



bus = smbus.SMBus(1)   # novejsi varianta RasPi (512MB)
#bus = smbus.SMBus(0)   # starsi varianta RasPi (256MB)

addr = 0x40            # I2C adresa obvodu PCA9685 (kdyz jsou vsechny adresovaci vstupy v "0", je adresa 0x40)



bus.write_byte_data(addr,0x00,0b00010000)  # SLEEP
bus.write_byte_data(addr,0xFE,5)           # nastaveni frekvence prescaleru  (cislo 5 je asi 1kHz)
bus.write_byte_data(addr,0x01,0b00000100)  # Logika vystupu: Spinani pres NPN tranzistor (INVRT="0", OUTDRV="1")



#  zmeny jasu mezi jednotlivymi kroky
#  vzdycky pro 4 LED v rade
 
urovne = [0, 0, 0, 0, 2, 8, 50, 256, 900, 4095 , 900, 256, 40, 6, 1, 0, 0, 0, 0]
#                   LED_A , LED_B , LED_C , LED_D
#     prvni krok  =    0  ,    0  ,    0  ,    0
#     druhy krok  =    0  ,    0  ,    0  ,    2
#     treti krok  =    0  ,    0  ,    2  ,    8
#     ctvrty krok =    0  ,    2  ,    8  ,   50
#     paty krok   =    2  ,    8  ,   50  ,  256
#     sesty krok  =    8  ,   50  ,  256  ,  900
#  .......
#   posledni krok =    0  ,    0  ,    0  ,    0





# hlavni smycka pro postupne prepinani jasu LED v 16 krocich
for krok in range (16):


  #  LED_A 
  kanal = 0                                 # cislo kanalu, na ktery je pripojena prvni LED (PWM0)
  adr_kan = 6 + (kanal * 4)                 # kazdy kanal se ridi pomomci 4 bajtu. Nulty kanal zacina na adrese 6

  sirka_H = urovne[krok]
  dolnibajt_H = int(sirka_H % 256)          # prepocet 12-bitove sirky impulzu na horni a dolni bajt
  hornibajt_H = int(sirka_H / 256)
  bus.write_byte_data(addr, adr_kan,     0) # prechod signalu z "0" na "1" v case "T + nula"  8xLSB
  bus.write_byte_data(addr, adr_kan + 1, 0) #                                                 4xMSB
  bus.write_byte_data(addr, adr_kan + 2, dolnibajt_H) #  cas prechodu z "1" na "0" 8xLSB
  bus.write_byte_data(addr, adr_kan + 3, hornibajt_H) #                            4xMSB




  #  LED_B 
  kanal = 1                                 # cislo kanalu, na ktery je pripojena druha LED (PWM1)
  adr_kan = 6 + (kanal * 4)                 # kazdy kanal se ridi pomomci 4 bajtu. Nulty kanal zacina na adrese 6

  sirka_H = urovne[krok+1]
  dolnibajt_H = int(sirka_H % 256)          # prepocet 12-bitove sirky impulzu na horni a dolni bajt
  hornibajt_H = int(sirka_H / 256)
  bus.write_byte_data(addr, adr_kan,     0) # prechod signalu z "0" na "1" v case "T + nula"  8xLSB
  bus.write_byte_data(addr, adr_kan + 1, 0) #                                                 4xMSB
  bus.write_byte_data(addr, adr_kan + 2, dolnibajt_H) #  cas prechodu z "1" na "0" 8xLSB
  bus.write_byte_data(addr, adr_kan + 3, hornibajt_H) #                            4xMSB



  #  LED_C 
  kanal = 14                                # cislo kanalu, na ktery je pripojena treti LED   (PWM14)
  adr_kan = 6 + (kanal * 4)                 # kazdy kanal se ridi pomomci 4 bajtu. Nulty kanal zacina na adrese 6

  sirka_H = urovne[krok+2]
  dolnibajt_H = int(sirka_H % 256)          # prepocet 12-bitove sirky impulzu na horni a dolni bajt
  hornibajt_H = int(sirka_H / 256)
  bus.write_byte_data(addr, adr_kan,     0) # prechod signalu z "0" na "1" v case "T + nula"  8xLSB
  bus.write_byte_data(addr, adr_kan + 1, 0) #                                                 4xMSB
  bus.write_byte_data(addr, adr_kan + 2, dolnibajt_H) #  cas prechodu z "1" na "0" 8xLSB
  bus.write_byte_data(addr, adr_kan + 3, hornibajt_H) #                            4xMSB



  #  LED_D 
  kanal = 15                                # cislo kanalu, na ktery je pripojena ctvrta LED
  adr_kan = 6 + (kanal * 4)                 # kazdy kanal se ridi pomomci 4 bajtu. Nulty kanal zacina na adrese 6

  sirka_H = urovne[krok+3]
  dolnibajt_H = int(sirka_H % 256)          # prepocet 12-bitove sirky impulzu na horni a dolni bajt
  hornibajt_H = int(sirka_H / 256)
  bus.write_byte_data(addr, adr_kan,     0) # prechod signalu z "0" na "1" v case "T + nula"  8xLSB
  bus.write_byte_data(addr, adr_kan + 1, 0) #                                                 4xMSB
  bus.write_byte_data(addr, adr_kan + 2, dolnibajt_H) #  cas prechodu z "1" na "0" 8xLSB
  bus.write_byte_data(addr, adr_kan + 3, hornibajt_H) #                            4xMSB

  
  
  # spusteni generatoru s  novymi parametry    
  bus.write_byte_data(addr,0x00,0b00000000)  # spust PWM generator
  time.sleep(0.5)                            # pul sekundy generovani signalu
  

