You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pca9685.go 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package adafruitPCA9685 // import "go.rls.moe/misc/adafruitPCA9685"
  2. import (
  3. "fmt"
  4. "golang.org/x/exp/io/i2c"
  5. "log"
  6. "math"
  7. "sync"
  8. )
  9. type PCA9685 struct {
  10. dev *i2c.Device
  11. mode1 byte
  12. debugger *log.Logger
  13. lock sync.Mutex
  14. }
  15. func NewPCA9685(addressPtr *int, bus byte, debug *log.Logger) (*PCA9685, error) {
  16. if debug != nil {
  17. debug.Print("Beginning Device Setup")
  18. }
  19. var address int
  20. if addressPtr == nil {
  21. address = c_PCA9685_ADDRESS
  22. } else {
  23. address = *addressPtr
  24. }
  25. i2cDev := fmt.Sprintf("/dev/i2c-%d", bus)
  26. d, err := i2c.Open(&i2c.Devfs{Dev: i2cDev}, address)
  27. if err != nil {
  28. return nil, err
  29. }
  30. pca := &PCA9685{dev: d, debugger: debug, lock: sync.Mutex{}}
  31. pca.logDebug("Setting up Controller")
  32. err = pca.SetAllPWM(0, 0)
  33. if err != nil {
  34. pca.logDebug("Error on SetAllPWM : ", err)
  35. return nil, err
  36. }
  37. err = pca.writeBReg(c_MODE2, c_OUTDRV)
  38. if err != nil {
  39. pca.logDebug("Error on write MODE2 OUTDRV : ", err)
  40. return nil, err
  41. }
  42. err = pca.writeBReg(c_MODE1, c_ALLCALL)
  43. if err != nil {
  44. pca.logDebug("Error on write MODE2 ALLCALL : ", err)
  45. return nil, err
  46. }
  47. pca.WaitForOscillator()
  48. pca.mode1, err = pca.readBReg(c_MODE1)
  49. if err != nil {
  50. pca.logDebug("Error on read MODE1 : ", err)
  51. return nil, err
  52. }
  53. pca.mode1 = pca.mode1 & byte(^uint8(c_SLEEP))
  54. if err = pca.writeBReg(c_MODE1, pca.mode1); err != nil {
  55. pca.logDebug("Error on write MODE1 ", pca.mode1, " : ", err)
  56. }
  57. pca.WaitForOscillator()
  58. pca.logDebug("Controller has finished setup")
  59. return pca, nil
  60. }
  61. func (p *PCA9685) SetPWMFreq(freq_hz uint64) error {
  62. p.lock.Lock()
  63. defer p.lock.Unlock()
  64. var prescaleval float64 = 25000000.0 // 25 MHz
  65. prescaleval /= 4096.0 // 12-bit
  66. prescaleval /= float64(freq_hz)
  67. prescaleval -= 1.0
  68. p.logDebug("Setting PWM Frequency to ", freq_hz, " Hz")
  69. p.logDebug("Estimated pre-scale: ", prescaleval)
  70. prescale := byte(math.Floor(prescaleval + 0.5))
  71. p.logDebug("Final pre-scale: ", prescale)
  72. oldmode, err := p.readBReg(c_MODE1)
  73. if err != nil {
  74. p.logDebug("Error on read MODE1: ", err)
  75. return err
  76. }
  77. newmode := (oldmode & 0x7F) | 0x10 // sleep
  78. if err := p.writeBReg(c_MODE1, newmode); err != nil {
  79. p.logDebug("Error on write MODE1 ", newmode, " : ", err)
  80. return err
  81. }
  82. if err := p.writeBReg(c_PRESCALE, prescale); err != nil {
  83. p.logDebug("Error on write PRESCALE ", prescale, " : ", err)
  84. return err
  85. }
  86. if err := p.writeBReg(c_MODE1, oldmode); err != nil {
  87. p.logDebug("Error on write MODE1 ", oldmode, " : ", err)
  88. return err
  89. }
  90. p.WaitForOscillator()
  91. if err := p.writeBReg(c_MODE1, oldmode|0x80); err != nil {
  92. p.logDebug("Error on write MODE1 ", oldmode, " : ", err)
  93. return err
  94. }
  95. return nil
  96. }
  97. func (p *PCA9685) SetPWM(channel byte, on, off int16) error {
  98. p.lock.Lock()
  99. defer p.lock.Unlock()
  100. if err := p.writeBReg(c_LED0_ON_L+4*channel, byte(on&0xFF)); err != nil {
  101. p.logDebug("Error on write LED0_ON_L : ", err)
  102. return err
  103. }
  104. if err := p.writeBReg(c_LED0_ON_H+4*channel, byte(on>>8)); err != nil {
  105. p.logDebug("Error on write LED0_ON_H : ", err)
  106. return err
  107. }
  108. if err := p.writeBReg(c_LED0_OFF_L+4*channel, byte(off&0xFF)); err != nil {
  109. p.logDebug("Error on write LED0_OFF_ON_L : ", err)
  110. return err
  111. }
  112. if err := p.writeBReg(c_LED0_OFF_H+4*channel, byte(off>>8)); err != nil {
  113. p.logDebug("Error on write LED0_OFF_ON_H : ", err)
  114. return err
  115. }
  116. return nil
  117. }
  118. func (p *PCA9685) SetAllPWM(on, off int16) error {
  119. p.lock.Lock()
  120. defer p.lock.Unlock()
  121. if err := p.writeBReg(c_ALL_LED_ON_L, byte(on&0xFF)); err != nil {
  122. p.logDebug("Error on write LED0_ON_L : ", err)
  123. return err
  124. }
  125. if err := p.writeBReg(c_ALL_LED_ON_H, byte(on>>8)); err != nil {
  126. p.logDebug("Error on write LED0_ON_H : ", err)
  127. return err
  128. }
  129. if err := p.writeBReg(c_ALL_LED_OFF_L, byte(off&0xFF)); err != nil {
  130. p.logDebug("Error on write LED0_OFF_ON_L : ", err)
  131. return err
  132. }
  133. if err := p.writeBReg(c_ALL_LED_OFF_H, byte(off>>8)); err != nil {
  134. p.logDebug("Error on write LED0_OFF_ON_H : ", err)
  135. return err
  136. }
  137. return nil
  138. }