умная теплица (или как оптимизировать скетч?) нужна помощь

Nec132113
Offline
Зарегистрирован: 17.11.2014

Добрый день коллеги?

Помогите начинающему программисту

Задумал я сотворить проект умная теплица. Проект был начат на mege 2560, индикаторе (pg 24018 на контроллере T6963c) за основу я взял проект часов  https://code.google.com/p/arduino-t6963c/ , далее были установлены дачики, и установлен исполнительный механизм (силовая часть реле для управлением насоса pin 12). Все быхорошо, но при выполнении работ я перенёс проект на uno так-как не решил, что нецелесеобразно использовать такие ресурсы mega. Далее начались выкрутасы на uno часы не стали тянуть секунды начали перескакивать (1, 3, 4, 5, 7), но часы шли правильно, принял решение не много разгрузить uno убрал аналоговые часы, но проблему это не решило, далее я убрал секунды из часов, и вроде бы всё ок, но ....... После написания управляющей части для насоса я столкнулся с проблемой, что пока идет "полив" ни измерения датчиков ни часы не работают(просто висит до окончания выполнения процедуры). Один умный человек мне сказал что это переполнение стека, что возможно необходимо переименовать некоторые переменные (float, int на byte), но результата это не дало. Я пришул к такому мнению, что необходимо распароллелить процессы, но как это сделать не хватает знаний. 

Спасибо за понимание и сильно не ругайте я только учусь.

#include "T6963.h"  // библиотека индикатора
#include <Wire.h>          // I2C Bus Library DS1307,DS3231
#include <DS1307.h>
#include <OneWire.h>       // One Wire Library DS1820 Temp Sensor
#include <DallasTemperature.h>
#include "Harddisc__30.h" //Digital Clock Font
#include "GLCD_Clock.h"   //Analog Clock Picture
#include <BMP085.h>
#include "Arial_Unicode_MS__6_angl1.h"
#include "DHT.h"

#define DHTPIN 10     // what pin we're connected to

#define DHTTYPE DHT11   // DHT 11 
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

int button = 12; // для кнопки
int pin = 13; // для кнопки

T6963 LCD(240,128,6,32);// 240x64 Pixel and 6x8 Font

BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0;

// Data wire DS1820 one Wire is plugged into port 11 on the Arduino
#define ONE_WIRE_BUS 11

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
char tVal[6];

// Clock init. 
char strclock[26];
char* Month[] = { 0, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };// Monat
int sec, pcount, state=0, HR_circle, MIN_circle, SEC_circle;
String inByte;

// Set Realtime Clock with buildin Serial Monitor
void setclock()
     {
     RTC.stop(); // start set clock 
     inByte="";
     
     while (Serial.available()) { 
	  delay(10); 
      if ( Serial.available()>0)
         {
         char c = Serial.read();
         inByte += c;
         }} 
            
    if (inByte.length() >0) {
          
      char this_char[inByte.length() + 1]; // convert String to int
      inByte.toCharArray(this_char, sizeof(this_char));
      int num = atoi(this_char);          // End convert String to int
      
      switch (state) {
    case 1:
      RTC.set(DS1307_SEC,num);        //set the seconds 0-59
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the minutes 0-59 : ");
      state=2;
      break;
    case 2:
      RTC.set(DS1307_MIN,num);     //set the minutes 0-59
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the hours 1-23 : ");
      state=3;
      break;
    case 3:
      RTC.set(DS1307_HR,num);       //set the hours 1-23 
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the day of the week 1-7 Sunday-Saturday : ");
      state=4;
      break;
    case 4:
      RTC.set(DS1307_DOW,num);       //set the day of the week 1-7 Sunday-Saturday
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the date 1-28/29/30/31 : ");
      state=5;
      break;
    case 5:
      RTC.set(DS1307_DATE,num);       //set the date 1-28/29/30/31
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the month 1-12 : ");
      state=6;
      break;
    case 6:
      RTC.set(DS1307_MTH,num);        //set the month 1-12
      Serial.println(num); //
      clock_main();
      Serial.print("Please set the year 0-99 : ");
      state=7;
      break;
    case 7:
      RTC.set(DS1307_YR,num);         //set the year 0-99
      Serial.println(num); //
      clock_main();
      Serial.print("all done.");
      RTC.start(); //end set clock
      state=0;
      break;
          
    default: ;
      // if nothing else matches, do the default
      // default is optional
  }
 }
}
// Dayweek line
void dayofweek(int x, int y) //Day of the Week x,y
      {
      int offset=3;    //Offset Position Cursor
      LCD.TextGoTo(x,y);
      LCD.writeString("Su Mo Tu We Th Fr Sa");
      int dow=(RTC.get(DS1307_DOW,true)-1)*offset;
      LCD.drawrectbyte((x+dow)*LCD.getFw(),y,8,2,0b111111); // draw dayweek Cursor
      }
      // Digital Clock
