Files
arduino-libs/arduino-cli/libraries/Blynk/examples/Blynk.Inject/myPlant_ESP8266/myPlant_ESP8266.ino
2024-07-20 22:09:06 +08:00

196 lines
5.6 KiB
C++

/*************************************************************
This is a DEMO sketch which works with Blynk myPlant app and
showcases how your app made with Blynk can work
You can download free app here:
iOS: https://itunes.apple.com/us/app/blynk-myplant/id1163620518?mt=8
Android: https://play.google.com/store/apps/details?id=cc.blynk.appexport.demo
If you would like to add these features to your product,
please contact Blynk for Businesses:
http://www.blynk.io/
*************************************************************/
#define USE_SPARKFUN_BLYNK_BOARD // Uncomment the board you are using
//#define USE_NODE_MCU_BOARD // Comment out the boards you are not using
//#define USE_WITTY_CLOUD_BOARD
//#define USE_CUSTOM_BOARD // For all other ESP8266-based boards -
// see "Custom board configuration" in Settings.h
#define APP_DEBUG // Comment this out to disable debug prints
#define BLYNK_PRINT Serial
#include "BlynkProvisioning.h"
void setup() {
delay(500);
Serial.begin(115200);
/**************************************************************
*
* Workflow to connect the device to WiFi network.
* Here is how it works:
* 1. At the first start hardware acts as an Access Point and
* broadcasts it's own WiFi.
* 2. myPlant smartphone app connects to this Access Point
* 3. myPlant smartphone app request new Auth Token and passes
* it together with user's WiFi SSID and password
* 4. Hardware saves this information to EEPROM
* 5. Hardware reboots and now connects to user's WiFi Network
* 6. Hardware connects to Blynk Cloud and is ready to work with app
*
* Next time the hardware reboots, it will use the same configuration
* to connect. User can RESET the board and re-initiate provisioning
*
* Explore the Settings.h for parameters
*
**************************************************************/
BlynkProvisioning.begin();
example_init(); // Initialize this example
}
void loop() {
// This handles the network and cloud connection
BlynkProvisioning.run();
// Run this example periodic actions
example_run();
}
/**************************************************************
*
* myPlant example App code
*
* The following code simulates plant watering system
*
**************************************************************/
BlynkTimer timer; // Initiating timer to perform repeating event
static int sensorSoilMoisture = 60;
static int sensorAirHumidity = 50;
static int wateringAmount = 5;
static int wateringTimer = -1;
static bool isNotificationSent = false;
// Getting data from "Set watering amount" slider
BLYNK_WRITE(V5) {
wateringAmount = param.asInt();
DEBUG_PRINT(String("Watering amount: ") + wateringAmount);
}
// Getting data from "Start Watering" button
BLYNK_WRITE(V6) {
if (param.asInt() == 1) {
// If watering started -> start simulating watering
timer.enable(wateringTimer);
DEBUG_PRINT("Watering started by user");
} else {
// If watering stopped -> stop simulating watering
timer.disable(wateringTimer);
DEBUG_PRINT("Watering stopped by user");
}
}
// When device starts ->
// sync watering switch button status
// and watering amount level from the cloud (last App value)
BLYNK_CONNECTED() {
Blynk.syncVirtual(V5, V6);
}
// This is a sinusoidal function used for simulations
float sinusoidal(float minv, float maxv, float period) {
float amp = (maxv - minv) / 2.0;
float med = minv + amp;
return med + amp * sin((M_PI * 2 * millis()) / period);
}
// Simulating values jittering
float randomize(float minv, float maxv) {
return float(random(minv * 1000, maxv * 1000)) / 1000;
}
void example_init() {
// Update sensors each 3 seconds
timer.setInterval(3000L, []() {
// Soil moisture
if (sensorSoilMoisture < 33) {
Blynk.virtualWrite(V1, "DRY");
} else if (sensorSoilMoisture > 33) {
Blynk.virtualWrite(V1, "MOIST");
} else {
Blynk.virtualWrite(V1, "WET");
}
float dayPeriod = 3.0 * 60 * 1000;
// Light level
int light = sinusoidal(5, 95, dayPeriod);
if (light < 33) {
Blynk.virtualWrite(V2, "LOW");
} else if (light > 33) {
Blynk.virtualWrite(V2, "GOOD");
} else {
Blynk.virtualWrite(V2, "MED");
}
// Temperature
Blynk.virtualWrite(V3, sinusoidal(18, 23, dayPeriod) + randomize(-1.0, 1.0));
});
// Humidity updates at a different rate (5s)
timer.setInterval(5000L, []() {
sensorAirHumidity += random (-5, +5);
sensorAirHumidity = constrain(sensorAirHumidity, 30, 90);
Blynk.virtualWrite(V4, sensorAirHumidity);
});
// Soil Moisture decreases 3% every second
timer.setInterval(1000L, []() {
sensorSoilMoisture -= 3;
sensorSoilMoisture = constrain(sensorSoilMoisture, 7, 85);
if (sensorSoilMoisture < 20) {
if (isNotificationSent == false) {
Blynk.email("myPlant notification", "Your plant is thirsty!");
isNotificationSent = true;
DEBUG_PRINT("Email notification sent");
}
}
});
// Simulate watering process
wateringTimer = timer.setInterval(1000L, []() {
sensorSoilMoisture += wateringAmount;
sensorSoilMoisture = constrain(sensorSoilMoisture, 7, 85);
if (sensorSoilMoisture > 30) {
isNotificationSent = false;
}
if (sensorSoilMoisture >= 85) {
// Stop watering
timer.disable(wateringTimer);
// Update "Start Watering" button widget state
Blynk.virtualWrite(V6, 0);
DEBUG_PRINT("Watering stopped automatically");
}
});
timer.disable(wateringTimer);
}
void example_run() {
timer.run();
}