Today we are in a world where we can see many forest cutting, water pollution and so many things that destroy our environment. Currently there are so many organizations to stand against them. But that's not enough. If we can make our young generation to stand against them, it will lead to a green future.
To make them environmental lovers, we should give them the opportunity to spend time with trees, lakes, birds etc. In the meantime if they can observe the things and changes in the environment, they will gain knowledge on analyzing the various facts that the environment depends on. With this intention, I started working on a portable device, which can be carried and monitor several aspects of the environment.
This device will make our young generation interested in getting readings at various places of the environment, analyze the data and make conclusions. As an example, water quality of a lake can be monitored at various places and identify if there are any toxic sources which add unnecessary things to water.
The very special thing about this device is even a small kid can make this device on his own as I have avoided soldering and other risky actions. Almost all things are in plug and play style to make it easy for our small generation to make their own experiment kits.
What powers this device?I have chosen Arduino 101 board for this device as it contains an inbuilt IMU and Bluetooth Low Energy modules. The Intel Curie helps to process our data faster as we are going to use several sensors and filters.
Let's see what we need.
Basic Sensors and ModulesI have planned to develop this Portable Environment Monitor in two steps. At the initial steps some basic sensors are included to get various data from the environment.
The list of sensors is mentioned at the beginning.
Using these sensors we are going to measure following aspects of our environment.
- Light Intensity
- Humidity
- Temperature
- Sound Level
- Soil Moisture Level
- Ion Level in Water
Let's start plugin and coding.
Connect Sensors with Arduino 101Before beginning, Arduino 101 plugin should be installed. After opening the Arduino IDE go to Tools > Boards > Board Manager and select "Genuino 101" from the list and install. Now the IDE is ready to work with the 101 board.
Plug the Grove base shield to the Arduino board to make it easy to connect sensor modules.
First we connect the RGB LCD screen. Connect the LCD module to an I2C port of the Base shield using a universal cable.
Download and extract the Arduino library for the RGB LCD to the Documents > Arduino > libraries folder.
Open the Arduino IDE and select Genuino 101 under "Tools > Boards". Go to File > Examples > Grove_RGB_LCD > HelloWorld. Plug the Arduino board to the computer and upload the code by clicking on the right arrow button.
Now the LCD displays text as follows.
You can change the backlight color by changing the following Red , Green and Blue values.
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
Take DHT11 temperature and Humidity sensor and connect it as follows.
- Vcc > D2
- Gnd > D1
- Data > D3
Add DHT library and Adafruit sensors library to the Arduino libraries.
Now test the sensor by uploading the DHTtester code under examples. Open the serial monitor by clicking on the magnifying glass icon at the top right corner to monitor the temperature and humidity readings.
Connect the Light sensor module to A1 port of the Base shield using a universal cable. For this, a library doesn't require. We just have to read the analog values to measure the light intensity.
According to my observations, the analog values from the light sensor are nearly equal to the actual light intensity in "lux". "lux" is a unit which is used to measure the light intensity. Here are some light intensity values.
Let's display the values from the DHT11 and light sensor on the LCD display. Find the code file "Display" from the code files at the end of this tutorial and upload it.
As we have limited number of 5V and Gnd pins, I have defined additional pins to power up the DHT11 module using the following code.
pinMode (2,OUTPUT);
digitalWrite(2,HIGH); // Make D2 a 5V pin
pinMode (1,OUTPUT); // Make D1 a Gnd pin
Now, you can notice that the temperature, humidity and light intensity values are displayed on the LCD. Try to cover the light sensor, blow air to the DHT 11 and observe the changes in readings.
Now we move into a bit hard level. Just connecting and reading values are not enough for remaining sensors. We have to map the readings to get values with standard units. For this we need to use mathematical functions.
Let's begin with the sound detector.
Connect the Sound detector module to the base shield using jumper wires.
- Vcc > 5V
- Gnd > Gnd
- Envelop > A1
Open the AnalogReadSerial code from File > Examples > Basics. Change the pin number to A0 in the following code line.
int sensorValue = analogRead(A1);
After uploading the code open the Serial Plotter from Tools menu. We can notice a graph is plotting according to the sound level. Make some noise and observe the changes in the graph.
We are getting a voltage level according to the sound level. But the standard unit to measure the sound level is decibel. Hence, the voltage value needs to convert to a decibel value, using a mathematical function. Following is the general formula to achieve this.
dB = 20*log(Vo/Vref)
Though this is the ideal formula, we have to adjust this a bit according to our sensor. Use this chart as a reference to adjust our mathematical function. Vo is the raw voltage value and Vref is the maximum voltage resolution which is 1023. Therefore Vo is multiplied by (1/1023). We can change this value in order to achieve the required sound levels according to the chart. For my sensor, the function is as follows.
double d = 20*(log10(10*v)) ;
Now, we can measure the sound level in decibel scale using this function.
Connect the two probes to the soil moisture sensor module and connect the module to the base shield.
- Vcc > A3
- Gnd > Gnd
- Signal/Data > A2
The sensor values can be read using the AnalogReadSerial code. But the readings must be mapped in order to get useful values. Mainly this sensor can be used to measure the moisture level in soil and to measure the ion levels in water.
I collected some soil samples with different moisture levels and dipped the probes into soil. After taking the readings 2 threshold values are made to identify 3 moisture stages as dry, medium and high. Repeated the same process by collecting some water samples (drinking water, clean lake, polluted water).
In soil, if the analog reading is
- Greater than 900 - Dry,
- Between 650 and 900 - Medium moisture
- Below 650 - High moisture level
For water testing, if the reading is
- Greater than 750 - Error
- Between 600 and 750 - Distilled water
- Between 500 and 600 - Drinking water
- Between 350 and 500 - Good for fish but not for drinking
- Below 350 - Polluted water with high ionic levels and toxic
Now the basic things are done. Let's put all these in to our code file and display on the LCD. But wait... LCD is not enough to display all these information at once. Several pages are needed to display them with clear labels. We can use our button module to move between pages.
Following is my arrangement.
- 1st page - Temperature, Humidity and Light Intensity
- 2nd page - Sound level
- 3rd page - Water quality and Soil moisture level
Connect the button module to D8 port using a universal cable. A button can be read using the digitalRead function. I'm using the variable "page" to change between pages when the button is pressed.
int page = 0;
void loop() {
while (page == 0){
first_page();
if (digitalRead(button) == 1) //Go to the second page when button is pressed
page++;
}
delay(500);
while (page == 1){
second_page();
if (digitalRead(button) == 1) //Go to the third page when button is pressed
page++;
}
delay(500);
while (page == 2){
third_page();
if (digitalRead(button) == 1) //Go to the first page when button is pressed
page = 0;
}
delay(500);
}
Upload the "Basic_1.ino" code file to see how our device works.
Arduino 101 board has an inbuilt IMU. We can get readings from the accelerometer and the gyroscope according to our needs. For our project I will use these values to calculate pitch and roll angles to measure the angle of surfaces.
Upload the Accelerometer and Gyro codes (Examples > CurieIMU ) and check how this inbuilt IMU works. Using acceleration values in x,y and z axes the roll and the pitch can be calculated according to following formulas.
Following code lines can be used in our Arduino code to calculate pitch and roll angles.
CurieIMU.readAccelerometerScaled(accX, accY, accZ);
double roll = atan2(accY,accZ) * RAD_TO_DEG;
double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
Now, we need to display these angles on LCD. I'm using the second page for this as currently we planned only to display the noise level on second page.
Using FiltersWhen observing the light intensity, noise level and the roll and pitch angles you may notice that the values are changing rapidly. Sometimes it's hard to read an exact value because of this problem. Following image shows the light sensor readings with a constant light level.
To avoid this variation and stabilize readings up to some level, we need to use filters. But at the beginning, we can calculate an average value from several readings. The average gets stable with the number of samples. This is the most basic filter that we can use.
Following is the code to calculate the average value for the light intensity.
int light_l = 0;
for (int x=0; x<50;x++){
light_l = light_l + analogRead(light);
}
light_l = light_l/50;
When it comes to IMU, we can use more advanced filters to stabilize roll and pitch angles. Kalman filter is one of the best filters which we can use to filter the noise and stabilize readings.
To understand this filter, we need good mathematical knowledge. Hence, I will not explain how this filter works but if you are interested you can refer online articles.
Following video shows how my Kalman filter works for the roll angle.
Observe the stability of the filtered values over raw readings.
Since this algorithm is quite complex and lengthy, I have attached a separate header and source files with my Arduino code. Following variables in the "Kalman.h" file, are need to be adjusted to stabilize the sensor readings. These values varies from sensor to sensor.
Q_angle = 0.01;
Q_bias = 0.0001;
R_measure = 0.11;
I have tuned these values for Intel Curie IMU, which is in the Arduino 101 board as we are going to use it as our IMU. With this tuning, we can get the filtered values with the accuracy of 0.05 degress.
After uploading the "Final.ino" code our second page will look like this.
There are many experiments which can perform using this "Portable Environment Monitor".
Unique Plants for Forests
There are various areas in forests which have unique conditions. According to these conditions the plants are unique for that place. If we consider the light intensity, sometimes the particular area might have low light intensity. Hence, we can say that the plants in that area prefer low light conditions.
Here I have demonstrated how we can take the readings to analyze about plants in forests.
Mountain Areas
The main problem in mountain areas is rock slipping. We can identify this earlier if we monitor the soil moisture level and incline of the tree trunks time to time. If the soil moisture level is high, there is a high possibility for rock slipping. At the initial stages we can observe that the incline of the tree trunks is changing a bit by bit. Hence, using this device we can identify a rock slipping situation and it will help us to take precautions.
Apart from these things, you can monitor noise levels in construction sites and decide it's good or bad for the surrounding trees and animals.
Try to make this device at your home and do various experiments. Ideas and Suggestions are welcome.
Hope you enjoyed this project. For further information you may visit www.srqrobotics.com
Thank You.
Comments