Some time ago, we published here a similar project: "ArduFarmBot: Controlling a Tomato Home Farm using Arduino and IoT". On this new version, the ArduFarmBot 2, the main specification of the original project will be kept. We will develop a fully automated Gardening System based on NodeMCU ESP8266 and an IoT app, the BLYNK.
Basically, information from a plantation will be captured, temperature and humidity, both from air and soil. Based on those data, the ArduFarmBot 2 will decide the right amount (and when) the plantation should receive heat and water. Also the project should allow manual intervention of an operator in order to control a water pump and an electric lamp to generate heat for the plantation. The manual intervention must be both, local and remote via Internet.
In short, the system should receive as input:
Sensors:
- Air Temperature
- Air Relative Humidity
- Soil Temperature
- Soil Moisture (humidity)
Buttons:
- Pump ON/OFF
- Lamp ON/OFF
The system should provide as an output:
Actuators:
- Relay for Pump control
- Relay for Lamp control
Automatic messages must be sent on main events as:
- Pump ON
- Lamo On
- System Off-line
Data Display
- All analog and digital data should be available for instant evaluation
Data Storage
- Historic data should be storage remotely
The block diagram shows the main components of the project.
- NodeMCU WiFi Internet ESP8266 - ($8.79)
- Temperature and Humidity Sensor DHT22 - ($3.66)
- Soil Moisture Sensor - ($6.98) (Optional, can be DIY)
- Buttons (3X) - ($0.90)
- LEDs (2X) ($0.20)
- Jump wires (S1.00)
- Breadboard ($3.33)
- 4.7K Ohms resistor - ($0.03)
- 10K Ohms resistor - ($0.03)
- 220 Ohms resistor - ($0.03)
- 5V/ 2A External Power Supply ($7.55)
- Mini DC Water Pump ($8.95)
The NodeMCU ESP-12E is the integrated version of the popular ESP8266, a Serial to Wi-Fi System On a Chip (SoC) that appeared for the first time in 2013, been released on following year. The ESP8266 was developed by the Shanghai-based company Espressif Systems, an IC manufacturer focused on the development of RF chips, particularly Wi-Fi.
There are several modules in the market that use the ESP8266 chip, they are named ESP-NN, where NN is a number 01, 02, ... 12, sometimes followed by a letter. These modules typically carry the ESP8266 SoC, flash memory, a crystal, and in most cases, an onboard antenna. In the link you can find the full list of ESP8266 based devices found in the market: ESP8266 Module Family. The 2 more important modules are without doubt, the ESP-01 and the ESP-12E.
Here, we will use the ESP-12E Development Board (NodeMCU DevKit 1.0). This development board for the ESP8266 SoC inside the ESP-12E module is out-of-the-box ready for you to connect it to your computer, install USB drivers, and start writing programs that connect to your Wi-Fi network!
Technical Specifications- Support STA/AP/STA+AP 3 working modes;
- Built-in TCP/IP protocol stack, support multiple-channel TCP Client connection (max 5);
- 0~D8, SD1~SD3: used for GPIO, PWM (D1-D8), IIC, ect; the driven ability can be arrived at 15mA;
- AD0: one-way 10 bits ADC;
- Power input: 4.5V~9V(10VMAX), support USB powered and USB debug;
- Working current: ≈70mA(200mA MAX, continue), standby<200uA;
- Transmission data rate: 110-460800bps;
- Support UART/GPIO data communication interface;
- Support update firmware remotely (OTA);
- Support Smart Link;
- Working temperature:-40℃~+125℃;
- Driven mode: double large-power H bridge driven
- Weight: 7g.
(If you already have the NodeMCU installed with your IDE, please skip this step)
We will program and use the NodeMCU almost as a regular Arduino, using its IDE. It is important to remember that any new "custom firmware" will replace anything previously stored in the chip's flash memory, including the original firmware loaded at factory where the AT commands were common used. Although we can use the manufacturer's SDK to develop our custom firmware, it is much easier to use the good and old Arduino IDE.
Let's start:
In the Arduino IDE open the PREFERENCES window and enter the URL (marked in red in the above photo) into the Additional Boards Manager URLs field, and select OK.
- Select the MENU option Tools → Board → Boards Manager and scroll down and to locate the option esp8266 by ESP8266 Community which should be the last item on the list, and click INSTALL
- Installing The USB Drivers: The USB to Serial UART module included on the board is the Silicon Labs' CP2012, for which we usually need to install the readily available Virtual COM Port (VCP) drivers. In the case of my MAC, the device file created to communicate with the CP2102 has the name /dev/cu.SLAB_USBtoUART. You can find the appropriate drive for your computer at following link: CP210x USB to UART Bridge VCP Drivers
- After restarting the Arduino IDE we can now select the board we're using from the menu option Tools → Board → NodeMCU 1.0 (ESP-12E Module). Then we specify the correct CPU Frequency (Tools → CPU Frequency: "" → 80MHz) and Upload Speed (Tools → Upload Speed: "" → 115200). Finally, the last step is to select the correct option for the Port (Tools → Port → /dev/cu.SLAB_USBtoUART).
At this point we are ready to write our own firmware and upload it, but let's first try one of the examples File → Examples → ESP8266WiFi → WiFiScan. After uploading it, we can open the Serial Monitor window and observe the results. Note that we need to match the baud rate, so check that 115200 is selected from the drop down menu!
Step 4: Installing the OLEDIn order to verify the collected data locally, a small OLED Display should be installed. The model used on ArduFarmBot 2 is the OLED 128 x 64 SSD 1306 I2C. Looking the name we know that this display has as main characteristics:
Its is a I2C display, so we will connect it to the NodeMCU I2C pins, using:
- SCL ==> D1 (5)
- SDA ==> D2 (4)
- 128 pixels at horizontal and 64 pixels at vertical. So if you use 8x8 characters, we will get a "16X8" Display (8 lines of 16 characters each).
The SSD1306 can be powered with 5V (external) or 3.3V directly from the NodeMCU module. The first option was the chosen one (5V).
Once we have connected the display, let's download and install its library on our Arduino IDE. We will use the ACROBOT library version: SSD1306 Arduino Library
Once you have re-started the IDE, the library should be already installed. Let's now, upload the below sketch to test our OLED display:
/***********************************************************************
* NodeMCU and OLED display "Hello World" test
*
* MJRoBot 15march17
************************************************************************/
#include <Wire.h>
#include <ACROBOTIC_SSD1306.h>
void setup()
{
Wire.begin();
oled.init(); // Initialize SSD1306 OLED display
oled.clearDisplay(); // Clear screen
oled.setTextXY(0,0); // Set cursor position, start of line 0
oled.putString(" MJRoBot.org");
oled.setTextXY(4,0); // Set cursor position, start of line 4
oled.putString(" HELLO, WORLD");
}
void loop()
{
}
Note that when you do not define a different size of text character, the default is 8X8. To define a different one, you can use: oled.setFont(font5x7);
Below the code for "Hello World" test:
Step 5: Capturing Air Temperature and HumidityOne of most used sensors for capturing weather data is the DHT22 (or it's brother DHT11), a digital relative humidity and temperature sensor. It uses a capacitive humidity sensor and a thermistor to measure the surrounding air, and spits out a digital signal on the data pin (no analog input pins needed).
The sensor should be powered between 3.3V and 5V and will work from -40oC to +80oC with an accuracy of +/- 0.5oC for temperature and +/-2% for relative Humidity. It is also important to have in mind that the its sensing period is in average 2seconds (minimum time between readings). The site of Adafruit provides a lot of information about both, DHT22 and its brother DHT11. For more details, please visit: DHT22/11 Tutorial page. The DHT22 has 4 pins (facing the sensor, pin 1 is the most left):
- VCC (we will connect to 3.3V from NodeMCU);
- Data out;
- Not connected and
- Ground.
Once usually you will use the sensor on distances less than 20m, a 10K resistor should be connected between Data and VCC pins. The Output pin will be connected to NodeMCU pin D3 (see the diagram above). Once the sensor is installed at our module, download the DHT library from Adafruit github repository and install it in your Arduino's Library file. Once you reload your Arduino IDE, the "DHT sensor library" should be installed. Run the DHT Sensor code below to verify that everything is running OK:
Step 6: Capturing Soil Moisture HumidityOn the previous ArduFarmBot Project we explored how to work with a Soil Moisture Hygrometer to measure soil humidity. There we have explored a DIY type of sensor; here let's use a electronic one, very common in the market: the YL-69 sensor and LM393 Comparator module soil medium Hygrometer.
The LM393 module has 2 outputs, one digital (D0) that can be set-up using the potentiometer that exist on it and an analog one (A0). This module can be sourced with 3.3V, what is very convenient when working with an NodeMCU. What we will do is install the LM393 4 pins as below:
- LM393 A0 output to A0 NodeMCU A0 input
- LM393 VCC to NodeMCU VCC or to NodeMCU GPIO D3*
- LM393 GND to NodeMCU GND
- LM393 D0 open
It's important to highlight that the correct is to connect the Sensor VCC to a Digital Pin as output, so the LM393 will be powered only when we need a read. This is important no only to save power, but also to protect the probes from corrosion. With a DYI type of sensor as used on the original ArduFarmBot project, its work fine, but in the case here, the NodeMCU did not worked well the soilMoisterVcc PIN connected. Also I had eventual errors due the power consumption. So, I powered the LM393 direct to VCC (5V), the code does not need to be changed. It is worked fine.
A simple routine can be written to read the analog port:
/***************************************************
* Get Soil Moister Sensor data
**************************************************/
void getSoilMoisterData(void)
{
soilMoister = 0;
digitalWrite (soilMoisterVcc, HIGH);
delay (500);
int N = 3;
for(int i = 0; i < N; i++) // read sensor "N" times and get the average
{
soilMoister += analogRead(soilMoisterPin);
delay(150);
}
digitalWrite (soilMoisterVcc, LOW);
soilMoister = soilMoister/N;
Serial.println(soilMoister);
soilMoister = map(soilMoister, 600, 0, 0, 100);
}
Few comments about the above routine:
We use MAP to setup the range in percentage.
- Making a "short circuit" at the sensor probes (equivalent to "100% of humidity") we got a value of around 0 at ADC output and
- Leaving it "in the air" the value displayed at Serial Monitor would be around 600 (5V Powered source).
- The sensor data is captured 3 times and an average is taken.
Below a partial test code for this stage of project:
Step 7: Collecting Soil TemperatureWe will use on this project, a waterproofed version of the DS18B20 sensor. It is very useful for remote temperature on wet conditions, as an humid soil. The sensor is isolated and can take measurements until 125oC (Adafrut does not recommend to use it over 100oC due its cable PVC jacket).
The DS18B20 is a digital sensor what makes it good to use even over long distances! These 1-wire digital temperature sensors are fairly precise (±0.5°C over much of the range) and can give up to 12 bits of precision from the onboard digital-to-analog converter. They work great with the NodeMCU using a single digital pin, and you can even connect multiple ones to the same pin, each one has a unique 64-bit ID burned in at the factory to differentiate them.
The sensor works from 3.0 to 5.0V and has 3 wires:
- Black: GND
- Red: VCC
- Yellow: 1-Wire Data
Here, you can find the full data: DS18B20 Datasheet
In order to use the DS18B20 properly, two libraries will be necessary:
- OneWire (NOTE 1)
Install both libraries in your Arduino IDE Library depository.
For testing the sensor, you can use the code "Simple.ino" included on the Library Examples, as shown at the photo. Upload the code in your NodeMCU and monitor the temperature using the Serial Monitor. The above photo shows the expected result. Hold the sensor in your hand, you should see the temperature going to circa of 32/34oC.
NOTE1: The OneWire library MUST be the special one, modified to be used with ESP8266, otherwise you will get an error during compilation. You will find the last version at above link or from the below zip file:
Step 8: Completing the HWFollowing the above diagrams, complete the required system HW installing the buttons and LEDs.
Verify that all sensors (DHT22, DS18B20 and LM393/YL69) as the OLED are powered using the external 5V. The NodeMCU is used only to provide the control signals. Remember that using the NodeMCU 3.3V external pins to provide power can turn the system unstable due the current consumption.
LEDs
Note that LEDs connected on NodeMCU, are for testing only. They will "simulate", the Pump (Red LED) and the Lamp (Green LED). For the final circuity the Relays will connected to those outputs as described on the next Step.
Buttons
Based on the readings of sensors, an operator could be also decide manually control the Pump and/or Lamp. For that, three push-buttons will be incorporate to the project:
- RED: Pump Manual Ctrl
- GREEN: Lamp manual Ctrl
- YELLOW: Sensor Read Button (To update sensors, "light on" the OLED and present data (explained at next step)
The buttons will work on a "toggle" mode: If an actuator is "ON", pressing the button will "Turn-OFF" it and vice versa. The button's logic will be "normally closed", what means that NodeMCU Input will be constantly "HIGH". Pressing the button, a "LOW" will be applied at the specific pin (please see the above block diagram).
In order to read the local command, a function readLocalCmd() should be executed. This function will read each button, updating the status of actuators variables (pumpStatus and lampStatus). Note that the function type debounce(pin) is called instead a direct digitalRead (pin). This is to prevent false readings from the pushbutton. If you want to learn more about debouncing, please see this Debouncing Tutorial.
/****************************************************************
* Read local commands (Pump and Lamp buttons are normally "HIGH"):
****************************************************************/
void readLocalCmd()
{
boolean digiValue = debounce(PUMP_ON_BUTTON);
if (!digiValue)
{
pumpStatus = !pumpStatus;
aplyCmd();
}
digiValue = debounce(LAMP_ON_BUTTON);
if (!digiValue)
{
lampStatus = !lampStatus;
aplyCmd();
}
}
In the case where a button is pressed, another function will be called: aplyCmd(). And as the name says, will apply the correspondent command, turning the actuators ON or OFF:
/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
if (pumpStatus == 1)
{
digitalWrite(PUMP_PIN, HIGH);
displayData();
}
else
{
digitalWrite(PUMP_PIN, LOW);
displayData();
}
if (lampStatus == 1)
{
digitalWrite(LAMP_PIN, HIGH);
displayData();
}
else
{
digitalWrite(LAMP_PIN, LOW);
displayData();
}
}
Code considerations
When we think about the 4 big "group of tasks" so far:
- Read sensors
- Read buttons (local Command)
- Act on Pump/Lamp
- Display all Data
We will realize that the the timing when we should perform such tasks are not necessarily the same. For example, to read the Temperature and Humidity data from DHT 22, we will need to wait at least 2 seconds between measure, but minutes are OK. For Soil Moisture sensor, as less measurements we do, better (due probe corrosion generate by electrolise) and last but not least, daylight will not vary instantly. But when we think about the actuators, as soon we press a button, we would like (and possibly need) a quick reaction.
So, we must use here a "timer" to correctly control the correct timing of those tasks. We could do this using the millis(), as we did on the original ArdFarmBot Project, but let's introduce another great tool here:
SimpleTimer.h (follow the instructions on this link to install the Library: SimpleTimer)
The library must be included on the main body of your code, following by a timer definition:
SimpleTimer timer;
Next, define the timers:
timer.setInterval(1000L, readLocalCmd); // Read buttons at every 1 second
timer.setInterval(2000L, getSoilTempData); // Read Soil Temp at every 2 seconds
timer.setInterval(2000L, getDhtData); // Read DHT Sensor at every 2 seconds
timer.setInterval(10000, getSoilMoisterData); // Read Soil Humidity at every 10 seconds
timer.setInterval(10000, displayData); // Display Data at OLED at every 10 seconds
Step 9: The Local Control Station - Concluding the CodeIntroducing the Sensor Read Button (The yellow one!)
As we could see at last step, we will need wait long cycles between Soil Moisture sensor measurements. It is Ok, for our automatic needs, but for manual operation we will not want to "wait" 10, 15 or more seconds (or even minutes in real case) for a sensor measurements. Also in real world, make no sense keep the OLED display "ON" all the time. So, the default will be "dark" or "OFF".
So, we will introduce a 3rd push button to our project that will display the actual sensor data any time that we want, independent of the the timing of the automatic readings. Also, we will use this same button to display data at OLED when the sensors are updated. Below the changed readLocaCmd() function:
/**************************************************************************
* Read local commands (Pump, Lamp and Sensor buttons are normally "HIGH"):
**************************************************************************/
void readLocalCmd()
{
boolean digiValue = debounce(PUMP_ON_BUTTON);
if (!digiValue)
{
pumpStatus = !pumpStatus;
aplyCmd();
}
digiValue = debounce(LAMP_ON_BUTTON);
if (!digiValue)
{
lampStatus = !lampStatus;
aplyCmd();
}
digiValue = debounce(SENSORS_READ_BUTTON);
if (!digiValue)
{
turnOffOLED = !turnOffOLED;
if (!turnOffOLED)
{
oled.setTextXY(0,0); oled.putString("UPDATING SENSORS");
getDhtData();
getSoilMoisterData();
getSoilTempData();
oledStart();
displayData();
}else oled.clearDisplay(); //turn off OLED
}
}
At this point, all the HW is completed (using LEDs as actuators) and we have all SW parts to be put together. The video shows the ArduFarmBot 2, operation on a Local and Manual mode:
You can download the complete code for testing your "local Station" on its Manual mode only, at my GitHub: ArduFarmBot2_Local_Manual_Ctrl_V1
Step 10: Making our Gardening System fully automaticAt this point we have all HW in place and as saw at last step, the station can be controlled by a local operator via the buttons. What is missing is the "logic" allowing our system to really perform the task of irrigating the plantation automatically! We need to include some "brain" to our ArduFarmBot project.
Let's define the initial range where the Sensors would work. Those values should be changed later using practical values to be founded on the real plantation:
Soil Moisture:
- "WET": Over 88% (no watering at all)
- "Target Humid": Between 66% and 88% (Where we want to work) and
- "DRY": Below 66% (need turn on the pump to increase the humidity)
Air Temperature:
- COLD: Below 12oC (Turn-On the Light/Heat*)
- Optimum: between 12oC and 22oC
- HOT: Over 22oC (Do not Turn-On the Light/Heat)
You must have in mind that each type of seeds has a optimum range of temperature where it will grow faster. For example for Tomatos the minimum time for seeds to germinate will be 6 days on temperatures between 20 and 25 oC, going up for temperatures lower or higher than that (more than 43 days for temperature less than 10oC and 9 days for temperature over 35oC).
You can check more information about this relationship (Temp/Germination days) here: The effect of soil temperature on seeds germination.
Having this 4 reading (Air Temperature, Air Humidity, Soil Moisture and Soil Temperature), we can built a complex matrix defining how we want that our automatic Gardening System works. On the Step 7 of ArduFarmBot - Part 2: "Remote Station" an IoT Implementation, a complex Sensor-matrix approach was developed in deep.
So, let's define the below parameters to be used on our code:
/* Automatic Control Parameters Definition */
#define DRY_SOIL 66
#define WET_SOIL 85
#define COLD_TEMP 12
#define HOT_TEMP 22
#define TIME_PUMP_ON 15
#define TIME_LAMP_ON 15
TIME_PUMP_ON and TIME_LAMP_ON are the time in seconds that both pump and lamp must be ON during automatic operation.
Based on the above parameters, let's think about some very simple assumptions to be implemented on the code:
- If it's DRY ==> PUMP = ON
- If it's COLD ==> LAMP = ON
In this project we will keep it simple and will not explore all possible combinations and the role of Air humidity or soil temperature on the equation.
The Code:
Let's create a new function that based on sensors reading, will deal automatically with actuators, turning on/off the Pump and Lamp: autoControlPlantation(). This function as shown below, will be called on every Cycle of Sensors readings:
/**************************************************************
* Automatically Control the Plantation based on sensors reading
**************************************************************/
void autoControlPlantation(void)
{
if (soilMoister < DRY_SOIL)
{
turnPumpOn();
}
if (airTemp < COLD_TEMP)
{
turnLampOn();
}
}
The function will have 2 main tasks:
- Pump Control
- Lamp Control
Below, both functions:
***************************************************
* Turn Pump On for a certain amount of time
****************************************************/
void turnPumpOn()
{
pumpStatus = 1;
aplyCmd();
delay (TIME_PUMP_ON*1000);
pumpStatus = 0;
aplyCmd();
}
/***************************************************
* Turn Lamp On for a certain amount of time
****************************************************/
void turnLampOn()
{
lampStatus = 1;
aplyCmd();
delay (TIME_LAMP_ON*1000);
lampStatus = 0;
aplyCmd();
}
At last, but not least, let's use the Sensor Read button ("yellow one") to not only pause the program for a certain time during the start-up but also to display the most important initial parameters, as shown at above photo.
At this point the ArduFarmBot is fully functional in terms of HW and SW. The video shows the ArduFarmBot 2, operation on a Local and Automatic mode:
Below the ArduFarmBot2 code in its version of "Local and Automatic control". You can download them on my GitHub: ArduFarmBot2_Local_Automatic_Ctrl_V2.
Step 11: Creating the BLYNK AppIt is really very easy to built IoT projects using BLYNK. The first you need is to have the BLINK App installed on you phone its Library on the Arduino IDE. If you do not have them yet, please follow the below steps:
- Download BLYNK app for Apple Iphone or Google Android
- Install BLYNK Library for Arduino. Note that you will download the zip file (There are 5 files there that you must manually install in your Arduino Library).
- Once the Arduino IDE is reloaded, you should be OK to start using BLINK on your IoT project.
Now, let's open our app at the SmartPhone:
- Open Blynk app.Tap on "Create New Project" screen
- Give a name for your project (For example "ArduFarmBot 2")
- Select the appropriated Hardware Model: "NodeMCU"
- Take note from Authorization Token (you can e-mail it to you to ease copy&past on your code)
- Press "OK". A Blank screen with dots will appear.
- Tap the Screen to open the "Widget Box"
OK, let's take a moment and think about our ArduFarmBot 2 Blynk App and define what will be the Widgets to be installed. Revisiting the general specification at introduction, we can summarize that our app we be needed for:
- Read all Sensors and verify the actuators status
- Take remote actions, "turning on/off" Pump and Lamp
- Sending messages when the System is "off-line" and/or an actuator is ON
- Record the general sensors data
In order to organize things, let's split the above "tasks" in 3 tabs:
- SENSORS
- ACTUATORS / CONTROL
- GRAPHICS
"Tabs" will be the first Widget to be installed. Enter on it and define the above "Tab names". Next, go to each Tab and install the Widgets as described below:
SENSORS
- Gauge: "Temp Air [oC]" Blue; input: V10 0 to 50; frequency: 5 sec
- Gauge: "Humidity Air [%]" Green; input: V11 0 to 100; frequency: 5 sec
- Gauge: "Soil Humidity [%]" Red; input: V12 0 to 100; frequency: 5 sec
- Gauge: "Soil Temperature[oC]" Yellow; input: V13 -10 to 50; frequency: 5 sec
- LED: "PUMP" Red; V0
- LED: "LAMP" Green; V1
ACTUATORS / CONTROL
- Button: "PUMP" Red; output: V3 0 to 1; mode: Switch; label: on: ACT, off: OK
- Button: "LAMP" Green; output: V4 0 to 1; mode: Switch; label: on: ACT, off: OK
- LED: "PUMP" Red; V0
- LED: "LAMP" Green; V6
- Notifications: Notify When HW goes offline: ON
GRAPHICS
- Data to Show:
- V10 "Temp Air"
- V11 "Humidity Air"
- V12 "Soil Humidity "
- V13 "Soil Temp"
To run run a Blynk app together with your code, you will need:
- Include the BlynkSimpleEsp8266 library at beginning of your code
- During Setup(), initiate Blynk credentials: Blynk.begin(auth, ssid, pass);
- Define a timing to send local data to Blynk server: timer.setInterval(5000L, sendUptime);
- Call the function Blynk.run(); at loop()
- Create the function sendUtime(); where you will introduce the sensor data to be sent to Blynk Server: Blynk.virtualWrite(VirtualPin, sensor data);
The code must include now the "StationCredentials.h":
char auth[] = "YOUR PROJECT TOKEN"; // Blynk project: "ArduFarmBot2"
char ssid[] = "YOUR LOCAL WIFI NAME";
char pass[] = "YOUR WIFI PASSWORD";
Other considerations:
To use the "Virtual LED" at Blynk app, you must define them at beginning of your code as below:
WidgetLED PUMPs(V0); // Echo signal to Sensors Tab at Blynk App
WidgetLED PUMPa(V5); // Echo signal to Actuators Tab at Blynk App
WidgetLED LAMPs(V1); // Echo signal to Sensors Tab at Blynk App
WidgetLED LAMPa(V6); // Echo signal to Actuators Tab at Blynk App
To "turn on" or "turn off" the the PUMPs LED that is connected with virtual PIN V0, for example, call respectively the functions:
- PUMPs.on() or
- PUMPs.off()
We will include dos commands at applyCmd() function, so the LEDs on Blynk app will mimic the real LEDs of our project. We should also include the command: Blynk.notify("Message to be sent"); on the same applyCmd() function, one for the Pump and another for the Lamp. Below, the new function:
/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
if (pumpStatus == 1)
{
Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON");
digitalWrite(PUMP_PIN, HIGH);
if (!turnOffOLED) displayData();
PUMPs.on();
PUMPa.on();
}
else
{
digitalWrite(PUMP_PIN, LOW);
if (!turnOffOLED) displayData();
PUMPs.off();
PUMPa.off();
}
if (lampStatus == 1)
{
Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
digitalWrite(LAMP_PIN, HIGH);
if (!turnOffOLED) displayData();
LAMPs.on();
LAMPa.on();
}
else
{
digitalWrite(LAMP_PIN, LOW);
if (!turnOffOLED) displayData();
LAMPs.off();
LAMPa.off();
}
}
To receive a command from a Blynk button, a function BLYNK_WRITE() must be defined outside a function, loop() or setup(). For that, the below code was created, one for each Blynk Button (PUMP and LAMP):
/****************************************************************
* Read remote commands
****************************************************************/
BLYNK_WRITE(3) // Pump remote control
{
int i=param.asInt();
if (i==1)
{
pumpStatus = !pumpStatus;
aplyCmd();
}
}
BLYNK_WRITE(4) // Lamp remote control
{
int i=param.asInt();
if (i==1)
{
lampStatus = !lampStatus;
aplyCmd();
}
}
Below, the video shows the automatic operation of ArduFarmBot 2, now including Blynk:
The ArduFarmBot2 code in its version of "Remote and Automatic control", using Blynk can be download from my Github:ArduFarmBot2_Ext_Auto_Ctrl__V3_0.
Step 13: Relays as ActuatorsAs discussed at introduction, our final goal here is to take care of a plantation. With the data provide by sensors, we will know the air and soil temperature, air relative humidity and the most important how "dry" is the soil. With those data in hand, our program should calculate if would be necessary to irrigate the plantation, turning on a water pump or to turn on an electric lamp to provide the appropriate heat to the crop. For that, we will use a small dual 5V Relay Module for Pump and Lamp activation.
The Relay Module diagram circuit can be seen below:
Looking at the diagram, you must connect (depending of your Relay Module, labels could be different):
- Power Supply 5V ==> (4) "Vcc"
- NodeMCU D6 ==> (3) "IN1" (Pump)
- NodeMCU D7 ==> (2) "IN2" (Lamp)
- NodeMCU GND ==> (1) "GND"
Usually you will see as output, 3 Pins for each relay: "NO" ("Normal Open"), "Ref" or "COM" ("Reference" or "Common") and "NC" ("Normal Closed"). We will use the NO and COM for each Relay. On the above example, the "COM" is the terminal to connect to external Positive Pin of the 5V Power Supply (in the case of the Pump) or the 220VAC for the Lamp. The "NO" will be connected to Pump (or Lamp).
In the case of the Relay chosen and confirming on the above diagram, normally the IN1 and IN2 must be at HIGH and its activation will happen with a LOW level (less than 2V). With a LOW level from NodeMCU, the current will flow from VCC to NodeMCU Pin D6, activating the optocoupler input. The Relay output will close and the NO will close, turning ON the Pump on the example.
Regarding the SW, we must "invert" the logic. The Output Pins D6 and D7 should be normally HIGH. So at setup(), change their initial condition:
digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
And also invert the conditions at applyCmd() function:
/***************************************************
* Receive Commands and act on actuators
****************************************************/
void aplyCmd()
{
if (pumpStatus == 1)
{
Blynk.notify("ArduFarmBot2: Warning ==>> Pump ON");
digitalWrite(PUMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
if (!turnOffOLED) displayData();
PUMPs.on();
PUMPa.on();
}
else
{
digitalWrite(PUMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
if (!turnOffOLED) displayData();
PUMPs.off();
PUMPa.off();
}
if (lampStatus == 1)
{
Blynk.notify("ArduFarmBot2: Warning ==>> Lamp ON");
digitalWrite(LAMP_PIN, LOW); // To be used with Relay module (inverted logic: activate with LOW)
if (!turnOffOLED) displayData();
LAMPs.on();
LAMPa.on();
}
else
{
digitalWrite(LAMP_PIN, HIGH); // To be used with Relay module (inverted logic: normally HIGH)
if (!turnOffOLED) displayData();
LAMPs.off();
LAMPa.off();
}
}
The ArduFarmBot2 code in its version of "Remote and Automatic control", using Blynk and real Relay (activation LOW) can be download from my Github: ArduFarmBot2_Ext_Auto_Ctrl__V4_0
Step 14: Testing with a real PumpTo run run a Blynk app together with your code, you will need:
The Pump chosen is a Mini DC Water Pump. You can install it submerse in water or "inline". We have used the second one. Follow the photos and connect the Pump at yours tank's button. After, connect the one of the Pump's wire to Relay IN1 and the other one to the External 5V Power Supply Pin (+). Take the Power Supply Pin (-) and connect it to the Relay COM1.
The below movie shows a manual local and remote operation of the ArduFarmBot 2:
And, finally the below video shows its automatic operation:
Step 15: ConclusionAs always, I hope this project can help others find their way in the exciting world of electronics and IoT!
For updated files, please see the ArduFarmBot2 GitHub repository.
ArduFarmBot, the Book!"ArduFarmBot, the book" is also at Amazon.com! You can get it, by clicking here
The book uses the electronic controller ArduFarmBot as a basis for teaching how to work in both HW and SW, with: a) LCD and OLED type displays; b) LEDs and buttons; c) Activation of pumps and lamps via relays and d) Sensors such as: DHT22 (temperature and relative air humidity), DS18B20 (soil temperature), YL69 (soil moisture) and LDR (luminosity).
All key stages of the project are documented in detail through explanatory texts, block diagrams, high-resolution color photos, electrical diagrams using Fritzing application, complete codes stored in GitHub and YouTube videos.
Two versions of the electronic controller ArduFarmBot are developed in detail in the book. From capture of data coming from a garden, such as air and soil temperature, relative humidity, soil moisture and luminosity, the ArduFarmBot helps to control when a crop should receive heat and water. Control will happen automatically, locally and remote via internet The book is divided into 3 parts. In the first part, the Arduino Nano is the starting point for development of a local version of ArduFarmBot, that can be controlled both, manually and automatically.
In the second part, the book dives into automation design, introducing remote operation through the creation of a webpage. The ESP8266-01 is used for Wi-Fi connection, sending data to an important web service in the field of IoT, the ThingSpeak.com.
In the third part, a second version of ArduFarmBot is developed, introducing the NodeMCU ESP8266-12E, a powerful and versatile IoT device, which replaces both the Arduino Nano and the ESP8266-01, used in the earlier parts of the book.
In this last part of the book, a new service platform of the IoT universe, the Blynk, is also explored.
Download the book, give it a review and please use the message board here to give us any comment, suggestion or critic!
For more projects, please visit my blog: MJRoBot.org
Saludos from the south of the world!
See you at my next project!
Thank you
Marcelo
Comments