123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- # https://how2electronics.com/how-to-control-servo-motor-with-raspberry-pi-pico/
-
- import time
- from machine import Pin, PWM, ADC
- from servo import Servo
-
- class Toy:
- """ Tools to control the Cat Toy hardware.
- Attributes:
- servo1: GPIO pin number of the pan servo.
- servo2: GPIO pin number of the tilt servo.
- laser: GPIO pin number of the laser diode.
- button: GPIO pin number of an active high push button.
- led: GPIO pin number of an active high LED.
- battery: ADC pin number of battery voltage divider.
- """
-
- # maximum movements on cardboard box
- # pan_min, pan_max, tilt_min, tilt_max
- maximum_limits = (20, 160, 0, 90)
-
- last_button = None
- time_button = None
- last_value = None
-
- # Battery Voltage divider
- r1 = 18000.0
- r2 = 10000.0
-
- def __init__(self, servo1 = 28, servo2 = 27, laser = 2, button = 22, led = 16, battery = 26):
- self.laserPin = PWM(Pin(laser, Pin.OUT))
- self.laserPin.freq(1000)
- self.laser(0)
-
- self.pan = Servo(servo1)
- self.tilt = Servo(servo2)
-
- pan_min, pan_max, tilt_min, tilt_max = self.maximum_limits
- self.angle(self.pan, int((pan_max - pan_min) / 2) + pan_min)
- self.angle(self.tilt, int((tilt_max - tilt_min) / 2) + tilt_min)
- time.sleep(0.2)
- self.free()
-
- self.button = Pin(button, Pin.IN, Pin.PULL_UP)
- self.led = Pin(led, Pin.OUT)
- self.battery = ADC(Pin(battery, Pin.IN))
-
- def map_value(self, x, in_min, in_max, out_min, out_max):
- return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
-
- def angle(self, servo, angle):
- if angle < 0:
- angle = 0
- if angle > 180:
- angle = 180
- servo.goto(int(self.map_value(angle, 0, 180, 0, 1024)))
-
- def laser(self, value):
- v = 1.0 - value
- self.laserPin.duty_u16(int(v * 65535))
-
- def getBatteryVoltage(self):
- adc = self.battery.read_u16()
- u2 = adc / 65535.0 * 3.3
- u1 = u2 / (self.r2 / (self.r1 + self.r2))
- #print("ADC:", adc, u2, u1)
- return u1
-
- def status(self, state):
- self.led(1 if state else 0)
-
- def poll(self, callback):
- val = not self.button.value()
- if val != self.last_button:
- self.time_button = time.ticks_ms()
- self.last_button = val
-
- if time.ticks_diff(time.ticks_ms(), self.time_button) > 50:
- if self.last_value != val:
- callback(val)
- self.last_value = val
-
- def free(self):
- self.tilt.free()
- self.pan.free()
-
- def test(self, steps = 10):
- pan_min, pan_max, tilt_min, tilt_max = self.maximum_limits
-
- self.laser(1)
-
- for y in range(tilt_min, tilt_max, int((tilt_max - tilt_min) / steps)):
- self.angle(self.tilt, y)
-
- for x in range(pan_min, pan_max, int((pan_max - pan_min) / steps)):
- self.angle(self.pan, x)
- time.sleep(0.2)
-
- self.free()
- self.laser(0)
|