XBee3 Thing Plus Hookup Guide
Experiment 2: Pulse Width Modulation (PWM)
Pulse width modulation is the technique of switching a digital signal on and off very quickly to control a variety of electrical components. By varying the amount of time a signal is on vs off, you can vary the amount of electrical power provided to a component. We can use this, for example, to dim an LED or control the speed of a motor. To learn more about PWM, see this tutorial.
In this example, we are going to create a simple LED animation that occurs as long as a button is held down.
Connect an LED and a button to the XBee3 Thing Plus as per the following diagram:
Code: LED Animation
Open a new file in your favorite text editor, enter the following code:
language:python import machine import sys import utime # Pin definitions repl_button = machine.Pin(machine.Pin.board.D5, machine.Pin.IN, machine.Pin.PULL_UP) repl_led = machine.Pin(machine.Pin.board.D4, machine.Pin.OUT) button = machine.Pin(machine.Pin.board.D11, machine.Pin.IN, machine.Pin.PULL_UP) pwm_pin = machine.Pin(machine.Pin.board.D10, machine.Pin.OUT) # Create a PWM object out of our pin object pwm = machine.PWM(pwm_pin) # Slowly fade LED brightness while True: # If button 5 is pressed, turn on LED and drop to REPL if repl_button.value() == 0: print("Dropping to REPL") repl_led.value(1) sys.exit() # Increase brightness of LED if button is held for i in range(1024): if button.value() == 0: pwm.duty(i) utime.sleep_ms(2) else: pwm.duty(0)
Save your file as main.py on your local file system, overwriting your previous main.py file. Upload the code to your XBee3 Thing Plus as outlined in Experiment 1. Press RST to auto-run the new main.py file.
After the code has been uploaded and the board reset, hold down the button (the one on the breadboard that is connected to pin 11. You should see the LED slowly brighten, turn off, and then begin the brightening animation over again as long as the button is held down.
Code to Note
Much of the code should look familiar from the previous experiment, as we are creating a
machine.Pin object for our LED and another one for our button. Note that we are keeping the "drop to REPL" snippet in, as we always want a way to exit out of our code's main loop.
The main difference is that we are creating
machine.PWM object out of our
machine.Pin object (the pin object that we've created with the
pwm_pin variable. With the
machine.PWM object, we can call the
pwm.duty() method, which allows us to control the amount of on vs. off time on pin 11. A duty cycle of 0 means that the pin is always 0 V. A duty cycle of 511 (about half of 1023) means that pin 11 should rapidly switch between 0 V and 3.3 V equally (50%). Finally, a duty cycle of 1023 means that pin 11 should be always on (always at 3.3 V). Again, refer to the Pulse Width Modulation tutorial for more information on pwm and duty cycles.
pwm.duty() inside a for loop, we can increase the brightness one stage at a time with a 2 ms delay between each stage. This ultimately gives the effect of a slowly increasing LED brightness.
Notice that we check for button 5 at the beginning of the for loop. That means that you need to hold down button 5 until the for loop (LED animation) has completed one iteration before the program realizes you've pressed the button (and should therefore exit to REPL). To help you know when you have successfully exited the program into REPL, we added
repl_led.value(1) to turn on the onboard blue LED.