# Where to place the flowers Tomas Schoenmaker (tj222r) This tutorial aims to find out which one of my windows that is best suited for my flowers regarding energy-input from the sun. With the materials listed this tutorial should not take more than 3 hours to complete. ## Objective I have several windows on different latitudes in my appartment. I have always had trouble finding which one is the optimal for flowers to thrive in. One could assume that its only the duration of the light that matters but after some googling i realized that what matters is the amount of energy provided. That is why i thought of using a solar cell to measure the energy input from light in the vicinity of the flowers and while a sensor of this kind is deployed i thought that i might as well measure the soil-moisture, temperature and humidity at the same time. ### Reasons for chosing the materials First of all its a good idea to summarize the expectated values this project should produce. 1. Energy input from the sun 2. Moisture content in the soil 3. Temperature and humudity With a list like this we go on to look on how we can achieve these things: #### 1. Energy input This will be achieved with the solar cells but how do you measure the output from a solar cell. Well first of all the voltage is monitored but this just gives halt the result current will also have to be monitored. These things combined will tell how much energy is provided. The current will be monitored with a ACS711EX sensor, this sensor works by deviating from a voltage depending on much current is passed. #### 2. Moisture content This is measured with a dedicated sensor which also supplies a different voltage level depending on the moisture content of the soil. #### 3. Temperature and humidity This will be measured with a DHT22 which outputs a signal to a digital GPIO using a dedicated library. Now to sum it up we will summarize what inputs we need. * 2 analog inputs for the energy measurement. * 1 analog input for the soil moisture. * 1 digital input for the temperature/humidity. With this in mind one can quickly realize that the ESP just wont make the cut. That is the reason we will couple the ESP with an Arduino as an I/O-expander these two controllers will communicate via I2C. ## Materials - Table | Thing. | Link | Price | | ------------- |:----------------------- | --- | | NodeMCU | [:link:][GitHub-Sync] | 89kr | | Arduino UNO | [:link:][HackMD-it] | 99kr | | DHT22 | [:link:][Book-mode] | 69kr | | ACS711EX | [:link:][Slide-mode] | 49kr | | Solar Cell | | | | Soil Moisture | [:link:][Share-Publish] | 69kr | [GitHub-Sync]: https://pchbutik.se/nytt-pa-lager/1091-nodemcu-lua-wifi-development-board-based-on-the-esp8266-cp2102-internet-of-thing.html?search_query=esp8266&results=19 [HackMD-it]: https://pchbutik.se/mcu/1630-uno-kort-budget-version-av-arduino-uno-r3.html?search_query=arduino+uno&results=320 [Book-mode]: https://lawicel-shop.se/tillverkare/ovrigt/dht22-temperature-humidity-sensor/ [Slide-mode]: https://lawicel-shop.se/elektronik/givare-sensorer/strom/acs711ex-current-sensor-31a/ [Share-Publish]: https://lawicel-shop.se/elektronik/givare-sensorer/fukt/sparkfun-soil-moisture-sensor/ ## Computer and Device Setup ### Chosing an IDE The IDE is used to upload the code to your microcontrollers, since both boards in this tutorial uses the CH340g to communicate between the microcontroller and USB the arduino IDE is an excellent choice. ### Requirements of computer In the case that your computer dont find the microcontrollers when you connect them that problably is caused by a missing driver. it can be downloaded here: https://sparks.gogo.co.nz/ch340.html ## Connecting things The following is a list of how all of it will come together: ##### DHT22 * Connected to 5v and GND * Data-pin is pulled up via a 10K resistor and connected to D8 on the Arduino. ##### ACS711EX * Connects to 5V and GND * Output connects to A1 on Arduino * Solar cell is connected to measure-points * Positive from solar cell is connected to A2 ##### Soil moisture * Connects to 5V and GND * Signal is connected to A0 on Arduino ##### ESP - Arduino connection I2C uses to pins to communicate between slave and master. These connects to SDA and SCL, these are marked on both ESP and Arduino. Furthermore the GND needs to be connected between the two boards to give them a common reference. ##### Result The image below depicts the wiring diagram of the whole circuit. ![](https://i.imgur.com/6TEDBd1.png) However a diagram seldom reflects reality and below is a picture of the resulting circuit. ![](https://i.imgur.com/rkm8dOP.jpg) ## Adafruit IO My first thought was to have a local server recieve the data but on second thought my decision fell to Adafruit IO. This is a IoT platform with excellent documentation and a free to use function. Here is a link: https://io.adafruit.com/ ## The code ### The Arduino This code goes in the arduino which acts as a I2C slave: ```c= #include <DHT.h> //library for DHT sensor #include <DHT_U.h> #include <Wire.h> #define DHTTYPE DHT22 // DHT 22 DHT dht(DHTPIN, DHTTYPE); //start DHT reading //Name pins used by sensors int currentpin = A0; int voltagepin = A1; int moistpin = A2; int DHTPIN = 2; DHT dht(DHTPIN, DHTTYPE); //start DHT reading //Define holders of future values float temperature; float humidity; int current; int voltage; int moist; String data; String humidityStr; String temperatureStr; String moistStr; String currentStr; String voltageStr; void setup() { Serial.begin(9600); Wire.begin(8); // join i2c bus with address #8 dht.begin(); Wire.onRequest(requestEvent); // register event } void loop() { delay(1000); humidity = dht.readHumidity(); temperature = dht.readTemperature(); current = analogRead(currentpin); voltage = analogRead(voltagepin); moist = analogRead(moistpin); //Format each value to always contain 4 bytes and format them to be strings for ease of transmission via I2C if(moist < 10){ if(moist = 0){ moistStr = "0000"; } else{ moistStr = "000" + String(moist); } } if(moist > 10 and moist < 100){ moistStr = "00" + String(moist); } if(moist > 100 and moist < 1000){ moistStr = "0" + String(moist); } if(moist > 1000){ moistStr = String(moist); } if(voltage < 10){ if(voltage = 0){ voltageStr = "0000"; } else{ voltageStr = "000" + String(voltage); } } if(voltage > 10 and voltage < 100){ voltageStr = "00" + String(voltage); } if(voltage > 100 and voltage < 1000){ voltageStr = "0" + String(voltage); } if(voltage > 1000){ voltageStr = String(voltage); } if(current < 10){ if(current = 0){ currentStr = "0000"; } else{ currentStr = "000" + String(current); } } if(current > 10 and current < 100){ currentStr = "00" + String(current); } if(current > 100 and current < 1000){ currentStr = "0" + String(current); } if(current > 1000){ currentStr = String(current); } //Remove decimals from temp and humidity humidityStr = String(humidity); humidityStr = humidityStr.substring(0,2); temperatureStr = String(temperature); temperatureStr = temperatureStr.substring(0,2); //Make a data-block for transmission data = String(currentStr) + String(voltageStr) + String(moistStr) + String(humidityStr) + String(temperatureStr); } // function that executes whenever data is requested by ESP void requestEvent() { char buffer[17]; data.toCharArray(buffer, 17); Wire.write(buffer); } ``` ### The ESP This code goes in that ESP8266 which acts as a I2C master. ```c= #include <Wire.h> #include "config.h" //Declare what feeds to update to IO AdafruitIO_Feed *energy = io.feed("energy"); AdafruitIO_Feed *humidity = io.feed("humidity"); AdafruitIO_Feed *temperature = io.feed("temperature"); AdafruitIO_Feed *moisture = io.feed("moisture"); //Define holders of future values String data = ""; String temperatureStr; String humidityStr; String voltageStr; String currentStr; String moistStr; int temperatureVal; int humidityVal; int voltageVal; float currentVal; int moistVal; float energyVal; void setup() { Wire.begin(); // join i2c bus Serial.begin(9600); // start serial for output // connect to IO Serial.print("Connecting to Adafruit IO"); io.connect(); while(io.status() < AIO_CONNECTED) { Serial.print("."); delay(500); } Serial.println(); Serial.println(io.statusText()); } void loop() { io.run(); Wire.requestFrom(8, 16); // request 16 bytes from slave device #8 data = ""; while( Wire.available()){ data += (char)Wire.read(); if(int(data.length()) > 15){ //only handle data if it is complete Serial.println(data); //Extract data from incomming string currentStr = data.substring(0,4); voltageStr = data.substring(4,8); moistStr = data.substring(8,12); humidityStr = data.substring(12,14); temperatureStr = data.substring(14,16); //Convert to Int/Float for handling and transfer currentVal = currentStr.toFloat(); voltageVal = voltageStr.toInt(); moistVal = moistStr.toInt(); humidityVal = humidityStr.toInt(); temperatureVal = temperatureStr.toInt(); //Format for transfer to IO if(currentVal < 523){ currentVal = 1023 - currentVal; } currentVal = (currentVal - 523)/16; voltageVal = voltageVal / 204; energyVal = voltageVal * currentVal; moistVal = (moistVal / 1023) * 100; //Make the transfer to IO temperature->save(temperatureVal); humidity->save(humidityVal); moisture->save(moistVal); energy->save(energyVal); //perform once a second delay(1000); } } } ``` ### Code breakdowns #### Arduino The basic thing this device does is collect the values from the different sensors and then transfer them to the ESP for transmission to IO. The biggest quirk in that code is to format the read values to have a uniform length for easier processing on the ESP later. if this would not be done the analog reads could change between 1 to 4 bytes and processing would become tricky on the ESP. #### ESP This device requests data from the arduino, it then reads the string, process them as floats at Ints and handles the calculations for transmission to IO. ## Transmission to IO So how will this be tranfered to IO, it all starts with the Arduino collecting the different values from the sensors. The arduino employs the I2C-protocol(Inter-Integrated Circuit) which uses a bus to communicate between different devices. Therefore in theory if there where another device you need to collect data from you would just connect it to the same 2 pins on the master. The ESP will then handle the transmitted data from the arduino to forward it via WiFi to internet and the IO. To not flood the feed which will be throttled down in the free version if that is the case, we limit the transmissions to just 4 each minute if there are data to transmit. ## Presenting the data ![](https://i.imgur.com/WOrzwDe.png) The dashboard in Adafruit IO is a realy intuitive interface. I urge you to click around and explore on your own to realy get the hang of it. I will emphasize one thing thou. In order for the IO to accept your sent in values you need to create your feeds. In this project there are 4 of them: * temperature * humidity * energy * moisture As shown in the image above the values of the energy and moisture are realy spikey, i never could get that to flatten out. However in the whole scheme of things you will see changes in the spikes which will give you the info you need to make the correct decision. ## Going forward ![](https://i.imgur.com/kwK5eQx.jpg) Here is a picture of the result of the project, as you can se its a hot mess. Going forward my aim is to switch out the Arduino UNO for a Nano(See below) ![](https://i.imgur.com/N2uZOl8.jpg) This ICU is so much smaller but packing the same punch, with this smaller ICU making an enclosement for the whole project will be a walk in the park. I hope you enjoyed what i made here, more updates are sure to come! Have a great day.