Introduction: School Bell for Distance Students

About: I enjoy building hardware and software.

With the COVID-19 pandemic, many kids' schools have gone to distance delivery. This home school bell is a fun way to stay on schedule that uses a Raspberry Pi and a USB speaker. You can make it with your kid and they can learn about programming and can "ring the bell". I built this for my daughter who is going into 7th grade (currently via distance delivery), and it is working well to keep us on time.

Supplies

For this project, you will need:

  • A Raspberry Pi computer -- It works best if you have WiFi, I used a RPi 3B from a Kano kit
  • A Speaker -- I used a USB speaker

The code could easily run on your student's linux computer or even a microcontroller running micropython, as long as the microcontroller has some mechanism to get the current date/time. Also any amplified speaker, or even cooler a relay / analog bell, could be used.

Step 1: Set Up Your Raspberry Pi

There are a large number of resources for setting up a Raspberry Pi computer, so I refer you to one that Google finds. The important thing is that your computer has a way to get the correct date and time. Most modern WiFi-enabled Raspberry Pi computers use the NTP protocol to set the time from the internet, which is the way I got the correct time. I set up my RPi to be "headless", meaning it has no keyboard or monitor, but is accessible by secure shell (SSH) over the internet. If you are good with RPi, you can do this setup without a keyboard / video / mouse, but it is easier to just set up the pi with those accessories.

Note that I didn't need to use the graphical interface, so I just downloaded the "Raspberry Pi OS (32-bit) Lite", which is smaller and faster to download and boots faster.

Configure the Raspberry Pi's network and interfacing options

$ sudo raspi-config

