Wednesday, November 13, 2024

Celebrating working a year with Linux

For an index to all my stories click this text.

Commercial company's need to make money. And sometimes that makes us dependent on them. Ignorance helps them enormously while a cheap solution is sometimes right around the corner if you dare to experiment. Read on.........

Last year November I was getting really annoyed with my computer.
I bought my system in 2018 (so 6 year old) and it runs Windows.
From powering up to the moment I can actually do something with it, takes several minutes. Well to put it exact: about 3-5 annoying minutes. And shutting down sometimes even took longer. That is not the worse part. Sometimes, while working,  the computer slows down so much that it is unworkable.

A lot of that is because the computer is updating Windows and several programs in the background. And at the same time my virus scanner is doing its work. All that takes time and slows everything down.
Another thing was, that Windows informed me, that I would not be able to run Windows 11 on my computer because it was too old.

So time to buy a new machine right ???

Well, I decided to try something else first. And man am I glad that I did.

Linux dual boot

As I was going to buy a new computer I first made a backup of all my data.
That would make it easy to transfer all my texts, schematic's foto's etc to my new machine.
Then I took the plunge and installed Linux on my old machine. I made it dual boot so I could always fall-back to Windows.


I installed Kubuntu. This is a special version of Ubuntu Linux with the KDE desktop. It has the most look and feel like Windows. That would make the switch easier.
And from that moment on I started working with Linux. And of course I had the safety net of a dual boot system, so I could switch back to Windows anytime.

And I never did.

I never went back to Windows !!!

All the programs I need are available under Linux. To name a few: Office (LibreOffice), the Gimp, Thonny, Fritzing, Arduino IDE, Audacity, Cura, Prusa slicer, Firefox, Chromium (a Chrome clone), Discord, VNC viewer, Kicad etc.
My Epson Ecotank ET-2814 printed immediately and it's scanner was also direct recognized and worked flawless. Same for my external harddisks, USB sticks and communication with ESP's and Raspberry Pico's over USB.

Next to that: my system starts within 2 minutes and shuts down within a few seconds. No annoying updates in the background forcing me to restart. Virus-scanner ??? No sir. Linux is a very safe operating system and there are almost no viruses around. And yes: there is a virus scanner if that makes you feel safer.

So, I did not buy a new computer and happily work with my crusty old system.
At this moment it is fast enough to be my daily workhorse but eventually it will break down due to its age. And I already have an idea on what my new computer will be.
Actually I have already discussed it this year on this weblog.........

For now:
All glory to Tux !!!


The above image is a picture of Tux. The Linux mascotte. Picture courtesy of Wikipedia.

So if you own an old computer and think about getting a new one: try Linux first. You may get pleasantly surprised.

Till next time

Luc Volders

Friday, November 8, 2024

Pico audio Part 5 - Talking clock

For an index to all my stories click this text

This is another entry in the series about producing audio with the Raspberry Pi Pico. Audio on the Pico sounds great. Not like the vintage Commodore speech synthesises. No this sounds like real audio. In this story I will show how to build a speaking clock. This story heavily leans on the previous stories so I urge you to read them first.

I like to emphasize again that this delivers a very good audio quality !!!

Audacity. This was the first story in this series. Here I showed how to record audio and save it in the required 8k wav file format. I chose audacity for this while it not only allows to record audio with a microphone but also can convert other audio files (like mp3) to the format we need. Read that story here:
http://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

Pico audio 2. This story shows how to build the hardware needed for producing audio. Do not worry is is very cheap. The only thing you need is 6 resistors and 2 capacitors. Oh, and of course a Raspberry Pi Pico or Pico W. You can find this story here:
http://lucstechblog.blogspot.com/2024/10/audio-on-pico-part-2-hardware.html

Pico audio 3. This story deals with the software side. To produce audio on your Pico you will need no less then 5 libraries. This story shows where to get them and how to write your first program that speaks out loud "Hello World". All done in MicroPython. Read the story here:
http://lucstechblog.blogspot.com/2024/10/pico-audio-part-3.html

Pico audio 4. This story brings the first practical project: a speaking thermometer. For  building this project you will need a Dallas DS18B20 digital thermometer, next to the hardware described in the second story. The program is written in MicroPython. Read the story here:
http://lucstechblog.blogspot.com/2024/11/pico-audio-part-4-talking-thermometer.html

