Introduction: Raspberry Pi Bulletin Board

This is a project I worked on for my church. We wanted an electronic bulletin board that would be mounted in the narthex/lobby area and would cycle through static slides every few seconds.

These were our design goals:

  • Static slides, no video or audio
  • Admin generates slides in Powerpoint (familiar tool, no new software to learn)
  • Admin can drag and drop new presentation to replace old one
  • No cloud-based solution, since the bulletin board would be on our private wireless network
  • No monthly license fees or proprietary software, other than what we already had (Windows, Office, Powerpoint)
  • 49" screen, in portrait/vertical mode (though landscape/horizontal mode is also possible and described below)
  • Desired cost: <$1000

We managed to do this and came in under budget. I recently helped another nearby church do the same project, and the total cost (not including cost of an electrician to bring power to the right place on the wall and the labor involved in mounting) was less than $500.

Because of the low cost and essentially zero ongoing costs (just electricity), this would also fit well with schools, libraries, museums, non-profits, or other organizations with limited budget.

Feedback is welcome.

Step 1: Equipment List

Here is a list of equipment we used. Comments are added. I try to link to the manufacturer's site where possible, rather than a retailer.

  • TV/monitor. Most any modern TV or monitor will do, as long as it has CEC (see this article on Wikipedia for more information about CEC: https://en.wikipedia.org/wiki/Consumer_Electronics_Control). Most monitors are made to be mounted in either vertical/portrait or in horizontal/landscape mode. TVs are designed to be horizontal, so mounting them vertically is a bit trickier. Also, many TVs are asymmetric top-to-bottom (i.e. the bottom edge is often bigger than the top), so mounting it vertically may look a bit odd. Still, TVs are cheaper overall, so we went with a TV. Of course, if your preferred orientation is landscape, it doesn't matter. We went with this one: LG 49" LED TV.
  • TV Mount: This was tricky, because we bought a TV and wanted to mount it vertically. Things to consider are the style of mount and whether it will be visible, especially if the TV is mounted vertically. The mount is placed on the wall in the same orientation as if you were mounting the TV horizontally. If you opt to mount the TV vertically, you need to consider whether the screw mounting holes in the TV mount can accomodate the rotated mounting holes in the TV. Some TVs space their mount screws in a square pattern, whereas some are a rectangular pattern. Think this through and make sure you mount will work in the desired location before purchasing.
  • Raspberry Pi, case, cables, heat sink, fan, etc.: I recommend you get the latest and greatest version. At the time we built the project, it was the Raspberry Pi 3 B+, but now the Raspberry Pi 4 B is out. As far as case, power cord, heat sinks, fan, we decided that since the Raspberry Pi will be running 24/7, we wanted a case with a fan, albeit a quiet one. And having a power cord with an inline power switch makes it easy to reset the system without having to pull the plug. The other main difference between the Raspberry Pi 3 B+ and Raspberry Pi 4B is that the 4 B has a micro-HDMI plug, which means you need an adapter (it is included in the kit below).
  • HDMI cable: Any is fine, as long as it supports CEC. Note that typically, the Raspberry Pi will be mounted on the wall behind the TV/monitor or possibly attached to the TV/monitor itself, so a short 3' cable is probably plenty. Too long of a cable and it will show. Also consider where the HDMI ports are on the TV/monitor and whether you might consider a 90-degree cable end (for example, if the HDMI ports are on one side).
  • MicroSD card. This doesn't matter much, either. We chose 32GB rather than standard 16GB, just to have extra space for additional software, if we wanted, and to have a place to store multiple presentations. We chose this one: SanDisk Ultra PLUS 32GB MicroSD Card . Note that it is easier if you buy a MicroSD card with NOOBS already installed, like this one: SD Card with NOOBS. I didn't do that, but you can save a step if you do. See here for more information: NOOBS

A note on CEC: CEC (Consumer Electronics Control) allows some components control each other through the HDMI cable. For example, a DVD player could turn on/off the connected TV through the HDMI cable if both support CEC. This is useful in our case, as the Raspberry Pi can turn on/off the TV/monitor as it wishes. For example, in a church setting, we would like to have the monitor on only during hours when the church is open, and that varies by day of the week. CEC allows the Pi to turn the TV on and off in an arbitrarily complex time schedule.

Step 2: Assemble the Pi Case

Assembly is fairly straightforward. Stick the heat sinks on the chips of corresponding size on the Raspberry Pi, assemble the case layer by layer. Don't forget to remove the thin plastic protective sheets from each layer.

Step 3: Install Raspbian

There is an excellent guide on the Raspberry Pi site. Follow those instructions to set it up.

Setting up your Raspberry Pi

I used Raspbian Lite, as it doesn't have extra applications that you won't need for this project.

Step 4: Add Standard and Custom Software

Once NOOBS installs Raspbian, the first time you login, you will be prompted for things like language, time zone, etc. It will also prompt for WiFi network and password information, unless you are on a wired connection. Finally, it will download and install any Raspbian updates. It helps if you are on the same internet connection as in the final setup, but it doesn't have to be. That is, you can do this step at home before setting up in the final location. Just remember to set up the new internet connection before the final reboot in the last step.

Open a terminal window (click on the black rectangular icon near the upper left corner of the screen).

First we double-check to see if there are any further Raspbian updates. Type the following lines, one at a time

sudo apt update
sudo apt upgrade

(say "Y" if it asks whether you want to install updates).

Next we install Samba, which allows folder sharing with the Windows machine(s) on the network.

sudo apt install samba samba-common-bin smbclient cifs-utils

Next we install fbi. fbi is the unix utility that displays graphics on a screen not running a window manager.

sudo apt install fbi

Next we install inotify-tools. inotify-tools allows the slideshow to watch the shared folder for any changes.

sudo apt install inotify-tools

Next we install cec-utils. cec-utils allows the Raspberry Pi to turn the TV on and off via the HDMI cable.

sudo apt install cec-utils

Next you'll need to download the small utilities I wrote to play the slideshow.

git clone https://github.com/dgrannes/raspi_slideshow.git

This will fetch the code and put it in a directory called raspi_slideshow.

Now all the software is available on the Raspberry Pi. The next steps go through the configuration.

Step 5: Set Up Shared Folder

By default, the slideshow code searches for a directory (folder) /shared/Presentation.

We need to create that directory. Since it is at the root level, we need root permissions, so a sudo is in order. You may need to type the password (default is raspberry) when you do this command:

sudo mkdir -p /shared/Presentation

Next, we need to make this readable and writable by anyone on this Pi. Type the following command:

sudo chmod a+rwx /shared/Presentation

This makes it visible only on this Pi. Next, we need to share this folder with the world (actually, only other machines on the same network). That is why we recommend this be on a private (password-protected) Wi-Fi network or a wired local network.

When we installed samba in the previous step, it created a default file /etc/samba/smb.conf

We need to add a bunch of lines to the end of that file. The lines are in the file raspi_slideshow/add_to_smb.conf

The easiest way to do this is the following:

sudo bash

cat raspi_slideshow/add_to_smb.conf >> /etc/samba/smb.conf

exit

This basically concatenates the add_to_smb.conf file to the end of /etc/samba/smb.conf

You may choose to do it via an editor like nano if you prefer, but it's a fair amount of typing.

Basically it shares the /shared directory as a directory that is readable and writable by anyone on the local network. I won't go through how to protect it here, but if you want it to be protected (to require a password to edit), you can read up on Samba and change the settings accordingly.

Step 6: Configure Monitor On/off Settings

We use cron to turn on and off the TV/monitor at scheduled times. Cron is a linux utility that runs tasks at scheduled times. If you want your TV/monitor to run 24/7 or you want to turn it on and off manually, you may skip this step.

Copy the example crontab file from the raspi_slideshow directory to the home directory.

cp raspi_slideshow/crontab_example.pi crontab.pi

The file crontab_example.pi is an example that shows how this type of file works. There is plenty of documentation in Wikipedia and elsewhere: https://en.wikipedia.org/wiki/Cron

Now we edit it. It helps to have your schedule already figured out. The example schedule is

  • Sunday: on at 7am, off at 9pm
  • Wednesday: on at 8am, off at 9pm
  • Saturday: on at 7am, off at 9pm
  • Other days: on at 8am, off at 5pm

I like nano since it is installed with Raspbian and easy to use. You may use vi or any other editor.

nano crontab.pi 

Edit the file to specify on/off times for each day. Use the arrow keys to move around. Backspace to delete, type to insert. When you are finished, Control-O to save (you will have to hit "enter" to confirm the file name), and Control-X to exit nano.

Once you have your cron file the way you want it, tell Raspbian you want to execute it:

crontab crontab.pi

If you ever want to change your schedule, you may edit $HOME/crontab.pi and re-execute the crontab command immediately above. That will replace your old schedule with the new one.

Step 7: Configure Display Settings

We are almost done! We need to configure the display settings. fbi is the utility that we use to display the slides. It reads its settings from the file .fbirc in the home directory.

First, make sure we are in the home directory.

cd $HOME

Next copy the file from the raspi_slideshow directory to home

cp raspi_slideshow/.fbirc .

You shouldn't need to edit the file. However, if you choose, the three settings that are of interest are:

random = false

blend-msecs = 500

timeout = 8

The random line determines whether fbi randomizes the slide order. true means it does randomize the slides, false means it doesn't. Since we wanted some control over what order the slides are in, we set it to false.

The blend-msecs line says how many milliseconds (1000= 1 second) does each transition last. A value of 0 means the slides change instantly from one to the next. Our setting of 500 means the slides fade into each other over a period of 0.5 seconds.

Timeout is the time (in seconds) that each slide is displayed before transitioning to the next. You may adjust this if you want slides to be longer or shorter. Just remember that this applies to all slides equally. There is no way to have some slides appear longer and others shorter.

Rotate display

If you have your TV/monitor mounted vertically, as we do, you will need to rotate the display 90 degrees or 270 degrees. If you have your TV/monitor mounted horizontally, you can skip the rest of this step.

Use nano again. This time you need to run as root, so you'll need to sudo, which may require you to reenter your password (default is raspberry)

sudo nano /boot/config.txt

Use the down arrow to go all the way to the bottom of this file. Add the following line to the end of the file:

display_rotate=1

This will rotate the display 90 degrees. If after mounting, your display is upside down, change the 1 to a 3.

Basically display_rotate = 0 (no rotation), 1 (90 degrees), 2 (180 degrees), 3 (270 degrees)

In the picture above, we had set display_rotate=1 and had to go back and change it to display_rotate=3. Much easier than re-mounting the TV!

Step 8: Change Password and Set Up Auto-run

At this point, we are almost finished!

Click on the raspberry menu in the upper left, select Preferences->Raspberry Pi Configuration

That brings up a dialog box. Click on "Change Password..." and change it to something you will remember!

You may choose to change the name of the system (Hostname field).

Make sure you click Boot "To CLI"

Set auto-login ("Login as user 'pi'")

Now you need to set up the slideshow to run when you boot. The easiest way is to add one line to your .bashrc file. Firing up our nano editor:

nano .bashrc

Down-arrow to the end of the file and add the following line:

python3 raspi_slideshow/play_slideshow.py

These settings mean that:

  • Whenever it is rebooted, the Raspberry Pi will automatically login as user pi
  • It will not start a window manager, but just run on the screen ("Boot to CLI")
  • It will start up the bash shell, which reads the .bashrc file, and the last line of that file says to run the slideshow.

After this, reboots will NOT fire up the window manager, and will automatically run the slideshow. You can stop the slideshow by hitting Control-C during the slideshow. This will bounce you back out to the bash prompt ($).

If you want to start the window manager from this point (for debugging or easier manipulation of settings), you can do it by typing "startx" at the command line.

Step 9: Use (Setting Up the Windows Machine)

In actual use, our Raspberry Pi connects to our private wireless network on startup. It shares its /shared directory (and everything beneath) to the network. In order to see this folder from a Windows machine, make sure you are on the same network.

I assume you will be connecting to this from a Windows computer in an office. For either Windows 7 or Windows 10, open up a File Explorer to view the files/folders on your computer. Right-click on the left where it says "Computer" or "My Computer", then select "Map Network Drive..."

That will bring up a dialog box. Choose what letter, e.g. "Z:" you want to map your drive to. Then in the Folder field, type:

\\{name-of-your-Pi-computer}\shared

where {name-of-your-Pi-computer} is the name you gave your Raspberry pi back in the previous step (see previous picture with the dialog box).

Be sure to click "Reconnect at login". It is possible that if the Raspberry Pi is powered off when the Windows computer boots, that this step may have to be repeated (or the Windows computer rebooted) in order to see the shared folder.

If you choose to password-protect your folder, you can add credentials by selecting "Connect using different credentials" and entering the username/password for the Raspberry Pi.

Now, when you want slides to go into your slideshow, copy individual slide images(*) into the Presentation folder.

The script will monitor and display ONLY the contents of the Presentation folder, and nothing at the level above that (\shared). Thus, we sometimes use the trick of putting commonly-used slides in the top level and then dragging them as needed into or out of the Presentation folder.

Remember, when anything in the Presentation folder changes (files are added, deleted, or modified) the slideshow script waits 2 minutes (120 seconds, configurable in play_slideshow.py, search for wait_time) before resetting and displaying the new slides. This gives the person time to make all the changes necessary without resetting after each new file is added.

Individual slide images are jpeg, gif, or png files that represent a single slide. The easiest way to generate these is using Microsoft PowerPoint or a similar program. You can generate as many slides as you'd like in Microsoft PowerPoint and save it as a PowerPoint presentation. Then click File->Export->Change File Type and save as either PNG or JPEG. This will output the slides as individual files, e.g. slide1.png, slide2.png, etc. You can then drag and drop individual files into Z:\Presentation (or whatever drive letter you used). Note that the presentation is put together in alphabetical (not numerical) order, so slide11.png comes after slide1.png and before slide2.png. You may of course rename the slides before copying them into the network folder. Just make sure they retain their extension (e.g. .png). The slideshow script currently looks only for files with the following extensions: .PNG, .png, .GIF, .gif, .JPG, .jpg This is configurable in play_slideshow.py (search for glob_strings).

Step 10: Troubleshooting

Most problems can be solved by the old "try turning it off and on again" solution.

If your Raspberry Pi is not connecting, not updating, or seems to be generally stuck, try power cycling it.

If your Windows machine loses the mapped network drive, try power cycling it or manually add the drive again.

If you have other questions/problems, please post in the comments and I'll update this step with common problems and their solutions.

Step 11: Conclusion and Future Work

DONE!

At this point, you can reboot your Raspberry Pi, either through the menus or with the power button on the power cord. The nice thing about this setup is that whenever the Pi boots (power failure, crash, whatever), it starts up in slideshow mode, so you can power-cycle at will and it should recover fine. Once this is installed and working, you can pretty much "set it and forget it", other than the updates to the slides. In our case, our church admin updates the slides weekly, and this system has been working flawlessly for about a year.

Please give feedback! I'm receptive to fixing bugs or inaccuracies. I understand there are many different ways to do things, so I'm not excited about answering questions like "why did you use python instead of {programming language X}?" Or suggestions that are functionally the same (like "sudo apt" all the packages at once instead of one at a time). However, functional improvements are always welcome! I try to make this as functional and useful as possible while also being easy to install and easy to maintain. I particularly enjoy feedback from those who have benefited from this Instructable. I am happy to help if I am able.

Future work

I am starting to work on a version that will allow video files (with sound) to be intermixed with the static slides. I think I can use vlc for that from the command line. I will update this if I am able to get it to work. Feel free to make suggestions!