Доступная автоматика на Ардуино Мега 2560

Форум самогонщиков, пивоваров, виноделов Оборудование Автоматика
1 ... 493 494 495 496 497 498 499 ... 521 496
msg31 Научный сотрудник Барнаул 4159 2017
Отв.9900  24 Июля 18, 08:48
Да добавление подачи уже через 5-10 секунд видно на нижнем датчикеSA1348, 24 Июля 18, 08:45
А какая высота колонны, диаметр и количество тарелок?


Добавлено через 1мин.:

Можешь проверить сам, утеплив датчик и играясь в ручном режиме подачей.SA1348, 24 Июля 18, 08:45
А какая у тебя высота колонны, диаметр и количество тарелок?
SA1348 Профессор Саратов 2501 1008
Отв.9901  24 Июля 18, 08:52, через 4 мин
около 98msg31, 24 Июля 18, 08:39
Засеки значение при подачи чистой воды вместо браги и отталкивайся от него, удерживая температуру в пределах - 0,8°С от температуры при подаче воды.
А какая высота колонны, диаметр и количество тарелок?msg31, 24 Июля 18, 09:48
Вн.Д. 51, 23 тарелки Средняя колонна. Не ХД4 но и до ХД5 далеко.


Добавлено через 19мин.:

конечно, сделаю такую опцию.msg31, 24 Июля 18, 08:45
Но, как я понимаю лишь для коммерческих версий автоматики.
Mim Специалист Ульяновск 185 16
Отв.9902  24 Июля 18, 09:47, через 55 мин
Вн.Д. 51, 23 тарелки Средняя колонна. Не ХД4 но и до ХД5 далекоSA1348, 24 Июля 18, 08:52
хд3 значит))
SA1348 Профессор Саратов 2501 1008
Отв.9903  24 Июля 18, 10:09, через 23 мин
Не СиВ
msg31 Научный сотрудник Барнаул 4159 2017
Отв.9904  24 Июля 18, 10:33, через 24 мин
А высота какая?
SA1348 Профессор Саратов 2501 1008
Отв.9905  24 Июля 18, 10:48, через 16 мин
Честно говоря не помню, только дома вечером смогу посмотреть
titan777 Специалист Москва 147 102
Отв.9906  24 Июля 18, 14:41
я вот еще в марте 2017 алгоритм расписал.
Он у меня и по сей день работает в автомате.
И по нижнему, и по верхнему, и давление , все задействуется.

Открыть алгоритм
Я у себя давно сделал регулировку подачи насоса от Т-верх, Т-низ , и давления.

Сначала смотрю по верхнему датчику Т, если Т ниже нужной(задается в настройках) к примеру ниже 92С, то скорость насоса снижается, пропорционально величине разницы с минимальной заданной Т.

примерно так в коде

int TempDefMin = 920; // заданная пользователем минимальная Т вверху
int SpeedNasosMax = 50; // скорость насоса заданная пользователем в %
int x1, x2;

if TempDef<TempDefMin {
  x1 = TempDefMin-TempDef;
  if x1>20  x1=20 ;
  x2 = map(x1, 0, 20, 100, 30); // константы здесь нужно подбирать
  SpeedNasos = float() (SpeedNasosMax * x2 /100); // здесь возможно с преобразование типов нужно уточнить
  // пример Тдеф 95С = насос 100%
  // Тдеф 92С = 100%
  // Тдеф 91С = 60%
  // Тдеф 90С = 30%
  // Тдеф 89С = 30%
}



Потом проверяю давление, если выше заданного пользователем максимума, то по той-же схеме снижаю подачу.
Потом по нижнему датчику Т проверяю , если Т упала от максимально зафиксированной ранее, снижаю скорость насоса так-же.

И в конце смотрю по какому условию получилась минимальная скорость насоса, ее и использую.

НБК по такому алгоритму работает на 90% в автомате, само скорость то поднимет, то опустит, постепенно устаканивается и так и стоит.
Только вот иногда пена начинает идти, и ее пока не нашел способа отследить, пока нет захлеба, потом уже автоматика вступает.
Посл. ред. 30 Марта 17, 00:23 от titan777

