Writing MicroPython Code
00:00 Writing MicroPython Code. In this section, you will see some basic examples of interaction with hardware that’s connected to a MicroPython board. In this case, the board will be a Pyboard Lite, as this is a vanilla implementation of MicroPython which is one of the most affordable boards available, and you’ll see it connected to some external components to give you an idea of how you can interface with them.
00:24 Once you’re comfortable with output to and input from simple devices, you can build systems with MicroPython providing the control logic and you can look to more complex devices to interface with.
00:37
Creating a Digital Output. Many devices are described as being digital, and indeed, all the computers and microcontrollers we use are digital at their core. But in this context, digital refers to the output having two states: either off, which is 0
or False
, in terms of logic, and typically means 0 Volts in the real world; or on, which is 1
or True
in terms of logic, and 3.3 Volts in the real world.
01:07 Here, you can see we’re running Thonny, and the first step is to connect to the Pyboard, as seen previously. So we go to the Run menu, pick Select Interpreter…, change to MicroPython, then select the COM port that the Pyboard is connected on.
01:25 We can see in the Shell window that we’re now connected to the Pyboard, and the MicroPython device appears in the Files tab here. Now we can look at creating a digital output.
01:37 As you can see onscreen at the moment, the connection between the LED and the Pyboard is fairly simple. The cathode side of the LED—the negative—is connected to GND (Ground), whereas the anode side—the positive—is connected to X1 via a resistor.
01:53 This resistor is to limit the current that travels through the LED.
01:59
This code is an example of how to turn the pin on and off. So we’re importing Pin
from pyb
, and importing time
to allow us to delay the loop which happens later on. The Pin
is set up by naming the Pin
'X1'
and picking the mode—in this case, Pin.OUT_PP
, which is push-pull and allows the LED to be driven.
02:22
The delay
variable is set outside of the loop to allow us to change it as we want. And the main loop, which runs indefinitely, merely turns the LED on, waits for delay
, and then turns it off.
02:36 If needs be, you can stop the backend and then rerun it with the play button. As you can see, the LED is flashing. This is easily altered by stopping it, changing the delay time, re-saving the file, and then running it.
02:59 Being able to turn pins on and off is useful, allowing control over any device where it has two states of on or off, such as a relay. Often, though, you’ll be driving LEDs, and it would be nice to be able to vary the brightness of that LED.
03:13 This could be achieved by using an analog output and varying the voltage that’s driving the LED, but this approach has problems. The relationship between LED current and LED brightness is not straightforward, and the circuitry to control an analog signal can be complex and inefficient.
03:31 It’s a much better idea to use pulse width modulation, where the LED is turned on and off very quickly—too quickly for our eyes to notice it—and the ratio between on and off defines the brightness.
03:43 You’ve probably noticed that if you turn your head quickly while looking at some LED lights—such as car taillights—you can see dots in your vision. This is because the movement of your head allows your eyes to see these individual flashes, even though they all seem to be happening at the same time.
04:00 The Pyboard has the ability to create PWM easily using a hardware-based timer. Let’s take a look at that code in Thonny. So, as you can see, slightly more needs to be implemented here.
04:13
We’re importing Timer
as well as Pin
. We’re importing the sin()
function to allow us to have a cyclic pulsing of that light, and still importing time
.
04:22
The Pin
is set up simply with 'X1'
, and now we’re tying into a specific Timer
. The Timer
to use depends on which pin you’re using and which Pyboard you’re using. In this case, Timer
number 5
on channel number 3
is what’s needed for pin X1 to work. We set up this Timer.channel
here, using PWM
and attaching it to the Pin
, and these two variables are to allow us to cyclically vary the brightness throughout our loop. As you can see here, this is another while
loop which runs indefinitely, and it uses an absolute sine value to provide the brightness of the LED.
05:03
That value is then set as the pulse width percent of the channel in question, changing the brightness of the LED. The position
variable is altered to change the sine wave on the next cycle, and then a small delay happens. Running this code will allow you to see the brightness of the LED changing.
05:24 If we could see this at great speed, you would actually see the LED turning on and off for different intervals but unfortunately, the camera won’t run that fast.
05:36 Creating a Digital Input. In the case of digital inputs, the situation is a little more complex, but as long as you’re aware of the potential downfalls, you’ll be okay.
05:47
Let’s take a look at some simple code that you think would be the right code to do this. Here, you can see the code. We’ve imported Pin
from the pyb
module, set up a Pin
, again on 'X1'
, and set mode
to be Pin.IN
.
06:04
This time our infinite loop checks the value of p
and prints it out to the console, sleeps for a short time, and then repeats.
06:13 As you can see onscreen, the wiring is fairly simple with GND (Ground) being connected to the switch, and the other side of the switch being connected to X1.
06:24 To help visualize the results, we’re going to make use of Thonny’s plotter, which is turned on by going to View and then Plotter. Once the program runs, as Thonny says here, the plotter will visualize the numbers printed out to the shell.
06:40 So, let’s see what happens when we run this code.
06:46
We seem to be getting random values. Sometimes it’s set to 0
, sometimes it’s set to 1
. Pressing the button
06:55
we’ve set it to 0
, but as soon as it’s released, the value becomes random again. So, what’s happening? The circuitry connected to the X1 pin of the MicroPython board is picking up signals from the environment—electrical signals, which are then being misinterpreted.
07:13 What we need is a thing called a pull-down or a pull-up resistor. This ties the input to either a low or high state, unless there’s an input voltage present which is enough to drive it to the appropriate state, even with the resistor present. On the Pyboard, fortunately, this is available as a virtual resistor, which can be specified when creating the input object.
07:37
Let’s take a look at that. Here, you can see the code, and the only difference is pull
has been specified with Pin.PULL_UP
. This will pull the value up unless it is grounded by the switch.
07:50 Let’s see that in action.
07:54
So you can see it’s presenting 1
, and as soon as we’ve pressed the switch, we go back to 0
.
08:01 So this is now working as it should do, registering only the genuine button presses and giving MicroPython the true state of the outside world.
08:12
Creating an Analog Input. The switch we just saw had two states: off and on, 1
and 0
. While this is useful for MicroPython to detect situations which only have two states, much of the world is more complex and has many states or positions that an object can be in. To allow measurements of such variables, an analog input is typically needed. While analog inputs can take many forms, in this case, a joystick controller with two potentiometers will be used, as you can see in the circuit diagram onscreen now. These allow reading the horizontal and vertical position of the joystick as they return a voltage representing that position on a third pin.
08:56
In MicroPython terms, the ADC
class is used, which allows the pin to be configured to read the data in 12-bit resolution, giving 4,096 possible values from 0 to 4,095. And as with the digital input seen previously, the output will be printed out and Thonny’s plotter will be used to visualize the readings. So here, you can see the code with ADC
, which is the analog to digital converter, and it’s been tied to pin X1 and pin X2.
09:29
As ever, a simple loop which runs indefinitely, printing out the values of p1
and p2
, and then with a short break.
09:42 As soon as the code is run, you can see that the values are varying slightly. If this was an issue, you’d probably want to average them over a few values to get a smoother reading.
09:52 But moving the joystick…
09:58 shows deflection in either direction for the blue line and the orange line. And they can, of course, work together.
10:13 With these examples, you’ve seen the basics of how to interface MicroPython to the real world. Once you’ve got comfortable with these, you can add more of them, different types, and there’s almost no limit to what you can interface with to control and measure the real world.
Become a Member to join the conversation.