Système d’irrigation intelligente Arduino Utilisation de l’application ESP32 et Blynk

Smart Irrigation System using ESP32 and Blynk

Copier de code

//ESP32 smart irrigation code
#define BLYNK_TEMPLATE_ID    "Replace your BLYNK_TEMPLATE_ID here"
#define BLYNK_TEMPLATE_NAME  "Replace your BLYNK_TEMPLATE_NAME here"
#define BLYNK_AUTH_TOKEN     "Replace your BLYNK_AUTH_TOKEN here"
#define BLYNK_PRINT Serial
#include 
#include 
#include "DHT.h"
#include 
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wifi Name";
char pass[] = "Wifi Password";
#define LED_PIN     21
#define BRIGHTNESS  255
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
const uint8_t kMatrixWidth  = 16;
const uint8_t kMatrixHeight = 16;
const bool    kMatrixSerpentineLayout = true;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight)
// The leds
CRGB leds[kMatrixWidth * kMatrixHeight];
BlynkTimer timer;
bool ledStripOn = false;
// The 16 bit version of our coordinates
static uint16_t x;
static uint16_t y;
static uint16_t z;

uint16_t speed = 20; // speed is set dynamically once we've started up
uint16_t scale = 30; // scale is set dynamically once we've started up
uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
CRGBPalette16 currentPalette( PartyColors_p );
uint8_t       colorLoop = 1;
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int soilMoisturePin = 35; // Analog pin for the soil moisture sensor
const int waterLevelPin = 34;   // Analog pin for the water level sensor
const int ledPin = 2;

// Constants for soil moisture thresholds
const int SOIL_MOISTURE_LOW = 50;  // Adjusted to match the 0-100 range
const int SOIL_MOISTURE_HIGH = 50; // Adjusted to match the 0-100 range
const int pumpPin = 5;  // Change this to the actual pin connected to the DC pump on ESP32
int pumpState = LOW;    // Initialize pumpState to LOW (off)
int pumpMode = 0;       // 0 for automatic, 1 for manual
int waterLevel = 0;     // Water level indicator value
unsigned long previousMillis = 0;
const unsigned long interval = 1000; // Interval in milliseconds
float mappedSoilMoisture = 0; // Declare mappedSoilMoisture as a global variable
void setup() {
  Serial.begin(115200);
  digitalWrite(pumpPin,LOW);
  pinMode(ledPin, OUTPUT);
  pinMode(pumpPin, OUTPUT);
  dht.begin();
  Blynk.begin(auth, ssid, pass);
  Blynk.virtualWrite(V2, LOW);
  Blynk.virtualWrite(V3, "LED OFF");
  Blynk.virtualWrite(V6, LOW); // Initialize the mode button to automatic mode
  Blynk.virtualWrite(V5, LOW); // Initialize the pump button to OFF
  Blynk.virtualWrite(V8, LOW); // Initialize the new feature button to OFF
  delay(3000);
  LEDS.addLeds(leds,80);
  LEDS.setBrightness(BRIGHTNESS);
  // Initialize our coordinates to some random values
  x = random16();
  y = random16();
  z = random16();
}
BLYNK_WRITE(V5) { // This function is called when the pump button state changes (Manual Control)
  if (pumpMode == 1) { // Check if the mode is manual
    pumpState = param.asInt(); // Read the state of the pump button (0 for OFF, 1 for ON)
    digitalWrite(pumpPin, pumpState); // Turn the pump on or off based on button state
  }
}
BLYNK_WRITE(V6) { // This function is called when the mode button state changes
  pumpMode = param.asInt(); // Read the state of the mode button (0 for automatic, 1 for manual)
}
BLYNK_WRITE(V8) {
  int value = param.asInt();
  if (value == 1) {
    // Turn on the LED strip and start the animation
    ledStripOn = true;
  } else {
    // Turn off the LED strip
    ledStripOn = false;
    // You can also add code to clear the LED strip here if needed
  }
}