Добавлено через 2мин.:

Открыть код ардуино

void ProcessNBK()  { //112  НБК
float Speed1, Speed2;
float n, n1;
int m;
   TEMP_KUB=3;
   TEMP_TSA=0;
   TEMP_DEFL=2;
   TEMP_RK20=1;
   
  if (flAlarmUroven && StateMachine<100) { // Переводим автомат в стадию завершения
   SecondsEnd=Seconds;
   time2=60;
    StateMachine=100;        
  }
  
  if (flAlarmMPX5010) {
    StateMachine=102; // Переводим в режим тревоги по датчику давления
  }

  switch  (StateMachine) {  //112  НБК
  case 0: // Процесс не запущен
   break;
  case 1: // Начало процесса
   if (BeepStateProcess) beep2();
   if (ds1820_devices>0 && (ds1820_devices!= cntDS18Nbk) ) {  // на НБК 4 датч темп
      StateMachine=106;
      beep5();
      break;
   }
   //MAX_KLP = 1;
   //PIN_KLP_BEG[KLP_SR] = 26; // для насоса спирта 13 // для клапана 26
   //PIN_KLP_BEG[KLP_GLV] = 26; // для насоса голов 12 // для клапана
   
    //PowerState=2;
   //PowerTen=PowerTenNBK;
    maxTempRK20_NbkCnt=0;
   SpeedNBK=0;      
   stopNasosNBK();   //digitalWrite(PIN_STOP_NASOS_NBK, 1);
   startTimer3();   
   SpeedNBK=0;
   //if (BeepStateProcess) beep2();
   PrepareProcess();
    KlOpen[KLP_VODA]=0;
    KlClose[KLP_VODA]=10;
    StateMachine=2;   
    //if (BeepStateProcess) beep2();
  case 2:  //Ожидание закипания (прогреется дефлегматор)
   maxTempRK20_Nbk=0;
   SpeedNBK=0;
    UstPower=PowerTen;
    //if (temps[TEMP_DEFL]<TempDeflBegDistil  && ds1820_devices>1) break;
    if (temps[TEMP_DEFL]<TempDeflBegDistil && plusStateMachine==0) break;
    if (temps[TEMP_KUB]<985) break;
   KlOpen[KLP_VODA]=0;
    KlClose[KLP_VODA]=10;
   
   TempPrev=temps[TEMP_RK20];
    if (maxTempRK20_Nbk<TempPrev) maxTempRK20_Nbk=TempPrev;
   SecTempPrev=Seconds; // Запоминаем дату последнего изменения температуры
   startNasosNBK();   //digitalWrite(PIN_STOP_NASOS_NBK, 0);
    plusStateMachine=0;
   StateMachine=3;
   startTimer3();
   time3=120;
    if (BeepStateProcess) beep2();
  case 3: //Стабилизация   
    SpeedNBK=SpeedNasosNBK*40/100;
    UstPower=PowerNBK;
   if (UstPower> PowerTenNBK) UstPower=PowerTenNBK;
   KlOpen[KLP_VODA]=PER_KLP_OPEN;
    KlClose[KLP_VODA]=PER_KLP_CLOSE;
   time1=60;
   time3=60;
   if (plusStateMachine==1) {
      plusStateMachine=0;
      StateMachine=4;         
        if (BeepStateProcess) beep3();//my_beep(BEEP_LONG);
        SecTempPrev=Seconds;
   }
   
    if (temps[TEMP_RK20]>500) { // Если температура больше 70 градусов (вдруг куб прогрелся, а колонна еще нет, нелогично, конечно, но на всякий случай учтем)      
        if (abs(temps[TEMP_RK20]-TempPrev)<2) { //Если текущая температура колонны равна температуре, запомненной ранее за исключением погрешности 0,2 градуса
          if (Seconds - SecTempPrev > 60) { //Если с момента последнего измерения прошло более 60 секунд , тогда считаем, что температура внизу стабилизировалась
            // Переходим к следующему этапу         
         StateMachine=4;         
            if (BeepStateProcess) beep2();//my_beep(BEEP_LONG);
            SecTempPrev=Seconds;
          } else break;  
        } else {
          TempPrev=temps[TEMP_RK20];// Запоминаем температуру
          if (maxTempRK20_Nbk<TempPrev) maxTempRK20_Nbk=TempPrev;
        SecTempPrev=Seconds; // Запоминаем время последнего изменения температуры
          break;
        }
      
    } else {
      break;
   }
  case 4:
    UstPower=PowerNBK;      //
   Speed1=SpeedNasosNBK;   //
   Speed2=SpeedNasosNBK;
   //if (temps[TEMP_DEFL]<600) temps[TEMP_DEFL]=900;
   if (maxTempRK20_Nbk < temps[TEMP_RK20] || maxTempRK20_NbkCnt > 30) {
      maxTempRK20_Nbk=temps[TEMP_RK20];
      maxTempRK20_NbkCnt=0;
   }
   
   if (temps[TEMP_DEFL] >= MinTempNBKdef) {
      Speed2 = SpeedNasosNBK ;
   } else {         //  920    -    920  (900)     =   0  (20)    
      n1 = MinTempNBKdef - temps[TEMP_DEFL];
    if (n1 > 30) n1 = 30;
    if (n1 < 0) n1 = 0;    
      n = map( n1 , 0 , 30 , 99, 40) ;
      Speed2 = SpeedNasosNBK * n / 100;
   }
   
   m = U_MPX5010 * 100 / AlarmMPX_NBK ; //    80*100/200=40   130*100/200=65  160*100/200=80  180*100/200=90  
   if (m > 100) m = 100;
    if (m < 30) m = 30;
  
   if (m > 80) {//         180/180=1.00   60/180=0.33
      n = map( m , 100 , 80 , 50, 100)  ;   //100=0.50 80=1.00
   } else if (m < 50) {
      n = map( m , 50 , 30 , 100, 120)  ;   //50=1.00  30=1.20
   } else {
      n=100;
   }   
   UstPower = UstPower * (n / 100);
   
   if (UstPower> PowerTenNBK) UstPower=PowerTenNBK;   
   
   if (time3 > 0) {
      n1 = time3;
      n = map( n1  , 0 , 60 , 99, 40) ;   
      Speed1 = Speed2 * (n / 100) ; // первые 2 минуты брагу подаем медленно
      time2=20;
      maxTempRK20_NbkCnt=0;
   } else {//if (time3 <=1 ) {
      if (U_MPX5010 > (AlarmMPX_NBK * 0.7) ) {
         if (time2<=0) {            //PowerNBK = PowerNBK - 10;
            time2 = 20;
         }
      }
      
   /*   if (U_MPX5010 < (AlarmMPX_NBK * 0.5) ) {
         UstPower = UstPower * 1.2;
      } else if (U_MPX5010 < (AlarmMPX_NBK * 0.6) ) {
         UstPower = UstPower * 1.1;
      }
      
      if (U_MPX5010 > (AlarmMPX_NBK * 0.7) ) {
         UstPower = UstPower * 0.9;
      } else if (U_MPX5010 > (AlarmMPX_NBK * 0.8) ) {
         UstPower = UstPower * 0.7;
      } else if (U_MPX5010 > (AlarmMPX_NBK * 0.9) ) {
         UstPower = UstPower * 0.5;
      } else if (U_MPX5010 > (AlarmMPX_NBK) ) {
         UstPower = UstPower * 0.3;
      }*/   
      
      //if (UstPower> PowerTenNBK) UstPower=PowerTenNBK;
      
      if ( (maxTempRK20_Nbk-temps[TEMP_RK20])<3 ) {  
            Speed1=Speed2;  
            time2=20;
            maxTempRK20_NbkCnt=0;
      } else    if ((maxTempRK20_Nbk-temps[TEMP_RK20])<4 ) {
            Speed1=Speed2*0.9;
            if (time2<=0) {               //if (SpeedNasosNBK>0) SpeedNasosNBK-=1;
               time2=30;
               maxTempRK20_NbkCnt++;
            }
      } else if ( (maxTempRK20_Nbk-temps[TEMP_RK20])<5 ) {
            Speed1=Speed2*0.7;
            if (time2<=0) {               //if (SpeedNasosNBK>0) SpeedNasosNBK-=1;
               time2=20;
               maxTempRK20_NbkCnt++;
            }
      } else if ( (maxTempRK20_Nbk-temps[TEMP_RK20])<7 ) {  
            Speed1=Speed2*0.5;
            if (time2<=0) {               //if (SpeedNasosNBK>0) SpeedNasosNBK-=1;
               time2=10;
               maxTempRK20_NbkCnt++;
            }
      } else if ((maxTempRK20_Nbk-temps[TEMP_RK20])<10 ) {  
            Speed1=Speed2*0.3;
            if (time2<=0) {               //if (SpeedNasosNBK>0) SpeedNasosNBK-=1;
               time2=10;
               maxTempRK20_NbkCnt++;
            }
      } else {
            Speed1=0;
            maxTempRK20_NbkCnt=0;
      }      
   }

      
   //if (Speed1 < Speed2) SpeedNBK=Speed1; else SpeedNBK=Speed2;
   SpeedNBK=Speed1;
   startNasosNBK();   //digitalWrite(PIN_STOP_NASOS_NBK, 0);
    timeNBK=20;
    
   if  (temps[TEMP_DEFL]>=tEndNBK && time1<=0 || plusStateMachine==1) {
      //Если температура превысила максимальную и с момента старта прошло более 20 минут, то считаем, что произошла авария - заклинил насос или кончилась брага.
      // Ждем 1/2 минут и завершаем процесс.
      time2=60;
      plusStateMachine=0;
     StateMachine=5;
      if (BeepStateProcess) beep2();//my_beep(BEEP_LONG);
    }

   if  (temps[TEMP_DEFL]>=tEndNBK && time1>0) {
      time1=60;
   }
   // не работает нагрев
   if  (time3<=0 && temps[TEMP_RK20]<970 && U_MPX5010<20) {
      StateMachine=100;
      SecondsEnd=Seconds;
      SpeedNBK=0;
      stopNasosNBK();      //digitalWrite(PIN_STOP_NASOS_NBK, 1);
      beep7();
   }   
    
   break;
   
  case 5: //Превышение температуры вверху
    UstPower=PowerNBK;
   SpeedNBK=SpeedNasosNBK;
   startNasosNBK();   //digitalWrite(PIN_STOP_NASOS_NBK, 0);
    timeNBK=20;
    if  (temps[TEMP_DEFL]<tEndNBK) {  
       StateMachine=4;
    }
    beep3();//my_beep(BEEP_LONG);
    if (time2<=0) {
      StateMachine=100;
     SecondsEnd=Seconds;
     time2=60;
     SpeedNBK=0;
     stopNasosNBK();     //digitalWrite(PIN_STOP_NASOS_NBK, 1);
    }
    break;
  case 101: // Превышение температуры в ТСА!!!
  case 102: // Превышение давления
  case 106: // Неверное колич датчиков температуры
    break;
    beep3();//my_beep(3*BEEP_LONG);
  case 100:// Конечное состояние автомата
    KlOpen[KLP_VODA]=0;
    KlClose[KLP_VODA]=10;   
   stopNasosNBK();//digitalWrite(PIN_STOP_NASOS_NBK, 1);
   SpeedNBK=0;
    timeNBK=0;
    
    UstPower=0;
    CloseAllKLP();
//    digitalWrite(PIN_REG_ON,LOW);
    digitalWrite(PIN_RZG_ON,!RELAY_HIGH);
    digitalWrite(PIN_ALL_OFF,ALL_OFF_HIGH);
   flAllOff=1;
   stopTimer3();
   StateMachine=103;
  case 103:   
   if (StateMachine==103 && BeepEndProcess && time2>0) beep3();//my_beep(BEEP_LONG);
    break;
  }
}


