Sari la conținut
ELFORUM - Forumul electronistilor

Automatizare udare flori cu arduino si o electrovalva de 12V


Postări Recomandate

Salut, eu sunt o persoana care se poate deplasa, numai, intr-un scaun cu rotile. Imi plac foarte mult florile, pe care vara le mut in curte. Sunt in jur de 40 ghivece. Am cumparat un sistem de udare, pe care vreau sa il automatizez, prin inserierea unei electrovalve, pe coloana de alimentare cu apa a sistemului.Vreau sa comand aceasta electrovalva, cu ajutorul unui sistem de comanda, format din: arduino nano, display I2C 1602 si un encoder. Un prieten s-a oferit sa imi scrie codul pentru arduino, insa in ciuda numeroaselo variante de cod, ceva nu functioneaza bine. Eu vreau sa pot, seta o ora de pornire a electrovalvei, si ora de oprire a electrovalvei, cu ajutorul encoderului. Daca cineva poate scrie codul contra unei sume de bani, rezonabile, va rog sa ma ajutati.

In continuare gasiti ultimul cod incarcat in arduino care afisa pe display  urmatoarele:

Setare ora udare:
Pornire: 00:00
Oprire: 00:00
Pompa pornita

Insa nu pot sa setez nimic din encoder.

 

Codul este acesta:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RotaryEncoder.h>
#include <TimeLib.h>

// Pinii pentru pompă și encoder
const int pompaPin = 3;
const int encoderPin1 = 2;
const int encoderPin2 = 4;
const int encoderButtonPin = 5;

// Declarații pentru LCD și encoder
LiquidCrystal_I2C lcd(0x27, 20, 4);
RotaryEncoder encoder(encoderPin1, encoderPin2);
int lastButtonState = HIGH;
int buttonState;

// Variabile pentru setarea orelor de pornire și oprire
int oraPornire = 0;
int oraOprire = 0;
bool setareOraPornire = false;
bool setareOraOprire = false;

void setup() {
  // Inițializarea LCD
  lcd.init();
  lcd.backlight();
  lcd.print("Setare ora udare:");
  lcd.setCursor(0, 1);
  lcd.print("Pornire: 00:00");
  lcd.setCursor(0, 2);
  lcd.print("Oprire: 00:00");

  // Inițializarea encoderului
  encoder.setPosition(0);
  attachInterrupt(digitalPinToInterrupt(encoderPin1), encoderISR, CHANGE);

  // Inițializarea pinului pentru pompă
  pinMode(pompaPin, OUTPUT);
  digitalWrite(pompaPin, LOW);

  // Inițializarea pinului pentru butonul encoderului
  pinMode(encoderButtonPin, INPUT_PULLUP);
}

void loop() {
  // Citește poziția encoderului
  int encoderPosition = encoder.getPosition();

  // Verifică dacă s-a rotit în sensul orar
  if (encoderPosition > 0) {
    if (setareOraPornire) {
      // Incrementăm ora de pornire
      oraPornire++;
      if (oraPornire > 23) {
        oraPornire = 0;
      }
      afisareOraPornire();
    } else if (setareOraOprire) {
      // Incrementăm ora de oprire
      oraOprire++;
      if (oraOprire > 23) {
        oraOprire = 0;
      }
      afisareOraOprire();
    }
  }
  // Verifică dacă s-a rotit în sensul antiorar
  else if (encoderPosition < 0) {
    if (setareOraPornire) {
      // Decrementăm ora de pornire
      oraPornire--;
      if (oraPornire < 0) {
        oraPornire = 23;
      }
      afisareOraPornire();
    } else if (setareOraOprire) {
      // Decrementăm ora de oprire
      oraOprire--;
      if (oraOprire < 0) {
        oraOprire = 23;
      }
      afisareOraOprire();
    }
  }

  // Citește starea butonului encoderului
  buttonState = digitalRead(encoderButtonPin);

  // Verifică schimbarea stării butonului
  if (buttonState != lastButtonState) {
    if (buttonState == LOW) {
      // Butonul a fost apăsat
      if (setareOraPornire) {
        // Încetăm setarea orei de pornire și începem setarea orei de oprire
        setareOraPornire = false;
        setareOraOprire = true;
        lcd.setCursor(0, 2);
        lcd.blink();
      } else if (setareOraOprire) {
        // Terminăm setarea orei de oprire și revenim la afișarea orelor
        setareOraOprire = false;
        lcd.setCursor(0, 2);
        lcd.noBlink();
      } else {
        // Începem setarea orei de pornire
        setareOraPornire = true;
        lcd.setCursor(0, 1);
        lcd.blink();
      }
    }
  }

  // Actualizăm ultima stare a butonului
  lastButtonState = buttonState;

  // Verificăm dacă este momentul de pornire/oprire a pompei
  int oraCurenta = hour();
  if (oraCurenta == oraPornire) {
    pornestePompa();
  } else if (oraCurenta == oraOprire) {
    oprestePompa();
  }
}

