ColorPicker
The goal of this project is to measure colors, and translate them to other color systems. Using just the RGB values given by the sensor, you can translate to HSL, CYMK, HEX and also the nearest RAL code (standard used for paint). This project requires a basic knowledge of Python, MySQL, Linux and Javascript.
If you are also familiar with the Flask framework and SocketIO, then the code for this project should be easy to understand for you.
This project can be used by painters, interiour designers or just by anyone who needs to measure colors.
This project is not so expensive, and costs an estimated __ euros, shipping not included.
Supplies
We can split this section in two parts:
- Hardware
- Software
Hardware
We use the following components
- HC04: Distance sensor, how far are we measuring from the object
- LCD display 2x16
- LCD I2C module (HW061)
- TCS34725 Color sensor module (Adafruit)
- White LED
- Raspberry Pi 3 (Any Raspberry Pi should work)
- 5x 1k Ohm resistor
- 1x 220 or 330 Ohm resistor
- SD card 16GB (14.4GB)
Software
- Python IDE, like Visual Code or Pycharm (Pycharm used here)
- MySQL Workbench
- Putty (Download Putty)
- Rufus or any other SD card writer (Download Rufus)
Pricing
This project is quite cheap, if you already have a Rapsberry Pi.
- HC04: Starting around €2.5 euros (China) and up to €6 for more local shops.
- LCD: Around 6-8 euros.
- I2C module: As cheap under €1 (China) , but up to €4 for more local shops.
- TCS34725: Around €9-12 euros. Most expensive part (Excluding RPi)
- White led: Bought in bulk, 20 LEDS as low as €1
- Raspberry Pi: Depending on which version, around €40 euros
- Resistors: €0.10 for one resistor
- SD card: around €8
The power adapter for the Raspberry Pi is excluded in the price cost, since this adapter is quite common.
Overal price range: around €70, if you included the Raspberry Pi and the case for the project.
To build the case, I used lightweight thin wood. I recycled this wood from furniture. The material for the case is up to you.
Step 1: Installing RPi OS, Configuring SSH and Internet Access
Step 1.1: Installing the image
Download the image from the official site of the Raspberry Pi. It doesn't really matter what image you install. For this project, a GUI is not needed, since we will only connect using SSH.
Write the image to the (empty) SD card (All files on the card will be erased).
To write everything to the SD card, we will use a tool called 'Rufus'. After downloading the image, open Rufus and select the image file. Select the target drive and write the image to the drive. This can take a while.
>> Rufus
Step 1.2: Installing SSH
The next step is creating a connection to the SD card. To do that, we need to enable SSH.
To do that without using a monitor, open your file explorer and open the boot partition of the SD card. Create a empty file called "ssh", without file extension.
Also, open "cmdline.txt "
Add "169.254.10.1" in the end of the file and save it.
Unmount the SD card and insert it in the Raspberry Pi.
Now we can connect the Raspberry Pi to a power source and boot up and connect using SSH.
To connect using SSH, we use the program "Putty". Connect your RPi and PC using an ehternet cable before doing that. Open Putty and go to the SSH tab, and fill in this IP: 169.254.10.1. Click 'connect' and you will be connected.
>> Putty
The default login used by the Raspberry Pi is 'pi' as username and 'raspberry' for the password.
Step 1.3: Wireless connection
Your Raspberry Pi is now powered on.
We also want to connect to the RPi using Wifi, that way we don't need an ethernet cable anymore.
Execute the following line:
- 'sudo nano /etc/wpa_supplicant/wpa_supplicant.conf'
This will open the 'nano' text editor with elevated rights.
Add the following lines in the file:
network={
ssid="SSID"
psk="Password"
}
Replace "SSID" with the SSID of your Wifi network
Replace "Password" with your password.
Then do Ctrl+X and select the 'yes' option. The file will now be saved.
Now we need to restart the networking service
Execute the following commands:
- 'sudo -i'
- 'sudo systemctl restart networking'
You can test your internet connection using the wget command.
Example: 'wget google.com'
>> Wget command
Step 2: Installing Software on the RPi
For this project we need to install a few libraries.
- Mariadb: MySQL database (sudo apt-get install mariadb-server)
- Adafruit library for the color sensor: Measuring colors (pip3 install adafruit-circuitpython-tcs34725)
-
PHPmyAdmin: ('sudo apt install phpmyadmin', choose apache webserver)
Also install the following pip libraries:
- flask_socketio
- flask
- flask_cors
- board
- busio
- netifaces
Step 3: Connecting to the MySQL Database, Creating Database
The next step, is to connect to the MySQL database using the MySQL workbench.
>> IP a
Execute the command 'ip a', as shown in the image above (Click link)
In most situations, there will be shown 3 entries. We need the 'wlan0' entry. Copy the IP next to 'inet', or in this example '192.168.1.44'
As shown in the image above, create a new connection with the following paramters (Image below for params)
Double click the newly created connecton to connect.
If there shows up a prompt, click 'Yes'.
This is still an empty database, so let's add some tables.
First create a schema, to do that, at the left side 'right click' and choose 'create schema'.
Give the schema a name and confirm.
Now we need to add tables. Expand the schema and 'right-click', 'tables'.
Create the following schema's:
>> Table 3: Measurements (In the picture, 'metingen' is used, Dutch for measurements)
>> Table 4: Website_data || Table 4 bottom
MySQL is a relational database system, that means we can create relations between the tables.
The first relation we have to create is between 'sensor_type' and 'measurements'.
As shown in the picture, link the two keys.
Don't forget to save the changes by click 'Apply' in the bottom corner.
Also edit the 'website_data' table and link 'MetingID'.
Now we are done with creating the tables and creating the relationships.
Adding data:
The RALcolors table is a fixed table, where the values will never change. We can add these values
very easily.
Download the excel file above and select all data and 'copy'. Do like in the image
>> Show table
'right-click' on the table and choose 'Paste rows'. 'click' 'apply' in the bottom corner to add the data.
Now all RALcolors are saved in the database.
We only need to add the sensor_type to the database now.
Note: The description of the sensor is in 'Dutch'
Step 4: Filezilla
To easily connect to the Raspberry Pi and transfer files, we can use Filezilla.
File in the connection details and connect. At the right-side you can now transfer files by dragging them in.
Download the files from the github source above.
Step 5: Creating the Website
For the hosting of the website, we use PHPmyAdmin and Apache2.
The webserver on the Raspberry Pi uses the '/var/www/html' directory as root.
If you place your files there, they will be hosted on the IP of the Raspberry Pi. (IP = see 'ip a')
You can download the required files from my github repo (previous step)
In the '/var/www/html/', paste all files from the 'Frontend' folder.
Step 6: Creating the Backend (Flask)
The website backend is based on Flask.
All files can be found at the github repo.
Copy all files to any directory on the Raspberry Pi.
For example '/home/pi/colorpicker.
To create a directory, navigate to the destination directory using 'cd <path> ', and then execute 'mkdir '.
That's all for now. The code will be explained in the next steps.
Step 7: Hardware
Create the scheme like shown in the document above.
NOTE: Also add one white LED, with one resistor (220 or 330 Ohms).
Explaining the hardware
HC04
The HC04 sensor emits waves, which reflect and are recieved again by the sensor.
By calculating the time delta between emit and recieve, we can calculate the distance.
Distance = ((Timestamp_recieve - Timestamp_emit) / speed of sound) /2
We divide by two because the wave reflects, meaning it travels the distance twice.
LCD
We use a LCD display to show the RGB and HEX, as wel the IP when the program starts.
For this LCD, I bought an I2C module. We only need 4 wires now. SDA, SCL, GND, VCC
To use this LCD, I wrote a Python class, to make it easier to use.
TCS34725
This sensor allows you to measure colors. We use a library to measure the RGB value.
Step 8: Code Explained
The frontend
The frontend exists out of three major parts.
First are the html files, which build the structure of our website, but do not contain or minimal layout.
Second we have the css files, or style files, which style and layout our website.
The two are quite easy to read and understand, which is why I won't explain them.
Last we have Javascript, with two libraries.
The two libraries used are SocketIO and URLSearchParams.
SocketIO allows you to send messages from the backend to the frontend, and vice versa.
The messages can be send to one client, but also multiple clients (Broadcast)
In the images above, you can see one of the Socket connections made in this project.
The command to send messages is 'emit', recieving is done by 'on'.
URLSearchParms allow you to get values from a querystring easily.
Example querystring: example.com/index.html?id=1
URLSearchParams will give you back: {'id'='1'}
The backend
The backend is fully written in Python, with a bunch of libraries.
The first library we import is 'Flask'. This library is needed to create an API, to do all CRUD actions for the MySQL database. CRUD stands for Create Read Update Delete.
>> Flask
The image above shows a few Flask 'routes'. By surfing to a route, you will automatically do a 'GET' method, the code will execute and you will recieve the value from the return method. There are also other methods, like 'POST' and 'DELETE'. To test such methods, you will need a program like Postman.
The next import library is SocketIO, which I explained already in the front end section.
Next one is GPIO.
This allows you to control the GPIO pins of the Rapsberry Pi.
The most important commands are:
- GPIO.setmode(GPIO.BCM) Choose the config of the pins.
- GPIO.output(<pin>, GPIO.LOW or GPIO.HIGH) Write a LOW or HIGH to a pin.
- GPIO.setup(<pin>, <type ex: GPIO.OUT or GPIO.IN>) Define a PIN as input or output, or pulldown or pullup
Next we have threading.
The only commands we use are:
- Thread(target=<function>)
- <thread_variable>.start()
Using threads, we can run multiple instances of code at the same time. This way we can measure distance and at the same time, listen to incoming socket io messages.
The first command Thread(target=<function>) will create a Thread class, wich upon started using 'start()', will run the function in the keyword 'target', which was given on creation of the class.
Next we have the library of the colorsensor, which is quite straight forward. I wont explain this library, because the methods are very clear and explained in the code.
Last we have netifaces. This alows us to retrieve the IP address we use for the Wireless and Wired connection.
Last I made some classes myself for the distance sensor, the LED and the LCD.
I won't explain how those work.
Step 9: Creating a Case
For this project, I created a wooden case.
The wood is lightweight, thin and does not cost much.
As dimensions I used:
- Height: 5 cm
- Width: 10.5cm
- Length: 12.5cm
For the sensors, you need to add 2 holes and place them next to each other.
After creating the case, install the sensors, LED and LCD.
Final Steps
Everything is basicly done.
Now we only have to make sure that our code starts, the moment we plug in our power source.
There are a lot of methods to do this.
>> Examples
We will use the first method:
Execute this line: 'sudo nano /etc/rc.local'
Add your command to run the code: 'sudo python3 <path to file>'
Save the file using Ctrl-X.
If you have problems editing. Re-do this step, but first execute 'sudo -i'.