2023 – PiHut Advent Calendar Pico – Review

We missed the chocolates and instead opted for the Pi Hut’s Codemas Advent calendar.

I know, I know £40 is steep (even high class Lindt don’t charge that much) for a calendar but as a package and from what’s been done so far, its been well worth the money.

Basically, the calendar has a different set of projects to do for 12 days. Lucody (11) and his sister (14) get to eat some chocolate once the projects are completed.

Getting Started with Pico

Admittedly, Lucody was disappointed. And asked if there was also a chocolate calendar coming. I ignored this disappointing comment with a smile (like from fantastic Mr Fox sort of smile) and said you’re gonna like this.

Lucody’s sister wanted to join in as she thought the Pico looked kind of cool. Excellent, I thought!

The first goody box in the calendar contains:

A Raspberry Pi Pico H

1M Micro USB Cable

1 x 400 point solderless breadboard

So, no hot soldering just soldiering on. I know irritating.

We read through the explanation of the Pico. It’s a microcontroller board (not a microcomputer) and its brain is a RP2040 microcontroller chip (uncorrupted Chinese version we hope). The Pico is tiny and we tried to estimate how many of these chips would fit in a container ship from China but lost count.

The difference between the Pico and a Raspberry Pi microcomputer is that the Pico is designed for physical computing projects – controlling LEDs, buttons, sensors and motors. We wondered if it could be used in our pursuit of building a workable robot for PiWars 2024 (just the mention makes a dry throat). Maybe a pico could be added as an extra to do some things for specific Pi Wars Challenges?

Fortunately, the Pi Hut has put together a very useful set of instructions and right from the start and from following step by step it became very apparent that decent thought has gone into the logical steps and clear instructions.

The Pico can use many programming languages but for the Codemas projects the Pico uses MicroPython, which I guess is a smaller version of Python. The Pico is a powerful microcontroller and whilst the Pi Hut acknowledges this, it also (thankfully) keeps to the basics.

The first step was setting up the software. Thonny so that the Pico could be programmed with MicroPython.

For Lucody and his sister the acronyms and catchy names do a lot. IDE for one. Yes, an Integrated Development Environment – so in English this may mean something like a special place for developing ideas in an integrated kind of way. But let’s not think about that sort of stuff.

A link took us to Thonny and this was easy to download. We just went with the flow and didn’t get phased by the bumps about 64 bit.

Then we installed MicroPython onto the Pico. I left to get back to some important work related things…

A short while later….

from machine import Pin
onboardLED = Pin(25, Pin.OUT)
onboardLED.value(1)

And an LED was on. Lucody and his sister thought this was awesome!

Getting Flash

Lucody said a decision had been made to space the days out – as there were only 12, so every other day. A good move. In today’s box were the following:

  • 1x 5mm Red LED (with a clear lens)
  • 1x 5mm Amber LED (with a clear lens) 
  • 1x 5mm Green LED (with a clear lens) 
  • 3x 330 ohm resistors
  • 4x Male to male jumper wires

Some discussion took place around how the colours could be there if the lenses are clear. Lucody (with previous knowledge of resistors) was able to explain the Ohms to his sister and flow of electric – which then went to dimmable switches and lights in general. There was some amusement with the male to male jumper wires for obvious reasons. Though when Lucody mentioned male to female wires there was some opportunity for a discussion of ‘birds and bees’ but heck this is about wires!

So, back to the project.

Long legs, short legs, Cathode and Anode. Positive and negative.

A Pinout – simplified map of pins on Pico

Activity 1– ON/OFF LED

There was some fiddly wire stuff and soon realised a recap on breadboards was in order – how the rails are and positive and negative. The first activity was to get each LED to flash for a bit.

from machine import Pin
import time

red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)

red.value(1)
amber.value(1)
green.value(1)

time.sleep(5)

red.value(0)
amber.value(0)
green.value(0)

Activity 2 – Flash LEDs

Then Activity 2 (on day 2) was flashing LEDs

This introduced while loops to the code and other terms such as variables, indentation and code commentary.

While Loops

