Pwm.js 5.2 KB

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