├── LICENSE ├── README.md ├── examples └── twist-example.py └── servo.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Microbit Playground 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Class for Servo Control in Python on the Microbit 2 | 3 | This is a simple class for controlling servos on the microbit in Python. 4 | 5 | ## Using the Modules 6 | 7 | There are two ways: 8 | 9 | #### Quick and Easy 10 | 11 | Cut and paste [the class in servo.py](https://github.com/microbit-playground/microbit-servo-class/blob/master/servo.py) to the top of the program. 12 | 13 | See [here for an example](https://github.com/microbit-playground/microbit-servo-class/blob/master/examples/twist-example.py). 14 | 15 | #### Proper Way 16 | 17 | The correct approach is to copy the module to the filesystem. It can then be accessed in the same way the `microbit` module is imported at the start of each program. 18 | 19 | The are two steps: copying the module to the microbit and importing the module into your program. 20 | 21 | 22 | ##### Copying the module: 23 | 24 | 1. Save [the module](https://github.com/microbit-playground/microbit-servo-class/blob/master/servo.py) to your computer. 25 | 26 | 2. Copy the downloaded module to the `/mu_code/` directory in the root of your home directory. 27 | 28 | 3. Flash your program to mu. 29 | 30 | 4. An error message will scroll across the screen about the lack of the servo module. 31 | 32 | 5. Once it has finished, click the 'files' icon in mu and upload the `servo.py` file to your microbit. 33 | 34 | 6. Press reset on your microbit. When the program runs again it will load the module. 35 | 36 | ##### In your program: 37 | 38 | ``` 39 | from microbit import * 40 | 41 | # from servo.py import the Servo class 42 | from servo import Servo 43 | 44 | # this can now be accessed within your program 45 | sv1 = Servo(pin0) 46 | sv1.write_angle(50) # turn servo to 50 degrees 47 | ``` 48 | 49 | ## Code Examples 50 | 51 | ##### 180 degree SG90 Hobby Servo @ 3.3v on pin0: 52 | 53 | ``` 54 | sv1 = Servo(pin0) 55 | sv1.write_angle(50) # turn servo to 50 degrees 56 | ```` 57 | ##### 180 degree SG90 Hobby Servo @ 4.8v on pin0: 58 | 59 | _note how min_us and max_us changes. These details will be on the servo's datasheet._ 60 | 61 | ``` 62 | sv1 = Servo(pin0, min_us=1000, max_us=2000) 63 | sv1.write_angle(180) # turn servo to 180 degrees 64 | ```` 65 | 66 | ##### 180 degree Parallax 900-00005 (BS1) Servo @ 6v on pin1: 67 | 68 | ``` 69 | sv1 = Servo(pin1, min_us=750, max_us=2250) 70 | sv.write_angle(10) 71 | ``` 72 | 73 | [Code from The Sheep on Bitbucket](https://bitbucket.org/thesheep/micropython-servo/src/f562a6abeaf0e83b752838df7cd31d88ea10b2c7?at=default) and made compatable (and worse) by me. Rescale function by [Tom Viner](https://www.youtube.com/channel/UCmA_ydtrCCQ7twKpovboiPA) -------------------------------------------------------------------------------- /examples/twist-example.py: -------------------------------------------------------------------------------- 1 | # Rotates the servo depending on the microbit's rotation through the x axis. 2 | # pressing button_a sweeps the servo from 0 degrees to 180 degrees 3 | # pressing button_b gives 0 degrees then 180 degrees. 4 | # Tested with SG90 servo @ 3.3v 5 | 6 | from microbit import * 7 | 8 | class Servo: 9 | 10 | """ 11 | A simple class for controlling hobby servos. 12 | 13 | Args: 14 | pin (pin0 .. pin3): The pin where servo is connected. 15 | freq (int): The frequency of the signal, in hertz. 16 | min_us (int): The minimum signal length supported by the servo. 17 | max_us (int): The maximum signal length supported by the servo. 18 | angle (int): The angle between minimum and maximum positions. 19 | 20 | Usage: 21 | SG90 @ 3.3v servo connected to pin0 22 | = Servo(pin0).write_angle(90) 23 | """ 24 | 25 | def __init__(self, pin, freq=50, min_us=600, max_us=2400, angle=180): 26 | self.min_us = min_us 27 | self.max_us = max_us 28 | self.us = 0 29 | self.freq = freq 30 | self.angle = angle 31 | self.analog_period = 0 32 | self.pin = pin 33 | analog_period = round((1/self.freq) * 1000) # hertz to miliseconds 34 | self.pin.set_analog_period(analog_period) 35 | 36 | def write_us(self, us): 37 | us = min(self.max_us, max(self.min_us, us)) 38 | duty = round(us * 1024 * self.freq // 1000000) 39 | self.pin.write_analog(duty) 40 | self.pin.write_digital(0) # turn the pin off 41 | 42 | def write_angle(self, degrees=None): 43 | degrees = degrees % 360 44 | total_range = self.max_us - self.min_us 45 | us = self.min_us + total_range * degrees // self.angle 46 | self.write_us(us) 47 | 48 | 49 | 50 | while True: 51 | if button_a.is_pressed(): 52 | for x in range(0, 180, 5): 53 | # from 0 to 180 in steps of 5 54 | # write the angle of the step (x) 55 | Servo(pin0).write_angle(x) 56 | sleep(200) 57 | if button_b.is_pressed(): 58 | # show maximum and minimum rotation if button 59 | # b pressed 60 | Servo(pin0).write_angle(0) 61 | sleep(2000) 62 | Servo(pin0).write_angle(180) 63 | sleep(2000) 64 | else: 65 | # rescale accelerometer x axis to between 0 and 180 66 | rescaled_angle = rescale((-1024, 1024), (0, 180), accelerometer.get_x()) 67 | Servo(pin0).write_angle(rescaled_angle) # write rescaled angle 68 | sleep(200) -------------------------------------------------------------------------------- /servo.py: -------------------------------------------------------------------------------- 1 | class Servo: 2 | 3 | """ 4 | A simple class for controlling hobby servos. 5 | 6 | Args: 7 | pin (pin0 .. pin3): The pin where servo is connected. 8 | freq (int): The frequency of the signal, in hertz. 9 | min_us (int): The minimum signal length supported by the servo. 10 | max_us (int): The maximum signal length supported by the servo. 11 | angle (int): The angle between minimum and maximum positions. 12 | 13 | Usage: 14 | SG90 @ 3.3v servo connected to pin0 15 | = Servo(pin0).write_angle(90) 16 | """ 17 | 18 | def __init__(self, pin, freq=50, min_us=600, max_us=2400, angle=180): 19 | self.min_us = min_us 20 | self.max_us = max_us 21 | self.us = 0 22 | self.freq = freq 23 | self.angle = angle 24 | self.analog_period = 0 25 | self.pin = pin 26 | analog_period = round((1/self.freq) * 1000) # hertz to miliseconds 27 | self.pin.set_analog_period(analog_period) 28 | 29 | def write_us(self, us): 30 | us = min(self.max_us, max(self.min_us, us)) 31 | duty = round(us * 1024 * self.freq // 1000000) 32 | self.pin.write_analog(duty) 33 | self.pin.write_digital(0) # turn the pin off 34 | 35 | def write_angle(self, degrees=None): 36 | degrees = degrees % 360 37 | total_range = self.max_us - self.min_us 38 | us = self.min_us + total_range * degrees // self.angle 39 | self.write_us(us) 40 | --------------------------------------------------------------------------------