While loops are used to repeat a block of code as long as the condition remains true. In this instance making the LEDs flash 10 times and then stopping.

In terms of Variables the Pi Hut explained:

‘A variable is just somewhere to store a value (a ‘container’), which we can also update when we want to. When we need to use the variable in a line of code, we just use its name.

In our example below our variable is called counter. We create this before the while loop and set an initial value of 1.

In programming, a variable can be a whole number (an ‘integer‘), a number with a decimal place (a ‘floating-point value‘ or ‘float‘) or a word/text (a ‘string‘).’

The budding coders gave some thought to ‘integers’, ‘floats’ and ‘strings’. How do letters and words start as ones and zeros?

This then went into a small discussion about ASCII and other things like how images and videos are binary numbers. Videos being still frames. This was a good conversation and also allowed us to talk about ‘floats’ and discuss 1/10ths 1/100ths and 1/1000ths and so on.

This was the code:

from machine import Pin
import time

Set up our LED names and GPIO pin numbers

red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)

counter = 1 # Set the counter to start at 1

while counter < 11: # While count is less than 11…

print(counter) # Print the current counter

# LEDs all on
red.value(1)
amber.value(1)
green.value(1)

time.sleep(0.5) # Wait half a second

# LEDs all off
red.value(0)
amber.value(0)
green.value(0)

time.sleep(0.5) # Wait half a second

counter += 1 # Add 1 to our counter

Following the PiHut idea prompts – changing the time.sleep values increased/decreased the speed of the flashing LEDS. And 0.2 felt like the sweet spot.

Activity 3 – Flashing LEDs like a Christmas Decoration

The key part to below was ensuring 2/3 were off when the one was on. We talked about this a bit

Imports

from machine import Pin
import time

Set up our LED names and GPIO pin numbers

red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)

counter = 1 # Set the counter to 1

while counter < 11: # While count is less than 11

print(counter) # Print the current counter

# Red ON
red.value(1) # ON
amber.value(0) # OFF
green.value(0) # OFF

time.sleep(0.5) # Wait half a second

# Amber ON
red.value(0) # OFF
amber.value(1) # ON
green.value(0) # OFF

time.sleep(0.5) # Wait half a second

# Green ON
red.value(0) # OFF
amber.value(0) # OFF
green.value(1) # ON

time.sleep(0.5) # Wait half a second

counter += 1 # Add 1 to our counter

In summary a circuit had been created and the ‘time module’ had been used to add delays. While loops and conditions had been introduced and our discussions included how such things could be used (and are used around us in games for example). The ‘counter’ was the variable that had been used and we looked at the code without commentary/comments and realised that by having such commentary it brings more ‘human’ meaning. And we are human afterall!

It was a good set of projects and a great way for this cunning duo to spend time together!

Boundless Buttons

In the words of Lucody this was the ‘most demanding set of tasks’ and definitely took a while. A period of fault finding alone took an hour!

This day had 5 Activites and the instructions/code are loaded!

Covered – IF statements. Whilst the example of excel use was introduced as a primer, my personal experience with excel is filtering, sorting and extracting. Unfortunately, I’ve never had requirements beyond this. As for the children, Excel may as well be a distant galaxy. Anyway, IF statements enable us to give code different outcomes depending on values, inputs and other things. So, the example below is saying:

IF this condition is met do this output (outcome)

or

IF button 1 is on light the red LED.

Impatient types may well be thinking, yes, how many different ways do you want to say the same thing, but its important to keep children in mind and not get to bobblygobbly with the hoobly gibberty.

Pull Downs – Used as sending 3.3volts to selected GPIO pin to set it HIGH. But must be LOW in the first place for code to detect change. Just leave that there for the moment for another thing to understand fully in the future.

The code was as follows:

# Imports
from machine import Pin
import time

# Set up our button name and GPIO pin number
# Also set the pin as an input and use a pull down
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)

while True: # Loop forever

    time.sleep(0.2) # Short delay
    
    if button1.value() == 1: #If button 1 is pressed
        print("Button 1 pressed")

