Pwm.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // PCA9685 PWM控制模块
  2. const i2cBus = require("i2c-bus")
  3. const { Pca9685Driver } = require("pca9685")
  4. const RPIO = require("rpio");
  5. class ContrlService {
  6. constructor() {
  7. // PWM 和 舵机配置
  8. this.pwmOption = {
  9. i2c: i2cBus.openSync(1), // 树莓派1:scl1
  10. address: 0x40, //板子地址
  11. frequency: 50, //频率
  12. debug: false
  13. }
  14. //PCA 板子位置电调+舵机
  15. this.MoAndSero = {
  16. m1: 0,
  17. m2: 1,
  18. s1: 2,
  19. s2: 3
  20. }
  21. // prio init
  22. RPIO.init({ mapping: "gpio" });
  23. // 继电器解锁
  24. RPIO.open(22, RPIO.OUTPUT, RPIO.HIGH);
  25. RPIO.open(23, RPIO.OUTPUT, RPIO.HIGH);
  26. // 开灯
  27. RPIO.open(22, RPIO.OUTPUT, RPIO.HIGH);
  28. // init PWM
  29. this.PWM = new Pca9685Driver(this.pwmOption, er => {
  30. if (er) {
  31. console.error("Error initializing PCA9685");
  32. }
  33. })
  34. // 解锁计数器
  35. this.Snum = 0
  36. // 解锁状态
  37. this.enable = false
  38. }
  39. // 设置pwm
  40. async changPWM (params) {
  41. const { v0, v1, v2, v3 } = params
  42. if (typeof (v0) == 'number' || typeof (v3) == 'number') {
  43. if (this.enable) {
  44. // 解锁之后需要2秒给电调中立值
  45. if (this.Snum >= 50 && this.Snum <= 61) this.Snum++
  46. if (this.Snum >= 60) {
  47. if (Math.abs(+v2 - 128) < 20) {
  48. console.log('前后', v3)
  49. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(+v3 - 256)));
  50. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(+v3 - 256)));
  51. } else {
  52. // 分左右
  53. if ((+v2 - 128) > 20) {
  54. // 右
  55. console.log('右', +v2);
  56. const a = 128 - (+v2 - 128)
  57. const b = 128 + (+v2 - 128)
  58. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
  59. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
  60. } else if (+v2 - 128 < -20) {
  61. // 左
  62. console.log('左', +v2);
  63. const a = 128 - (+v2 - 128)
  64. const b = 128 + (+v2 - 128)
  65. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
  66. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
  67. }
  68. }
  69. //云台
  70. if (v0 || v1) {
  71. console.log('云台', v0, v1)
  72. const a = +v1 > 200 ? 200 : +v1
  73. this.PWM.setPulseLength(this.MoAndSero.s1, this.Servo2pwm(+v0));
  74. this.PWM.setPulseLength(this.MoAndSero.s2, this.Servo2pwm(+a));
  75. }
  76. }
  77. } else {
  78. this.unLOCK(v0, v1, v2, v3)
  79. }
  80. } else {
  81. console.log('参数格式错误,自动略过');
  82. return
  83. }
  84. }
  85. /**
  86. * 内八解锁
  87. * @param {*} v0
  88. * @param {*} v1
  89. * @param {*} v2
  90. * @param {*} v3
  91. */
  92. unLOCK (v0, v1, v2, v3) {
  93. // 未解锁=>进行解锁:发送端的频率是0.04S,0.05*60 = 3S
  94. // 内八 :v0<50,v1>200,v2>200,v3<50
  95. if (+v0 <= 60 && +v1 >= 190 && +v3 >= 190 && +v2 <= 60) {
  96. if (this.Snum >= 0 && this.Snum <= 51) this.Snum++
  97. } else {
  98. this.Snum = 0
  99. }
  100. if (this.Snum == 50) {
  101. RPIO.open(23, RPIO.OUTPUT, RPIO.HIGH);
  102. this.enable = true
  103. }
  104. console.log('解锁中', v0, v1, v2, v3)
  105. }
  106. /**
  107. * 电调换算比例:摇杆范围0-256,PWM范围500~1500~2500
  108. * @param {number} v
  109. * @returns
  110. */
  111. Motor2pwm (v) {
  112. // 分为6挡位,中值128,步进256/6
  113. const num = parseInt(256 / 6)
  114. // 方向调换
  115. const dirc = Math.abs(v - 256)
  116. // 真实值
  117. let value = 128
  118. // 步进取中间值
  119. if (dirc > 0 && dirc < num) {
  120. value = num / 2
  121. } else if (dirc > num && dirc <= num * 2) {
  122. value = num + (num / 2)
  123. } else if (dirc > num * 2 && dirc < 128) {
  124. value = 128 - (num / 2)
  125. } else if (dirc > 128 && dirc <= (128 + num)) {
  126. value = 128 + (num / 2)
  127. } else if (dirc > (128 + num) && dirc <= (128 + num * 2)) {
  128. value = 128 + num + (num / 2)
  129. } else if (dirc > (128 + num * 2) && dirc <= 256) {
  130. value = 256 - (num / 2)
  131. } else {
  132. value = 128
  133. }
  134. return parseInt(value / (256 / 2000)) + 500
  135. }
  136. /**
  137. * 舵机换算比例:摇杆范围0-256,PWM范围1000~1500~2000
  138. * @param {number} v
  139. * @returns
  140. */
  141. Servo2pwm (v) {
  142. return parseInt(v / (256 / 1000)) + 1000
  143. }
  144. }
  145. module.exports = new ContrlService()