Introduction: Smart Wine Box
In this instructable I will show you how to make a smart wine box with the raspberry pi.
This is my first Internet Of Things project.
The wine box has a servo motor to control acces while keeping track of incoming data from 3 different sensors.
Data history will be kept in a MYSQL database.
The data will be shown on a (Flask) website hosted by the raspberry Pi.
With an LCD we will show the current IP adress in use.
Full code can be found on my github.
Note: The datahandler file can be left out since I put the same code in script.js
Step 1: Parts and Material List for Project
Computer/microcontroller:
- Raspberry Pi 4 Model B (with GPIO attachment)
Parts
- MG 996R Servo motor
- DHT11 sensor
- DHT22 sensor
- GL5537 LDR sensor
- (16x2) LCD - display
- Basic (electrolytic) Capacitor
- Potentiometer
- (Tactile) push button
- DuPont Male-Female jumper wires
- Breadboard wires
- 1 x 10k Ω(ohm) resistor
- 1 x 470 Ω(ohm) resistor
Housing
- I used a regular wooden wine box.
I cut some wood out for cabling and electronics.
Extra
- I made a wooden attachment for the servo motor (optional).
Software
- Visual studio code
- MYSQL workbench
Make sure that you have SSH connection with the Pi
For an estimation of the price, you can check out the BOM (Bill Of Material) file.
Attachments
Step 2: Breadboard Circuit
Breadboard and GPIO
- Both sides of the breadboard should be connected to the GPIO Ground(Gnd) of each side.
- One side will be 3.3V and the other 5V. It's recommended to use an external power source.
DHT11:
- Signal --> GPIO(4)
- Vcc(+) --> Breadboard (+) (5V side)
- Gnd(-) --> Breadboard (-) (5V side)
DHT22:
- Signal --> GPIO(26)
- Vcc(+) --> Breadboard (+) (5V side) + 10k Ohm resistor to Signal
- Gnd(-) --> Breadboard (-) (5V side)
LDR and Capacitor:
- LDR(-) + Capacitor(+) --> GPIO(27)
- LDR(+) -- Breadboard(+) (5V side)
- Capacitor(-) --> Breadboard (-) (3.3V side)
LCD display and potentiometer:
- Vss --> Breadboard(-) (5V side)
- Vcc --> potentiometer (+)
- V0 --> potentiometer(signal)
- RS --> GPIO(21)
- R/W --> Breadboard(-) (5V side)
- E --> GPIO(20)
- DB0 --> GPIO(16)
- DB1 --> GPIO(12)
- DB2 --> GPIO(25)
- DB3 --> GPIO(24)
- DB4 --> GPIO(23)
- DB5 --> GPIO(26)
- DB6 --> GPIO(19)
- DB7 --> GPIO(13)
- Led(+) --> potentiometer(+)
- Led(-) --> potentiometer(-)
- potentiometer(+) --> Breadboard(+) (5V side)
- potentiometer (-) --> Breadboard(-) (5V side)
Button:
- Button(+) --> GPIO(18)
- Button (-) --> 470 ohm resistor --> Breadboard(-) (3.3V side)
Servo motor:
- Signal --> GPIO(22)
- Servo (+) --> Breadboard(+) (5V side)
- Servo(-) --> Breadboard(-) (5V side)
Step 3: Database Setup
MYSQL table
For the database, make a new table and configure it like this:
- Number as Primary Key(PK) and INT (Also check the Auto Increment box)
- SensorId as INT to know from which sensor the data comes from.
- Measurement/value as FLOAT and Not Null(this ensures that we only insert real vales from the sensors)
- StartDate and EndDate as DATETIME . This is only needed to make charts.
Database in IDE (VsCode): config.py and repositories directory
IMPORTANT: connect in VsCode with SSH first
Make a repository or workspace where you will put all your project files in:
- Make a file named config.py and connect it to your mysql database (change your database name ofcourse).
- Make a directory named repositories.
- In the repostories directory make 1 file named Database.py and DataRepository.py.
Database.py
- Make sure to install the correct packages with pip3 install mysql-connector-python.
- You don't have to change anything in the file.
DataRepository.py
- This file is used to store the received data from the sensors to the database.
- SELECT statements are used to select specific data from sensor x.
- INSERT statements are used to push data from sensor x to the database.
Step 4: App.py (Flask Setup)
app.py
- Make a file named app.py.
This will be the main file where we use Flask to host our webserver. - Install the correct packages:
- pip3 install flask-socketio
- pip3 install flask-cors
- pip3 install gevent
- pip3 install gevent-websocket
- If you get an error saying there are packages missing, install the missing packages.
Step 5: App.py (Flask Routes)
Flask routing in app.py
- We make make use of Flask routes to reach the sensors data (with GET methods).
- Have a look at the code and how it calls the methods from DataRepository.py.
- The first route goes to index.html for our frontend later on.
Attachments
Step 6: Sensors Code (DHT11,DHT22)
GPIO
- GPIO.setmode(GPIO.BCM) because BCM numbering is used in the code.
DHT11 and DHT22
- We use the Adafruit library to help us read the sensors.
- Again in the code we use the methods from DataRepository to insert data this time.
Step 7: Sensors Code (LDR)
LDR
- First we have the function read_sensor_light which is the
individual code to get the measurement of the LDR. - With sensor_light function we insert the data to the database.
Step 8: Result of Inserting Data From Sensors to Database
Step 9: Frontend : Index.html, Style.css
For the frontend webserver we use the standard
- index.html
- style.css
- (normalize.css)
Index.html
- Inside the index.html there will also be references to
- style.css for styling
- script.js for Javascript
- chart.js and chartJS library for our charts
- SocketIO library
Step 10: Frontend: Script.js
Preparing data for data filling
- Get data from the database (getTemperature)
- Fill the data with a show function (showTemperature)
Filling dynamic data into our index.html
Now to insert dynamic data to our index.html we make use of 'js-classes' which we will fill with the data we have from the sensors in the script.js
Step 11: Frontend: Result of Data Filling
Now the website shows live data that we get from the database.
Step 12: Frontend: Chart.js
Inserting chart in index.html
- Make sure that the index.html has canvasses for each chart, every chart has it's own class.
Step 13: Frontend: Chart.js
Preparing data for charts in chart.js
- First we have to get the data from the database (getTemperatureData)
- Then we have to create 2 empty lists which we will fill in our data (showTemperatureData)
- Push the data inside the drawchart function to create the chart
Creating /drawing the charts in chart.js
- Reference the js-class from index.html
- Make a drawchart function to create the chart.
Step 14: Frontend: Result of Creating a Chart
Step 15: SocketIO in Script (to Control Servo Motor From Web)
The script.js file also has
- listenToSocket function checks the socket connection in the webserver.
- listenToUI function that has a click function inside of it and sends
a socket send (with message F2B) to app.py.
Step 16: SocketIO in App.py (to Control Servo Motor From Web)
In the app.py
- listen_to_cta_click listens to the 'F2B' message which will then call the open_chest function.
- open_chest function contains the servomotor controlcode.
Step 17: Motor Control Through the Website (with SocketIO)
When the button is clicked on the website, the servomotor will unlock the wine box temporary.
Step 18: LCD
For this project I also have an LCD that shows the IP adress.
The code is in app.py
- set_data_bits()
- send_instruction(value)
- send_character()
- init_LCD() to initialize the LCD, have a look at the datasheet for the functionalities of the LCD.
- write_message()
- set_LCD() prints the IP adress
- cursor_home()





