Доступная автоматика HelloDistiller на Ардуино Мега 2560
Отв.9880 24 Июля 18, 10:09
Не СиВ
msg31
Научный сотрудник
Барнаул
4.6K 2.5K


А высота какая?
Отв.9882 24 Июля 18, 10:48 (через 16 мин)
Честно говоря не помню, только дома вечером смогу посмотреть
titan777
Специалист
Москва
192 136
Отв.9883 24 Июля 18, 14:41
я вот еще в марте 2017 алгоритм расписал.
Он у меня и по сей день работает в автомате.
И по нижнему, и по верхнему, и давление , все задействуется.
Добавлено через 2мин.:
Он у меня и по сей день работает в автомате.
И по нижнему, и по верхнему, и давление , все задействуется.
Открыть алгоритм
Я у себя давно сделал регулировку подачи насоса от Т-верх, Т-низ , и давления.
Сначала смотрю по верхнему датчику Т, если Т ниже нужной(задается в настройках) к примеру ниже 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
Кандидат наук
Ульяновск
438 71


вот ещеtitan777, 24 Июля 18, 14:41. Это вот куда воткнуть, для таких как я не понимающих
titan777
Специалист
Москва
192 136
Отв.9885 24 Июля 18, 15:18 (через 28 мин)
У меня программа сильно переделана, я выложил весь код управления НБК.
Можно взять за основу.
Просто так вставить увы не получится.
Можно взять за основу.
Просто так вставить увы не получится.
Отв.9886 24 Июля 18, 18:16
titan777, Надо внимательно изучить. А времени как обычно нет. На беглый взгляд case 101 превышение темперературы ТСА не сработает как и в оригинале.
А высота какая?msg31, 24 Июля 18, 10:331400 мм
Phisik
Куратор
Екатеринбург
706 1.5K
Отв.9887 24 Июля 18, 22:38
алгоритмtitan777, 24 Июля 18, 14:41Код можно убирать под спойлер c помощью тегов [ hide=Заголовок ][/hide] без пробелов.
Пример
Куча места на странице экономится
titan777
Специалист
Москва
192 136

Спс. Спрятал.
qwest_ans
Бакалавр
Самара
84 7
Отв.9889 26 Июля 18, 20:42
Замучился подключать ЛСДи кейпад шедуэл - видна только вехняя строка с клеточками, и в УНО и в МЕГЕ, кейпад D1 ROBOT, смог только по и2С подключить другой дисплей. есть ли возможность использовать и2С, не нашел где можно переназначить адрес на 0х3ф, или подскажите как изнасиловать кейпад шедуэл.
Phisik
Куратор
Екатеринбург
706 1.5K
Отв.9890 26 Июля 18, 20:54 (через 12 мин)
есть ли возможность использовать и2Сqwest_ans, 26 Июля 18, 20:42LiquidCrystal_I2C lcd(0x27, 16, 2), 0x27 - это и есть адрес
qwest_ans
Бакалавр
Самара
84 7
Отв.9891 27 Июля 18, 04:50
Благодарю, он указывается только в variables?
Phisik
Куратор
Екатеринбург
706 1.5K
Отв.9892 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
Бакалавр
Самара
84 7
Отв.9893 27 Июля 18, 08:44 (через 37 мин)
А для бестолковых типа меня - как подробнее...
т.е. beginb и blacklith должны встать после LiquidCrystal_I2C lcd(0x3f, 16, 2)?
Ну не программер я _____ . В темном лесу блукаю.
т.е. beginb и blacklith должны встать после LiquidCrystal_I2C lcd(0x3f, 16, 2)?
Ну не программер я _____ . В темном лесу блукаю.
Отв.9894 27 Июля 18, 09:40 (через 56 мин)
qwest_ans, Если самостоятельно переделываешь, находишь lcd.begin в скетче
и после добавляешь
и после добавляешь
lcd.init();
lcd.backlight();
подскажите как изнасиловать кейпад шедуэл.qwest_ans, 26 Июля 18, 20:42Заливаешь тестовый скетч для дисплеев и вращением потенциометра добиваешься отображения на экране всех строк. Новый из коробки без кручения 90% не заработает.
qwest_ans
Бакалавр
Самара
84 7
Отв.9895 27 Июля 18, 11:08
Крутил - не помогает, вторая строка вообще не светится, а в первой только яркость меняется. Arduino 1.8.5
Там этих lcd.begin - аж в глазах темнеет - сам наверное не смогу. Надо кейпад как-то оживлять.
Добавлено через 19ч. 22мин.:
Как я понял у меня неактивирован дисплей как проверить какие ноги надо указать LiquidCrystal lcd(8, 9, 4, 5, 6, 7) или какие то другие. есть какой нибудь тест для кейпад шилда который покажет какими ногами он должен дрыгать?
Там этих lcd.begin - аж в глазах темнеет - сам наверное не смогу. Надо кейпад как-то оживлять.
Добавлено через 19ч. 22мин.:
Как я понял у меня неактивирован дисплей как проверить какие ноги надо указать LiquidCrystal lcd(8, 9, 4, 5, 6, 7) или какие то другие. есть какой нибудь тест для кейпад шилда который покажет какими ногами он должен дрыгать?
Отв.9896 28 Июля 18, 08:12
qwest_ans, Проверь правильность одевания шилда на ардуино.
qwest_ans
Бакалавр
Самара
84 7
Отв.9897 28 Июля 18, 08:19 (через 8 мин)
На меге ещё можно ошибиться но на уно как?
Phisik
Куратор
Екатеринбург
706 1.5K
Отв.9898 28 Июля 18, 15:54
как проверить какие ноги надо указатьqwest_ans, 27 Июля 18, 11:08Вот пример работы в lcd keypad shield. Там все разжевано. Если не работает - нет контакта или не так подключил. Возьми уно, залей тестовый скетч и крути потенциометр ДО КОНЦА(!) по часовой, потом против часовой. Он многооборотный, т.е. 25 раз надо крутануть полный круг, чтобы от ноля до номинала дойти. Если экран не оживет - может непропай или обрыв где на плате.
qwest_ans
Бакалавр
Самара
84 7
Отв.9899 28 Июля 18, 16:39 (через 45 мин)
Картина одинаковая и на меге и на уно, все скетчи из первой двадцатки гугла заливал в мегу и в уно, менял пины в ликвид кристал на всё что находил - ничего не менялось. нашел скеч с тестов выходов уно, проверил - всё ровно. Всё - кейпад в утиль.