void encoderISR() {
  // Funcție golă pentru întreruperea encoderului
}

void afisareOraPornire() {
  lcd.setCursor(9, 1);
  if (oraPornire < 10) {
    lcd.print("0");
  }
  lcd.print(oraPornire);
  lcd.print(":00");
}

void afisareOraOprire() {
  lcd.setCursor(9, 2);
  if (oraOprire < 10) {
    lcd.print("0");
  }
  lcd.print(oraOprire);
  lcd.print(":00");
}

void pornestePompa() {
  digitalWrite(pompaPin, HIGH);
  lcd.setCursor(0, 3);
  lcd.print("Pompa pornita    ");
}

void oprestePompa() {
  digitalWrite(pompaPin, LOW);
  lcd.setCursor(0, 3);
  lcd.print("Pompa oprita     ");
}

 

Editat de gpmarian2005
Adaugare lamuriri suplimentare
Link spre comentariu
  • Răspunsuri 10
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Ai încercat să pui codul respectiv pe Chat GPT și să-i ceri ,,AI,, să-l îmbunătățească/corecteze ?

Am înțeles că A.I. poate scrie și coduri relativ simple....și o face gratis.Nu neapărat mai bine ca un programator uman, dar mai repede și asta poate fi un avantaj uneori...

Link spre comentariu

Am o problema asemanatoare cu florile deoarece mai plecam din localitate.

Sistemul de udare l-am luat de la Lidl, cel cu duze la bucata si furtun de 6mm, am pus o pompa de apa murdara deoarece nu face presiune intr-un butoi de 150l in balcon si o alimentam printr-o priza programabila, 30-40 lei Leroy.

Am program pe 7 zile si e perfect pentru ce vreau, simplu si eficient.

De ce butoi si nu cu valva legata la apa curenta? la fel de simplu, de Doamne fereste, o ia ceva razna si curge, curge pina ajung acasa, asa am doar 150l de curs doar in balcon deoarece am scurgere.

Link spre comentariu

Nu trebuie platit nimic pentru ChatGPT, ia uite ce a generat la rugamintea asta:

 

"I want an arduino code which to use an  I2C 1602 LCD display and a rotary encoder, the code should let me set the current time in hour and minute format and then an interval consisting by a start time and end time. Then between the two interval have an output switch on. Basically a simple programmable timer."

 

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define LCD module settings
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Define pins for the rotary encoder
const int encoderPinA = 2;
const int encoderPinB = 3;
const int buttonPin = 4;

// Define variables for time and interval
int currentHour = 0;
int currentMinute = 0;
int startHour = 0;
int startMinute = 0;
int endHour = 0;
int endMinute = 0;
bool timerActive = false;

// Define variables for rotary encoder
int lastEncoderState = 0;
int encoderState = 0;
int encoderPinALastState = HIGH;
int encoderValue = 0;
bool encoderButtonPressed = false;

void setup() {
  // Initialize LCD display
  lcd.begin(16, 2);
  lcd.print("Time: 00:00");

  // Set up rotary encoder pins
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);

  // Attach interrupt to encoder pin A
  attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE);
}

void loop() {
  // Check if the encoder button is pressed
  if (digitalRead(buttonPin) == LOW) {
    encoderButtonPressed = true;
    delay(100);  // Debounce delay
  }

  // Check if the timer is active
  if (timerActive) {
    // Get the current time
    int currentTime = getCurrentTime();

    // Check if the current time is within the interval
    if (isTimeInRange(currentTime, startHour, startMinute, endHour, endMinute)) {
      // Turn on the output switch
      digitalWrite(outputPin, HIGH);
    } else {
      // Turn off the output switch
      digitalWrite(outputPin, LOW);
    }
  }

  // Update the LCD display
  updateLCD();

  // Reset encoder button state
  encoderButtonPressed = false;
}