void digital_clock(int x, int y, int TimeZone) //Position x, Position y, Set TimeZone
      {
      sprintf(strclock, "%2.2d:%2.2d", RTC.get(DS1307_HR,false)+TimeZone, RTC.get(DS1307_MIN,false), RTC.get(DS1307_SEC,false)); //Anzeigeformat Uhrzeit
      LCD.glcd_print2_P( x-80, y-8, (strclock), &Harddisc__30,0);
      }
//  Day Month Year line     
void daymonthyear(int x, int y) //Day Month Year x,y
      {
      int size = 0 ;  
      sprintf(strclock, "%2.2d.%s.%4.4d", RTC.get(DS1307_DATE,false), Month[RTC.get(DS1307_MTH,false)],RTC.get(DS1307_YR,false)); //Anzeigeformat Monat und Datum
      size = strlen(strclock);
      LCD.TextGoTo(2,0);
      LCD.writeString(strclock);
      } 
void clock_main()// full screen clock main
      {
      dayofweek(20,0); // Position x,y
      digital_clock(90,12,0); // Position x,y,TimeZone
      daymonthyear(40, 7);  // Position x,y
      
       if (state >0) // jump to setclock if state >0
          {
          setclock();
          }    
}

void setup() {
 Serial.begin(9600);
 // Set RTC Instruction
 Serial.println("'s' Set Clock Time and Date"); // so I can keep track of what is loaded
 Serial.println("");
 Serial.println("set the seconds 0-59");
 Serial.println("set the minutes 0-59");
 Serial.println("set the hours 1-23");
 Serial.println("set the day of the week 1-7 Sunday-Saturday");
 Serial.println("set the date 1-28/29/30/31");
 Serial.println("set the month 1-12");
 Serial.println("set the year 0-99");
 
pinMode(pin, OUTPUT); // pin для управления насосом
pinMode(button, INPUT); // pin для кнопки

   Wire.begin();
   dps.init();   
 sensors.begin();

  LCD.Initialize();
  LCD.setMode('x','I'); //Mode Set for Reverse Text T6963
//  LCD.drawPic( 0, 0, GLCD_Clockbmp ,GLCD_ClockHEIGHT, GLCD_ClockBYTEWIDTH ); // draw Clock Wallpaper

}
void loop(){ 
  // draw Temp line
      LCD.glcd_print2_P(0, 72, "Temperatura v bane   :", &Arial_Unicode_MS__6_angl1, 0);
      sensors.requestTemperatures();
      int temp2C = sensors.getTempCByIndex(0);
      dtostrf(temp2C,4,2,tVal);    // convert temperature value to xx.xx output format                    
      LCD.glcd_print2_P(138 , 72, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(166 , 72, "°S", &Arial_Unicode_MS__6_angl1, 0);
    
      dps.getTemperature(&Temperature); 
      dps.getPressure(&Pressure);

      
      LCD.glcd_print2_P(0, 62, "Temperatura na ulice :", &Arial_Unicode_MS__6_angl1, 0);
      int Temper = Temperature/10.00;
      dtostrf(Temper,4,2,tVal); 
      LCD.glcd_print2_P(138, 62, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(166, 62, "°S", &Arial_Unicode_MS__6_angl1, 0);
      
      LCD.glcd_print2_P(0, 112, "Atmosf", &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(37, 112, "ernoe", &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(0, 120, "davlenie       :", &Arial_Unicode_MS__6_angl1, 0);
      int Press = Pressure/133.3;
      dtostrf(Press,4,2,tVal);
      LCD.glcd_print2_P(92, 120, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(133, 120, "mm rt.st.", &Arial_Unicode_MS__6_angl1, 0);
      
      LCD.glcd_print2_P(0 , 92, "Vlajnost* v teplice  :", &Arial_Unicode_MS__6_angl1, 0);
      int h = dht.readHumidity();
      dtostrf(h,4,2,tVal); 
      LCD.glcd_print2_P(138, 92, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(175 , 92, "%", &Arial_Unicode_MS__6_angl1, 0);
      
      LCD.glcd_print2_P(0 , 82, "Temperatura v teplice:", &Arial_Unicode_MS__6_angl1, 0);
      int t = dht.readTemperature();
      dtostrf(t,4,2,tVal); 
      LCD.glcd_print2_P(138, 82, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(166 , 82, "°S", &Arial_Unicode_MS__6_angl1, 0);
      
      LCD.glcd_print2_P(0, 102, "Vlajnost* po&vy      :", &Arial_Unicode_MS__6_angl1, 0);
      int sensorValue = (((analogRead(A6))-1023)*-0.160514);
      dtostrf(sensorValue,4,2,tVal); 
      LCD.glcd_print2_P(138, 102, tVal, &Arial_Unicode_MS__6_angl1, 0);
      LCD.glcd_print2_P(175, 102, "%", &Arial_Unicode_MS__6_angl1, 0);
      
     
      int vremh = RTC.get(DS1307_HR,false);
      int vremm = RTC.get(DS1307_MIN,false);
      
     if (sensorValue<=40 | digitalRead(button) == HIGH | vremh == 18 & vremm == 1)                  // управление насосом для полива по влажности почвы, времени, по нажатию кнопки  
       { 
        if (sensorValue<=40)
         {digitalWrite(pin, HIGH);
         LCD.glcd_print2_P(0, 42, "Po&va suha( proizvodits( ", &Arial_Unicode_MS__6_angl1, 1); 
         LCD.glcd_print2_P(0, 52, "avtomati&eskiq poliv" , &Arial_Unicode_MS__6_angl1, 1);  
         delay (600000);
         digitalWrite(pin, LOW); 
         LCD.glcd_print2_P(0, 42, "                                        ", &Arial_Unicode_MS__6_angl1, 1); 
         LCD.glcd_print2_P(0, 52, "                                      " , &Arial_Unicode_MS__6_angl1, 1);}
         
          else 
           if (digitalRead(button) == HIGH)
            {digitalWrite(pin, HIGH);
           LCD.glcd_print2_P(0, 42, "Nasos vklu&en prinuditel*no", &Arial_Unicode_MS__6_angl1, 1);
           delay (600000);
           digitalWrite(pin, LOW);
           LCD.glcd_print2_P(0, 42, "                                     ", &Arial_Unicode_MS__6_angl1, 1); }
           
            else
              if (vremh == 18 & vremm <=1 & sensorValue <=60)
               {digitalWrite(pin, HIGH);
               LCD.glcd_print2_P(0, 42, "Proizvodits( poliv po vremeni", &Arial_Unicode_MS__6_angl1, 1);
               delay (600000);
               digitalWrite(pin, LOW);
               LCD.glcd_print2_P(0, 42, "                                   ", &Arial_Unicode_MS__6_angl1, 1); }  
               
             else
              {digitalWrite(pin, LOW);
               LCD.glcd_print2_P(0, 42, "Vlajnost* po&vy normal*na(           ", &Arial_Unicode_MS__6_angl1, 0);}
          
          }
  
      
  if (state >0)
     {
      setclock();
     }    
     else if( sec != RTC.get(DS1307_SEC,true))// Draw Clock 
            {
            if (Serial.available() >0)
               {
               char inChar = Serial.read();
               Serial.println(inChar); //
               if (inChar == 's') // s start set clock
                  {
                  Serial.print("Please set the seconds 0-59 : ");
                  state=1;
                  }
              }  
           clock_main();
           }
       
   sec = RTC.get(DS1307_SEC,true); 
   // End draw Clock     
     
  
}

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

гыыы переполнение стека на 10 минут? пните своего знакомого под зад... там где то есть тема как мигать светодиодами без делей

delay (600000);

bwn
Offline
Зарегистрирован: 25.08.2014

Хосподи, это что же можно из термометра с реле сотворить(((. Сердцем чуял, что в тепличке без графического дисплея, ну просто никуда.

Поменьше наворотов, побольше автоматики.

Nec132113
Offline
Зарегистрирован: 17.11.2014

Коллеги спасибо, но вот оставшийся вопрос, почему секунды в часах не поспевают за real time? ведь в проекте имело место быть аналоговым часам и секундам, может uno не фирменное китайское хотя amtel не обманешь

И вопрос как можно в проекте (Поменьше наворотов, побольше автоматики.

bwn
Offline
Зарегистрирован: 25.08.2014

Да не успевает оно отрисовывать. Поставьте обычный 1602 за 100рублей, а добавьте влажность, открытие форточек и что фантазия навеет. То, что имеется сейчас, чудесно обслужит механический таймер с розеткой.

Nec132113
Offline
Зарегистрирован: 17.11.2014

Коллеги чё то я не пойму у меня не получается запуск полива, что я не так сделал, в предыдущем скетче хотя бы выполнение с задержкой было а сейчас тихо, инфрмация на дисплей не выводится покажите пример хотябы на одном датчике.

Спасибо. 

const int ledPin =  13;      // номер выхода, подключенного к насосу

int ledState = LOW;       // этой переменной устанавливаем состояние pin13
      
long previousMillis = 0;  

long interval = 600000;  

void setup()

            { pinMode(ledPin, OUTPUT);} // выход для насоса 

void loop()
      { unsigned long currentMillis = millis(); 

       if (sensorValue<=40) 

         {LCD.glcd_print2_P(0, 42, "Po&va suha( proizvodits( ", &Arial_Unicode_MS__6_angl1, 1); 
          LCD.glcd_print2_P(0, 52, "avtomati&eskiq poliv" , &Arial_Unicode_MS__6_angl1, 1); 

              if(currentMillis - previousMillis > interval) // сохраняем время последнего переключения

                { previousMillis = currentMillis; // если светодиод не горит, то зажигаем, и наоборот
                      if (ledState == LOW) 
                       ledState = HIGH; 
              else
                 ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод

               digitalWrite(ledPin, ledState);}

 LCD.glcd_print2_P(0, 42, " ", &Arial_Unicode MS__6_angl1, 1); 
LCD.glcd_print2_P(0, 52, " " , &Arial_Unicode_MS__6_angl1, 1);
} }
bwn
Offline
Зарегистрирован: 25.08.2014

А он вообще компилируется? Например, чему равен interval ? И как вы умудряетесь работать не инициировав переменные?

Nec132113
Offline
Зарегистрирован: 17.11.2014

Я очень извиняюсь, но пока переносил из id ардуино выскочили где то. Поправил смотрите выше

bwn
Offline
Зарегистрирован: 25.08.2014

У вас много вложенных if-ов и непонятного дисплея. Закомментируйте для начала все что не относится к реле (светику) и добейтесь его четкого срабатывания, скажем раз в пять секунд. Потом введите в игру ваш сенсор и посмотрите с ним. Контрольные значения мониторьте пока через Serial. Когда нормально заработает логика управления начинайте вводить свой дисплей.
Рубите задачу на маленькие части, а потом постепенно усложняйте.