Getting the time.

Generally when you are working with your Pico in MicroPython you will have the Pico connected to Thonny. If you type the next commands in the shell:

import time
print(time.localtime())


The Pico will respond with something like:

(2023, 1, 25, 21, 8, 58, 2, 25)

The answer is build up like this:
year, month, day, hour, minute, seconds, weekday, yearday

The year is 2023, the month is 1 (January), the day is 25, the hour is 21, minutes is 8,seconds 58, weekday is 2 and yearday is 25. This data is stored in a tuple.

To get the hour you need to fetch the 3d element in the tuple like this:
hour = time.localtime()[3]

To get the minutes, fetch the 4th element like this:
minute = time.localtime()[4]

As you can see I was writing this story on the 25th of january 2023 at 21 hour 8 minutes and 58 seconds.
The weekday is 2. Weeks start at 0 on Sunday. So weekday 2 is tuesday. And it is the 25th day of this year.

So print(time.localtime()) gives us a load of information. Useful information with which we can make some great projects. Think Internet Of Things and actions that only need to be taken on MondaĆ½s for example or every 10th day.

But.........There always is a but...........

When you connect the Pico to Thonny your Pico gets the right time from your computer through Thonny. This means that if you disconnect and therefore power-down, Pico loses the right time.
So if you use the Pico stand-alone and power it from a usb power supply or battery or power-bank the Pico does not get the right time. So it starts with it's initial time and that is the unix Epoch time. The date is set to 1 January 1970 at midnight.

How to set the right time.

It is not much of a clock if it does not give you the right time.
There are 3 ways to set the right time in the Pico.

The first one is the old fashioned way to set the time manually. Add some switches to the Pico and with each press of one of the switches add 1 to the hour or add 1 to the minutes.

The second way is to use a special device called a real-time-clock. This is a clock chip with a small battery that operates for several year. I am not going to use that here.

Mind you. The Pico has a build in RTC (real time clock) but no battery back-up. So you still have to set the time each time the Pico reboots.

The third solution is to use a Pico W. The Pico W has wifi and can connect to a so called NTP-server. This is an abbreviation of Network-Time-Protocol server. You need to install a MicroPython library for this. If you want to know how to do that just look at this story:
http://lucstechblog.blogspot.com/2023/04/getting-right-time-with-micropython.html

In this version of the talking clock we are going to set the time manually by means of 2 buttons: one for the hour and one for the minutes.

With print(time.localtime()) we can get the time. However we can not set the right time this way. We need to address the internal RTC for that. Therefore the RTC library is needed and that is included in MicroPython so no need to download that.

The exact syntax for this is:

import machine
rtc = machine.RTC()


and then:

rtc.datetime((year, month, date, weekday, hour, minute, seconds, subseconds))

The value of subseconds is hardware dependent so different values on a Pico then from another microcontroller. Usually you will only set year, month, day, hour and minutes and set the remaining variables to zero. That is when setting the time manually. The NTP server or a RTC module will give the right seconds to.

Now we know how to set the right time we need to complete our speech files.

Revisit Audacity

In the first story I used Audacity to record audio files with a microphone. We recorded the words 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 40, 50, "it is now", "degrees". We needed those for our talking thermometer.

Please restart Audacity and record the words "minutes", "midnight" and "hour" and add these to your Pico's Sounds directory.

The hardware setup

For building the talking clock we need the Raspberry Pi Pico (or Pico W) and the hardware for producing the audio as discussed in the second story in this series. You can find that here:
http://lucstechblog.blogspot.com/2024/10/audio-on-pico-part-2-hardware.html



For setting the clock's hour and minutes I added two buttons. And I added another button to get the time. The buttons are attached to a 10K pull-up resistor. The hour button is attached to GP18. The minutes button is attached to GP19. The button for getting the time is attached to GP20.

The talking clock program

In the Picoaudio 2 story you can find where to get the necesary libraries. It also discuses a small test program to check wether your audio setup is working correctly. Please read that story first and try the test before proceeding.

And here is the full program:

import time
import machine
from wavePlayer import wavePlayer

but01=machine.Pin(18, machine.Pin.IN)
but02=machine.Pin(19, machine.Pin.IN)
but03=machine.Pin(20, machine.Pin.IN)

