MailBuddy - the Smart Mailbox
by Tijn Sandra in Circuits > Raspberry Pi
7 Views, 0 Favorites, 0 Comments
MailBuddy - the Smart Mailbox




Hello!
Have you ever had the problem that you forgot to check your mail, or that you did check it, but there wasn't anything? Well, with the MailBuddy smart mailbox those problems are of the past. It checks if there is mail, and shows it with a LED and a flag, and instead of messing around with keys it opens using an RFID-tag. To top it off all the data is stored in a database, and can be viewed live on the website.
I apologise in advance if the code or documents are unclear, since they're in Dutch.
I made this project at the end of the first year of my bachelor MCT at Howest.
Supplies
For this poject you'll need:
- 1 raspberry pi (I used a 5, but a 4 should also be okay).
- 1 Power cable for Raspberry Pi.
- 1SD-card (for the Raspberry Pi), and a way to write on it.
- 1 or 2 breadboard(s) (possibly 2 since you'll use a level shifter)
- 1 T-coupler with flatcable to connect the Pi to the breadboard.
- 1 HX711 weight sensor board with load cell (I used a 1kg load cell), this will detect the mail.
- 1 LDR, to see if it's dark in the box, which will then close the lock.
- 1 MCP3008, that will convert the analog value from the LDR to a digital value which the Pi can read
- 1 reed switch, to detect if the letter flap is open.
- 1 RFID-sensor (RFID-RC522), to check if a user wants to open the lock.
- 2 x pushbuttons, one for calibrating the weight sensor in case of a wrong reading, and one that will correctly shutdown the Pi.
- 2 x servo, one as the lock, the other will control the flag.
- 1 LED, which will indicate if there is mail (more visible in the dark than the flag).
- 1 1.3 inch oled screen, this will show the local IP (which hosts the website) when a correct RFID-tag is presented, along with the username of this tag.
- 1 extern power supply that fits on the breadboard, along with a cable for it.
- 1 level shiter (we'll only use 2 channels).
- A bunch of wires, both male-male and male-female.
- 1 1cm sized round magnet (I would advice you to take a pretty strong one)
For more details and links to examples, see my bill of materials. I estimated the cost to be about €152.40 .
The tools you will need are:
- Glue (superglue, woodglue, contact glue, ... You'll glue wood together, as well as wood and plastic)
- Some glue clamps (unless your glue dries quickly)
- Sandpaper
- Something to drill small holes (I used a small combitool)
- Something to sand away small holes (I used the combitool for that as well)
- A small saw
Downloads
Get Your Pi Ready
Start by installing Raspberry Pi OS on the SD-card with the Raspberry Pi Imager. For more info, check out: Getting started - Raspberry Pi Documentation
Next, start up Visual Studio Code, and connect with your Pi. Then, check out my github-repository: howest-mct/2024-2025-projectone-mct-SandraTijn: Project One 2025 MCT and clone it.
Venv and Requirements
Now in Visual Studio Code delete my venv called "venv_test" (just to make sure everything is getting installed right). Open a python file (this will help VSC to recognise it's for Python), and open a new terminal. Make a new venv (python3 -m venv <venv_name> for windows). Then do "pip install -r ./own_requirements.txt" to install all the libraries you'll need.
Apache2 and MySQL
You'll need to install Apache2 (which will host your website), and MySQL (which will handle the database) on your raspberry pi. See this Instructables: Installing LAMP (Linux, Apache, MySQL, PHP) on a Raspberry Pi : 7 Steps - Instructables for more info (only Apache and MySQL are required for this project).
The Wiring


Now, we're going to wire everything up. This can be a little tricky, since it's a lot of wires, but closely follow the schematics and you'll be fine.
Some notes:
- Orange = 3.3V (raspberry pi), Red = 5V, black = ground
- If possible, wire the 5V of the extern power supply to one side of a breadboard, and the other side to 3.3V (the Pi doesn't have much power, so the extra 3.3V is a must have)
- The load cell is wired to the HX711 weight sensor: Red: E+, Black: E-, Green: A-, White: A+
- The weight sensor is powered on 5V, so use the level shifter to connect the DT to GPIO17 and the CLK to GPIO27.
- The servo's are also powered on 5V, but can be controlled using the Pi's 3.3V, so a level shifter isn't necessairy.
Test Everything Out


To check if you wired everything up correctly, I included a test code in testen/volledig/code.py (2024-2025-projectone-mct-SandraTijn/testen/volledig/code.py at main · howest-mct/2024-2025-projectone-mct-SandraTijn). This will test the flag, lock and weight sensor, as well as the RFID sensor. The weight sensor will tare, then the lock will open and close, the flag goes up and down, and every 10s the weight sensor will output a value. This code will also help by giving the RFID-code of a tag it doesn't recognise, which you should copy and store somewhere to be put in the database.
Also, let's test out if Apache works. On your PC, and on the same network as the Pi, open a browser and paste the Pi's IP-address in the address bar (the big bar on top, not the search bar like on Google's start page). When everything is okay you should get a default Apache web page.
The Database






First you should make a connection from your PC to the database with MySQL Workbench (install it if you haven't already). Just open Workbench, and click the + next to "MySQL Connections". Then insert the Pi's IP adress, the username and password (you created this when you installed MySQL on the Pi).
Then, download the dump folder from the "data" folder in the repository (2024-2025-projectone-mct-SandraTijn/data/Dump20250619 at main · howest-mct/2024-2025-projectone-mct-SandraTijn), and unzip it. Then in Workbench go to "Server", then click "Data import". Check "Import from Dump Projecct Folder", and select my folder. Then press import. It should now have created a database called "project_one" with the same tables and connections as in the picture.
Then select the database by double clicking it (the name should now be in bold text), and make a new script. Insert: "select * from User;" and execute using the lightning icon above it. It should now output users. You can delete all users, except the first (the website), and add your own using the RFID-ID from the tag, and a name of your choosing. Do mind that due to UI reasons (of the website), the name is limited to 9 characters. Don't forget to press "apply" at the bottom when you're done, and check by re-running the "select * from User;".
Make the Connection Between Python and the Database

Now that we have wired everything up and made the database it's time we connect the two. In the "backend" folder there is a file named "config_example.py" (2024-2025-projectone-mct-SandraTijn/backend/config_example.py at main · howest-mct/2024-2025-projectone-mct-SandraTijn). Copy it, and rename it to "config.py" .
In this file, you'll change the "USER_HERE" at "user" to the user of the database, "PASSWORD_HERE" to the database password, and "DATABASENAME_HERE" to the name of the database ("project_one" if you haven't changed it). Don't use any apostrophes. It's normal that it gives an error, but just ignore them.
Notes About the Code


Now that the connection is made let's look over the code (app.py, 2024-2025-projectone-mct-SandraTijn/backend/app.py at main · howest-mct/2024-2025-projectone-mct-SandraTijn). There are a few things you can or cannot tweak, let's go over them:
- The "SHUTDOWN_PASSWORD" is the password that will be asked when you press the website's shutdown button. This is hard-coded, so if you want to change it you can change it here.
- The trigger values ("triggerwaarde(n)" in Dutch) and the delaytimes get overwritten by the database (and can be changed there or on the website), so don't change these here.
- Same for the user_ids, they get read from the database.
- The weight sensor uses a reference unit to conver it's value to the right weight. Once you've builded the enclosure you should change this to the right value (see later). That's why the weight sensor will for now give ridiculous values.
Connect Apache to the Website
Since you would want to use the website using the Pi's IP (and not using liveserver for example), you'll want to change the default Apache page to the "index.html". To do so follow these steps:
- Open a terminal
- Write "sudo -i" and press enter. The promt should now change, indicating you are root.
- Now execute "nano /etc/apache2/sites-available/000-default.conf", this should open a file.
- Now go down to where it says: " DocumentRoot /var/www/html " and change this to " DocumentRoot /<location of repository>/<name of repository>/front "
- Save by pressing Ctrl X, then press Y and Enter. You should now be back in the terminal.
- Restart Apache2 by executing "service apache2 restart"
- Now, execute "nano /etc/apache2/apache2.conf" (you should be in a text file again).
- Find:
> \<Directory />\
> Options FollowSymLinks\
> AllowOverride All\
> Require all denied\
> \</Directory>
- And change it to:
> \<Directory />\
> Options Indexes FollowSymLinks Includes ExecCGI\
> AllowOverride All\
> Require all granted\
> \</Directory>
- Ctrl X, Y and Enter again
- Now we just have to get some premissions right
- Execute: "sudo chown <username on pi>:www-data /<location of repo>/<repo-name>/front"
- Execute: "sudo chmod 0750 /<location of repo>/<repo-name>/front"
- Restart Apache2 again by executing "service apache2 restart"
Run the App.py


Now it's time to test the main code. Go to "backend", and run the app.py. If everything goes allright, it should give an output like in the picture, which says the backend is running correctly, as well as the lock, flag and LED testing again. If this is indeed happening, go to the IP address again, and now it should give you a website. If this is the case, congratulations: everything works!
Get the Program to Run on Startup
But, you probably don't want to connect and execute the app.py everytime, so let's set it up so it runs on startup.
- make a file (in a location you know) called "mijnproject.service" (you can give it another name, but then change it too in the next steps)
- In that, paste:
[Unit]
Description=ProjectOne Project
After=network.target
[Service]
ExecStart=/home/student/project/<repo name>/<venv-name>/bin/python -u /<repo location>/<repo - name>/backend/app.py
WorkingDirectory=/<repo location>/<repo-name>/backend
StandardOutput=inherit
StandardError=inherit
Restart=always
User=student
CPUSchedulingPolicy=rr
CPUSchedulingPriority=99
[Install]
WantedBy=multi-user.target
- Now copy it with "sudo cp mijnproject.service /etc/systemd/system/mijnproject.service"
Test out if you did it correctly with:
- sudo systemctl start mijnproject.service
And stop it with:
- sudo systemctl stop mijnproject.service
Now to make it run on startup:
- sudo systemctl enable mijnproject.service
Enclosure I (box)














Now we'll make the enclosure, so that we have an actual mailbox. I've included the files I used. There is an outside box, which is the outside, and an inside. The inside consists of 2 rectangles that fit inside, one at the bottom for the weight sensor (one side is screwed into the bottom, the other in the plate), the other is held up about 80mm from the top (but not glued) with some corner brackets (Thanks to Tez_Gelmir for his design: Internal Corner Bracket by Tez_Gelmir - Thingiverse . I only made it square inside, see later). This 80mm high area will be where the breadboard and Raspberry Pi are located, and the power cables can nicely fit throug the hole on the left side.
There are some problems with my SVGs tho. There are no holes for the lock or for cables to go through to the bottom, and neither are there holes in the bottom inner plate for the cables of the weight sensor. I didn't add these since I wasn't entirely sure how everything would be positioned. Luckily adding them is easy, just drill some some holes where the hole in the corner brackets are, and for the bottom plate just saw away the corners.
Lastly, print 4 more corner brackets and glue them to the bottom, since there are 2 screws from the weight sensor in the bottom. That's why I changed the brackets a bit to make them square inside.
Calibrate the Weight Sensor
When you're weight sensor is in place, it is time to calibrate it. Comment out the "hx.set_reference_unit(516.82)" line and run the code. Now place something you know the weight of on the scale, and write down the value you get.
Then, use the formula:
weight = raw_value / reference_unit
<=>
reference_unit = raw_value / weight
Now you should have a reference unit. Remove the comment of "hx.set_reference_unit(516.82)", and replace the value with your new reference unit.
Enclosure II (letter Flap)


Now we'll install the letter flap. I made the letterflap-outside, and the flap itself. There is one with "MailBuddy" on it, and one without. The flap can be attached to the outside with a paperclip, or a piece of filament if your printer has a good resolution.
Then glue a magnet in the 1cm-wide hole at the bottom of the flap. Then glue the whole thing inside the hole (the longest side of the box at the top). Next, secure the reed-switch inside. I used tape, since reed-switches are very fragile (which I found out the hard way), but glue would look a lot nicer.
Test it out. The flap should open en close, and when it's closed the magnet should affect the reed switch.
The Lock

To make the lock, I used the files Geekmakes made (Servo Linear Actuator (9g) + adjustable backlash Version by Geekmakes - Thingiverse) It works perfectly for a 9g servo, though I do advise to sand it well so there is no friction between the casing and the gear. Assembly is pretty easy, see the link for more info.
Saw out a small hole in the inner plate, big enough for the lock and part of the casing to fit through where you want the lock to be. Keep in mind you'll place the RFID-sensor next to it, so leave some space.
Then just glue it inside the box, make sure the linear gear is free to move in both directions. It has to be pretty far down zo it doesn't hit the top, and that it reaches the door.
Enclosure III (door)




Next we'll make the door at the back. Start by glueing the hinges (make sure they're oriented good, the part where the hinge itself is stiff should be at the side of the box, aligned with the hole, see the pictures). Then, glue the handle.
Thanks to guppyk for the hinges (I used the 60x40 version): Hinges 180° and 270° - 34 Sizes, All Purpose, Print-in-Place, Ready-to-Print by guppyk - Thingiverse
Enclosure IV (top of Backplate)







Now we'll handle the top of the backplate. Start by, depending on the model of your oled-screen, sanding the top and bottom a bit, for the pins and the screens flatcable. Then make a hole in the top inner plate where you want the lock to be. Then solder some wires to the buttons, and push those cables throug it. Glue the buttons to the box if you want. Add the screen and secure it in place.
For the LED, print the ledcover (I reccommend a high infill and resolution), and slide it into the hole. Then insert the LED at the other side. It's a pretty tight fit, so glue won't be necessary.
Finally secure the RFID-sensor to the plate. If you want, you can use my RFID-stencil to paint or draw it at the outside to mark it's position.
Enclosure V (lock Catch)


This is a bit tricky. Glue the lock catch inside the door, but make sure it's correctly aligned so it can "catch" the lock. I glued some cardboard to the "legs" of the catch to make sure they were high enough, but it isn't necessary.
Enclosure VI (Flag)


Lastly put the flag-servo in the hole on the right side. Then when you are sure the servo is in the right position (run the code and stop it after the flag went up and down) screw the flag onto the servo. The screws that came with the servo are perfect for this.
Downloads
Test It Out!
Now everything should be ready. Put the top plate on top, secure it if you want, and test it out. Congratulations with your new smart mailbox!