/ Servo_Tester / code.py
code.py
1 # SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 """ 6 Servo Tester 7 8 Adafruit invests time and resources providing this open source code. 9 Please support Adafruit and open source hardware by purchasing 10 products from Adafruit! 11 12 Written by Dave Astels for Adafruit Industries 13 Copyright (c) 2018 Adafruit Industries 14 Licensed under the MIT license. 15 16 All text above must be included in any redistribution. 17 """ 18 19 import time 20 import board 21 import busio 22 import digitalio 23 import rotaryio 24 import pwmio 25 import adafruit_ssd1306 26 from adafruit_motor import servo 27 from adafruit_debouncer import Debouncer 28 29 #-------------------------------------------------------------------------------- 30 # Initialize Rotary encoder 31 32 button_io = digitalio.DigitalInOut(board.D12) 33 button_io.direction = digitalio.Direction.INPUT 34 button_io.pull = digitalio.Pull.UP 35 button = Debouncer(button_io) 36 rotary_encoder = rotaryio.IncrementalEncoder(board.D10, board.D11) 37 38 #-------------------------------------------------------------------------------- 39 # Initialize I2C and OLED 40 41 i2c = busio.I2C(board.SCL, board.SDA) 42 43 oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 44 oled.fill(0) 45 oled.show() 46 47 min_pulses = [ 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000] 48 max_pulses = [2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400, 2450, 2500] 49 50 min_pulse_index = 10 51 max_pulse_index = 0 52 53 #------------------------------------------------------------------------------- 54 # Initialize servo 55 56 pwm = pwmio.PWMOut(board.D5, frequency=50) 57 test_servo = servo.Servo(pwm, min_pulse=1000, max_pulse=2000) 58 test_servo.angle = 0 59 60 current_position = None # current encoder position 61 change = 0 # the change in encoder position 62 angle = 0 63 mode = 0 64 sweep_time = 1.0 65 last_movement_at = 0.0 66 delta = 5 67 68 69 def get_encoder_change(encoder, pos): 70 new_position = encoder.position 71 if pos is None: 72 return (new_position, 0) 73 else: 74 return (new_position, new_position - pos) 75 76 #-------------------------------------------------------------------------------- 77 # Main loop 78 79 while True: 80 now = time.monotonic() 81 button.update() 82 83 if mode == 1: 84 if now >= (last_movement_at + sweep_time / 36): 85 last_movement_at = now 86 angle += delta 87 if (angle > 180) or (angle < 0): 88 delta *= -1 89 angle += delta 90 91 if button.fell: 92 servo.angle = 0 93 if mode == 0: 94 mode = 1 95 sweep_time = 1.0 96 last_movement_at = now 97 elif mode == 1: 98 mode = 2 99 angle = 0 100 elif mode == 2: 101 mode = 3 102 angle = 180 103 elif mode == 3: 104 mode = 0 105 angle = 0 106 107 else: 108 current_position, change = get_encoder_change(rotary_encoder, current_position) 109 if change != 0: 110 if mode == 0: 111 angle = min(180, max(0, angle + change * 5)) 112 elif mode == 1: 113 sweep_time = min(5.0, max(1.0, sweep_time + change * 0.1)) 114 elif mode == 2: 115 min_pulse_index = min(10, max(min_pulse_index + change, 0)) 116 test_servo = servo.Servo(pwm, 117 min_pulse=min_pulses[min_pulse_index], 118 max_pulse=max_pulses[max_pulse_index]) 119 angle = 0 120 elif mode == 3: 121 max_pulse_index = min(10, max(max_pulse_index + change, 0)) 122 test_servo = servo.Servo(pwm, 123 min_pulse=min_pulses[min_pulse_index], 124 max_pulse=max_pulses[max_pulse_index]) 125 angle = 180 126 127 oled.fill(0) 128 if mode == 0: 129 oled.text("Angle: {0}".format(angle), 0, 0) 130 elif mode == 1: 131 oled.text("Sweep time: {0}".format(sweep_time), 0, 0) 132 elif mode == 2: 133 oled.text("Min width: {0}".format(min_pulses[min_pulse_index]), 0, 0) 134 elif mode == 3: 135 oled.text("Max width: {0}".format(max_pulses[max_pulse_index]), 0, 0) 136 oled.show() 137 138 test_servo.angle = angle