player = wavePlayer()

rtc = machine.RTC()

# set your own date and time here
year = 2023  
month = 1
date = 25
hour = 17
minute = 54

rtc.datetime((year, month, date, 0, hour, minute, 00, 0))

print(time.localtime())
time.sleep(2)

while True:
        
  if (but01.value()==0):
      print("button 1 pressed")
      hour = time.localtime()[3]
      minute = time.localtime()[4]
      hour = hour + 1
      if (hour == 24):
          hour = 0
      hour2=hour

      print (hour2)
      rtc.datetime((year, month, date, 0, hour, minute, 00, 0))
      if (hour2 == 00):
        player.play("/Sounds/midnight.wav") 
      if (hour2>0 and hour2<=20):
        player.play("/Sounds/"+str(hour2)+".wav")
      if (hour2 == 24):
        player.play("/Sounds/midnight.wav")   
      if (hour2>20 and hour2<=23):
        player.play("/Sounds/"+str(20)+".wav")
        hour2 =  hour2-20
        player.play("/Sounds/"+str(hour2)+".wav")
      print(time.localtime())
      time.sleep(.5)
    
  if (but02.value()==0):
      print("button 2 pressed")
      hour = time.localtime()[3]
      minute = time.localtime()[4]
      minute = minute + 1
      if (minute == 60):
          minute = 0
      minute2=minute    
      rtc.datetime((year, month, date, 0, hour, minute, 00, 0))
      if (minute2 == 0):
        print("0 minutes")   
      if (minute2>0 and minute2<=20):
        player.play("/Sounds/"+str(minute2)+".wav")
        
      if (minute==30):
        player.play("/Sounds/"+str(30)+".wav")
      if (minute2>20 and minute2<30):
        player.play("/Sounds/"+str(20)+".wav")
        minute2 =  minute2-20
        player.play("/Sounds/"+str(minute2)+".wav")
        
      if (minute==40):
        player.play("/Sounds/"+str(40)+".wav")
      if (minute2>30 and minute2<40):
        player.play("/Sounds/"+str(30)+".wav")
        minute2 =  minute2-30
        player.play("/Sounds/"+str(minute2)+".wav")

      if (minute==50):
        player.play("/Sounds/"+str(50)+".wav")
      if (minute2>40 and minute2<50):
        player.play("/Sounds/"+str(40)+".wav")
        minute2 =  minute2-40
        player.play("/Sounds/"+str(minute2)+".wav")
 
      if (minute2>50 and minute2<60):
        player.play("/Sounds/"+str(50)+".wav")
        minute2 =  minute2-50
        player.play("/Sounds/"+str(minute2)+".wav")
      print(time.localtime())
      time.sleep(.5)
      
  if (but03.value()==0):
    print("=========================================")  
    print(time.localtime())
    print("=========================================")
    player.play("/Sounds/itsnow.wav")
    
    # get the stored hour
    hour = time.localtime()[3]
    
    if (hour == 00):
      player.play("/Sounds/midnight.wav") 
    if (hour>0 and hour<=20):
      player.play("/Sounds/"+str(hour)+".wav")
    if (hour == 24):
      player.play("/Sounds/midnight.wav")   
    if (hour>20 and hour<=23):
      player.play("/Sounds/"+str(20)+".wav")
      hour =  hour-20
      player.play("/Sounds/"+str(hour)+".wav")
    player.play("/Sounds/hour.wav")  
    
    # get the stored minutes
    minute = time.localtime()[4]

    if (minute>0 and minute<=20):
        player.play("/Sounds/"+str(minute)+".wav")
        
    if (minute==30):
        player.play("/Sounds/"+str(30)+".wav")
    if (minute>20 and minute<30):
        player.play("/Sounds/"+str(20)+".wav")
        minute =  minute-20
        player.play("/Sounds/"+str(minute)+".wav")

    if (minute==40):
        player.play("/Sounds/"+str(40)+".wav") 
    if (minute>30 and minute<40):
        player.play("/Sounds/"+str(30)+".wav")
        minute =  minute-30
        player.play("/Sounds/"+str(minute)+".wav")

    if (minute==50):
        player.play("/Sounds/"+str(50)+".wav") 
    if (minute>40 and minute<50):
        player.play("/Sounds/"+str(40)+".wav")
        minute =  minute-40
        player.play("/Sounds/"+str(minute)+".wav")
 
    if (minute>50 and minute<60):
        player.play("/Sounds/"+str(50)+".wav")
        minute =  minute-50
        player.play("/Sounds/"+str(minute)+".wav")
        
    if (minute != 0): 
        player.play("/Sounds/minutes.wav")

    time.sleep(1)