void updateEncoder() {
  // Read the current state of encoder pins
  encoderState = digitalRead(encoderPinA);

  // Check if the state of pin A has changed
  if (encoderState != lastEncoderState) {
    // Check if pin A is low and pin B is high
    if (encoderState == LOW && digitalRead(encoderPinB) == HIGH) {
      encoderValue++;
    }

    // Check if pin A is low and pin B is low
    if (encoderState == LOW && digitalRead(encoderPinB) == LOW) {
      encoderValue--;
    }
  }

  // Store the current state for comparison in the next iteration
  lastEncoderState = encoderState;

  // Check if the encoder button is pressed
  if (encoderButtonPressed) {
    // Set the current time
    if (encoderValue == 0) {
      currentHour++;
      if (currentHour > 23) {
        currentHour = 0;
      }
    } else if (encoderValue == 1) {
      currentMinute++;
      if (currentMinute > 59) {
        currentMinute = 0;
      }
    }
    // Set the start time
    else if (encoderValue == 2) {
      startHour++;
      if (startHour > 23) {
        startHour = 0;
      }
    } else if (encoderValue == 3) {
      startMinute++;
      if (startMinute > 59) {
        startMinute = 0;
      }
    }
    // Set the end time
    else if (encoderValue == 4) {
      endHour++;
      if (endHour > 23) {
        endHour = 0;
      }
    } else if (encoderValue == 5) {
      endMinute++;
      if (endMinute > 59) {
        endMinute = 0;
      }
    }

    // Reset encoder value
    encoderValue = 0;
  }
}

int getCurrentTime() {
  // Get the current time in minutes
  int currentTime = hour() * 60 + minute();
  return currentTime;
}

bool isTimeInRange(int currentTime, int startHour, int startMinute, int endHour, int endMinute) {
  // Convert the start and end times to minutes
  int startTime = startHour * 60 + startMinute;
  int endTime = endHour * 60 + endMinute;

  // Check if the current time is within the interval
  if (startTime <= endTime) {
    if (currentTime >= startTime && currentTime <= endTime) {
      return true;
    }
  } else {
    if (currentTime >= startTime || currentTime <= endTime) {
      return true;
    }
  }

  return false;
}

void updateLCD() {
  // Clear the LCD display
  lcd.clear();

  // Print the current time
  lcd.setCursor(0, 0);
  lcd.print("Time:");
  lcd.setCursor(6, 0);
  printFormattedTime(currentHour, currentMinute);

  // Print the interval start time
  lcd.setCursor(0, 1);
  lcd.print("Start:");
  lcd.setCursor(7, 1);
  printFormattedTime(startHour, startMinute);

  // Print the interval end time
  lcd.setCursor(10, 1);
  lcd.print("End:");
  lcd.setCursor(14, 1);
  printFormattedTime(endHour, endMinute);
}

void printFormattedTime(int hour, int minute) {
  if (hour < 10) {
    lcd.print("0");
  }
  lcd.print(hour);
  lcd.print(":");
  if (minute < 10) {
    lcd.print("0");
  }
  lcd.print(minute);
}

 

Editat de Bandi Szasz
Link spre comentariu

Cam asta este raspunsul lui pentru a scapa de if-else

 

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define LCD module settings
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Define pins for the rotary encoder
const int encoderPinA = 2;
const int encoderPinB = 3;
const int buttonPin = 4;

// Define variables for time and interval
int timeValues[6] = {0};  // [0] -> currentHour, [1] -> currentMinute, [2] -> startHour, [3] -> startMinute, [4] -> endHour, [5] -> endMinute
bool timerActive = false;

// Define variables for rotary encoder
int lastEncoderState = 0;
int encoderState = 0;
int encoderPinALastState = HIGH;
int encoderValue = 0;
bool encoderButtonPressed = false;

// Define the maximum values for each setting
int maxValues[] = {23, 59, 23, 59, 23, 59};

void setup() {
  // Initialize LCD display
  lcd.begin(16, 2);
  lcd.print("Time: 00:00");

  // Set up rotary encoder pins
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);

  // Attach interrupt to encoder pin A
  attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE);
}

void loop() {
  // Check if the encoder button is pressed
  if (digitalRead(buttonPin) == LOW) {
    encoderButtonPressed = true;
    delay(100);  // Debounce delay
  }

  // Check if the timer is active
  if (timerActive) {
    // Get the current time
    int currentTime = getCurrentTime();

    // Check if the current time is within the interval
    if (isTimeInRange(currentTime, timeValues[2], timeValues[3], timeValues[4], timeValues[5])) {
      // Turn on the output switch
      digitalWrite(outputPin, HIGH);
    } else {
      // Turn off the output switch
      digitalWrite(outputPin, LOW);
    }
  }

  // Update the LCD display
  updateLCD();

  // Reset encoder button state
  encoderButtonPressed = false;
}