Questions that arose – What’s underneath the bonnet? Where does ‘machine’ and ‘Pin’ and ‘time’ come from? A sneaky suspicion is that underneath there’s complex code (hidden) and probably for a good reason. This will be something to explore later on.

And it worked – when button 1 pressed it printed ‘Button 1 Pressed’.

And yes, a lot just to do such a simple thing many of us do everyday, without thinking about it! A discussion point was the buttons in lifts and thinking about the different outputs/outcomes depending on which button is pressed.

Activity 2 – Changing IF Statements

Added 2 more buttons and changed the IF statement by adding more.

Looping forever. But what does the == mean?

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)
button3 = Pin(3, Pin.IN, Pin.PULL_DOWN)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1: # If button 1 is pressed
        
        print("Button 1 pressed")
        
    if button2.value() == 1: # If button 2 is pressed
        
        print("Button 2 pressed")
        
    if button3.value() == 1: # If button 3 is pressed
        
        print("Button 3 pressed")

So far. so good and once put into Thonny and run prints were as above!

Activity 3 – Introducing ELIF and ELSE.

Yes, you may of thought that being a Christmas themed advent calendar that ELIF is some sort of ELF but it isn’t.

ELIF is short for Else If.

If your first IF statement isn’t true the code will check to see if any following IF statements are – true. As a discussion point we talked about cash machine pins (needing certain buttons pressed) and if after so many attempts card will get swallowed. Then we thought of a situation where 2 buttons might be needed to be pressed at the same time. And locks came to mind or even types of alarm clocks or to reset a fire alarm system. But back to our buttons.

Below, the instructions ensure that an IF statement starts, then the ELIF statements follow. So, translating this means the code checks to see if button 1 is being pressed, if not (ELSE IF), it checks for button 2, and still if not (ELSE IF) it checks for button 3. Neat, but we’re very aware that we don’t know the significance of () == and :. But, we’re sure this will fall into place and as such won’t ‘sweat’ the small stuff (but we also anticipate this isn’t ‘small stuff’).

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)
button3 = Pin(3, Pin.IN, Pin.PULL_DOWN)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1: # If button 1 is pressed
        
        print("Button 1 pressed")
        
    elif button2.value() == 1: # If button 2 is pressed
        
        print("Button 2 pressed")
         
    elif button3.value() == 1: # If button 3 is pressed
        
        print("Button 3 pressed")

The ELSE statement – If none of the statements above have their conditions met, do this instead.

Or Else, as Ma used to say. Okay, mum. I’ll put my shoes away then (hint hint Lucodey!)

Back to ELSE, as this sounds familiar, like a flow chart of some kind.

A,B if not C. Pass Go.

Or maybe a parking machine that displays ‘insert coins’ if nothing else is going on, like coins dropping into the slot.

Or from discussion like a message displayed on a game prompting user input – token or coins.

