Аппаратная платформа Arduino для автоматизации наших процессов
dee
Научный сотрудник
Минск
8.1K 2.1K
Отв.980 06 Окт. 14, 23:43
вещь называется интерполяция, самый простой вариант - линейная. находишь первое число в массиве значений i которого больше чем температура термометра (и соответствующее ему значение крепости) и берешь предыдущую пару i-1 потом по формуле %i - %i-1 / Ti-1 - Ti считаешь прирост крепости на градус цельсия в диапазоне от i-1 до i и добавляешь к первому значению крепости дельту температуры умноженой на прирост крепости: %текущее = %i-1 + (Tтекущее - Тi-1)*прирост крепости (только по знакам смотри, могу нахомутать че и с минусом значения будут)
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.981 07 Окт. 14, 00:07, через 24 мин
2Брагин Спасибо. Я правильно понял, мне нужен только этот кусок кода?
Кстати, в этом скетче удобно спрятано меню инициализации датчиков DS18B20
а то как проедешь мимо, так и сбились все датчики, а тут отдельно.
PS: не понял, как потом выводить символ градус Цельсия?
int Term []={782,962,961,785,942,932,790,918,892,795,901,854,800,877,787,805,863,733,810,850,677,815,838,619,820,828,569,825,818,516,830,810,481,835,802,440,840,793,403,845,784,374,850,772,340,855,761,312,860,750,290,865,736,265,870,724,245,875,714,229,880,695,206,885,684,194,890,677,185,895,658,166,900,646,156,905,637,148,910,612,131,915,594,120,920,575,110,925,558,101,930,537,93,935,516,85,940,492,77,945,466,69,950,438,62,955,415,54,960,383,47,965,342,40,970,300,33,975,255,27,980,207,21,985,158,15,990,112,10,995,47,3,100,0,0,50,100,100};
byte degc[8] = // объявление символа градусцельсия
{
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
B00000,
};
float spirt (float TempIn, int mode) { //TempIn -входная температура, mode - 0 -пар, 1-жидкость
int temp=TempIn*10;
if (temp<=781) {TempOut=100.0;}
else {
int p=0;
do {
if (mode==0) {TempOut=((float)Term[p+1])/10;}
else {TempOut=((float)Term[p+2])/10;}
p=p+3 ;
} while (temp>=Term[p]);
}
return TempOut;
}
lcd.print(spirt);
Кстати, в этом скетче удобно спрятано меню инициализации датчиков DS18B20
а то как проедешь мимо, так и сбились все датчики, а тут отдельно.
PS: не понял, как потом выводить символ градус Цельсия?
svarnoy
Профессор
Жуковский.
9.1K 4.6K
Отв.982 07 Окт. 14, 11:39
_k0t_,
На лабспирте тему глянь
http://labspirt.com/forum/index.php/topic,2403.0.html
Вот формула оттуда без интерполяции:
"Короче вот формула, она конечно тоже не самая простая, но легко встраивается в программирование.
К%мас - удалено,т.к. было сделано по "не очень правильным" таблицам)))
К%об = 16,75 - 19,05 * Ti + 12,64 * Ti ^ 2 - 3,69 * Ti ^ 3 - 0.38 * Ti ^ 4
Где Ti = ( t[град] - 89,03 ) / 6,54
Где t[град] - температура где угодно (где кипит спиртосодержащая жидкость) в градусах Цельсия.
Пользуйтесь.
И для гурманов - восьмая степень .
К%об = 17,26 - 18,32 * Ti + 7,81 * Ti ^ 2 - 1,77 * Ti ^ 3 +4,81 * Ti ^ 4 - 2,95 * Ti ^ 5 - 1,43 * Ti ^ 6 + 0,8 * Ti ^ 7 + 0,05 * Ti ^ 8
Где Ti = ( t[град] - 89 ) / 6,49"
Автор наш форумчанин mekkaod
Я давно сравнивал реальные показания термометра при разной спиртуозности,эту формулу,и калькулятор "руди",Формула кривовато считала,потом за темой не следил.
На лабспирте тему глянь
http://labspirt.com/forum/index.php/topic,2403.0.html
Вот формула оттуда без интерполяции:
"Короче вот формула, она конечно тоже не самая простая, но легко встраивается в программирование.
К%мас - удалено,т.к. было сделано по "не очень правильным" таблицам)))
К%об = 16,75 - 19,05 * Ti + 12,64 * Ti ^ 2 - 3,69 * Ti ^ 3 - 0.38 * Ti ^ 4
Где Ti = ( t[град] - 89,03 ) / 6,54
Где t[град] - температура где угодно (где кипит спиртосодержащая жидкость) в градусах Цельсия.
Пользуйтесь.
И для гурманов - восьмая степень .
К%об = 17,26 - 18,32 * Ti + 7,81 * Ti ^ 2 - 1,77 * Ti ^ 3 +4,81 * Ti ^ 4 - 2,95 * Ti ^ 5 - 1,43 * Ti ^ 6 + 0,8 * Ti ^ 7 + 0,05 * Ti ^ 8
Где Ti = ( t[град] - 89 ) / 6,49"
Автор наш форумчанин mekkaod
Я давно сравнивал реальные показания термометра при разной спиртуозности,эту формулу,и калькулятор "руди",Формула кривовато считала,потом за темой не следил.
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.983 07 Окт. 14, 14:34
Вроде разобрался, забыл:
1. переменную еще нужно определить - float TempOut ;
2. lcd.print(spirt(T[1],0)); так вроде нужно выводить спирт в струе?
3. lcd.createChar(0,degc); - записать символ С°
Пошел пробовать. Спасибо за помощь.
1. переменную еще нужно определить - float TempOut ;
2. lcd.print(spirt(T[1],0)); так вроде нужно выводить спирт в струе?
3. lcd.createChar(0,degc); - записать символ С°
Пошел пробовать. Спасибо за помощь.
mak
Модератор
Екатеринбург
6.3K 1.8K
Отв.984 07 Окт. 14, 14:38, через 5 мин
формула местами не точно считает, да и тяжелые там вычисления
поэтому гораздо проще с табличными значениями работать
делал такой термометр на атмега8 - если что есть алгоритм, но писал там в CV не для ардуинки
хотя адаптировать несложно, если что - в личку
поэтому гораздо проще с табличными значениями работать
делал такой термометр на атмега8 - если что есть алгоритм, но писал там в CV не для ардуинки
хотя адаптировать несложно, если что - в личку
сообщение удалено
Брагин
Магистр
Краснодар
278 76
Отв.985 07 Окт. 14, 19:48
_k0t_, все верно
градус цельсия объявлен первым символом в наборе.
проверь по куркуляторам, вроде правду показывает. lcd.print(spirt(T[1],0)) 0 -пар, 1 -куб.
если есть желание можно добавить таблицу с точностью до 0.25 градуса, если не лень.
полином с восьмой степенью считать не советую, памяти еще много - проще таблицу увеличить чем загрузить МК. ему подсчета средневыпрямленного итак хватает...
это ж не 8 ядер интела.
формат наверное понял (градус, температура 1, температура 2.Г.Т1.Т2...) снизу вверх. значения умножены на 10 - что б использовать таблицу с целыми числами - я так думаю и места в памяти меньше занимают и быстрее считать. а на 10 умножить\поделить уже в программе
градус цельсия объявлен первым символом в наборе.
проверь по куркуляторам, вроде правду показывает. lcd.print(spirt(T[1],0)) 0 -пар, 1 -куб.
если есть желание можно добавить таблицу с точностью до 0.25 градуса, если не лень.
полином с восьмой степенью считать не советую, памяти еще много - проще таблицу увеличить чем загрузить МК. ему подсчета средневыпрямленного итак хватает...
это ж не 8 ядер интела.
формат наверное понял (градус, температура 1, температура 2.Г.Т1.Т2...) снизу вверх. значения умножены на 10 - что б использовать таблицу с целыми числами - я так думаю и места в памяти меньше занимают и быстрее считать. а на 10 умножить\поделить уже в программе
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.986 07 Окт. 14, 19:58, через 11 мин
Да, вроде понял с данными в массиве. Сегодня погонял, потестил:
в среднем получается врет на 5% в бОльшую сторону. Чтобы поправить,
нужно переделывать весь массив, как я понимаю? Да, и наверно
было бы не плохо, еслиб: spirt >= 96, то отображать
на экране, например: n/a. 100 как-то глаза режет )
в среднем получается врет на 5% в бОльшую сторону. Чтобы поправить,
нужно переделывать весь массив, как я понимаю? Да, и наверно
было бы не плохо, еслиб: spirt >= 96, то отображать
на экране, например: n/a. 100 как-то глаза режет )
mak
Модератор
Екатеринбург
6.3K 1.8K
Отв.987 07 Окт. 14, 21:23
Я когда оптимизировал размещение в памяти, целую часть в один массив байтовый, дробную в другой ))
Так каждое число всего 2 байта занимает
Так каждое число всего 2 байта занимает
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.988 08 Окт. 14, 20:27
Опять прошу помощи, не могу разобраться, в чем проблема?
Вот в в аттаче скетч, который я использую, будет время,
посмотрите, пожалуйста. Проблема вот в чем:
Все работает, но при запуске программы фракционной дистилляции
происходит следующее:
1. Не срабатывает сигнал и не программа переходит на следующий шаг после отбора голов.
2. То же самое с хвостами.
Срабатывает только сигнал при переполнении емкости, когда поднят поплавок,
и при окончании дистилляции. Самое интересное:
если заново запустить программу, когда датчики показывают температуру больше 88 -
программа моментально проходит все шаги, с сигнализацией и остановкой на смену тары.
Иногда глючат показания датчиков температуры, на короткое время может показать и >20000 градусов.
Вроде и раньше они глючили, но программа раньше проходила все шаги постепенно.
Может я что-то не так сделал? Очень прошу помощи у Брагина т.к.программа его
и ему будет легче разобраться. Заранее огромное спасибо.
Вот в в аттаче скетч, который я использую, будет время,
посмотрите, пожалуйста. Проблема вот в чем:
Все работает, но при запуске программы фракционной дистилляции
происходит следующее:
1. Не срабатывает сигнал и не программа переходит на следующий шаг после отбора голов.
2. То же самое с хвостами.
Срабатывает только сигнал при переполнении емкости, когда поднят поплавок,
и при окончании дистилляции. Самое интересное:
если заново запустить программу, когда датчики показывают температуру больше 88 -
программа моментально проходит все шаги, с сигнализацией и остановкой на смену тары.
Иногда глючат показания датчиков температуры, на короткое время может показать и >20000 градусов.
Вроде и раньше они глючили, но программа раньше проходила все шаги постепенно.
Может я что-то не так сделал? Очень прошу помощи у Брагина т.к.программа его
и ему будет легче разобраться. Заранее огромное спасибо.
Брагин
Магистр
Краснодар
278 76
Отв.989 08 Окт. 14, 21:20, через 54 мин
я ничего не понял с системой поплавка, фракции три, а вход один.
и если окончание фракции определять по поплавку и переход на следующий шаг то делать это следует в строчках
if (!is_h && Step==0) {Step++;}
if (!is_b && Step==1) {Step++;}
или если поплавок переставляеться с банки на банку то лепить надо в
if (T[1] > Th && Step==0) {Stop=4; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // отобрали головы
if (T[1] > Tb && Step==1) {Stop=4; tone(buzzer, 2000, 500);delay(200); tone(buzzer, 1000, 5000);} // отобрали тело
типа такого
if (T[1] > Th && Step==0) {Stop=4; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // отобрали головы
if (P4==0 && Step==0) {Stop=3; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // поплавок поднят, головы
if (T[1] > Tb && Step==1) {Stop=4; tone(buzzer, 2000, 500);delay(200); tone(buzzer, 1000, 5000);} // отобрали тело
if (P4==0 && Step==1) {Stop=3; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // поплавок поднят, хвосты
НО для помощи с логикой работы надо описать логику работы однозначно, без догадок
и если окончание фракции определять по поплавку и переход на следующий шаг то делать это следует в строчках
if (!is_h && Step==0) {Step++;}
if (!is_b && Step==1) {Step++;}
или если поплавок переставляеться с банки на банку то лепить надо в
if (T[1] > Th && Step==0) {Stop=4; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // отобрали головы
if (T[1] > Tb && Step==1) {Stop=4; tone(buzzer, 2000, 500);delay(200); tone(buzzer, 1000, 5000);} // отобрали тело
типа такого
if (T[1] > Th && Step==0) {Stop=4; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // отобрали головы
if (P4==0 && Step==0) {Stop=3; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // поплавок поднят, головы
if (T[1] > Tb && Step==1) {Stop=4; tone(buzzer, 2000, 500);delay(200); tone(buzzer, 1000, 5000);} // отобрали тело
if (P4==0 && Step==1) {Stop=3; tone(buzzer, 1000, 500); delay(200);tone(buzzer, 2000, 1000);} // поплавок поднят, хвосты
НО для помощи с логикой работы надо описать логику работы однозначно, без догадок
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.990 08 Окт. 14, 23:28
Поплавок у меня только для определения полноты сосуда.
Нет возможности поставить большую емкость, поэтому при срабатывании
поплавка я просто меняю посуду. При этом не важно, какой шаг программы выполняется.
Видимо я сделал не правильно, и у меня после срабатывания поплавка сбрасывается переменная step?
Мне нужно, чтобы после того, как сработал поплавок, программа продолжила с момента
срабатывания поплавка, не важно, какая фракция при этом отбиралась.
Головы, - значит продолжить дальше отбирать головы, тело - так тело.
Спасибо за помощь.
Нет возможности поставить большую емкость, поэтому при срабатывании
поплавка я просто меняю посуду. При этом не важно, какой шаг программы выполняется.
Видимо я сделал не правильно, и у меня после срабатывания поплавка сбрасывается переменная step?
Мне нужно, чтобы после того, как сработал поплавок, программа продолжила с момента
срабатывания поплавка, не важно, какая фракция при этом отбиралась.
Головы, - значит продолжить дальше отбирать головы, тело - так тело.
Спасибо за помощь.
Брагин
Магистр
Краснодар
278 76
Отв.991 09 Окт. 14, 00:04, через 36 мин
попробуй за строчками
case 5:
lcd.print("water leakage");
break;
case 6:
lcd.print("overheating");
break;
}
if (butPush == 2) {Stop=0; Menu(0);}
if (butPush == 4) {Stop=0; running=1; Step++; Menu(0);}
добавить
if (butPush == 5) {Stop=0; running=1; Menu(0);}
по идее будет стоять, а продолжение банкета с этого же шага, но по кнопке "вниз"
все я спать
case 5:
lcd.print("water leakage");
break;
case 6:
lcd.print("overheating");
break;
}
if (butPush == 2) {Stop=0; Menu(0);}
if (butPush == 4) {Stop=0; running=1; Step++; Menu(0);}
добавить
if (butPush == 5) {Stop=0; running=1; Menu(0);}
по идее будет стоять, а продолжение банкета с этого же шага, но по кнопке "вниз"
все я спать
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.992 09 Окт. 14, 00:36, через 32 мин
Спасибо. Завтра я на работу, а послезавтра обязательно попробую.
Но то что это из-за поплавка - точно, я проверил. Кинул поплавок рядом,
чтобы он не срабатывал, и вся программа прошла успешно. Попробую потом по кнопке
вниз с добавлением этой строчки.
Но то что это из-за поплавка - точно, я проверил. Кинул поплавок рядом,
чтобы он не срабатывал, и вся программа прошла успешно. Попробую потом по кнопке
вниз с добавлением этой строчки.
_k0t_
Бакалавр
Санкт-Петербург
56 22
Отв.993 12 Окт. 14, 14:46
Добрался до аппарата только сегодня, все проверил,
Брагину спасибо, все работает. Потом, если не будет лень,
добавлю конструкцию if-else при нажатии кнопки "вправо".
Наверно нужно будет еще какой нибудь "флаг" организовывать,
на срабатывания поплавка. Ну то есть: если флаг - 0 -
то step++, если 1 - тогда нет.
if (butPush == 4 && FlagFloat == 0)
{Stop=0; running=1; Step++; Menu(0);}
else
{Stop=0; running=1; Menu(0);}
Брагину спасибо, все работает. Потом, если не будет лень,
добавлю конструкцию if-else при нажатии кнопки "вправо".
Наверно нужно будет еще какой нибудь "флаг" организовывать,
на срабатывания поплавка. Ну то есть: если флаг - 0 -
то step++, если 1 - тогда нет.
if (butPush == 4 && FlagFloat == 0)
{Stop=0; running=1; Step++; Menu(0);}
else
{Stop=0; running=1; Menu(0);}
demyan2
Доктор наук
Уфа
701 76
Отв.994 12 Окт. 14, 15:22, через 37 мин
LVit
Специалист
город на Даугаве
126 59
Отв.995 28 Окт. 14, 15:34
вот такой конструктив.В деле пока не пробовал, на столе работает отлично.Твёрдотельное реле без радиатора, не знаю как поведёт себя с 1.5 квт
zZombie
Магистр
Msk
293 71
Отв.996 28 Окт. 14, 16:15, через 42 мин
отлично! компоновку внутрЕ покажи.
msg31
Научный сотрудник
Барнаул
4.6K 2.5K
Отв.997 28 Окт. 14, 17:25
Твёрдотельное реле без радиатора, не знаю как поведёт себя с 1.5 квтLVit, 28 Окт. 14, 15:34Перегреется и сгорит.
LVit
Специалист
город на Даугаве
126 59
Отв.998 28 Окт. 14, 20:15
Этто понятно что сгорит, посмотрю как греться будет, выключу если что. Внутрянку сфотаю завтра
ys1797
Доцент
Санкт-Петербург
1K 339
Отв.999 28 Окт. 14, 22:19
Купи огнетушитель.