Hello! In this article I want to tell you how to make the soil moisture sensor work a year on two batteries (AAA) and at the same time do everything more or less correctly. The first article is about the
choice of development environment (Arduino IDE) and the Blynk platform .
Picture of homemade oak to attract attentionGardener amateur
For a start, a little recognition - I'm not a programmer and I'm a home gardener. Both are my hobbies. I have shelves made on the windowsills, with a special blue-red LED backlight, under which the plants should grow with more enthusiasm. Without going into the details of photosynthesis and other botany, we can say that the LED light created one problem, solving which was born the device, which this article is devoted to.
')
SpoilerThe LEDs are warming up, the earth is drying, I water something.
LED lines (power about 6 W), they heat up quite strongly themselves and heat the shelf and the pot with the plant that stands on it. The plant itself, heated soil does not bring any discomfort, but there is a problem of rapid drying of the soil.
At the same time, the earth in pots, which stand simply on the windowsill, dries out more slowly. And on the upper shelves, where the state of the soil is not visible during irrigation, overflows or droughts regularly occur.
Of course, everything has already been invented, and on Ebay you can buy a car of various soil moisture meters. For example, one copy of a moisture meter with a beeper was purchased (the price is about 300 rubles).
The device works, but there are a few but:
- It is not clear what level of humidity is set to beeper.
- If there are more than one device, you will have to walk and listen.
- I can do that too.
And then Ostap suffered, because there is an experience (
once and
twice ). Thus, a device was born capable of measuring soil moisture, light, temperature and air humidity, transmitting measurement results to a mobile application and operating from batteries for quite a long time.
About iron here . And about the software features I want to tell more in this article.
Analyzing power consumption
According to the datasheet, ESP8266 consumes up to 170 mA in WiFi mode, 15 mA with the modem turned off (Modem Sleep) and nothing at all in Deep Sleep mode - about 10 µA.
From the consumer in our device, you can select a WiFi modem, an AM2302 sensor (to which 3.3 V is fed through the TPS60240DGKR booster) and a multiplexer (CD74HC4051M96) for switching the ADC inputs.
WiFi makes the biggest contribution to power consumption, and therefore the first thing to do is to force the ESP8266 to start with the radio off. After loading in Modem Sleep mode, you can make all the measurements and only then turn on the modem and transfer data to the Blynk server (for optimization of consumption, MQTT has disconnected), and then fall asleep until the next time.
Deep sleeep
Provided that all legs are connected with hardware correctly (RST pin is connected to GPIO16), you can transfer ESP to Deep Sleep mode with one command:
ESP.deepSleep(sleep_time, WAKE_RF_DISABLED);
sleep_time – , , , ( blynk) – 5-10 . , .
WAKE_RF_DISABLED — , WiFi .
WiFi
Captive . , , WiFiManager, . . UART — :
- ( ).
- ( ).
- WiFiManager.
Captive , WiFi Blynk token.
, WiFi ESP.
WiFi.forceSleepWake();
WiFi.mode(WIFI_STA);
delay(100);
if (WiFi.SSID()) WiFi.begin();
ESP8266 WiFi.disconnect(); WiFi . , SSID() , .
AM2302
\
DHT Sensor Library Adafruit. , , , GPIO. , , ( 99%) 5 . «» , AM2302 , .. \ .
: , . — ().
ESP8266 10-, 0..1 . , 1 . — . , .
4 . ., , . , 3.3 2.5 ( ) .
\\ :
q_w = (adcbattery * 4) / 15; //
q_l = (adcbattery * 25) / 101; //
( ) . , ( ) .
float adcRead[3];
void quickSort(float *s_arr, int first, int last){
if (first < last){
int left = first, right = last, middle = s_arr[(left + right) / 2];
do{
while (s_arr[left] < middle) left++;
while (s_arr[right] > middle) right--;
if (left <= right){
int tmp = s_arr[left];
s_arr[left] = s_arr[right];
s_arr[right] = tmp;
left++;
right--;
}
}
while (left <= right);
quickSort(s_arr, first, right);
quickSort(s_arr, left, last);
}
}
void analogReadMedian(){
adcRead[0] = analogRead(ADCPin);
delay(10);
adcRead[1] = analogRead(ADCPin);
delay(10);
adcRead[2] = analogRead(ADCPin);
}
void readADC_median(int input){
switch(input){
case 1 :
digitalWrite(BPin, HIGH);
digitalWrite(C_DHTPin, LOW);
delay(50);
analogReadMedian();
quickSort(adcRead, 0, 2);
adcbattery = adcRead[1] * 4;
q_w = (adcbattery * 4) / 15;
q_l = (adcbattery * 25) / 101;
digitalWrite(BPin, LOW);
break;
case 2 :
digitalWrite(BPin, LOW);
digitalWrite(C_DHTPin, LOW);
analogWrite(PWMPin, 412);
delay(50);
analogReadMedian();
quickSort(adcRead, 0, 2);
adcwater = 5*(100 - 100*(adcRead[1] / q_w));
if (adcwater > 100) adcwater = 100;
if (adcwater < 0) adcwater = 0;
analogWrite(PWMPin, 0);
break;
case 3 :
digitalWrite(BPin, LOW);
digitalWrite(C_DHTPin, HIGH);
delay(50);
analogReadMedian();
quickSort(adcRead, 0, 2);
adclight = 100*(adcRead[1] / q_l);
if (adclight > 100) adclight = 100;
if (adclight < 0) adclight = 0;
break;
default :
delay(1);
}
}
, , , «» . , «» — , - 100 . , 100 50% .
, ESP8266 78 , 75 .
:
pinMode(PWMPin, OUTPUT);
analogWriteFreq(75000);
analogWrite(PWMPin, 512);
analogWrite(PWMPin, 0);
, 1 , (2 ) 4 5760 . 12 ( ), (480 ).
, WiFi «», . , . , .. Deep sleep . EEPROM, ESP ( ).
, 512 RTC , , Deep sleep. .
ESP.rtcUserMemoryWrite(offset, &data, sizeof(data))
ESP.rtcUserMemoryRead(offset, &data, sizeof(data))
, () () . . , , , .
.
.
.PS. .