Pwm.js 5.0 KB

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