Or may be an a data feed on a commodity index and until a certain price is hit – message – hold back. When price hit, triggers ‘buy order’ or something of the kind. Heck, the mind boggles! Stop loss, market if touched, trigger high, then so many points above (and hold for such an such a time frame) then trigger ‘Buy’ Action. Is that really all the black boxes are? (Sorry I diverge into a distant memory of open outcry ‘Pit’ Trading before the ‘bots’ arrived.

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1: # If button 1 is pressed
        
        print("Button 1 pressed")
        
    elif button2.value() == 1: # If button 2 is pressed
        
        print("Button 2 pressed")
        
    else: # If no buttons are being pressed
        
        print("No button presses")

So far, so good. The code runs and keeps printing ‘No button presses’ until 1 or 2 are pressed.

Looking above, its IF=ELIF=Else.

The next part was to put them in with a combination of the LEDs. And interestingly below we think we (hopefully understand the ==. The code checks if buttons 1 and 2 have been held together. Look below – using –

IF statement (button1.value() ==1′ and the ‘and button2.value() ==1′ . So if 1 and 2 are pressed down together ‘green.value(1) – green LED on.

Then ELIF – Or ELSE if button 1 pressed put the amber LED on. If you follow the code it makes sense, probably more than my take on it, which I find by writing out makes it sink in better and gives use the opportunity to slow down and think about the code. This is an important learning point. We’ve deliberately taken our time with this. It hasn’t been a frantic speed test to get through each of the days on the Advent calendar. If we wanted that we could just copy the code and just see if it works, but what would we be learning?

Enough of that interlude and explanation. What’s with the justification anyhow?

The last statement – ELSE – this means no buttons pressed then RED LED on.

Like the picture below the code.

bsdbcsv # Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)
button3 = Pin(3, Pin.IN, Pin.PULL_DOWN)

# Set up our LED names and GPIO pin numbers
red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1 and button2.value() == 1: # If button 1 and 2 are pressed at the same
        
        print("Buttons 1 and 2 pressed")
        green.value(1) # green LED on
        red.value(0) # red LED off

    elif button1.value() == 1: # If button 1 is pressed
        
        print("Button 1 pressed")
        amber.value(1) # amber LED on
        red.value(0) # red LED off

    else: # If no buttons are being pressed
        
        red.value(1) # red LED on
        amber.value(0) # amber LED off
        green.value(0) # green LED off

Activity 4: This button or that button (or this way or that way?)

This activity introduced ‘OR’ between conditions – to check if button being pressed

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)

# Set up our LED names and GPIO pin numbers
green = Pin(20, Pin.OUT)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1 or button2.value() == 1: # If button 1 OR button 2 is pressed
        
        print("Button 1 or 2 pressed")
        
        green.value(1) # green LED on
        time.sleep(2)
        green.value(0) # green LED off

And then a prompt – to think for ourselves with the resultant:

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)
button3 = Pin(3, Pin.IN, Pin.PULL_DOWN)

# Set up our LED names and GPIO pin numbers
green = Pin(20, Pin.OUT)

while True: # Loop forever
    
    time.sleep(0.2) # Short Delay
        
    if button1.value() == 1 or button2.value() == 1 or button3.value() ==1: # If button 1,2 OR button 3 is pressed
        
        print("Button 1 or 2 or 3 pressed")
        
        green.value(1) # green LED on
        time.sleep(2)
        green.value(0) # green LED off

And then for extra, adding in RED Led and making that the one to flash when pressed. It’s at this point that things start to sink in of the possibilities. Again, whilst this is very basic stuff, it’s really really interesting and an excellent starting place (by going at the right pace) to understand coding concepts. At this point I’d like to say to the PI Hut people – Well Done! And as an additional point, the children have purposely typed out the code. It’s a nice touch that it can just be copied (and just work as it is) but as my daughter pointed out – by typing it in, it slows things down and whilst errors are made, it ‘tunes’ your eyes in. Which I believe is a very important point.

Activity 5 – To Toggle or not to Toggle

Toggling with GPIO pins – HIGH to LOW to HIGH

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)

# Set up our LED names and GPIO pin numbers
red = Pin(18, Pin.OUT)

while True: # Loop forever

    time.sleep(0.5) # Short delay
            
    if button1.value() == 1: #If button 1 is pressed
        
        print("Button 1 pressed")
        
        red.toggle() # Toggle Red LED on/off

Pressing button makes RED LED flash and then adding in AMBER LED, as below does the same:

# Imports
from machine import Pin
import time

# Set up our button names and GPIO pin numbers
# Also set pins as inputs and use pull downs
button1 = Pin(13, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(8, Pin.IN, Pin.PULL_DOWN)


# Set up our LED names and GPIO pin numbers
red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)


while True: # Loop forever

    time.sleep(0.5) # Short delay
            
    if button1.value() == 1: #If button 1 is pressed
        
        print("Button 1 pressed")
        
        red.toggle() # Toggle Red LED on/off
        
    if button2.value() == 1: #If button 1 is pressed
        
        print("Button 2 pressed")
        
        amber.toggle() # Toggle Red LED on/off

Analogue

Activity 1 – Printing Analogue Values

In this activity we used one of the Analogue to Digital Converter (ADC pins). We used a variable resistor called a potentiometer. Its value changes by turning the knob below, a bit like cranking up the volume on a NAD amp system and belting out some classic Christmas songs…..like