You can copy this and paste it into Thonny.

As usual on this weblog I am going to discuss some of the details in this program.

import time
import machine
from wavePlayer import wavePlayer

These are the necesaqry libraries. Time is obviously needed when building a clock.... The machine library is needed for thr RTC and the buttons. And the waveplayer library is the one that produces the audio.

but01=machine.Pin(18, machine.Pin.IN)
but02=machine.Pin(19, machine.Pin.IN)
but03=machine.Pin(20, machine.Pin.IN)

The buttons are defined and assigned to their pins. but01 on GP18 for setting the hour. but02 on GP19 for setting the minutes. And but03 on GP20 for getting the time.

player = wavePlayer()

rtc = machine.RTC()

The waveplayer library is initiated and we call it player for convenience. The RTC library is also initiated and that is called rtc.

# set your own date and time here
year = 2023  
month = 1
date = 25
hour = 17
minute = 54

rtc.datetime((year, month, date, 0, hour, minute, 00, 0))

print(time.localtime())
time.sleep(2)

If you start the program from Thonny, which you should for testing purposes, you can fill in here the current date and time. Then you do not need to set the time with the buttons. You can fill in any date you like. The RTC does not mind....... For testing purposes set the hour and minutes a bit earlier so you can test the buttons.

  if (but01.value()==0):
      print("button 1 pressed")
      hour = time.localtime()[3]
      minute = time.localtime()[4]

When the first button is pressed the program gets the hour and minutes from the rtc using time.localtime. The first time the program is run the hour and minutes are those that we put in at the beginning of the program. The second time the button is pressed the hour is already different and therefore we need to check it.

      hour = hour + 1
      if (hour == 24):
          hour = 0
      hour2=hour