// Fill the x/y array of 8-bit noise values using the inoise8 function.
void fillnoise8() {
  // If we're runing at a low "speed", some 8-bit artifacts become visible
  // from frame-to-frame.  In order to reduce this, we can do some fast data-smoothing.
  // The amount of data smoothing we're doing depends on "speed".
  uint8_t dataSmoothing = 0;
  if( speed < 50) {
    dataSmoothing = 200 - (speed * 4);
  }
  
  for(int i = 0; i < MAX_DIMENSION; i++) {
    int ioffset = scale * i;
    for(int j = 0; j < MAX_DIMENSION; j++) {
      int joffset = scale * j;
      
      uint8_t data = inoise8(x + ioffset,y + joffset,z);
      // The range of the inoise8 function is roughly 16-238.
      // These two operations expand those values out to roughly 0..255
      // You can comment them out if you want the raw noise data.
      data = qsub8(data,16);
      data = qadd8(data,scale8(data,39));
      if( dataSmoothing ) {
        uint8_t olddata = noise[i][j];
        uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing);
        data = newdata;
      }
      
      noise[i][j] = data;
    }
  }
  
  z += speed;
  
  // apply slow drift to X and Y, just for visual variation.
  x += speed / 8;
  y -= speed / 16;
}
void mapNoiseToLEDsUsingPalette()
{
  static uint8_t ihue=0;
  
  for(int i = 0; i < kMatrixWidth; i++) {
    for(int j = 0; j < kMatrixHeight; j++) {
      // We use the value at the (i,j) coordinate in the noise
      // array for our brightness, and the flipped value from (j,i)
      // for our pixel's index into the color palette.
      uint8_t index = noise[j][i];
      uint8_t bri =   noise[i][j];
      // if this palette is a 'loop', add a slowly-changing base value
      if( colorLoop) { 
        index += ihue;
      }
      // brighten up, as the color palette itself often contains the 
      // light/dark dynamic range desired
      if( bri > 127 ) {
        bri = 255;
      } else {
        bri = dim8_raw( bri * 2);
      }
      CRGB color = ColorFromPalette( currentPalette, index, bri);
      leds[XY(i,j)] = color;
    }
  }
  
  ihue+=1;
}
void loop() {
  Blynk.run();
  timer.run();
 
  updateLEDStrip();
  unsigned long currentMillis = millis();
  
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    // Read soil moisture or water level based on the flag
    if (pumpMode == 0) {
      int soilSensorValue = analogRead(soilMoisturePin);
      Serial.println(soilSensorValue);
      mappedSoilMoisture = map(soilSensorValue, 1023, 2750, 100, 0); // Update mappedSoilMoisture
      autoControlPump(mappedSoilMoisture); // Automatically control the pump based on soil moisture if in automatic mode
    }
    
    // Read water level
    waterLevel = analogRead(waterLevelPin);
    Serial.println(waterLevel);
    if (waterLevel < 450) {
      waterLevel = 0; // Set water level to 0 if below a threshold
    } else {
      waterLevel = map(waterLevel, 1200, 1600, 0, 100); // Map water level to 0-100
    }
    
    // Control LED
    controlLED(mappedSoilMoisture);
    // Read and send sensor data
    readAndSendSensorData();
    Blynk.virtualWrite(V7, waterLevel); // Send water level to Blynk
  }
}
void autoControlPump(float mappedSoilMoisture) {
  if (waterLevel < 30 || waterLevel < 20) {
    // Water level is too low, do not turn on the pump
    pumpState = LOW;
    digitalWrite(ledPin, LOW);
    Blynk.virtualWrite(V2, HIGH);
    Blynk.setProperty(V2, "color", "#D3435C");
    
  } else if (mappedSoilMoisture <= SOIL_MOISTURE_LOW) {
    // If soil moisture is below the threshold and water level is okay, turn the pump ON
    pumpState = HIGH;
  } else if (mappedSoilMoisture >= SOIL_MOISTURE_HIGH) {
    // If soil moisture is above the threshold, turn the pump OFF
    pumpState = LOW;
  }
  digitalWrite(pumpPin, pumpState); // Update the pump state
  if (pumpMode == 0) {
    Blynk.virtualWrite(V5, pumpState); // Update the pump button status on Blynk
  }
}
void controlLED(float mappedSoilMoisture) {
  if (mappedSoilMoisture <= SOIL_MOISTURE_LOW) {
    digitalWrite(ledPin, HIGH);
    Blynk.virtualWrite(V2, HIGH);
    Blynk.setProperty(V2, "color", "#00FF00");
    Blynk.virtualWrite(V3, "LED ON");
    Blynk.setProperty(V3, "color", "#00FF00");
  } else if (mappedSoilMoisture >= SOIL_MOISTURE_HIGH) {
    digitalWrite(ledPin, LOW);
    Blynk.virtualWrite(V2, HIGH);
    Blynk.setProperty(V2, "color", "#D3435C");
    Blynk.virtualWrite(V3, "LED OFF");
    Blynk.setProperty(V3, "color", "#D3435C");
  }
}
void readAndSendSensorData() {
  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();
  if (!isnan(humidity) && !isnan(temperature)) {
    Blynk.virtualWrite(V0, temperature);
    Blynk.virtualWrite(V1, humidity);
    Serial.println(temperature);
    Serial.println(humidity);
  } else {
    Serial.println(F("Failed to read from DHT sensor!"));
  }
  if (pumpMode == 0) {
    Blynk.virtualWrite(V4, mappedSoilMoisture); // Update mappedSoilMoisture on Blynk
  }
}
void updateLEDStrip() {
  if (ledStripOn) {
    // Your LED strip animation code here
    // This code will run when the LED strip is turned on
    // Make sure to update the leds array
    // For example, mapNoiseToLEDsUsingPalette();
    ChangePaletteAndSettingsPeriodically();
    fillnoise8(); // Call the noise generation function
    mapNoiseToLEDsUsingPalette(); // Map the noise data to LEDs
    LEDS.show(); // Show the LEDs
    // You may need to adjust the animation speed based on your preference
    delay(10); // Delay between frames (adjust as needed)
  } else {
    // Turn off the LED strip
    // You can also add code to clear the LED strip here if needed
    fill_solid(leds, NUM_LEDS, CRGB::Black);
    LEDS.show();
  }
}
// There are several different palettes of colors demonstrated here.
//
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
//
// Additionally, you can manually define your own color palettes, or you can write
// code that creates color palettes on the fly.
// 1 = 5 sec per palette
// 2 = 10 sec per palette
// etc
#define HOLD_PALETTES_X_TIMES_AS_LONG 1
void ChangePaletteAndSettingsPeriodically()
{
  uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60;
  static uint8_t lastSecond = 99;
  
  if( lastSecond != secondHand) {
    lastSecond = secondHand;
    if( secondHand ==  0)  { currentPalette = RainbowColors_p;         speed = 20; scale = 30; colorLoop = 1; }
    if( secondHand ==  5)  { SetupPurpleAndGreenPalette();             speed = 10; scale = 50; colorLoop = 1; }
    if( secondHand == 10)  { SetupBlackAndWhiteStripedPalette();       speed = 20; scale = 30; colorLoop = 1; }
    if( secondHand == 15)  { currentPalette = ForestColors_p;          speed =  8; scale =120; colorLoop = 0; }
    if( secondHand == 20)  { currentPalette = CloudColors_p;           speed =  4; scale = 30; colorLoop = 0; }
    if( secondHand == 25)  { currentPalette = LavaColors_p;            speed =  8; scale = 50; colorLoop = 0; }
    if( secondHand == 30)  { currentPalette = OceanColors_p;           speed = 20; scale = 90; colorLoop = 0; }
    if( secondHand == 35)  { currentPalette = PartyColors_p;           speed = 20; scale = 30; colorLoop = 1; }
    if( secondHand == 40)  { SetupRandomPalette();                     speed = 20; scale = 20; colorLoop = 1; }
    if( secondHand == 45)  { SetupRandomPalette();                     speed = 50; scale = 50; colorLoop = 1; }
    if( secondHand == 50)  { SetupRandomPalette();                     speed = 90; scale = 90; colorLoop = 1; }
    if( secondHand == 55)  { currentPalette = RainbowStripeColors_p;   speed = 30; scale = 20; colorLoop = 1; }
  }
}
// This function generates a random palette that's a gradient
// between four different colors.  The first is a dim hue, the second is 
// a bright hue, the third is a bright pastel, and the last is 
// another bright hue.  This gives some visual bright/dark variation
// which is more interesting than just a gradient of different hues.
void SetupRandomPalette()
{
  currentPalette = CRGBPalette16( 
                      CHSV( random8(), 255, 32), 
                      CHSV( random8(), 255, 255), 
                      CHSV( random8(), 128, 255), 
                      CHSV( random8(), 255, 255)); 
}
// This function sets up a palette of black and white stripes,
// using code.  Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.
void SetupBlackAndWhiteStripedPalette()
{
  // 'black out' all 16 palette entries...
  fill_solid( currentPalette, 16, CRGB::Black);
  // and set every fourth one to white.
  currentPalette[0] = CRGB::White;
  currentPalette[4] = CRGB::White;
  currentPalette[8] = CRGB::White;
  currentPalette[12] = CRGB::White;
}
// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
  CRGB purple = CHSV( HUE_PURPLE, 255, 255);
  CRGB green  = CHSV( HUE_GREEN, 255, 255);
  CRGB black  = CRGB::Black;
  
  currentPalette = CRGBPalette16( 
    green,  green,  black,  black,
    purple, purple, black,  black,
    green,  green,  black,  black,
    purple, purple, black,  black );
}

//
// Mark's xy coordinate mapping code.  See the XYMatrix for more information on it.
//
uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }
  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  return i;
}
 

Retrouvez l’histoire de Raspberry Pi dans cette vidéo :

YouTube video

  • SUNFOUNDER GalaxyRVR Mars Rover Kit Robot vidéo Intelligent Compatible avec Arduino UNO R3 avec ESP32 Cam pour visuels FPV en Temps réel, Carte R3 et Piles Rechargeables incluses
  • Arduino Nesso N1 [TPX00227] - (M5Stack) Kit IoT ESP32-C6 tout-en-un Wi-Fi 6, Bluetooth 5.0, Thread, LoRaWAN, IMU, IR, écran tactile de 1,14"", Grove/QWIIC