But back to this – What’s going on? Well the objective is to ‘convert an analogue input into a digital form we can use‘. But what does this mean in English? It’s a signals thing? Anyway, as the well put together tutorial puts it….Analogue signals offer a wide range of number to represent values instead, which is much more suitable for sensors, dials and similar components. AHA – so does this mean that possible (in terms of making a motor go faster and slower that Analogue signals have to be used in a Robot (that moves?) Is this part of the puzzle? I appreciate this is side tracking but in terms of motor movements (for Pi Robot) we’re going backwards and forwards, and turning, but we need control of speed – could this be a solution?

The intstructions from the PiHut explain:

Think of digital as a light switch – it’s either on or it’s off. Think of analogue as a volume dial on a stereo – you can twist the dial to gradually turn the volume up and down by small amounts.

Our potentiometer can pass these analogue signals (in the form of voltage) to our Raspberry Pi Pico, giving us a gradual input with a wide range of values for us to play with in our code.

Then to print the values. Code imports ADC (GPIO27) as ADC pin and then WHILE loop prints the readings from potentiometer every second.

Explaining the code, the PiHut says:

The read_u16 part does this, taking the varying voltage applied to the pin from the potentiometer and scaling this to range of usable output values between 0 and 65535

For those who want to get technical – the Pico’s ADC pins are 12-bit, however MicroPython scales this to a 16-bit range which is 0-65535

All good but initially plugged middle wire into wrong pin and just had readings in a high narrow range. Realised middle wire had to go into physical pin 32. Once this was done, slight tweak to the right sent to 7,000bit more to 24,886, fully to 65535.

So, appear to be working as planned.

Activity 2: Controlling LEDs with analogue values – USE analogue signals to control

Making connected LEDs flash faster or slower using potentiometer. A time delay VARIABLE is used. And by setting amber pin and amber LED can get RED and Amber to flash together and both respond to turns on potentiometer.

# Imports
from machine import ADC, Pin
import time

# Set up the potentiometer on ADC pin 27
potentiometer = ADC(Pin(27))

# Set up the red LED pin
red = Pin(18, Pin.OUT)
# Set up the amber LED pin
amber = Pin (19,Pin.OUT)

# Create a variable called mydelay and start at 0
mydelay = 0

while True: # Loop forever

    # Update our variable with the reading divided by 65000
    mydelay = potentiometer.read_u16() / 65000
    
    # Red LED on for the variable delay period
    red.value(1)
    # Red amber on for the variable delay period
    amber.value(1)
    time.sleep(mydelay)
    
    # Red LED off for the variable delay period
    red.value(0)
    # amber LED off for the variable delay period
    amber.value(0)
    time.sleep(mydelay)

The Pi Hut instructions explain the code:

Takes a reading from the potentiometer and…

  • Divides the reading to give us a number that’s more usable as a time delay
  • Assigns the divided reading to the variable mydelay
  • Uses that delay variable to control how long the LEDs are left on and off to create a flashing sequence.’

It’s heavy but after reading it a couple of times it makes sense.

Activity 3 – Variable potentiometer values lighting different LEDs

Use IF statements to ‘trigger’ different outcome/action depending on where in range we are.

IF here or here do this, if between here and here do this, and if between here and here do this.

Operators – <= if reading <= 20000

if looking for value between 2 numbers – if 20000<reading<40000

and ‘greater than or equal to’ used >=, so if reading>=40000

# Imports
from machine import ADC, Pin
import time

# Set up the potentiometer on ADC pin 27
potentiometer = ADC(Pin(27))

# Set up the LED pins
red = Pin(18, Pin.OUT)
amber = Pin(19, Pin.OUT)
green = Pin(20, Pin.OUT)

# Create a variable for our reading
reading = 0

while True: # Run forever
    
    reading = potentiometer.read_u16() # Read the potentiometer value and set this as our reading variable value
    
    print(reading) # Print the reading
    
    time.sleep(0.1) # short delay
    
    if reading <= 20000: # If reading is less than or equal to 20000
         
        red.value(1) # Red ON
        amber.value(0)
        green.value(0)
        
    elif 20000 < reading < 40000: # If reading is between 20000 and 40000
    
        red.value(0) 
        amber.value(1) # Amber ON
        green.value(0)
        
    elif reading >= 40000: # If reading is greater than or equal to 40000
            
        red.value(0) 
        amber.value(0)
        green.value(1) # Green ON

Need to recap – ELIF follows IF, can it be IF IF, checked and no it can’t, as doesn’t run.

Activity 4 – FADER

Using Pulse Width Modulation (PWM) – Yes, you may think this could be a hairstyle with a certain kind of wave, and in your mind, you may be right. But for the purposes of this activity its used to fade LED in and out.

In order to run PWM – code needs values for Duty Cycle and Frequency

Duty Cycle – Changing the Duty Cycle will determine how long LEDs are ON. It is a % of the time that LED will be ON. Higher the Duty Cycle – the longer the LED will be ON and the brighter the LED will be.

PWM Frequency – Number of times per second that ON/OFF cycle will repeat.

# Imports (including PWM and ADC)
from machine import ADC, Pin, PWM
import time

# Set up the potentiometer on ADC pin 27
potentiometer = ADC(Pin(27))

# Set up the LED pin with PWM
led = PWM(Pin(18))

# Set the PWM Frequency
# Sets how often to switch the power between on and off for the LED
led.freq(1000)

# Create a variable for our reading
reading = 0

while True: # Run forever
    
    reading = potentiometer.read_u16() # Read the potentiometer value and set this as our reading variable value
    
    print(reading) # Print the reading
    
    # Set the LED PWM duty cycle to the potentiometer reading value
    # The duty cycle tells the LED for how long it should be on each time
    led.duty_u16(reading)
    
    time.sleep(0.001) # Short delay

Effectively, a dimmer switch. Unsure why Green LED stayed on? But code did make it so that as potentiometer Knob turned then RED LED increased/decreased in brightness – Cool!

There’s been a lot to think about and believe some real gems of information have been absorbed that will hopefully help with coding other components.

Making some NOOISE with a buzzer

Activity 1 – Making and changing Buzzer/sound

# Imports
from machine import Pin, PWM
import time

# Set up the Buzzer pin as PWM
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

# Set PWM frequency to 1000
buzzer.freq(7000)

# Set PWM duty
buzzer.duty_u16(10000)

time.sleep(1) # Wait 1 second

# Duty to 0 to turn the buzzer off
buzzer.duty_u16(0)

Very satisfying in a very annoying kind of way.

Activity 2 – Changing Tones


# Imports
from machine import Pin, PWM
import time

# Set up the Buzzer pin as PWM
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

# Set PWM duty
buzzer.duty_u16(10000)

# Set PWM frequency to 1000 for one second
buzzer.freq(1000)
time.sleep(1)

# Set PWM frequency to 500 for one second
buzzer.freq(500)
time.sleep(1)

# Buzzer off
buzzer.duty_u16(0)

And then:


# Imports
from machine import Pin, PWM
import time

# Set up the Buzzer pin as PWM
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

# Set PWM duty
buzzer.duty_u16(10000)

# Set PWM frequency to 1000 for one second
buzzer.freq(1000)
time.sleep(1)

# Set PWM frequency to 500 for one second
buzzer.freq(500)
time.sleep(1)

buzzer.freq(300)
time.sleep(1)

# Set PWM frequency to 1000 for one second
buzzer.freq(150)
time.sleep(1)

# Set PWM frequency to 500 for one second
buzzer.freq(710)
time.sleep(1)

buzzer.freq(525)
time.sleep(1)

# Buzzer off
buzzer.duty_u16(0)

Move aside Vince Clarke and Kraftwerk – there’s some new Synth sounds in town. Yes, Lucody and his sister gave a puzzled look and then this happened:

We Are The Robots

It was difficult to see if there were looks of disdain or whether it was bewilderment. So, I thought not much point in going into Jean Michel Jarre and maybe just update the code to Daftpunk – bit softer and more palatable to younger ears!

Activity 3 – Adjusting with Potentiometer

# Imports
from machine import Pin, PWM, ADC
import time

# Set up the Buzzer and Potentiometer
potentiometer = ADC(Pin(27))
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

reading = 0 # Create a variable called 'reading' and set it to 0

while True: # Run forever
    
    time.sleep(0.01) # Delay
    
    reading = potentiometer.read_u16() # Read the potentiometer value and store it in our 'reading' variable
    
    buzzer.freq(500) # Frequency to 500
    buzzer.duty_u16(reading) # Use the reading variable as the duty
    
    print(reading) # Print our reading variable

Of course, this almost caused a major incident. Like an out of control fire alarm or emergency alarm that doesn’t go off. Then realised the only way was to pull out the power! Phew!

Activity 4 – Festive Jingle – Yes it’s Christmas 2023!

# Imports
from machine import Pin, PWM
import time

# Set up the Buzzer pin as PWM
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

# Create our library of tone variables for "Jingle Bells"
C = 523
D = 587
E = 659
G = 784

# Create volume variable (Duty cycle)
volume = 10000

# Play the tune

# "Jin..."
buzzer.duty_u16(volume) # Volume up
buzzer.freq(E) # Set frequency to the E note
time.sleep(0.1) # Delay
buzzer.duty_u16(0) # Volume off
time.sleep(0.2) # Delay

# "...gle"
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "Bells"
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.5) # longer delay