In the configuration, do the following:

  • Change the password -- do this first, hopefully before going online!
  • In "Network Options",
    • Change the hostname. I used the hostname: "schoolbell".
    • Connect to your Wireless LAN (if you haven't done that in setup)
  • Under "Interfacing Options", turn on SSH access
  • It is always good to run the "Update" option

Once you have done this and rebooted, you should be able to connect to the Raspberry Pi from another computer on the same local network by using a SSH client. Connect to it by using the following credentials:

hostname: schoolbell.local
user: pi
password: whateveryousetitas

From a linux box, this is as simple as typing this command line at the $ prompt:

$ ssh pi@schoolbell.local
... enter password at prompt

That will log you in and you can check that the time on the Raspberry Pi is correct. At the command line, type the date command and check the response:

pi@schoolbell:~ $ date
Thu  3 Sep 20:44:34 AKDT 2020

Hopefully this is the current time. If it is not correct, google about setting up NTP on the Raspberry Pi.

Step 2: Get Your Sound System Working

We are going to be playing MP3 files for the bells, so we need to download software to decode these audio files. I got the mpg321 package by typing this command:

pi@schoolbell:~ $ sudo apt-get install mpg321

Follow the prompts to install this software.

I used an old USB speaker, which had a strange driver and didn't fully auto configure as the default sound card, so I found I could "hack" the speaker to work by using its hardware address. After plugging in the speaker, I used the command 'aplay -l' to list audio devices:

pi@schoolbell:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

The device I want is the lower one, card 1, device 0.

I tested the speaker with "speaker-test", using the device "hw:1,0", meaning hardware card 1, device 0

pi@schoolbell:~ $ speaker-test -D hw:1,0

This program puts out noise from the speakers. Enjoy the noise then type control-C when you get annoyed. If you hear no noise, try google.

Now you have sound!

Step 3: Test Playback of Bell Sounds And/or Make New Sounds

For my bell, I downloaded the "bing-bong" sound from "freesound.org". Thanks to Benboncan for making this sound available:

https://freesound.org/people/Benboncan/sounds/93646/

You can play the sound directly. I could directly download a mp3 version of this file by typing this command on the Raspberry Pi computer (assuming it is on WiFi):

pi@schoolbell:~ $ wget https://freesound.org/data/previews/93/93646_634166-hq.mp3

I then renamed this file:

pi@schoolbell:~ $ mv 93646_634166-hq.mp3 bing-bong-chime-hq.mp3

I then tested that I could ring the bell with this command (showing output):

pi@schoolbell:~ $ mpg321 -a hw:1,0 bing-bong-chime-hq.mp3 
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2, and 3.
Version 0.3.2-1 (2012/03/25). Written and copyrights by Joe Drew,
now maintained by Nanakos Chrysostomos and others.
Uses code from various people. See 'README' for more!
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!

Playing MPEG stream from bing-bong-chime-hq.mp3 ...
MPEG 1.0 layer III, 128 kbit/s, 44100 Hz mono
[0:02] Decoding of bing-bong-chime-hq.mp3 finished.

Congrats! You have audio.

Using the sound-editing code "audacity" on my laptop, I split the file into "bing" and "bong" for more fun. You can use any mp3 or maybe other format (I haven't tested others) sound files.

Step 4: Install the Code and Set Your Schedule

The code is a python script that gets the current date/time and if the date is a weekday and not a holiday, it checks if the time matches a bell time, chiming if it should.

First you will get it to work, then you will automate it to run every minute.

Download the code from Github:

https://gist.github.com/BillSimpson/d7a1a531995c8b63492bb47ef8872618

I find it easy to do this by saving the file on a local computer then using secure copy (scp) to put it onto the Raspberry pi.

On your local machine, copy the code from your browser, then paste into a text file and save it with the filename "schoolbell.py". Then scp the file over:

local-machine:~ $ scp schoolbell.py pi@schoolbell.local:~/

You will be prompted to enter the password for the user pi on schoolbell.local -- enter the password, and the file gets copied securely. This command should be run in the same directory where the python script was saved, and copies it to the home directory of the pi user. You can ssh over to schoolbell.local and the code should be there:

local-machine:~ $ ssh pi@schoolbell.local

Then on schoolbell.local, list the files (you may see more files):

pi@schoolbell:~ $ ls
bing-bong-chime-hq.mp3  schoolbell.py

Now edit the code to make it have your bell schedule by using an editor such as pico:

pi@schoolbell:~ $ pico schoolbell.py

The code has three "dictionaries" that define the bell tones to play, the times to play them, and the holidays to avoid, Bells on weekends are automatically skipped.

For example, the belltones dictionary is:

belltones = {
    'warn' : 'bing-bong-chime-hq.mp3',
    'start' : 'bing-bong-chime-hq.mp3',
    'end' : 'bing-bong-chime-hq.mp3'
}

This defines three types of bells, a warn bell, a start of class, and an end. Because we only have one bell tone, they all point to the same file, but if you make different tones, you can change them. You can even add other types of bells tones. I also played with using a speech synthesizer to speak the bells, but that was not viewed favorably by others in the house.

The bellschedule dictionary is similar, but the "key" is now the time for the bell. you need to use the format HH:MM with leading zeros and 24-hour time (military time).

bellschedule = {
        '09:00' : 'start',   # 'Bus' bell to be getting ready
        '09:28' : 'warn',
.....
        '13:58' : 'warn',    # for period 4
        '14:00' : 'start',
        '15:00' : 'end'
}

The value in this key:value pair is the type of bell tone to use and needs to match one of the belltones defined above.

Last, the holidays dictionary lists the holiday dates. The format is YYYY-mm-dd, with leading zeros as shown.

holidays = {
    '2020-09-07',
....
    '2021-03-11',  
    '2021-03-12'
}

Once you are done editing, save the file by exiting you editor, typing ctrl-X if you are using pico.

Make the python code executable by:

pi@schoolbell:~ $ chmod a+x schoolbell.py

This lets all users execute the code, "a" for all, "+" for add permission, and "x" for execute.

Now test run the code and observe the output. Note that you can run the file by typing the filename but need to specify that it is in the current directory by typing a "./" before the filename:

pi@schoolbell:~ $ ./schoolbell.py
It is a schoolday, checking time 21:35

The code will tell you if it is a schoolday (e.g. not a holiday or weekend) and sees if the time matches a bell time. In this case, it was not a bell time, so it just exited cleanly. If it happened to be a bell time, it would have rung.

To test that your code can play bells, use the command line option of a file to play. We will use our bing-bong file:

pi@schoolbell:~/schoolbell $ ./schoolbell.py bing-bong-chime-hq.mp3 
It is a schoolday, checking time 21:38
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2, and 3.
Version 0.3.2-1 (2012/03/25). Written and copyrights by Joe Drew,
now maintained by Nanakos Chrysostomos and others.
.... more output ....

You should have heard the bell.

Now test the code with using a time as the argument. Remember to enter the time with leading zeros. For example, to test my "school bus" bell at 9AM, I type:

pi@schoolbell:~ $ ./schoolbell.py 09:00

This should cause your bell to ring! You can also test that it doesn't ring at non-bell times.

Step 5: Automate the Running With Crond

The cron 'daemon' is a scheduler that runs repetitive tasks on a linux system. It checks to see if the date/time matches a pattern in the cron table (crontab) and then runs code if it does. You can edit it using the "crontab -e" command:

pi@schoolbell:~ $ crontab -e

This will open a file editor, and at the bottom of this file, you will add the following line:

* * * * *   python3  /home/pi/schoolbell.py

This command tells cron to run python3 executing your script in the normal home directory (/home/pi). The five *'s say that this should run every minute (first *), every hour (next * ...), every day of month, every month, and every day of week.

Now, every minute the schoolbell.py script will run. During most minutes, the code will run and find it should just quit without chiming, but if it turns out to hit a bell time, it will chime.

Note that because cron only runs every minute, you could not make the bells any more granular than to the minute. I think it is theoretically possible that if your system gets bogged down, cron might not run for a few seconds after the top of the minute, making the bell late. If somehow cron didn't run for the full minute, the bell would be missed.

Tip: For extended holidays (e.g. summer), you can add a hashtag (#) to the first character of this line, which turns it into a comment and thus ignores running it. When school is back in session, just remove the # and it will start to run again.

Step 6: Customize and Enjoy

Now, you should have a working home school bell system and your student should never be late for class.

You can customize this project by changing the bell tones.

  • You could make it ring Big Ben, with quarter-hourly chimes and ringing out the hours.
  • You could sample your favorite rapper's freestyle.
  • You could make subliminal messages to focus on studying.

Stay safe in this time of COVID.

"Can't Touch This" Family Contest

Runner Up in the
"Can't Touch This" Family Contest