Mim Специалист Ульяновск 185 16
Отв.9907  24 Июля 18, 14:51, через 10 мин
вот ещеtitan777, 24 Июля 18, 14:41
. Это вот куда воткнуть, для таких как я не понимающих
titan777 Специалист Москва 147 102
Отв.9908  24 Июля 18, 15:18, через 28 мин
У меня программа сильно переделана, я выложил весь код управления НБК.
Можно взять за основу.

Просто так вставить увы не получится.
SA1348 Профессор Саратов 2501 1008
Отв.9909  24 Июля 18, 18:16
titan777, Надо внимательно изучить. А времени как обычно нет. На беглый взгляд case 101 превышение темперературы ТСА не сработает как и в оригинале.
А высота какая?msg31, 24 Июля 18, 10:33
1400 мм
Phisik Бакалавр Екатеринбург 96 294
Отв.9910  24 Июля 18, 22:38
алгоритмtitan777, 24 Июля 18, 14:41
Код можно убирать под спойлер c помощью тегов [ hide=Заголовок ][/hide] без пробелов.
Пример
Куча места на странице экономится Улыбающийся
titan777 Специалист Москва 147 102
Отв.9911  24 Июля 18, 23:01, через 23 мин
Спс. Спрятал.
qwest_ans Студент Самара 49 4
Отв.9912  26 Июля 18, 20:42
Замучился подключать ЛСДи кейпад шедуэл - видна только вехняя строка с клеточками, и в УНО и в МЕГЕ, кейпад D1 ROBOT, смог только по и2С подключить другой дисплей. есть ли возможность использовать и2С, не нашел где можно переназначить адрес на 0х3ф, или подскажите как изнасиловать кейпад шедуэл.
Phisik Бакалавр Екатеринбург 96 294
Отв.9913  26 Июля 18, 20:54, через 12 мин
есть ли возможность использовать и2Сqwest_ans, 26 Июля 18, 20:42
LiquidCrystal_I2C lcd(0x27, 16, 2), 0x27 - это и есть адрес
qwest_ans Студент Самара 49 4
Отв.9914  27 Июля 18, 04:50
Благодарю, он указывается только в variables?
Phisik Бакалавр Екатеринбург 96 294
Отв.9915  27 Июля 18, 08:08
он указывается только в variablesqwest_ans, 27 Июля 18, 04:50
Да, только при создании объекта. Еще есть тонкость с библиотеками. Вот кусок кода из моей прошивки:
// AlexDol: Добавил стоку инициализации lcd.init() и строку управления подсветкой 
// Phisik:  у меня так не собралось, видимо от версии библиотеки зависит
//lcd.begin(LCD_WIDTH, LCD_HEIGHT);
//lcd.init();

