Pwm.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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(6, RPIO.OUTPUT, RPIO.LOW);
  25. //RPIO.open(13, RPIO.OUTPUT, RPIO.HIGH);
  26. //关闭继电器
  27. RPIO.open(13, RPIO.OUTPUT, RPIO.LOW);
  28. // 开灯
  29. RPIO.open(19, RPIO.OUTPUT, RPIO.LOW);
  30. // init PWM
  31. this.PWM = new Pca9685Driver(this.pwmOption, er => {
  32. if (er) {
  33. console.error("Error initializing PCA9685");
  34. }
  35. })
  36. // 解锁计数器
  37. this.Snum = 0
  38. // 解锁状态
  39. this.enable = false
  40. // 摇杆解锁
  41. this.contrlEnable = false
  42. // 摇杆中立值110-120
  43. this.centerNum = 120
  44. }
  45. // 设置pwm
  46. async changPWM(params) {
  47. const { v0, v1, v2, v3 } = params
  48. if (typeof (v0) == 'number' || typeof (v2) == 'number') {
  49. // 内八解锁
  50. if (this.enable) {
  51. //中位值
  52. if (!this.contrlEnable) {
  53. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(this.centerNum)));
  54. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(this.centerNum)));
  55. }
  56. //上推解锁
  57. if (!this.contrlEnable && +v3 < 200) this.contrlEnable = true
  58. // PWM操作
  59. if (this.contrlEnable) {
  60. // 注意中位误差
  61. if (Math.abs(+v3 - this.centerNum) < 20) {
  62. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(Math.abs(+v2 - 255)));
  63. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(Math.abs(+v2 - 255)));
  64. } else {
  65. // 分左右 注意左右误差
  66. if ((+v3 - this.centerNum) > 20) {
  67. // 右
  68. const a = this.centerNum - (+v3 - this.centerNum)
  69. const b = this.centerNum + (+v3 - this.centerNum)
  70. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
  71. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
  72. } else if (+v3 - this.centerNum < -20) {
  73. // 左
  74. const a = this.centerNum - (+v3 - this.centerNum)
  75. const b = this.centerNum + (+v3 - this.centerNum)
  76. this.PWM.setPulseLength(this.MoAndSero.m1, this.Motor2pwm(+a));
  77. this.PWM.setPulseLength(this.MoAndSero.m2, this.Motor2pwm(+b));
  78. }
  79. }
  80. }
  81. //云台
  82. if (v0 || v1) {
  83. const a = +v1 > 200 ? 200 : +v1
  84. this.PWM.setPulseLength(this.MoAndSero.s1, this.Servo2pwm(+v0));
  85. this.PWM.setPulseLength(this.MoAndSero.s2, this.Servo2pwm(+a));
  86. }
  87. console.log('前后', v3, '左右', v2, '云台', v0, v1)
  88. } else {
  89. this.unLOCK(v0, v1, v2, v3)
  90. }
  91. } else {
  92. console.log('参数格式错误,自动略过');
  93. return
  94. }
  95. }
  96. /**
  97. * 内八解锁
  98. * @param {*} v0
  99. * @param {*} v1
  100. * @param {*} v2
  101. * @param {*} v3
  102. */
  103. unLOCK(v0, v1, v2, v3) {
  104. // 未解锁=>进行解锁:发送端的频率是0.05S,0.05*60 = 3S
  105. // 内八 :v0<50,v1>200,v2>200,v3<50
  106. if (+v0 <= 60 && +v1 >= 190 && +v3 >= 190 && +v2 <= 60) {
  107. if (this.Snum >= 0 && this.Snum <= 51) this.Snum++
  108. } else {
  109. this.Snum = 0
  110. }
  111. if (this.Snum == 50) {
  112. setTimeout(() => {
  113. //继电器
  114. RPIO.open(19, RPIO.OUTPUT, RPIO.HIGH);
  115. //空闲继电器
  116. //RPIO.open(13, RPIO.OUTPUT, RPIO.HIGH);
  117. //空闲继电器
  118. //RPIO.open(6, RPIO.OUTPUT, RPIO.HIGH);
  119. this.enable = true
  120. }, 1000)
  121. }
  122. console.log('解锁中', v0, v1, v2, v3)
  123. }
  124. /**
  125. * 电调换算比例:摇杆范围0-255,PWM范围500~1500~2500
  126. * @param {number} v
  127. * @returns
  128. */
  129. Motor2pwm(v) {
  130. return parseInt(v / (256 / 1000)) + 1000
  131. }
  132. /**
  133. * 舵机换算比例:摇杆范围0-256,PWM范围1000~1500~2000
  134. * @param {number} v
  135. * @returns
  136. */
  137. Servo2pwm(v) {
  138. return parseInt(v / (256 / 1000)) + 1000
  139. }
  140. // 关闭
  141. stop() {
  142. if (this.PWM) this.PWM.dispose()
  143. RPIO.open(6, RPIO.OUTPUT, RPIO.LOW);
  144. RPIO.open(13, RPIO.OUTPUT, RPIO.LOW);
  145. RPIO.open(19, RPIO.OUTPUT, RPIO.LOW);
  146. this.PWM = null
  147. process.exit(1)
  148. }
  149. }
  150. module.exports = new ContrlService()