Here are some examples of pushbutton servo control:
In this activity, you will use MicroPython scripts to:
Along the way, you will learn about angular position vs. angular velocity, and ways they are measured and calculated.
In addition to the servo you have just built and tested, this activity will use the pushbutton circuits connected to P9 and P6 that were built earlier.
# servo_buttons_control from microbit import * display.off() pin9.set_pull(pin9.NO_PULL) pin6.set_pull(pin6.NO_PULL) pin16.set_analog_period(20) value = 77 while True: state9 = pin9.read_digital() state6 = pin6.read_digital() if state9 is 1: value = value + 1 if value > 128: value = 128 if state6 is 1: value = value - 1 if value < 26: value = 26 pin16.write_analog(value) sleep(20)
It's time to verify that button presses adjust your servo's position.
For pushbutton monitoring, the micro:bit display needs to be turned off. Also, since we have pull-down resistors connected to the pushbuttons, micro:bit I/O pin internal pull resistors should be set to NO_PULL.
display.off() pin9.set_pull(pin9.NO_PULL) pin6.set_pull(pin6.NO_PULL)
The servo control signal to P16 is set up with this statement. Later, pin16.write_analog calls will adjust the signal to make the servo turn its horn to various positions.
pin16.set_analog_period(20)
The value variable will be used to set the servo’s position. This script starts it at 77, for a 90° horn position (the halfway point in the servo’s position range).
value = 77
The first thing that happens in the main loop is that the pushbutton states are checked and stored in state9 and state6.
while True: state9 = pin9.read_digital() state6 = pin6.read_digital()
If the P9 pushbutton is pressed, state9 will be 1. When this happens, it will increase the value by 1, and check if it is above 128. If so, set it back to 128. The 128 value restricts the servo’s position to a maximum of 128.
if state9 is 1: value = value + 1 if value > 128: value = 128
If the P6 pushbutton is pressed, state6will be 1. When this happens, it will decrease the value by 1, and check if it is below 26. If so, set it back to 26. The 26 value restricts the servo’s position to a minimum of 26.
if state6 is 1: value = value - 1 if value < 26: value = 26
Each time through the loop, it updates the servo signal using the number stored in the value variable then waits 20 ms (1/50th of a second) before repeating the main loop.
pin16.write_analog(value) sleep(20)
The upper angle limit of 180° for the servo horn was determined by:
if value > 128: value = 128
Likewise, the lower 0° angle limit for the servo horn was determined by:
if value < 26: value = 26
These values can be changed to limit the servo to a smaller range of angles. For example:
if value > 102: value = 102
…would set the upper angle limit to 135°. The lower angle limit could also be limited to 45° with this:
if value < 51: value = 51
Let’s try it:
Up to now, your scripts have controlled the servo horn’s angle. That’s the direction the horn points, measured from 0° to 180° of its range. Your scripts can also control the angular velocity. That’s how fast the horn turns when it’s moving from one position to another.
The scripts currently have the angular velocity slowed down with statements like:
value = value + 1
While pressing and holding the P9 button, the value variable increases by 1 every 50th of a second. In response, the servo horn increases its angle by about 1.75° per 50th of a second. If value = value + 1 is changed to value = value + 3, the modified script will make the horn turn 3 times as fast while the P9 button is pressed and held. This is an example of changing the horn’s angular velocity.
Think back to the first servo control script. It took the servo some time to turn to each new position. In that example, the servo turned to each new position at top speed. If your script advances the value variable faster than the servo can turn, it will catch up eventually. Just keep in mind that increasing the number in the value = value + number statement can only go so far to speed up the servo since the servo has a mechanical speed limit as well.
Angles can be measured in degrees. The symbol for angle is the Greek letter theta Θ . Angles can be expressed in degrees like this: Θ = 30°.
Angular velocity is a measure of how fast (and in which direction) something turns. Angular velocity can be measured in degrees per second. Counterclockwise rotation is considered positive, and clockwise negative. In other words, if the angle is increasing, angular velocity is positive. If angle decreases over time, angular velocity is negative. The symbol for angular velocity is the Greek letter omega, ω, and one way angular velocity is expressed is in degrees per second with this notation: °/s.
When angular velocity is constant it can be measured as the change in angle over time. Change in angle can be measured as the final angle Θf minus the initial angle Θi divided by the time t it took for the object to rotate that far.
ω = (Θf - Θi) / t
Example: If it takes 2.1 seconds for the horn to rotate from 0° to 180°, what is its angular velocity?
ω = (Θf - Θi) / t
= ( 180° - 0°) / 2.1 s
≈ 85.7° / s
Example: If it takes 1.05 seconds for the horn to rotate from 135° to 45°, what is its angular velocity?
ω = (Θf - Θi) / t
= ( 45° - 135°) / 1.05 s
≈ -85.7° / s
Let’s try increasing the counterclockwise angular velocity to 3-times the original. After this change, the servo horn should take about ⅓ of the time it originally took to turn from 0° to 180°.
1. Solution: This script is written for the range of 0° to 45°. Any 45° span is acceptable.
from microbit import * display.off() pin9.set_pull(pin9.NO_PULL) pin6.set_pull(pin6.NO_PULL) pin16.set_analog_period(20) value = 77 while True: state9 = pin9.read_digital() state6 = pin6.read_digital() if state9 is 1: value = value + 1 if value > 51: value = 51 if state6 is 1: value = value - 1 if value < 26: value = 26 pin16.write_analog(value) sleep(20)
2. Solution:
from microbit import * display.off() pin9.set_pull(pin9.NO_PULL) pin6.set_pull(pin6.NO_PULL) pin16.set_analog_period(20) value = 77 while True: state9 = pin9.read_digital() state6 = pin6.read_digital() if state9 is 1: value = value + 1 if value > 128: value = 128 if state6 is 1: value = value - 2 if value < 26: value = 26 pin16.write_analog(value) sleep(20)
Links
[1] https://learn.parallax.com/tutorials/language/python/servo-position-control-python-and-microbit/setup-previous-tutorials
[2] https://python.microbit.org/v/2