# "Jin..."
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "...gle"
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "Bells"
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.5) # longer delay

# "Jin..."
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "...gle"
buzzer.duty_u16(volume)
buzzer.freq(G)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "All"
buzzer.duty_u16(volume)
buzzer.freq(C)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "The"
buzzer.duty_u16(volume)
buzzer.freq(D)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# "Way"
buzzer.duty_u16(volume)
buzzer.freq(E)
time.sleep(0.1)
buzzer.duty_u16(0)
time.sleep(0.2)

# Duty to 0 to turn the buzzer off
buzzer.duty_u16(0)

Activity 5 – Festive Jingle con’d using Functions

Blocks of code you can call at any time

Good for repetitive blocks of code

Example: def followed by name of function, this case ‘myfunction’ then parenthesis () and then colon:

Indentation is important:

def myfunction():
    print("This")
    print("is a")
    print("function")

Without a function – so repeating same command 3 times:

print("This")
print("is a")
print("function")

print("This")
print("is a")
print("function")

print("This")
print("is a")
print("function")

With a function – again repeating same command 3 times:

def myfunction():
    print("This")
    print("is a")
    print("function")
    
myfunction()
myfunction()
myfunction()

It run the same and whilst we can see the benefit (sort of like using shorthand) it will be more useful when we get to that point where we have a repetitive piece of code that we want to set up a function for.

