Mastering MicroPython Duty Cycle: A Comprehensive Guide
MicroPython is a lean and efficient implementation of the Python 3 programming language that includes a small subset of the Python standard library and is optimised to run on microcontrollers. One of the important concepts in MicroPython, especially when dealing with Pulse Width Modulation (PWM), is the duty cycle. The duty cycle is a measure of the proportion of time a signal is in an on state compared to the total period of the signal. It is usually expressed as a percentage, ranging from 0% (always off) to 100% (always on). Understanding and controlling the duty cycle in MicroPython can be incredibly useful in various applications, such as controlling the brightness of an LED or the speed of a motor.
Table of Contents#
- Fundamental Concepts of MicroPython Duty Cycle
- Usage Methods
- Common Practices
- Best Practices
- Conclusion
- References
1. Fundamental Concepts of MicroPython Duty Cycle#
Pulse Width Modulation (PWM)#
PWM is a technique used to control the power delivered to a device by rapidly switching the power on and off. The duty cycle is a key parameter in PWM. For example, if you have a PWM signal with a period of 10 milliseconds and a duty cycle of 50%, the signal will be on for 5 milliseconds and off for the remaining 5 milliseconds.
Duty Cycle Calculation#
The duty cycle is calculated using the following formula:
In MicroPython, when working with PWM, the duty cycle is often set as a value between 0 and 1023 (for a 10 - bit resolution). A value of 0 corresponds to a 0% duty cycle (always off), and a value of 1023 corresponds to a 100% duty cycle (always on).
2. Usage Methods#
Setting Up PWM in MicroPython#
To use PWM and set the duty cycle in MicroPython, you first need to import the necessary modules and initialise the PWM object. Here is an example of how to control the brightness of an LED using PWM:
from machine import Pin, PWM
# Create a PWM object on pin 25
led = Pin(25)
pwm_led = PWM(led)
# Set the frequency of the PWM signal
pwm_led.freq(1000)
# Set the duty cycle to 50% (in the range 0 - 1023)
pwm_led.duty(512)Changing the Duty Cycle Dynamically#
You can change the duty cycle dynamically in your code. For example, you can gradually increase the brightness of an LED:
from machine import Pin, PWM
import time
led = Pin(25)
pwm_led = PWM(led)
pwm_led.freq(1000)
# Gradually increase the duty cycle from 0 to 1023
for duty in range(0, 1024):
pwm_led.duty(duty)
time.sleep(0.01)
# Gradually decrease the duty cycle from 1023 to 0
for duty in range(1023, -1, -1):
pwm_led.duty(duty)
time.sleep(0.01)3. Common Practices#
Controlling Motor Speed#
One of the most common applications of duty cycle control in MicroPython is controlling the speed of a DC motor. By adjusting the duty cycle of the PWM signal sent to the motor driver, you can change the average voltage applied to the motor, thus controlling its speed.
from machine import Pin, PWM
import time
# Create a PWM object on pin 12 to control the motor
motor_pin = Pin(12)
pwm_motor = PWM(motor_pin)
pwm_motor.freq(50)
# Set different speeds by changing the duty cycle
speeds = [200, 500, 800]
for speed in speeds:
pwm_motor.duty(speed)
time.sleep(2)
# Stop the motor
pwm_motor.duty(0)Servo Motor Control#
Servo motors can also be controlled using PWM and duty cycle. Servo motors typically expect a PWM signal with a frequency of 50 Hz and a duty cycle in a specific range (usually around 2.5% - 12.5% to control the angle from 0° to 180°).
from machine import Pin, PWM
import time
# Create a PWM object on pin 13 to control the servo
servo_pin = Pin(13)
pwm_servo = PWM(servo_pin)
pwm_servo.freq(50)
# Map the angle to the duty cycle
def angle_to_duty(angle):
# Map 0 - 180 degrees to 25 - 125 duty cycle values (approx)
return int((angle / 180) * 100 + 25)
# Move the servo to different angles
angles = [0, 90, 180]
for angle in angles:
duty = angle_to_duty(angle)
pwm_servo.duty(duty)
time.sleep(1)4. Best Practices#
Error Handling#
When working with PWM and duty cycle, it's important to handle errors properly. For example, make sure that the duty cycle values you set are within the valid range (0 - 1023). You can add some validation code to ensure this:
from machine import Pin, PWM
led = Pin(25)
pwm_led = PWM(led)
pwm_led.freq(1000)
def set_duty_safely(duty):
if duty < 0:
duty = 0
elif duty > 1023:
duty = 1023
pwm_led.duty(duty)
# Try to set an invalid duty cycle
set_duty_safely(1500)Resource Management#
PWM resources should be properly managed. When you are done using a PWM object, it's a good practice to de - initialise it to free up resources.
from machine import Pin, PWM
led = Pin(25)
pwm_led = PWM(led)
pwm_led.freq(1000)
pwm_led.duty(512)
# Do some operations
# De - initialise the PWM object
pwm_led.deinit()5. Conclusion#
Understanding and effectively using the duty cycle in MicroPython is crucial for a wide range of applications, from simple LED brightness control to complex motor and servo control. By mastering the fundamental concepts, usage methods, common practices, and best practices, you can develop more robust and efficient MicroPython projects. Remember to handle errors properly and manage your resources effectively to ensure the stability of your applications.
6. References#
- MicroPython official documentation: https://docs.micropython.org/
- Arduino PWM Tutorial: https://www.arduino.cc/en/Tutorial/BuiltInExamples/PWM
- Servo Motor Control Basics: https://www.robotshop.com/community/tutorials/view/servo-motor-control-using-arduino