No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

toy.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. # https://how2electronics.com/how-to-control-servo-motor-with-raspberry-pi-pico/
  2. import time
  3. from machine import Pin, PWM, ADC
  4. from servo import Servo
  5. class Toy:
  6. """ Tools to control the Cat Toy hardware.
  7. Attributes:
  8. servo1: GPIO pin number of the pan servo.
  9. servo2: GPIO pin number of the tilt servo.
  10. laser: GPIO pin number of the laser diode.
  11. button: GPIO pin number of an active high push button.
  12. led: GPIO pin number of an active high LED.
  13. battery: ADC pin number of battery voltage divider.
  14. """
  15. # maximum movements on cardboard box
  16. # pan_min, pan_max, tilt_min, tilt_max
  17. maximum_limits = (20, 160, 0, 90)
  18. last_button = None
  19. time_button = None
  20. last_value = None
  21. # Battery Voltage divider
  22. r1 = 18000.0
  23. r2 = 10000.0
  24. def __init__(self, servo1 = 28, servo2 = 27, laser = 2, button = 22, led = 16, battery = 26):
  25. self.laserPin = PWM(Pin(laser, Pin.OUT))
  26. self.laserPin.freq(1000)
  27. self.laser(0)
  28. self.pan = Servo(servo1)
  29. self.tilt = Servo(servo2)
  30. pan_min, pan_max, tilt_min, tilt_max = self.maximum_limits
  31. self.angle(self.pan, int((pan_max - pan_min) / 2) + pan_min)
  32. self.angle(self.tilt, int((tilt_max - tilt_min) / 2) + tilt_min)
  33. time.sleep(0.2)
  34. self.free()
  35. self.button = Pin(button, Pin.IN, Pin.PULL_UP)
  36. self.led = Pin(led, Pin.OUT)
  37. self.battery = ADC(Pin(battery, Pin.IN))
  38. def map_value(self, x, in_min, in_max, out_min, out_max):
  39. return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
  40. def angle(self, servo, angle):
  41. if angle < 0:
  42. angle = 0
  43. if angle > 180:
  44. angle = 180
  45. servo.goto(int(self.map_value(angle, 0, 180, 0, 1024)))
  46. def laser(self, value):
  47. v = 1.0 - value
  48. self.laserPin.duty_u16(int(v * 65535))
  49. def getBatteryVoltage(self):
  50. adc = self.battery.read_u16()
  51. u2 = adc / 65535.0 * 3.3
  52. u1 = u2 / (self.r2 / (self.r1 + self.r2))
  53. #print("ADC:", adc, u2, u1)
  54. return u1
  55. def status(self, state):
  56. self.led(1 if state else 0)
  57. def poll(self, callback):
  58. val = not self.button.value()
  59. if val != self.last_button:
  60. self.time_button = time.ticks_ms()
  61. self.last_button = val
  62. if time.ticks_diff(time.ticks_ms(), self.time_button) > 50:
  63. if self.last_value != val:
  64. callback(val)
  65. self.last_value = val
  66. def free(self):
  67. self.tilt.free()
  68. self.pan.free()
  69. def test(self, steps = 10):
  70. pan_min, pan_max, tilt_min, tilt_max = self.maximum_limits
  71. self.laser(1)
  72. for y in range(tilt_min, tilt_max, int((tilt_max - tilt_min) / steps)):
  73. self.angle(self.tilt, y)
  74. for x in range(pan_min, pan_max, int((pan_max - pan_min) / steps)):
  75. self.angle(self.pan, x)
  76. time.sleep(0.2)
  77. self.free()
  78. self.laser(0)