Then we add 1 to the hour. Then we check if the hour is 24. If it is the clock must not say 24 hour xxx minutes. The clock starts again at 00 at 24.00 hour. So we set it to 0.
Next the value of the hour variable is copied into the hour2 variable. We will use that one to do some calculations.

      print (hour2)
      rtc.datetime((year, month, date, 0, hour, minute, 00, 0)

As a check the hour2 variable is printed in Thonny's shell. The Real Time Clock is set to the new values in this case only the hour has changed.

      if (hour2 == 00):
        player.play("/Sounds/midnight.wav") 

The program tests if the hour is 0 and then the player speaks the word "Midnight".

      if (hour2>0 and hour2<=20):
        player.play("/Sounds/"+str(hour2)+".wav")

If it is between 0 and 21 hour the player speaks out one of the 20 wav files in the Sounds library. The hour2 value is an integer value so we translate it first to a string and then add ".wav"
This way the hour 10 becomes "10.wav"

      if (hour2>20 and hour2<=23):
        player.play("/Sounds/"+str(20)+".wav")
        hour2 =  hour2-20
        player.play("/Sounds/"+str(hour2)+".wav")

If the hour is between 20 and 24 the player speaks out the file "20.wav" next 20 is subtracted from the hours value and the remaining figure is spoken.

This is code is basically the same for but02. Only here we test for the minutes and the test is a bit more extensive as the minutes go up to 59.

And for but03 the code is basically also the same. The difference is that this button is only used for having the clock speaking the time and no values are altered.

Using the clock

First you need to decide whether you want this clock program to start up immediately after the Pico is powered up. If so you need to save this program using the name main.py MicroPython automatically runs a program with the name main.py at powering up.

I advise however to first test this program running from Thonny. Then you can intervene if something is not working. So first save it as for example Talkclock.py

When powering the Pico from a power bank (and the program is started as main.py) the clock will not have the actual time. So press the hour button and each time you do the hours are raised by one and you will hear the clock saying the hour in your own voice. Same goes for setting the minutes with the second button.

When the time is set no further action is needed. Just press the third button when you want to know the time.


Here is my breadboard setup. The Pico on the right side with a label lying on top of it showing the pin numbers. You can find that here: http://lucstechblog.blogspot.com/2021/03/raspberry-pico-pin-layout-help.html The audio hardware is still on a separate breadboard as I use it on several Pico's.  The audio output is connected with crocodile clips to an active speaker. And yes: on the left side on the bottom is an SD card. 

Expansions

The clock speaks the time in hours and minutes. So at 13.45 it wil say "It is now 13 hour 45 minutes" At 10.30 the clock says "It is now 10 hour, 30 minutes"
This is not exactly like how we look at a clock in real life. Normally we say it is quarter to one or half past 10 etc. The problem is that we run out of memory on the Pico. There is not a lot room left to add more voice recordings. Luckily there is a solution. We can attach an SD card to the Pico and then we get virtually unlimited memory. That story is coming up.

If you are using the Pico W instead of the ordinary Pico you can connect the Pico to the internet to get the exact time from a Network Time Protocol server. You can put that time into the RTC and you always will have the right time.

Another expansion would be to attach the DS18B20 to the Pico like we did in the third story. Add another button and presto we have the time and temperature at hand.

Another thing that comes to my mind is incorporating an alarm. You can record the sound of an alarm bell or have your spouse/partner speak a wake-up call. For this we would also need more memory for the voice/audio recordings.

But for now this works great !!
And it really is a fun project.

Till next time.
Have fun


Luc Volders


Friday, November 1, 2024

Pico Audio part 4 - Talking thermometer

For an index to all my stories click this text

This is the fourth story on how to play audio on the Raspberry Pi Pico with MicroPython. In this story I am showing how to build a talking thermometer. The audio on the Pico does not sound like the crappy audio on the ESP32 with Talkie. That sounded like voice synthesizes on the Commodore 64 and Atari computers if you still remember that. No this is real clear audio. And for the talking thermometer we are going to use your own recorded voice.

I urge you to read the proceeding stories in which audio recording, the neccesary hardware and software were discussed.

Audacity. This is the first story in this series. With audacity we can record our own voice using a microphone or a build-in microphone in your webcam. You can also convert mp3 files to the required 8K wav files for this project. Read that story here:
http://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

Picoaudio 2 the hardware. This story shows what hardware you need. Don't worry its just a few resistors and some capacitors. The total cost will be around 1 Euro/USD without the Raspberry Pi Pico. And as you know the Pico itself will set you back around 5 Euro/USD for the non-wifi version and about 8 Euro/USD for the wifi version.
http://lucstechblog.blogspot.com/2024/10/audio-on-pico-part-2-hardware.html

Picoaudio 3 the software. This story describes which MicroPython drivers you will need. In total 5 drivers. The story gives you the links to the download site. The story also shows a small program that will play your first sounds.
http://lucstechblog.blogspot.com/2024/10/pico-audio-part-3.html

The thermometer.

To get the temperature we will use the readily available DS18B20 digital thermometer. In case you do not have one at hand, read further on for a simple solution.



To attach the DS18B20 to a Pico you only need the chip itself and a 4.7k pull-up resistor. If you are not familiar with this digital thermometer chip and how to use it with MicroPython you can read all about this in one of my books: Raspberry Pi Pico Simplified or Raspberry Pico W Simplified.



Here is the breadboard setup. The Dallas DS18B20 is attached (with a 4.7K pull-up resistor) to GP17 of the Pico. The rest of the setup is taken from my second story in this series: http://lucstechblog.blogspot.com/2024/10/audio-on-pico-part-2-hardware.html

First test

Before we are going to have our Pico speak out the temperature we first are going to do a test if everything works as we want.

Copy the following program in Thonny's editor and run it.

'''
Copy from Luc's book
Dallas on pin 17
'''

import machine
import onewire
import ds18x20
import time
 
dallaspin = machine.Pin(17)
sensor = ds18x20.DS18X20(onewire.OneWire(dallaspin))
 
roms = sensor.scan()
print('A ds18x20 is present')
 
while True:
  sensor.convert_temp()
  time.sleep(1)
  print(sensor.read_temp(roms[0]))
  time.sleep(2)


Thonny's shell will show you something like this:



The figures in your output will definitely be different. It was really cold in my mancave !!! As long as you get figures you know the DS18B20 is working fine. On to the next step.

Copy the Audacity files

In the first chapter in this series I asked you to make recordings of your own voice saying the words 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 40, 50, It is now, Degrees. If you did not do that please do that now. Make sure to record these words in 8K wav format. If you do not know how to do that please read the first story in this series: http://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html (Audacity)

Create a new directory in Thonny, call it "Sounds" and copy the recorded wav files to that directory. If you are not sure how to do this you can read a small tutorial here:
http://lucstechblog.blogspot.com/2023/07/a-few-small-thonny-tips.html (thonny tips).



When done your Pico's directory will look like this.

The talking thermometer program

The preparations are done meaning that the breadboard setup is build and all the audio files are copied to the Pico's memory. The last part is the program that glues all this together.

'''
Talking thermometer program
http://lucstechblog.blogspot.com/
'''

import machine
import onewire
import ds18x20
import time
from wavePlayer import wavePlayer

dallaspin = machine.Pin(17)
sensor = ds18x20.DS18X20(onewire.OneWire(dallaspin))
 
roms = sensor.scan()
print('A ds18x20 is present')

player = wavePlayer()

while True:
  sensor.convert_temp()
  time.sleep(.5)
  temp = int(sensor.read_temp(roms[0]))
  print (temp)
  player.play("/Sounds/itsnow.wav")
  if (temp<=20):
     player.play("/Sounds/"+str(temp)+".wav")
  if (temp>20 and temp<30):
      player.play("/Sounds/"+str(20)+".wav")
      temp = temp-20
      player.play("/Sounds/"+str(temp)+".wav")
  if (temp>30 and temp<40):
      player.play("/Sounds/"+str(30)+".wav")
      temp = temp-30
      player.play("/Sounds/"+str(temp)+".wav")
  player.play("/Sounds/degrees.wav")
  time.sleep(3)

As usual on this weblog (and in my books) I'll give a short explanation on some highlights of the program.

while True:
  sensor.convert_temp()
  time.sleep(.5)
  temp = int(sensor.read_temp(roms[0]))
  print (temp)
  player.play("/Sounds/itsnow.wav")

After the necessary libraries have been loaded an endless loop is started. Inside the loop the Dallas DS18B20 is accessed to get the temperature. The temperature is then printed in Thonny's shell as a check.
Then you can hear your own voice (or the one you recorded) through the speaker saying "it is now"

  if (temp<=20):
     player.play("/Sounds/"+str(temp)+".wav")

If the temperature is equal to or below 20 degrees the program converts the temperature's value into a string and plays XX.wav in which the xx's are the value of the temperature. Make sure that the .wav files are in the /Sounds/ directory. Otherwise change the name of the directory in this line.

  if (temp>20 and temp<30):
      player.play("/Sounds/"+str(20)+".wav")
      temp = temp-20
      player.play("/Sounds/"+str(temp)+".wav")

If the temperature is higher than 20 degrees and lower than 30 degrees first the word "twenty" is spoken, found in the file "20.wav". Then 20 is subtracted from the temperature's value and the remaining figure is spoken.

  if (temp>30 and temp<40):
      player.play("/Sounds/"+str(30)+".wav")
      temp = temp-30
      player.play("/Sounds/"+str(temp)+".wav")

The same we did for values between 20 and 30 happens here when the temperature is higher as 30 degrees and lower as 40.

  player.play("/Sounds/degrees.wav")
  time.sleep(3)

The player then speaks the word "degrees" and finaly there is a pause of 3 seconds after which the sequence repeats.

And that is all that is needed to build a talking clock.

Expansions for the talking thermometer.

This talking thermometer speaks the temperature out loud every 5 seconds or so. This is really annoying. So you can alter the pause so that it reads out the temperature every half our or so.

Add a button. Alter the software in such a way that the temperature is only proclaimed when the button is pressed.

You could alter the software in such a way that the temperature is only pronounced when it reaches a certain critical value.

If you do not know how to add a button to this program or test for a critical value in MicroPython please consider buying one of my books: Raspberry Pi Pico Simplified or Pico W simplified.

Coming up: a talking clock.

Till next time
have fun

Luc Volders





Friday, October 18, 2024

Pico Audio Part 3

For an index to all my stories click this text.

In this story I show how to install the necessary MicroPython drivers to play some real audio on the Raspberry Pico. And trust me it is worth while. The Pico is able to produce some excellent audio quality with the aid of just some resistors and capacitors !!

This is the third story on how to play audio files on the Raspberry Pi Pico.
The first story showed how to work with Audacity to record your own voice or convert existing audio to the wav format which can be played by the Pico. You can read that story here: http://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

The second story told how to build the hardware setup. You just need 4 resistors and 2 capacitors. The total cost of this project is about 1 Euro/USD. That is without the Raspberry Pi Pico itself. You can use the Pico or the Pico W for this. They work equally well. You can read how to build the hardware here:
http://lucstechblog.blogspot.com/2024/10/audio-on-pico-part-2-hardware.html

Now the preparations are done we can install the software.

MicroPython drivers.

To play audio (wav) files on the Pico with MicroPython we need some drivers.

From MicroPython we need two drivers called chunk.py and wave.py. You can get them here:
https://github.com/joeky888/awesome-micropython-lib/tree/master/Audio
Just read the text and halfway the page you will find the links.

Next to these you will need some extra drivers which you can find here:
https://github.com/danjperron/PicoAudioPWM
From this link you will need to copy: myDMA.py, myPWM.py and wavePlayer.py. These drivers are provided courtesy of Daniel Per.ron

Just download and copy these five drivers to your Pico's lib directory.

For your convenience I have made a collection of all necessary drivers in my Github repositry. Here is the link:

https://github.com/Lucvolders/MicroPython/tree/main/Libraries/PicoAudio

Every file is just a textfile and can be copied and then pasted in Thonny. You can then save the file in Thonny's lib directory. Make sure to give the file exact the same name as they have in the repositry.

Your Pico's lib directory should now look like this:



Undoubtedly you will have more libraries loaded but these should be present to play audio.

Back to Audacity

In a previous story on this weblog I showed how you can record your own voice with Audacity. You can read that story here:
http://lucstechblog.blogspot.com/2024/10/audacity-pico-audio-part-1.html

In that story I gave you some "homework". I asked you to record the sentence "Hello world, this is the Raspberry Pi Pico talking" and save it on your computer using the name hello.wav

If you haven't done that please do it now because we are going to use that as a test for our audio player.

Make a new directory on your Pico and call it testsounds. Copy hello.wav to that directory.

If you do not know how to copy data files to a directory on your Pico you can follow this tutorial: http://lucstechblog.blogspot.com/2023/07/a-few-small-thonny-tips.html



This is how your Pico's directory should look now in Thonny. Well that is if you are using a freshly installed Pico like I did.

Let's play some sound.

To play a sound we need just a small MicroPython program. Here it is:

from wavePlayer import wavePlayer
import time

player = wavePlayer()

while True:
    player.play('/testsounds/hello.wav')
    time.sleep(3)

I think this is self-explanatory nevertheless I will give some brief explanation.

from wavePlayer import wavePlayer
import time


The wavePlayer driver is imported in the Pico and so is the time library.
As stated in the beginning of this story we need 5 libraries to get the audio working. The wavePlayer library uses the other 4 libraries and loads them automatically.

player = wavePlayer()

The wavePlayer library is activated and we call it player.

while True:
    player.play('/testsounds/hello.wav')
    time.sleep(3)


An endless loop is created and in that loop player.play('/testsounds/hello.wav') plays the sound. Then there is a 3 second pause and the sound is repeated.

Space limitations.

Wave files take a lot of memory. My simple sentence "Hello world, this is the Raspberry Pi Pico talking" is converted in a 128k file. AS MicroPython itself also occupies a lot of flash memory there is in this example just 616K memory left for programs and libraries.

In the first story (the one about Audacity) I asked you to record several audio files. These take about 447k memory. So there is not much room for many or large audio files. But there is a solution for that which I will show in an upcoming story.

Ideas ???

Well this can be used in a lot of ways. In upcoming stories I'll show how to build a talking thermometer and a talking clock. Besides these how about:

- a talking doorbell
- audio feedback when a button was pressed
- an audio alarm when someone opens the cookie jar
- a piano that plays real recorded tones
- a musical greeting card
- an audio alarm for sensors

And last but not least. I will show you how to build a real audio player that plays music, podcasts etc as long as they are converted to 8k wav files !!!

Till next time
have fun

Luc Volders