# 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.

However a diagram seldom reflects reality and below is a picture of the resulting circuit.

## 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

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

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)

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.