lcd.begin();
lcd.backlight();
qwest_ans Студент Самара 49 4
Отв.9916  27 Июля 18, 08:44, через 37 мин
А для бестолковых типа меня - как подробнее...
т.е. beginb и blacklith должны встать после LiquidCrystal_I2C lcd(0x3f, 16, 2)?
Ну не программер я _____ . В темном лесу блукаю.
SA1348 Профессор Саратов 2501 1008
Отв.9917  27 Июля 18, 09:40, через 56 мин
qwest_ans, Если самостоятельно переделываешь, находишь lcd.begin в скетче
и после добавляешь
lcd.init();
  lcd.backlight();


подскажите как изнасиловать кейпад шедуэл.qwest_ans, 26 Июля 18, 20:42
Заливаешь тестовый скетч для дисплеев и вращением потенциометра добиваешься отображения на экране всех строк. Новый из коробки без кручения 90% не заработает.
qwest_ans Студент Самара 49 4
Отв.9918  27 Июля 18, 11:08
Крутил - не помогает, вторая строка вообще не светится, а в первой только яркость меняется. Arduino 1.8.5
 Там этих lcd.begin - аж в глазах темнеет - сам наверное не смогу. Надо кейпад как-то оживлять.

Добавлено через 19ч. 22мин.:

Как я понял у меня неактивирован дисплей как проверить какие ноги надо указать LiquidCrystal lcd(8, 9, 4, 5, 6, 7) или какие то другие. есть какой нибудь тест для кейпад шилда который покажет какими ногами он должен дрыгать?
SA1348 Профессор Саратов 2501 1008
Отв.9919  28 Июля 18, 08:12
qwest_ans, Проверь правильность одевания шилда на ардуино.