void updateEncoder() {
  // Read the current state of encoder pins
  encoderState = digitalRead(encoderPinA);

  // Check if the state of pin A has changed
  if (encoderState != lastEncoderState) {
    // Check if pin A is low and pin B is high
    if (encoderState == LOW && digitalRead(encoderPinB) == HIGH) {
      encoderValue++;
    }

    // Check if pin A is low and pin B is low
    if (encoderState == LOW && digitalRead(encoderPinB) == LOW) {
      encoderValue--;
    }
  }

  // Store the current state for comparison in the next iteration
  lastEncoderState = encoderState;

  // Check if the encoder button is pressed
  if (encoderButtonPressed) {
    // Increment the value for the current setting
    timeValues[encoderValue]++;

    // Wrap around if the value exceeds the maximum
    if (timeValues[encoderValue] > maxValues[encoderValue]) {
      timeValues[encoderValue] = 0;
    }

    // Reset encoder value
    encoderValue = 0;
  }
}

int getCurrentTime() {
  // Get the current time in minutes
  int currentTime = hour() * 60 + minute();
  return currentTime;
}

bool isTimeInRange(int currentTime, int startHour, int startMinute, int endHour, int endMinute) {
  // Convert the start and end times to minutes
  int startTime = startHour * 60 + startMinute;
  int endTime = endHour * 60 + endMinute;

  // Check if the current time is within the interval
  if (startTime <= endTime) {
    if (currentTime >= startTime && currentTime <= endTime) {
      return true;
    }
  } else {
    if (currentTime >= startTime || currentTime <= endTime) {
      return true;
    }
  }

  return false;
}

void updateLCD() {
  // Clear the LCD display
  lcd.clear();

  // Print the current time
  lcd.setCursor(0, 0);
  lcd.print("Time:");
  lcd.setCursor(6, 0);
  printFormattedTime(timeValues[0], timeValues[1]);

  // Print the interval start time
  lcd.setCursor(0, 1);
  lcd.print("Start:");
  lcd.setCursor(7, 1);
  printFormattedTime(timeValues[2], timeValues[3]);

  // Print the interval end time
  lcd.setCursor(10, 1);
  lcd.print("End:");
  lcd.setCursor(14, 1);
  printFormattedTime(timeValues[4], timeValues[5]);
}

void printFormattedTime(int hour, int minute) {
  if (hour < 10) {
    lcd.print("0");
  }
  lcd.print(hour);
  lcd.print(":");
  if (minute < 10) {
    lcd.print("0");
  }
  lcd.print(minute);
}

 

Link spre comentariu

Da ai dreptate, m-am uitat mai atent si sunt greseli pe acolo, a vrut sa se foloseasca de "system time" cu hour() si minute() care se foloseste de miilis() dar nu le seteaza cand modifici prin encoder ora si minutul actual. Am incercat sa ii explic si se cam invarte in jurul cozii, corecteaza un lucru si strica altele. Inca sunt safe job-urile IT'ist ilor. 

 

Ca sa facem si ceva practic o sa imi fac eu timp in zilele urmatoare si ii scriu programelul colegului, pro bono desigur

 

Dar @gpmarian2005 la placuta arduino ai cumva si un modul RTC ( real time clock ) ca altfel trebuie sa ne folosim de "millis()" din arduino insa nu este de loc precis si o sa o ia la pas cu cateva secunde bune pe zii daca nu minute ? 

 

Editat de Bandi Szasz
Link spre comentariu

La Lidl exista zilele astea, un computer de irigat, la 149 de lei. Este cea mai rapida si eleganta rezolvare: are electrovalva, se alimenteaza de la baterie, comunica pe bluetooth, etc.

Nu fac reclama, am asa ceva (versiunea veche din 2015) si sunt foarte multumit.

Link spre comentariu

Bună ziua, vă mulțumesc foarte mult pentru ajutor. 

Bandi să ști că am două module RTC, un ds3231 și ds1307, cred. 

 

Marin, cu ceva timp în urma am văzut o reclama, cu ceva asemănător, soția nu a

 găsit. Astăzi o să vadă dacă îl găsește. Eu am "programator", care dă drumul la apă pentru o perioadă de timp, pe care o setezi. Este mecanic, l-am luat de la Lidl.

Aștept ideile voastre. 

Vă mulțumesc!

 

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări