Помогите христа ради с "Автополивщик растений на Arduino"

Тема в разделе "Arduino & Shields", создана пользователем Disastor, 3 апр 2016.

  1. Disastor

    Disastor Нуб

    Я сейчас собираю похожий проект, но с блоком реле и еще небольшими отличиями.
    Мой код до безобразия прос, все построено на if...else.
    Тут же столкнулся с проблемой, при задержки после полива, дисплей обновляется тоже после задержки.
    И решил привести свой код к виду, как у Вас в уроке.
    Но опять столкнулся с проблемой, очень сложно читать некомментированный код, если Вам не сложно добавьте комментарии пожалуйста!
    http://wiki.amperka.ru/projects:irrigator?&#скетч_для_arduino
    Код (C++):
    #include "QuadDisplay.h"
    const int HUMIDY_MIN = 200;
    const int HUMIDY_MAX = 700;
    void setup(void)
    {
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(5, OUTPUT);
      displayInt(3, 0);
    }
    char intDigit(unsigned int val, char pos)
    {
      char buf[6];
      sprintf(buf, "%04u", val);
      return buf[3-pos]-'0';
    }
    unsigned int intDigitSet(unsigned int val, char pos, char d)
    {
      char buf[6];
      sprintf(buf, "%04u", val);
      buf[3-pos] = '0'+d;
      return atoi(buf);
    }
    unsigned int readHumidy(void)
    {
      static unsigned int oldval = 0;
      static unsigned int res = 0;
      static unsigned int stability[4] = { 0, 0, 0, 0 };
      char i;
      unsigned int val = analogRead(A0);
      for(i = 0; i < 4; i++) {
        if(intDigit(oldval, i) != intDigit(val, i)) {
          oldval = intDigitSet(oldval, i, intDigit(val, i));
          stability[i] = 0;
        }
        else {
          if(stability[i] < 10) stability[i]++;
          else res = intDigitSet(res, i, intDigit(val, i));
        }
      }
      return res;
    }
    void loop(void)
    {
      static unsigned long wait = millis() + 60000;
      static unsigned int oldhumidy = 0;
      static unsigned long stability = 0;
      unsigned int humidy = readHumidy();
      if(humidy != oldhumidy) {
        oldhumidy = humidy;
        displayInt(3, humidy);
      }
      if(wait != 0 && wait-millis() > 10) {
        return;
      } else wait = 0;
      if(humidy < HUMIDY_MIN) {
        digitalWrite(2, HIGH);
        analogWrite(5, 50);
        delay(1500);
        digitalWrite(2, LOW);
        digitalWrite(5, LOW);
        wait = millis() + 3*60000;
      }
    }

    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <DS1302.h>
    #include <DHT.h>
    #define DHTPIN 3
    #define DHTTYPE DHT11
    #define RELAY_PIN0 0
    #define RELAY_PIN1 1
    #define RELAY_PIN2 2
    #define RELAY_PIN3 3
    LiquidCrystal_I2C lcd(0x3f, 16, 2);
    int BH1750_address = 0x23;
    byte buff[2];
    DHT dht(DHTPIN, DHTTYPE);
    DS1302 rtc(4, 5, 6);

    byte temp[8] = //Битовая маска иконки термометра
    {
        B00100,
        B01010,
        B01010,
        B01110,
        B01110,
        B11111,
        B11111,
        B01110
    };
    byte hum[8] = //Битовая маска иконки освещенности
    {
        B00100,
        B00100,
        B01010,
        B01010,
        B10001,
        B10001,
        B10001,
        B01110,
    };
    byte illum[8] = //Битовая маска иконки влажности воздуха
    {
        B00100,
        B01110,
        B01110,
        B01110,
        B10101,
        B10101,
        B10001,
        B01110,
    };

    void setup()
    {
      rtc.halt(false);
      rtc.writeProtect(false);
      lcd.begin();              //инициализация дисплея
      lcd.backlight();          //инициализация подсветки
     
      //rtc.setDOW(SATURDAY);       // Настройка дня недели
      //rtc.setTime(9, 21, 00);     // Настройка часов в формате 12:00:00 (24 часа)
      //rtc.setDate(26, 9, 2015);   // Настройка даты в формате 01.01.2000
       
      Serial.begin(9600);
      pinMode( 8 , OUTPUT);
      pinMode( 9 , OUTPUT);
      pinMode( 10 , OUTPUT);
      pinMode( 11 , OUTPUT);
      dht.begin();
      Wire.begin();
      BH1750_Init(BH1750_address);
      lcd.begin();
      lcd.backlight();
      lcd.clear();
      lcd.createChar(1,temp);
      lcd.createChar(2,hum);
      lcd.createChar(3,illum);
    }
    void loop() {
      int h = dht.readHumidity();
      int t = dht.readTemperature();
      float valf = 0;
      float w1 = analogRead(A6);
      float w2 = analogRead(A7);
      float w3 = analogRead(A3);
     
    //выводим на последовательный порт значение освещенности
       Serial.print("Illuminance: "); if(BH1750_Read(BH1750_address)==2){ valf=((buff[0]<<8)|buff[1])/1.2; if(valf<0)Serial.print("> 65535"); else Serial.print((int)valf,DEC); } Serial.println(" Lx");
    //закончили вывод освещенности

    //выводим на последовательный порт значение влажности и температуру воздуха
      Serial.print("Humidity  Sensor: ");   Serial.print(h);  Serial.println(" %");  Serial.print("Temperature  Sensor: ");   Serial.print(t);  Serial.println(" *C");
    //закончили вывод влажности и температуры
     
    //выводим на последовательный порт значение датчиков влажности почвы
      Serial.print("Soil Moisture Sensor#1 Value: ");  Serial.println(w1);  Serial.print("Soil Moisture Sensor#2 Value: ");  Serial.println(w2);  Serial.print("Water level Sensor Value: ");  Serial.println(w3);
    //закончили вывод влажности почвы
     
    //выводим на последовательный порт значение даты и времени
      Serial.print(rtc.getDateStr());  Serial.print(" ");  Serial.print(rtc.getDOWStr());  Serial.print(" ");  Serial.println(rtc.getTimeStr());
    //закончили вывод даты и времени
     
    //выводим на экран данные с датчиков влажности, температуры и освещенности
      lcd.home();
      lcd.write(2);
      lcd.print(h);
      lcd.print("% ");
     
      lcd.setCursor(5, 0);
      lcd.write(1);
      lcd.print(t);
      lcd.print((char)223);
      lcd.print("C ");
     
      lcd.setCursor(11, 0);
      lcd.write(3);
      lcd.print((int)valf,DEC);
      lcd.print("Lx  ");
    //закончили вывод на экран данных влажности, температуры и освещенности
     
    //запрос влажности почвы и вывод результата на экран
        lcd.setCursor(0, 1);
      if((((w1)+(w2))/2) >= (1000))
      {
        lcd.home();
        lcd.setCursor(0, 1);
        lcd.print("Sensor ");
        lcd.print("ERROR     ");
      }
      if((((w1)+(w2))/2) < 1000 && ((((w1)+(w2))/2) >= (600)))
      {
        lcd.home();
        lcd.setCursor(0, 1);
        lcd.print("Sensor is ");
        lcd.print("DRY     ");
      }
      if((((w1)+(w2))/2) < 600 && ((((w1)+(w2))/2) >= (370)))
      {
        lcd.home();
        lcd.setCursor(0, 1);
        lcd.print("Sensor is ");
        lcd.print("HUMID     ");
      }
      if((((w1)+(w2))/2) < (370))
      {
        lcd.home();
        lcd.setCursor(0, 1);
        lcd.print("Sensor in ");
        lcd.print("WATER     ");
      }
    //закончили вывод влажности почвы на экран

    //если датчик воды#3 выводит показания больше "10", включается реле#1 с пином#8
    if ((((w1)+(w2))/2) >= (600))
    {
      digitalWrite( 8 , LOW );
      delay(100);
    }
    else
    {
      digitalWrite( 8 , HIGH );
      delay(100);
    }
    //конец реле#1

    //если датчик освещенности выводит показания меньше "50", включается реле#2 с пином#9
    if ((150)<(valf))
    {
      digitalWrite( 9 , LOW );
      delay(100);
    }
    else
    {
      digitalWrite( 9 , HIGH );
      delay(100);
    }
    //конец реле#2

    //если датчик температуры выводит показани¤ выше "30" градусов, включаетсявключается реле#3 с пином#10
    if ((30)<(t))
    {
      digitalWrite( 10 , LOW );
      delay(100);
    }
    else
    {
      digitalWrite( 10 , HIGH );
      delay(100);
    }
     
    //если датчик температуры выводит показани¤ ниже "20" градусов, включается реле#4 с пином#11
      if ((20)<(t))
    {
      digitalWrite( 11 , LOW );
      delay(100);
    }
    else
      {
      digitalWrite( 11 , HIGH );
      delay(100);
      }
     
    }
    //конец реле#3 и реле#4

    void BH1750_Init(int address){
      Wire.beginTransmission(address);
      Wire.write(0x10); // 1 [lux] aufloesung
      Wire.endTransmission();
    }

    byte BH1750_Read(int address){
      byte i=0;
      Wire.beginTransmission(address);
      Wire.requestFrom(address, 2);
      while(Wire.available()){
        buff[i] = Wire.read();
        i++;
      }
      Wire.endTransmission();
      return i;
    }
     
     
    Последнее редактирование: 3 апр 2016
  2. Disastor

    Disastor Нуб

    Люди добрые, если вам не сложно, добавьте комментарии к коду амперки, это все что мне нужно, дальше я разберусь сам!
     
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    странно, обычно у Амперки весь код с комментариями.

    Код (C++):
    #include "QuadDisplay.h"                  // подключаем библиотеку для дисплея Quad

    const int HUMIDY_MIN = 200;               // граница минимального значения влажности
    const int HUMIDY_MAX = 700;               // граница максимального значения влажности

    void setup(void)
    {
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(5, OUTPUT);
      displayInt(3, 0);
    }

    char intDigit(unsigned int val, char pos) // функция преобразования числа в цифры, входные данные: число, позиция
    {
      char buf[6];
      sprintf(buf, "%04u", val);
      return buf[3-pos]-'0';
    }

    unsigned int intDigitSet(unsigned int val, char pos, char d)
    {
      char buf[6];
      sprintf(buf, "%04u", val);
      buf[3-pos] = '0'+d;
      return atoi(buf);
    }

    unsigned int readHumidy(void)  // функция чтения сенсора влажности
    {
      static unsigned int oldval = 0;
      static unsigned int res = 0;
      static unsigned int stability[4] = { 0, 0, 0, 0 };
      char i;
      unsigned int val = analogRead(A0);
      for(i = 0; i < 4; i++) {
        if(intDigit(oldval, i) != intDigit(val, i)) {
          oldval = intDigitSet(oldval, i, intDigit(val, i));
          stability[i] = 0;
        }
        else {
          if(stability[i] < 10) stability[i]++;
          else res = intDigitSet(res, i, intDigit(val, i));
        }
      }
      return res;
    }


    void loop(void)
    {
      static unsigned long wait = millis() + 60000; //
      static unsigned int oldhumidy = 0;
      static unsigned long stability = 0;
      unsigned int humidy = readHumidy(); // читаем сенсор влажности
      if(humidy != oldhumidy) {           // если отличается от предыдущего измерения
        oldhumidy = humidy;
        displayInt(3, humidy);            // выводим на дисплей новое значение
      }
      if(wait != 0 && wait-millis() > 10) {
        return;
      } else wait = 0;
      if(humidy < HUMIDY_MIN) {     // если влажность ниже минимума
        digitalWrite(2, HIGH);      // включаем (реле?) на 1,5 сек
        analogWrite(5, 50);
        delay(1500);
        digitalWrite(2, LOW);
        digitalWrite(5, LOW);
        wait = millis() + 3*60000;
      }
    }
     
     
    Последнее редактирование: 5 апр 2016
  4. REKTOR

    REKTOR Нуб

    В видео инструкции на этот контакт вешали пищалку, чтобы сигнализировать начало работы насоса.