Pwm.js 5.1 KB

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