Function Arguments – This didn’t work for us, don’t know why.

Looking at the code below can see the usefulness of this:

Import>Setup>Variables>Function with arguments.

And can ge

# Imports
from machine import Pin, PWM
import time

# Set up the Buzzer pin as PWM
buzzer = PWM(Pin(13)) # Set the buzzer to PWM mode

# Create our library of tone variables for "Jingle Bells"
C = 523
D = 587
E = 659
G = 784

# Create volume variable (Duty cycle)
volume = 32768

# Create our function with arguments
def playtone(note,vol,delay1,delay2):
    buzzer.duty_u16(vol)
    buzzer.freq(note)
    time.sleep(delay1)
    buzzer.duty_u16(0)
    time.sleep(delay2)
    
# Play the tune
playtone(E,volume,0.1,0.2)
playtone(E,volume,0.1,0.2)
playtone(E,volume,0.1,0.5) #Longer second delay

playtone(E,volume,0.1,0.2)
playtone(E,volume,0.1,0.2)
playtone(E,volume,0.1,0.5) #Longer second delay

playtone(E,volume,0.1,0.2)
playtone(G,volume,0.1,0.2)
playtone(C,volume,0.1,0.2)
playtone(D,volume,0.1,0.2)
playtone(E,volume,0.1,0.2)

# Duty to 0 to turn the buzzer off
buzzer.duty_u16(0)

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top