Хочу выложить проект, но вот куда?
- Войдите на сайт для отправки комментариев
Ср, 16/03/2016 - 10:17
хочу выложить проект контролера муфельной печи, есть 2 проблеммы
1. В проекте есть PDF файлы (графики, статистика, методики, схемы)
2. Скетч разделен на 7 файлов, по этому выкладывать надо зип директории
здесь можно выкладывать только картинки :(
Сделайте архив на ядиске, сюда положите ссылку и коммениы.
хочу выложить проект контролера муфельной печи, есть 2 проблеммы
1. В проекте есть PDF файлы (графики, статистика, методики, схемы)
2. Скетч разделен на 7 файлов, по этому выкладывать надо зип директории
здесь можно выкладывать только картинки :(
*как там в 90-х, друг из прошлого?
Переводите пдф в картинку, картинку выкладываете в пост. Отдельные файлы скетчей помещаете каждый под свой спойлер. Кому надо - откроют, кому не надо - мимо пройдут. Как это сделать, рассказано в соответствующих "приклееных" темах.
это будет очень много... один скетч сейчас примерно 20 000 символов, плюс 3..5 фото, плюс 2..3 графика плюс таблицы и описание еще с несколькими картинками
это будет очень много... один скетч сейчас примерно 20 000 символов, плюс 3..5 фото, плюс 2..3 графика плюс таблицы и описание еще с несколькими картинками
я тоже думаю, что многовато как то насекомых надо избавиться от них http://dezin24.com/dezinfektsiya вызвал спецов все сделали быстро , теперь дома как в раю.
попробую тут, заодно может кто ошибок и опечаток найдет :)
ВНИМАНИЕ - это тестовая версия !!!!
файл term.ino :
001
// ---------------------------------------------------------
002
// управление муфельной печью модуль "term"
003
//
004
// состав проекта:
005
// Arduino R3 UNO
006
// LCD 1602 Keypad shield
007
// MAX6675 Module + K Type Thermocouple Sensor for Arduino
008
// UN3F SLA-05VDC-SL-A 5V 30A Relay Module For Arduino
009
//
010
// версия среды Arduino 1.5.2
011
//
012
// автор <a href="mailto:vde69@mail.ru">vde69@mail.ru</a> (с), процедуры главного алгоритма
013
// ---------------------------------------------------------
014
015
// добавляем необходимые библиотеки
016
017
#include <EEPROM.h>
018
#include <LiquidCrystal.h>
019
#include <util/delay.h>
020
021
// общие настройки
022
const
int
TIME_GET_THERMOMETR = 1000;
// время шага опроса термодатчиков
023
const
int
TIME_GET_ERROR = 1000;
// время шага диагностики ошибок
024
const
int
TIME_ANIME = 300;
// время шага анимации
025
const
int
TIME_RUN = 100;
// время шага расчета действий по включению/выключению нагрузки
026
const
int
TIME_STAB = 2000;
// время расчета в режиме стабилизации (при открытом муфеле)
027
const
int
BUTTON_TIME = 20;
// время между нажатием и отпусканием (устранение дребезга)
028
const
int
BUTTON_TIME_LONG = 5000;
// время перевода в режим SETUP
029
const
int
TERM_LIMIT = 1100;
// предельная температура контролера, установить температуру выше нельзя, при реальном превышении будет издавать звук
030
const
byte
TERM_GRADIENT = 5;
// допустимый градиент температуры (от установленой), влияет на процесс калибровки, рекомендуется от 5 до 20 (5 - самая точная калибрвка)
031
032
// статусы нажатых кнопок, определить несколько нажатых кнопок одновременно - нельзя
033
const
int
BUTTON_RIGHT = 1;
// 0 < 100
034
const
int
BUTTON_UP = 2;
// 148 < 200
035
const
int
BUTTON_DOWN = 3;
// 338 < 400
036
const
int
BUTTON_LEFT = 4;
// 515 < 600
037
const
int
BUTTON_SELECT = 5;
// 750 < 800
038
const
int
BUTTON_NONE = 0;
// 1023
039
040
// статусы режимов работы
041
const
byte
STATUS_STOP = 1;
// отображаем текущую и установленую температуру,
042
// установленую температуру можно редактировать,
043
// нагрузка не включается
044
// переход возможен в статусы RUN и SETUP
045
046
const
byte
STATUS_RUN = 2;
// отображаем текущую и установленую температуру,
047
// установленую температуру нельзя редактировать,
048
// нагрузка включается для поддержания установленой температуры
049
// переход возможен только в статус STOP
050
051
const
byte
STATUS_SETUP = 3;
// отображаем линейку настройки и вариант выхода STOP/START
052
// линейку и вариант выхода можно редактировать,
053
// нагрузка не включается, текущая температура отображается
054
// переход возможен только статус STOP или SETUP_RUN
055
056
const
byte
STATUS_SETUP_RUN = 4;
// отображаем линейку выполнения настройки контроллера, текущий этап
057
// нагрузка включается для определения параметров калибровки, текущая температура отображается
058
// переход возможен только в статус SETUP
059
060
const
byte
STATUS_ERROR = 5;
// отображаем описание ошибки,
061
// нагрузка не включается, текущая температура отображается
062
// переход возможен только в статус STOP
063
064
// --------------------------------------------------------
065
// объявления для индикаторов и кнопок управления
066
//
067
068
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );
069
070
// переменные для поддержки циклов анимации
071
unsigned
long
time_anime = 0;
072
unsigned
long
time_anime_new = 0;
073
int
step_anime = 0;
074
075
// переменные для поддержки циклов клавиатуры
076
unsigned
long
time_button = 0;
077
unsigned
long
time_button_new = 0;
078
079
// переменные для поддержки циклов опроса датчиков
080
unsigned
long
time_temp = 0;
081
unsigned
long
time_temp_new = 0;
082
083
// переменные для поддержки циклов включения/выключения нагревателя и расчетов
084
// обработка проходит в 10 степов, общее длинна всех степов TIME_RUN - милисекунд
085
unsigned
long
time_run = 0;
086
unsigned
long
time_run_new = 0;
087
088
// переменные для контроля, изменения и отображения температур
089
// конкретные значения могут переустанавливатся (из сохраненых в памяти) при старте системы
090
int
term_set = 0;
// установленая температура
091
int
term_set_display = 0;
// установленая температура выведеная на дисплей
092
int
term_set_new = 0;
// новая установленая температура
093
int
term_real = 0;
// текущая температура полученая от датчиков
094
int
term_real_display = 0;
// текущая температура выведеная на дисплей
095
int
term_real_new = 0;
// новая температура полученая от датчиков
096
097
// переменные для поддержки клавиатуры и экрана
098
int
button = BUTTON_NONE;
// текущаяя нажатая клавиша
099
int
button_new = BUTTON_NONE;
// новое значение нажатой клавиши
100
boolean FlagCursor =
false
;
// кеширующий флаг обозначающий, что включен режим курсора "Blink"
101
102
// переменные для поддержки статусов контроллера
103
byte
mode = STATUS_STOP;
// текущий статус работы контролера
104
int
edit_term = 0;
// номер знака редактирования у установленой температуры, 1...4-знаки, 0-не редактируется
105
106
// переменные для общения с термопарой
107
int
thermoDO = 17;
// А3 он же SO
108
int
thermoCS = 16;
// A2
109
int
thermoCLK = 15;
// A1 он же SCK
110
111
// переменные для реле
112
int
heatCTRL = 18;
// A4
113
114
// переменные для динамика
115
int
beepCTRL = 19;
// A5
116
117
// переменные для расчетов
118
int
r_pow;
// текущий коэффициэнт (сотая доля процента, 10000 = 100%) относительной мощность для поддержания планируемой температуры
119
int
r_term;
// текущий перебег (градусы), время перебега при нагреве до планируемой температуры со 100% мощностью
120
int
r_dt;
// время цикла on/off сек
121
int
r_step;
// время шага хранения истории сек (для апроксимации поддержания температуры)
122
123
// дополнительные коэффициэнты (сотая доля процента, 10000 = 100%)
124
int
rk_pow;
125
int
rk_term;
126
127
boolean mode_heat =
false
;
// флаг показывающий включена или нет нагрузка
128
unsigned
long
time_heat_start = 0;
// время последнего включения нагрузки
129
unsigned
long
time_heat_stop = 0;
// время последнего отключения нагрузки
130
131
// структуры которые хранят примерные таблицы тепловых характеристик
132
int
ar_temp[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
// температуры градусы
133
int
ar_pow[10] = { 3, 6, 12, 25, 40, 50, 55, 60, 65, 75};
// мощность процент
134
int
ar_tep[10] = {22, 20, 20, 20, 20, 20, 20, 20, 20, 20};
// температура перебега
135
int
ar_dt[10] = {20, 20, 20, 20, 20, 20, 20, 20, 20, 20};
// время цикла on/off нагрузки сек
136
int
ar_step[10] = {130, 25, 25, 25, 25, 25, 25, 25, 25, 25};
// время перебега температуры (инерционность) сек
137
int
ar_setup[10] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
// резерв для вычислений при выполнения SETUP
138
byte
ar_setup_scr[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// признаки для обновления на экране элементов массива ar_setup
139
140
byte
setup_step;
141
142
// переменные для расчетов
143
144
// переменные используемые только при калибровке, пишу сюда, что-бы были доступны для логов
145
unsigned
long
time_setup_t1;
// время достижения калибровочной температуры, или время запуска нагрева на втором этапе калибровки
146
unsigned
long
time_setup_t2;
// время достижения калибровочной температуры, или время запуска нагрева на втором этапе калибровки
147
int
term_setup_max;
// максимальная температура (поиск перебега)
148
int
pow_setup_max;
// минимальная мощность на которой проявился перегрев
149
int
pow_setup_min;
// максимальная мощность на которой проявился недогрев
150
int
pow_setup;
// текущая мощность
151
byte
step_run;
// текущий режим калибровки
152
// 0 - нет
153
// 1 - первичный разогрев
154
// 2 - поиск перебега
155
// 3 - остываение ниже градиента
156
// 4 - вторичный разогрев для поиска оптимальной мощности поддержания температуры
157
// текущий режим работы
158
// 0 - ожидание стабилизации
159
// 1 - первичный разогрев
160
// 2 - ожидание остывания до текущей температуры
161
// 3 - поддержание температуры
162
163
// переменные для ошибок
164
int
Error_Term;
// температура на которой зафиксирована ошибка
165
int
Error_Number;
// номер ошибки
166
unsigned
long
time_error;
//время последнего опроса ошибок
167
168
169
//*************************************************************************************************
170
// процедура инициализации контролера
171
//*************************************************************************************************
172
void
setup
()
173
{
174
int
i;
175
176
Serial
.begin(9600);
177
178
LogSerial(0);
179
180
// читаем сохраненные значения в энергонезависимой памяти
181
// первые 2 байта - сигнатура формата, для нашего проекта возьмем значение "T1", что равнозначно числу 21469
182
// при изменении физического местоположения сохраняемых значений идентификатор следует изменить
183
// при изменении идентификатора (и физического места данных), чтение производится не будет
184
// что будет равносильно полному заливки скетча в новый контроллер
185
186
i = Get_signature();
187
if
(i != 21469) {
188
// перезапишем все сохраняемые параметры
189
LogSerial(1);
190
i = 21469;
191
Set_signature(i);
192
Set_term_set(term_set);
193
for
(
byte
i1=0; i1 <= 9; i1++) {
194
Set_temp(i1, ar_temp[i1]);
195
Set_pow(i1, ar_pow[i1]);
196
Set_tep(i1, ar_tep[i1]);
197
Set_dt(i1, ar_dt[i1]);
198
Set_step(i1, ar_step[i1]);
199
Set_setup(i1, ar_setup[i1]);
200
}
201
}
202
// теперь читаем все параметры из энергонезависимой памяти
203
// читаем установленую температуру
204
i = Get_term_set(); term_set = i; term_set_display = i; term_set_new = i;
205
206
// читаем структуры
207
for
(
byte
i1=0; i1 <= 9; i1++) {
208
ar_temp[i1] = Get_temp (i1);
209
ar_pow[i1] = Get_pow (i1);
210
ar_tep[i1] = Get_tep (i1);
211
ar_dt[i1] = Get_dt (i1);
212
ar_step[i1] = Get_step (i1);
213
ar_setup[i1] = Get_setup(i1);
214
}
215
LogSerial(2);
216
217
// инициализируем модуль контролера термопары
218
219
pinMode(thermoCS, OUTPUT);
220
pinMode(thermoCLK, OUTPUT);
221
pinMode(thermoDO, INPUT);
222
223
digitalWrite(thermoCS, HIGH);
224
delay(500);
225
226
// инициализируем порт реле
227
pinMode(heatCTRL, OUTPUT);
228
off_Relay();
229
230
// инициализируем экран, у нас 16 символов и 2 строки
231
lcd.begin(16, 2);
232
lcd.noCursor();
233
234
screen_out(
true
,
true
,
true
);
235
Beep(1);
236
237
LogSerial(3);
238
}
239
240
//*************************************************************************************************
241
// главный цикл
242
//*************************************************************************************************
243
void
loop
() {
244
unsigned
long
time_loop_new;
245
unsigned
long
time_pause;
246
int
button_temp;
247
248
time_loop_new = millis();
// получим время начала цикла
249
250
// --------------------------------------------------------------------------------------------
251
// обработка управления кнопками, должена идти как можно ближе к началу цикла
252
button_temp = getPressedButton();
253
if
(button_new != button_temp) {
254
// изменилось состояние клавиатуры, запомним время и новое состояние
255
button_new = button_temp;
256
time_button_new = time_loop_new;
257
}
258
259
time_pause = getDelayTime(time_button_new, time_loop_new);
260
if
(time_pause <= BUTTON_TIME) {
261
// ожидание минимальной паузы
262
}
263
else
{
264
if
(button_new != button) {
265
// сотояния клавиатуры изменилось, минимальная пауза выдержана
266
if
(button_new == BUTTON_NONE) {
267
// кнопка отпущена
268
// вызовем обработчик, при этом расчитаем время нажатие от события нажатия а не от нового события отпускания
269
OnKeyUp (button, getDelayTime(time_button, time_button_new));
270
}
271
else
if
(button != BUTTON_NONE) {
272
// кнопка нажата, пока обработчик этого события мне не нужен,
273
// по тому, что кнопка SELECT обрабатывается по таймеру двумя разными способами
274
// здесь ничего не делаем, код оставляю для расширения в других проектах
275
}
276
else
{
277
// смена нажатой кнопки на другую, пока обработчик этого события мне не нужен
278
// по тому, что мы работаем не по событию нажатия, а по событию отжатия
279
// здесь ничего не делаем, код оставляю для расширения в других проектах
280
}
281
// изменения клавиатуры отработаны, теперь запомним новое состояние
282
time_button = time_loop_new;
283
button = button_new;
284
}
285
else
if
((button_new == button) && (button != BUTTON_NONE)) {
286
// есть какая-то зажатая кнопка
287
if
((button == BUTTON_SELECT) && (time_pause >= BUTTON_TIME_LONG)) {
288
// кнопка SELECT нажата достаточно долго для перехода в режим SETUP
289
// в текущем проекте это пока не нужно, мы пойдем другим путем и будем передовать время удержания в событие отжатия кнопки
290
// здесь ничего не делаем, код оставляю для расширения в других проектах,
291
// но, все-же, напомним звуком, что кнопка зажата или это ошибка...
292
Beep(2);
293
}
294
}
295
}
296
297
298
// --------------------------------------------------------------------------------------------
299
// получение актуальной температуры
300
time_pause = getDelayTime(time_temp, time_loop_new);
301
if
(time_pause > TIME_GET_THERMOMETR) {
302
time_temp = time_loop_new;
303
term_real_new = readCelsius();
304
}
305
306
// --------------------------------------------------------------------------------------------
307
// поиск и обработка ошибок
308
time_pause = getDelayTime( time_error, time_loop_new);
309
if
(time_pause > TIME_GET_ERROR) {
310
time_error = time_loop_new;
311
312
// включение пищалки динамика
313
if
( term_real_new > TERM_LIMIT
314
|| mode == STATUS_ERROR) {
315
Beep(2);
316
}
317
318
if
(mode == STATUS_RUN) {
319
// ошибки при работе
320
if
( term_real_new < -100
// ошибка термопары
321
|| term_real_new > (term_set + 50)
// перегрев на 50 градусов
322
|| term_real_new > TERM_LIMIT) {
// общий перегрев
323
mode = STATUS_ERROR;
324
Error_Term = term_real_new;
325
Error_Number = 1;
326
off_Relay();
327
screen_out(
true
,
true
,
true
);
328
}
329
}
330
else
if
(mode == STATUS_SETUP_RUN) {
331
// ошибки при калибровке
332
if
( term_real_new < -100
// ошибка термопары
333
|| term_real_new > TERM_LIMIT) {
// общий перегрев
334
mode = STATUS_ERROR;
335
Error_Term = term_real_new;
336
Error_Number = 1;
337
off_Relay();
338
screen_out(
true
,
true
,
true
);
339
}
340
}
341
342
}
343
344
// --------------------------------------------------------------------------------------------
345
// расчет параметров для включения и выключения разогрева
346
time_pause = getDelayTime(time_run, time_loop_new);
347
if
(time_pause > TIME_RUN) {
348
time_run = time_loop_new;
349
Run(time_loop_new);
350
}
351
352
// --------------------------------------------------------------------------------------------
353
// обновление экрана, это последнее...
354
time_pause = getDelayTime(time_anime, time_loop_new);
355
if
(time_pause > TIME_ANIME) {
356
time_anime = time_loop_new;
357
screen_out(
true
,
false
,
false
);
358
}
359
else
{
360
screen_out(
false
,
false
,
false
);
361
}
362
}
файл Screen_out.ino :
001
//*************************************************************************************************
002
// процедура выводит все параметры и оформление на экран
003
// anime - вызывает перерисовку анимации в зависимости он значения переменных time_anime, time_anime_new, step_anime
004
// face - вызывает перерисовку надписей и прочих статических значений в зависимости от текущего режима контролера
005
// force - параметр для явного обновления всего экрана вне зависимости от остальных параметров
006
// true - полностью обновляет все параметры
007
// false - обновляет только измененые параметры
008
//*************************************************************************************************
009
void
screen_out(boolean anime, boolean face, boolean force)
010
{
011
byte
ii;
012
013
// строка 1:
014
// текущая температура выводится всегда в колонках 12,13,14,15
015
// оформление текущей температувы выводится всегда в колонках 10,11,16
016
term_real_display = OutNumber(term_real_display, term_real_new, 11, 0, 4, force);
017
if
(force || face) {
018
PrintLcd(
"t:"
, 9, 0);
019
PrintLcd(
"c"
, 15, 0);
020
}
021
022
//-------------------------------------------------------
023
if
(mode == STATUS_STOP) {
024
// строка 1:
025
// анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9
026
if
(force || face) {
027
PrintLcd(
"=STOP= "
, 0, 0);
028
}
029
030
// строка 2:
031
// установленая температура выводится в колонках 12,13,14,15
032
// оформление выводим в колонки 1,2,3,4,5
033
// оформление установленой температувы выводится в колонки 6,7,8,9,10,11,16
034
term_set_display = OutNumber(term_set_display, term_set_new, 11, 1, 4, force);
035
if
(force || face) {
036
PrintLcd(
" "
, 0, 1);
037
PrintLcd(
"SET T:"
, 5, 1);
038
PrintLcd(
"c"
, 15, 1);
039
}
040
041
// установка курсора во вторую строку редактируемого поля
042
if
(edit_term == 0) {
043
if
(FlagCursor ==
true
) {
044
lcd.noBlink();
045
FlagCursor =
false
;
046
}
047
}
048
else
{
049
lcd.setCursor(10 + edit_term, 1);
050
if
(FlagCursor !=
true
) {
051
lcd.blink();
052
FlagCursor =
true
;
053
}
054
}
055
}
056
//-------------------------------------------------------
057
else
if
(mode == STATUS_RUN) {
058
059
// строка 1:
060
// очистим поле для анимации в колонках 1,2,3,4,5,6,7,8,9
061
if
(force || face) {
062
PrintLcd(
" "
, 0, 0);
063
}
064
065
// анимацию выводим в первую строку
066
if
(anime ==
true
) {
067
// делаем шаг анимации
068
if
(step_anime < 3) { step_anime = step_anime + 1; }
069
else
{ step_anime = 0; }
070
// выводим текущий шак на экран
071
if
(step_anime == 0) { PrintLcd(
"|"
, 0, 0); }
072
else
if
(step_anime == 1) { PrintLcd(
"/"
, 0, 0); }
073
else
if
(step_anime == 2) { PrintLcd(
"-"
, 0, 0); }
074
else
{ PrintLcd(
"-"
, 0, 0); }
075
}
076
077
// строка 2:
078
// установленая температура выводится в колонках 12,13,14,15
079
// оформление выводим в колонки 1,2,3,4,5
080
// оформление установленой температувы выводится в колонки 6,7,8,9,10,11,16
081
term_set_display = OutNumber(term_set_display, term_set_new, 11, 1, 4, force);
082
if
(force || face) {
083
PrintLcd(
" "
, 0, 1);
084
PrintLcd(
" T:"
, 5, 1);
085
PrintLcd(
"c"
, 15, 1);
086
}
087
}
088
089
//-------------------------------------------------------
090
else
if
(mode == STATUS_SETUP) {
091
// строка 1:
092
// анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9
093
if
(force || face) {
094
PrintLcd(
" =SETUP= "
, 0, 0);
095
}
096
097
// строка 2:
098
if
(force || face) {
099
PrintLcd(
" "
, 0, 1);
100
for
(
byte
ii=0; ii <= 9; ii++) {
101
if
(ar_setup[ii] == 0) { PrintLcd(
"_"
, ii + 3, 1); }
102
else
if
(ar_setup[ii] == 1) { PrintLcd(
"o"
, ii + 3, 1); }
103
else
if
(ar_setup[ii] == 2) { PrintLcd(
"O"
, ii + 3, 1); }
104
ar_setup_scr[ii] = 0;
105
}
106
}
107
else
{
108
for
(
byte
ii=0; ii <= 9; ii++) {
109
if
(ar_setup_scr[ii] == 1) {
110
if
(ar_setup[ii] == 0) { PrintLcd(
"_"
, ii + 3, 1); }
111
else
if
(ar_setup[ii] == 1) { PrintLcd(
"o"
, ii + 3, 1); }
112
else
if
(ar_setup[ii] == 2) { PrintLcd(
"O"
, ii + 3, 1); }
113
}
114
ar_setup_scr[ii] = 0;
115
}
116
}
117
118
// установка курсора во вторую строку редактируемого поля
119
if
(edit_term == 0) {
120
if
(FlagCursor ==
true
) {
121
lcd.noBlink();
122
FlagCursor =
false
;
123
}
124
}
125
else
{
126
lcd.setCursor(2 + edit_term, 1);
127
if
(FlagCursor !=
true
) {
128
lcd.blink();
129
FlagCursor =
true
;
130
}
131
}
132
}
133
134
//-------------------------------------------------------
135
else
if
(mode == STATUS_SETUP_RUN) {
136
// строка 1:
137
// очистим поле для анимации в колонках 1,2,3,4,5,6,7,8,9
138
if
(force || face) {
139
PrintLcd(
" SETUP "
, 0, 0);
140
}
141
142
// анимацию выводим в первую строку
143
if
(anime ==
true
) {
144
// делаем шаг анимации
145
if
(step_anime < 3) { step_anime = step_anime + 1; }
146
else
{ step_anime = 0; }
147
// выводим текущий шак на экран
148
if
(step_anime == 0) { PrintLcd(
"|"
, 0, 0); }
149
else
if
(step_anime == 1) { PrintLcd(
"/"
, 0, 0); }
150
else
if
(step_anime == 2) { PrintLcd(
"-"
, 0, 0); }
151
else
{ PrintLcd(
"-"
, 0, 0); }
152
}
153
154
// строка 2:
155
if
(force || face) {
156
PrintLcd(
" "
, 0, 1);
157
for
(
byte
ii=0; ii <= 9; ii++) {
158
if
(ar_setup[ii] == 0) { PrintLcd(
"_"
, ii + 3, 1); }
159
else
if
(ar_setup[ii] == 1) { PrintLcd(
"o"
, ii + 3, 1); }
160
else
if
(ar_setup[ii] == 2) { PrintLcd(
"O"
, ii + 3, 1); }
161
ar_setup_scr[ii] = 0;
162
}
163
}
164
else
{
165
for
(
byte
ii=0; ii <= 9; ii++) {
166
if
(ar_setup_scr[ii] == 1) {
167
if
(ar_setup[ii] == 0) { PrintLcd(
"_"
, ii + 3, 1); }
168
else
if
(ar_setup[ii] == 1) { PrintLcd(
"o"
, ii + 3, 1); }
169
else
if
(ar_setup[ii] == 2) { PrintLcd(
"O"
, ii + 3, 1); }
170
}
171
ar_setup_scr[ii] = 0;
172
}
173
}
174
}
175
176
177
//-------------------------------------------------------
178
else
if
(mode == STATUS_ERROR) {
179
// строка 1:
180
// анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9
181
if
(force || face) {
182
PrintLcd(
"=ERROR= "
, 0, 0);
183
}
184
185
// строка 2:
186
// температура ошибки выводится в колонках 12,13,14,15
187
// оформление выводим в колонки 1,2,3,4,5
188
// оформление температуры ошибки температувы выводится в колонки 6,7,8,9,10,11,16
189
term_set_display = OutNumber(Error_Term, Error_Term, 3, 1, 4, force);
190
if
(force || face) {
191
PrintLcd(
" T:"
, 0, 1);
192
PrintLcd(
"c"
, 15, 1);
193
}
194
}
195
}
файл Run.ino :
001
//*************************************************************************************************
002
// процедура расчитывает разогрев и включает, отключает нагрузку
003
//*************************************************************************************************
004
void
Run(unsigned
long
time_loop_new) {
005
int
temp_pow;
006
int
i;
007
int
i1;
008
009
//--------------------------------------------------------------------
010
if
(mode == STATUS_RUN) {
011
012
if
(step_run == 0) {
013
// ожидание стабилизации температуры, предотвращает перегрев нагревателей при открытом муфеле
014
off_Relay();
015
if
(getDelayTime(time_heat_start, time_loop_new) < TIME_STAB) {
016
if
( (term_real_new > (term_setup_max + TERM_GRADIENT * 2))
017
|| (term_real_new < (term_setup_max - TERM_GRADIENT * 2))) {
018
019
// температура скачет
020
time_heat_start = time_loop_new;
021
}
022
}
023
else
{
024
step_run = 1;
025
}
026
}
027
else
if
(step_run == 1) {
028
// разогрев с мощностью 100%
029
if
(term_real_new < (term_set - r_term)) {
030
on_off_heat(10000, r_dt * 1000, time_loop_new);
031
}
032
else
{
033
time_heat_start = time_loop_new;
034
time_setup_t1 = time_loop_new;
035
step_run = 2;
036
}
037
}
038
else
if
(step_run == 2) {
039
// ожидание остывания до текущей температуры
040
if
(term_real_new >= term_set) {
041
off_Relay();
042
}
043
else
{
044
time_heat_start = time_loop_new;
045
time_setup_t1 = time_loop_new;
046
step_run = 3;
047
}
048
}
049
else
if
(step_run == 3) {
050
// поддержание температуры
051
if
(term_real_new > (term_set + TERM_GRADIENT)) {
052
// явный перегрев, идем к предыдущему шагу
053
step_run = 2;
054
}
055
else
if
( (getDelayTime(time_heat_start, time_loop_new) < (1000.0 * r_dt))
// не закончен малый цикл on-off отсчитаного от времени включения реле
056
|| (getDelayTime(time_setup_t1, time_loop_new) < (1000.0 * r_step))) {
// или не прошло время перебега
057
058
on_off_heat(100 * r_pow + rk_pow, r_dt * 1000, time_loop_new);
059
}
060
else
{
061
// тут все равно попали мы в диапазон или нет, все равно вносим корректор...
062
063
temp_pow = 1.0 * (term_set / term_real_new) * (100 * r_pow + rk_pow);
064
rk_pow = (100 * r_pow) - temp_pow;
065
time_setup_t1 = time_loop_new;
066
on_off_heat(100 * r_pow + rk_pow, r_dt * 1000, time_loop_new);
067
LogSerial(5);
068
}
069
}
070
else
{ off_Relay(); }
071
}
072
073
//--------------------------------------------------------------------
074
else
if
(mode == STATUS_SETUP_RUN) {
075
// выбор полки калибровки
076
// надо проверить может мы отстали... проверяем всегда, без учета степов
077
for
(
byte
i=setup_step; i <= 9; i++) {
078
setup_step = i;
079
if
(ar_setup[setup_step] != 2) {
080
break
;
// все нормально, можно идти дальше (выходим из цикла)
081
}
082
}
083
084
if
(setup_step == 9) {
085
if
(ar_setup[setup_step] == 2) {
086
// это конец калибровки, переходим в режим SETUP
087
mode = STATUS_SETUP;
088
edit_term = 0;
089
off_Relay();
090
Beep(1);
091
// после изменения режима нужно полностью обновить экран
092
screen_out(
true
,
true
,
true
);
093
LogSerial(2);
094
return
;
095
}
096
}
097
098
// полка выбрана, идем дальше теперь собственно этапы калибровки
099
100
if
(step_run == 1) {
101
// этап 1. - разогрев до температуры полки
102
if
(term_real_new < ar_temp[setup_step]) {
103
// до температуры калибровки еще не дошли, греем дальше и запоминаем время
104
on_off_heat(10000, ar_dt[setup_step] * 1000, time_loop_new);
105
time_setup_t1 = time_loop_new;
106
}
107
else
{
108
off_Relay();
109
step_run = 2;
110
LogSerial(7);
111
}
112
}
113
else
if
(step_run == 2) {
114
// этап 2. - ожидание потолка перебега
115
off_Relay();
116
if
(term_real_new >= (term_setup_max-1)) {
117
// идет перебег, нагрев нужно выключить, и запомнить температуру (-1 это на дребезг темппературы)
118
if
(term_real_new > term_setup_max) {
119
term_setup_max = term_real_new;
120
time_setup_t2 = time_setup_t1;
121
}
122
}
123
else
{
124
// начали остывать, температура опустилась ниже максимума на 2 градуса, реальное время - середина между time_setup_t2 и time_setup_t1
125
// пишем результаты
126
if
(ar_tep[setup_step] != (term_setup_max - ar_temp[setup_step])) {
127
ar_tep[setup_step] = term_setup_max - ar_temp[setup_step];
128
Set_tep(setup_step, ar_tep[setup_step]);
// пишем температуру перебега
129
}
130
131
i = getDelayTime(time_setup_t1, time_loop_new) / 1000;
132
i1 = getDelayTime(time_setup_t2, time_loop_new) / 1000;
133
i = (i + i1) / 2;
134
if
(ar_step[setup_step] != i) {
135
ar_step[setup_step] = i;
136
Set_step(setup_step, ar_step[setup_step]);
137
}
138
139
ar_setup[setup_step] = 1;
140
ar_setup_scr[setup_step] = 1;
141
Set_setup(setup_step, ar_setup[setup_step]);
142
pow_setup_max = 100;
143
pow_setup_min = 0;
144
pow_setup = 0;
145
146
step_run = 3;
147
LogSerial(8);
148
}
149
}
150
else
if
(step_run == 3) {
151
// этап 3. - остывание ниже градиента
152
off_Relay();
153
154
if
(term_real_new <= (ar_temp[setup_step] - TERM_GRADIENT)) {
155
// остыли, будущую мощность выберем как среднюю между pow_setup_max и pow_setup_min
156
pow_setup = (pow_setup_min + pow_setup_max) / 2;
157
158
// запомним время перехода в 4 режим
159
time_setup_t1 = time_loop_new;
160
161
// нагрев был выключен, значит запуск этапа 4 нужно начинать со старта
162
mode_heat =
true
;
163
time_heat_start = time_loop_new;
164
on_Relay();
165
166
step_run = 4;
167
LogSerial(9);
168
}
169
}
170
else
if
(step_run == 4) {
171
// этап 4. - нагреваем с выбраной ранее мощностью
172
173
if
(term_real_new > (ar_temp[setup_step] + TERM_GRADIENT)) {
174
// явный перегрев, идем к предыдущему шагу
175
off_Relay();
176
pow_setup_max = pow_setup;
177
step_run = 3;
178
}
179
else
if
( (getDelayTime(time_heat_start, time_loop_new) < (1000.0 * ar_dt[setup_step]))
// не закончен малый цикл on-off отсчитаного от времени включения реле
180
|| (getDelayTime(time_setup_t1, time_loop_new) < (2000.0 * ar_step[setup_step]))) {
// или не прошло двойное время перебега
181
182
on_off_heat(pow_setup * 100, ar_dt[setup_step] * 1000, time_loop_new);
183
}
184
else
if
( ((pow_setup_max - pow_setup_min) == 1)
// разница между режимами перегрева и негорева 1%, дальше оптимизировать нечего
185
|| (term_real_new >= (ar_temp[setup_step] - TERM_GRADIENT))) {
// или мы попали в диапазон градиента
186
// мощность подобрана правильно
187
// этап 2 завершен, пишем результаты
188
if
(ar_pow[setup_step] != (pow_setup)) {
189
ar_pow[setup_step] = pow_setup;
190
if
(ar_pow[setup_step] > 100) {ar_pow[setup_step] = 100;}
191
192
Set_pow(setup_step, ar_pow[setup_step]);
193
}
194
195
ar_setup[setup_step] = 2;
196
ar_setup_scr[setup_step] = 1;
197
Set_setup(setup_step, ar_setup[setup_step]);
198
step_run = 1;
// по сколько этот этап мы прошли, следующий идем с первого шага
199
200
LogSerial(10);
201
}
202
else
{
203
// это недогрев, меняем параметры и продолжаем
204
pow_setup_min = pow_setup;
205
pow_setup = (pow_setup_min + pow_setup_max) / 2;
206
time_setup_t1 = time_loop_new;
207
step_run = 3;
208
}
209
}
210
else
{ off_Relay(); }
211
}
212
//--------------------------------------------------------------------
213
else
{ off_Relay(); }
214
}
файл other.ino :
001
// ---------------------------------------------------------
002
// вспомогательные процедуры
003
// ---------------------------------------------------------
004
005
//*************************************************************************************************
006
// процедура включает и выключает нагрев в зависимости от необходимой мощности
007
// p - относительной мощность сотые доли % (допустимые значения от 0 до 10 000)
008
// dt - общее время одного цикла вкл/выкл (в мсек, допустимые значения от 0 до 32 767), это время делется пропорционально параметра "p"
009
// 100% мощность этого времени не должно приводить к перебегу температуры выше разумной погрешности,
010
// по этому общее время одного цикла должно расчитыватся заранее.
011
// t - текущее время
012
//*************************************************************************************************
013
014
void
on_off_heat(
int
p,
int
dt, unsigned
long
t)
015
{
016
unsigned
long
t1 = 1;
017
018
if
(p >= 9900) {
019
// 99% мощности считаем как 100% в целях сохранения ресурса реле
020
mode_heat =
true
;
021
time_heat_start = t;
022
on_Relay();
023
}
024
else
if
(p <= 100) {
025
// 1% мощности считаем 0% в целях сохранения ресурса реле
026
mode_heat =
false
;
027
time_heat_stop = t;
028
off_Relay();
029
}
030
else
if
(mode_heat ==
true
) {
031
// идет нагрев, нужно проверить может стоит остановится
032
t1 = t1*dt/100*p/100;
033
if
(getDelayTime(time_heat_start, t) >= t1) {
034
mode_heat =
false
;
035
time_heat_stop = t;
036
off_Relay();
037
}
038
}
039
else
if
(mode_heat ==
false
) {
040
// идет охлаждение, нужно проверить может стоит запустится
041
t1 = t1*dt/100*(100-p/100);
042
if
(getDelayTime(time_heat_stop, t) >= t1) {
043
mode_heat =
true
;
044
time_heat_start = t;
045
on_Relay();
046
}
047
}
048
}
049
050
051
void
on_Relay()
052
{
053
//Serial.println("on reley");
054
digitalWrite(heatCTRL, HIGH);
055
}
056
057
void
off_Relay()
058
{
059
//Serial.println("off reley");
060
digitalWrite(heatCTRL, LOW);
061
}
062
063
064
//*************************************************************************************************
065
// процедура выводит на экран число и возвращает новое значение
066
// num - текущее значение числа
067
// new_num - новое значение числа
068
// col - номер позиции в строке экрана для вывода
069
// line - номер строки экрана для вывода
070
// count - количество символов на экране для вывода
071
// force - параметр для явного обновления
072
//*************************************************************************************************
073
int
OutNumber(
int
num,
int
new_num,
byte
col,
byte
line,
byte
count, boolean force)
074
{
075
String stringOne;
076
int
str_l;
077
078
if
(force || (new_num != num)) {
079
num = new_num;
080
stringOne = String(num);
081
str_l = count - stringOne.length();
082
for
(
int
i=1; i <= str_l; i++){
083
stringOne = String(
" "
) + stringOne;
084
}
085
PrintLcd(stringOne, col, line);
086
}
087
return
num;
088
}
089
090
//*************************************************************************************************
091
// процедура возвращает значение нажатой клавиши на клавиатуре
092
//*************************************************************************************************
093
int
getPressedButton()
094
{
095
int
buttonValue = analogRead(0);
// считываем значения с аналогового входа(A0)
096
if
(buttonValue < 100) {
097
return
BUTTON_RIGHT;
098
}
099
else
if
(buttonValue < 200) {
100
return
BUTTON_UP;
101
}
102
else
if
(buttonValue < 400){
103
return
BUTTON_DOWN;
104
}
105
else
if
(buttonValue < 600){
106
return
BUTTON_LEFT;
107
}
108
else
if
(buttonValue < 800){
109
return
BUTTON_SELECT;
110
}
111
else
if
(buttonValue >= 800){
112
return
BUTTON_NONE;
113
}
114
115
return
BUTTON_NONE;
116
}
117
118
//*************************************************************************************************
119
// процедура сравнивает два времени и возвращает разницу в виде числа, учитывает переход времени через 0
120
// start_time - начальное время
121
// end_time - конечное время
122
//
123
// !!!! процедура чуствительна к разрядности исполняемого кода !!!!
124
// !!!! процедура может работать неправильно при двойном переходе времени через 0 !!!!
125
//*************************************************************************************************
126
unsigned
long
getDelayTime(unsigned
long
start_time, unsigned
long
end_time)
127
{
128
unsigned
long
result;
129
if
(start_time <= end_time) {
130
result = end_time - start_time;
131
}
132
else
{
133
result = 4294967295 - end_time + start_time;
134
}
135
return
result;
136
}
137
138
//*************************************************************************************************
139
// процедура увеличивает или умеьшает значение разряда числа
140
// num - начальное число
141
// count - максимальная разрядность числа
142
// nb - номер разряда, считам с лево на право, например: num=2, count=4, nb=2 считаем разряд указаный "X" 0X02. Результат увеличения будет число 102.
143
// inc - флаг увеличение/уменьшения, если true - то увеличиваем
144
//*************************************************************************************************
145
int
ChangeValue(
int
num,
int
count,
int
nb, boolean inc) {
146
int
result;
147
String stringOne;
148
int
str_l;
149
int
sim;
150
151
// сначала добьем нулями разрядность
152
stringOne = String(num);
153
str_l = count - stringOne.length();
154
for
(
int
i=1; i <= str_l; i++){
155
stringOne = String(
"0"
) + stringOne;
156
}
157
158
// теперь изменяем нужный разряд
159
sim =
int
(stringOne.charAt(nb-1));
160
if
((inc ==
true
) && (sim < 57)) { sim = sim + 1; }
161
else
if
((inc ==
false
) && (sim > 48)) { sim = sim - 1; }
162
163
// запаковываем обратно в число
164
stringOne.setCharAt(nb-1,
char
(sim));
165
result = stringOne.toInt();
166
return
result;
167
}
168
169
//*************************************************************************************************
170
// процедура выводит на экран заранее подготовленую строку, при этом выключает режим "Blink"
171
// str - строка или String для вывода
172
// col - номер позиции в строке экрана для вывода
173
// line - номер строки экрана для вывода
174
//*************************************************************************************************
175
void
PrintLcd(String str,
int
col,
int
line)
176
{
177
if
(FlagCursor ==
true
) {
178
lcd.noBlink();
179
FlagCursor =
false
;
180
}
181
lcd.setCursor(col, line);
182
lcd.print(str);
183
}
184
185
//*************************************************************************************************
186
// процедура читает из энерго независимой памяти двухбйтовое число
187
// num - идентификатор памяти (номер двухбайтного слова)
188
//*************************************************************************************************
189
int
ReadInt(
int
num)
190
{
191
byte
a;
192
byte
b;
193
int
result;
194
195
a =
int
(EEPROM.read(num * 2));
196
b =
int
(EEPROM.read(num * 2 + 1));
197
result = a * 255 + b;
198
199
return
result;
200
}
201
202
//*************************************************************************************************
203
// процедура записывает в энерго независимую память двухбйтовое число
204
// num - идентификатор памяти (номер двухбайтного слова)
205
// value - записываемое значение
206
//*************************************************************************************************
207
void
WriteInt(
int
num,
int
value)
208
{
209
byte
a;
210
byte
b;
211
212
b = value % 255;
213
a = (value - b) / 255;
214
EEPROM.write(num * 2, a);
215
EEPROM.write(num * 2 + 1, b);
216
Beep(4);
// сделано для выявления безконтрольной записи и снижения ресурса EEPROM
217
}
218
219
//*************************************************************************************************
220
// процедура проверяет новую установленую температуру и сохраняет ее
221
//*************************************************************************************************
222
void
set_term_set()
223
{
224
if
(term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; }
225
226
if
(term_set_new != term_set) {
227
// применяем новую температуру и запоминаем ее
228
term_set = term_set_new;
229
Set_term_set(term_set);
230
}
231
}
232
233
//*************************************************************************************************
234
// две процедуры, для получения данных с термопары
235
//*************************************************************************************************
236
double
readCelsius() {
237
238
uint16_t v;
239
240
digitalWrite(thermoCS, LOW);
241
_delay_ms(1);
242
243
v = spiread();
244
v <<= 8;
245
v |= spiread();
246
247
digitalWrite(thermoCS, HIGH);
248
249
if
(v & 0x4) {
250
// uh oh, no thermocouple attached!
251
//return NAN;
252
return
-101;
253
}
254
v >>= 3;
255
256
return
v*0.25;
257
}
258
259
byte
spiread() {
260
int
i;
261
byte
d = 0;
262
263
for
(i=7; i>=0; i--)
264
{
265
digitalWrite(thermoCLK, LOW);
266
_delay_ms(1);
267
if
(digitalRead(thermoDO)) {
268
//set the bit to 0 no matter what
269
d |= (1 << i);
270
}
271
272
digitalWrite(thermoCLK, HIGH);
273
_delay_ms(1);
274
}
275
276
return
d;
277
}
278
279
//*************************************************************************************************
280
// процедура получает апромиксированое значение по температуре из эталонных массивов
281
// NumParam - номер массива, 1 - ar_pow, 2 - ar_tep, 3 - ar_dt, 4 - ar_step
282
// Term - температура к которой нужно получить значение
283
//*************************************************************************************************
284
int
GetParamProc(
byte
NumParam,
int
Term){
285
int
ir = 0;
286
byte
ii;
287
byte
i1;
288
byte
i2;
289
290
// найдем индексы
291
i1 = 0;
292
for
(
byte
ii=0; ii <= 9; ii++) {
293
if
(ar_temp[ii] > Term) {
294
ii = ii - 1;
295
break
;
296
}
297
}
298
299
if
(ii <= 0) {
300
i1 = 0;
301
i2 = 1;
302
}
303
else
if
(ii >=9) {
304
i1 = 8;
305
i2 = 9;
306
}
307
else
{
308
i1 = ii;
309
i2 = ii + 1;
310
}
311
312
// в i1 и i2 лежат индексы для массивов, начинаем апромиксацию
313
if
(NumParam == 1) { ir = ar_pow[i1] + 1.0 * (Term - ar_temp[i1]) * (ar_pow[i2] - ar_pow[i1]) / (ar_temp[i2] - ar_temp[i1]); }
314
if
(NumParam == 2) { ir = ar_tep[i1] + 1.0 * (Term - ar_temp[i1]) * (ar_tep[i2] - ar_tep[i1]) / (ar_temp[i2] - ar_temp[i1]); }
315
if
(NumParam == 3) { ir = ar_dt[i1] + 1.0 * (Term - ar_temp[i1]) * (ar_dt[i2] - ar_dt[i1]) / (ar_temp[i2] - ar_temp[i1]); }
316
if
(NumParam == 4) { ir = ar_step[i1]+ 1.0 * (Term - ar_temp[i1]) * (ar_step[i2]- ar_dt[i1]) / (ar_temp[i2] - ar_temp[i1]); }
317
318
return
ir;
319
}
320
321
//*************************************************************************************************
322
// процедуры, для записи и получении всех данных EEPROM
323
// собраны здесь для единообразного адресного хранения и визуализации карты использования EEPROM,
324
// адреса в двух байтовом виде (1 - это два байта с физическим адресом 2 и 3)
325
//*************************************************************************************************
326
327
// ------------------- чтение -------------------
328
int
Get_signature() {
return
ReadInt(0); }
// 0 - сигнатура
329
int
Get_term_set() {
return
ReadInt(1); }
// 1 - установленая температура
330
// 2...9 - резерв
331
int
Get_temp(
int
Num) {
return
ReadInt(Num+10); }
// 10..19 - массив калибровочных температур
332
int
Get_pow(
int
Num) {
return
ReadInt(Num+20); }
// 20..29 - массив мощности поддержания температуры
333
int
Get_tep(
int
Num) {
return
ReadInt(Num+30); }
// 30..39 - массив температур инерционности
334
int
Get_dt(
int
Num) {
return
ReadInt(Num+40); }
// 40..49 - массив времени цикла on/off
335
int
Get_step(
int
Num) {
return
ReadInt(Num+50); }
// 50..59 - массив времени инерционности
336
int
Get_setup(
int
Num){
return
ReadInt(Num+60); }
// 60..69 - массив флагов калибровки
337
// 70..99 - резерв
338
// 100..511 - свободно
339
340
// ------------------- запись -------------------
341
int
Set_signature(
int
value) { WriteInt(0, value); }
// 0 - сигнатура
342
int
Set_term_set(
int
value) { WriteInt(1, value); }
// 1 - установленая температура
343
// 2...9 - резерв
344
void
Set_temp(
int
Num,
int
value) { WriteInt(Num+10, value); }
// 10..19 - массив калибровочных температур
345
void
Set_pow(
int
Num,
int
value) { WriteInt(Num+20, value); }
// 20..29 - массив мощности поддержания температуры
346
void
Set_tep(
int
Num,
int
value) { WriteInt(Num+30, value); }
// 30..39 - массив температур инерционности
347
void
Set_dt(
int
Num,
int
value) { WriteInt(Num+40, value); }
// 40..49 - массив времени цикла on/off
348
void
Set_step(
int
Num,
int
value) { WriteInt(Num+50, value); }
// 50..59 - массив времени инерционности
349
void
Set_setup(
int
Num,
int
value) { WriteInt(Num+60, value); }
// 60..69 - массив флагов калибровки
350
// 70..99 - резерв
351
// 100..511 - свободно
файл OnKeyUp.ino :
001
//*************************************************************************************************
002
// обработчик вызывается при отпускании кнопки клавиатуры
003
// key - кнопка которая была отпущена
004
// pressing - время которое кнопка была нажата
005
//*************************************************************************************************
006
void
OnKeyUp (
int
key, unsigned
long
pressing)
007
{
008
int
i ;
009
010
if
(key == BUTTON_SELECT) {
011
// реализуем переход режима работы контроллера
012
013
// ******************** переход в режим RUN ********************
014
if
(mode == STATUS_STOP && pressing < BUTTON_TIME_LONG) {
015
016
// перед стартом применим (и сохраним) установленую температуру
017
set_term_set();
018
mode = STATUS_RUN;
019
020
// иницилизируем дефолтные параметры расчета
021
r_pow = GetParamProc(1, term_set);
022
r_term = GetParamProc(2, term_set);
023
r_dt = GetParamProc(3, term_set);
024
r_step = GetParamProc(4, term_set);
025
026
// дополнительные коэффициенты (плюсуются к основным)
027
step_run = 0;
028
time_heat_start = millis();
029
rk_pow = 0;
030
031
LogSerial(6);
032
Beep(3);
033
}
034
035
// ******************** переход в режим SETUP ********************
036
else
if
( (mode == STATUS_STOP && pressing >= BUTTON_TIME_LONG)
037
|| (mode == STATUS_SETUP_RUN)) {
038
mode = STATUS_SETUP;
039
off_Relay();
040
edit_term = 0;
041
}
042
043
// ******************** переход в режим STOP ********************
044
else
if
( (mode == STATUS_ERROR)
045
|| (mode == STATUS_RUN)
046
|| (mode == STATUS_SETUP && pressing < BUTTON_TIME_LONG)) {
047
mode = STATUS_STOP;
048
off_Relay();
049
edit_term = 0;
050
Error_Term = 0;
051
Error_Number = 0;
052
}
053
054
// ******************** переход в режим SETUP_RUN ********************
055
else
if
((mode == STATUS_SETUP) && (pressing >= BUTTON_TIME_LONG)) {
056
// перед калибровкой применим (и сохраним) установленую линейку порогов
057
for
(
byte
i=0; i <= 9; i++) {
058
if
(Get_setup(i) != ar_setup[i]) { Set_setup(i, ar_setup[i]); }
059
}
060
061
mode = STATUS_SETUP_RUN;
062
step_run = 1;
063
term_setup_max = 0;
064
pow_setup_max = 100;
065
edit_term = 0;
066
setup_step = 0;
067
Beep(3);
068
}
069
070
// после изменения режима нужно полностью обновить экран
071
screen_out(
true
,
true
,
true
);
072
}
073
else
if
(key == BUTTON_RIGHT) {
074
if
(mode == STATUS_STOP) {
075
// переключаем редактируемый разряд установленой температуры
076
if
(edit_term >= 4) { edit_term = 0; }
077
else
{ edit_term = edit_term + 1; }
078
079
if
(term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; }
080
screen_out(
false
,
false
,
false
);
081
}
082
else
if
(mode == STATUS_SETUP) {
083
if
(edit_term >= 10) { edit_term = 0; }
084
else
{ edit_term = edit_term + 1; }
085
086
screen_out(
false
,
false
,
false
);
087
}
088
}
089
else
if
(key == BUTTON_LEFT) {
090
if
(mode == STATUS_STOP) {
091
// переключаем редактируемый разряд установленой температуры
092
if
(edit_term == 0) { edit_term = 4; }
093
else
{ edit_term = edit_term - 1; }
094
095
if
(term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; }
096
screen_out(
false
,
false
,
false
);
097
}
098
else
if
(mode == STATUS_SETUP) {
099
if
(edit_term == 0) { edit_term = 10; }
100
else
{ edit_term = edit_term - 1; }
101
102
screen_out(
false
,
false
,
false
);
103
}
104
}
105
else
if
(key == BUTTON_UP) {
106
if
((mode == STATUS_STOP) && (edit_term != 0)) {
107
// мы редактируем текущий разряд установленой температуры
108
term_set_new = ChangeValue(term_set_new, 4, edit_term,
true
);
109
if
(term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; }
110
}
111
else
if
(mode == STATUS_SETUP) {
112
switch
(ar_setup[edit_term - 1]) {
113
case
0: ar_setup[edit_term - 1] = 2;
break
;
114
case
1: ar_setup[edit_term - 1] = 2;
break
;
115
case
2: ar_setup[edit_term - 1] = 0;
break
;
116
}
117
ar_setup_scr[edit_term - 1] = 1;
118
}
119
}
120
else
if
(key == BUTTON_DOWN) {
121
if
((mode == STATUS_STOP) && (edit_term != 0)) {
122
// мы редактируем текущий разряд установленой температуры
123
term_set_new = ChangeValue(term_set_new, 4, edit_term,
false
);
124
if
(term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; }
125
}
126
else
if
(mode == STATUS_SETUP) {
127
switch
(ar_setup[edit_term - 1]) {
128
case
0: ar_setup[edit_term - 1] = 2;
break
;
129
case
1: ar_setup[edit_term - 1] = 0;
break
;
130
case
2: ar_setup[edit_term - 1] = 0;
break
;
131
}
132
ar_setup_scr[edit_term - 1] = 1;
133
}
134
}
135
}
файл LogSerial.ino :
001
//*************************************************************************************************
002
// процедура выводит в порт лог глобальных переменных, собрано здесь для удобства включения/отключения
003
// и уменьшения текстов основной программы, Num - номер вызова лога
004
//*************************************************************************************************
005
void
LogSerial(
byte
Num) {
006
int
i;
007
008
// if (false) {
009
if
(
true
) {
010
011
switch
(Num) {
012
case
0:
013
Serial
.print(
"=debug (setup.Start)="
);
014
Serial
.println();
015
016
break
;
017
018
case
1:
019
Serial
.print(
"=debug (setup.FORMAT)="
);
020
Serial
.println();
021
022
break
;
023
024
case
2:
025
Serial
.print(
"=debug (setup.ActualTable)="
);
026
Serial
.println();
027
for
(
byte
i=0; i <= 9; i++) {
028
Serial
.print(
"i: "
);
Serial
.print(i);
029
Serial
.print(
", ar_temp: "
);
Serial
.print(ar_temp[i]);
030
Serial
.print(
", ar_pow: "
);
Serial
.print(ar_pow[i]);
031
Serial
.print(
", ar_tep: "
);
Serial
.print(ar_tep[i]);
032
Serial
.print(
", ar_dt: "
);
Serial
.print(ar_dt[i]);
033
Serial
.print(
", ar_step: "
);
Serial
.print(ar_step[i]);
034
Serial
.print(
", ar_setup: "
);
Serial
.print(ar_setup[i]);
035
Serial
.println();
036
}
037
038
break
;
039
040
case
3:
041
Serial
.print(
"=debug (setup.setup)= Complete."
);
042
Serial
.println();
043
044
break
;
045
046
case
4:
047
Serial
.print(
"=debug (Run.RunStep_1)="
);
048
Serial
.print(
" term_set: "
);
Serial
.print(term_set);
049
Serial
.print(
", term_real_new: "
);
Serial
.print(term_real_new);
050
Serial
.println();
051
052
break
;
053
054
case
5:
055
Serial
.print(
"=debug (Run.RunStep_2)="
);
056
Serial
.print(
", rk_pow: "
);
Serial
.print(rk_pow);
057
Serial
.println();
058
059
break
;
060
061
case
6:
062
Serial
.print(
"=debug (OnKeyUp.Start)="
);
063
Serial
.print(
" term_set: "
);
Serial
.print(term_set);
064
Serial
.print(
", r_pow: "
);
Serial
.print(r_pow);
065
Serial
.print(
", r_term: "
);
Serial
.print(r_term);
066
Serial
.print(
", r_dt: "
);
Serial
.print(r_dt);
067
Serial
.print(
", r_step: "
);
Serial
.print(r_step);
068
Serial
.println();
069
070
break
;
071
072
case
7:
073
Serial
.print(
"=debug (Run.Setup.1)="
);
074
Serial
.print(
" setup_step: "
);
Serial
.print(setup_step);
075
Serial
.print(
", term_real_new: "
);
Serial
.print(term_real_new);
076
Serial
.println();
077
078
break
;
079
080
case
8:
081
Serial
.print(
"=debug (Run.Setup.2)="
);
082
Serial
.print(
" setup_step: "
);
Serial
.print(setup_step);
083
Serial
.print(
", ar_tep[setup_step]: "
);
Serial
.print(ar_tep[setup_step]);
084
Serial
.print(
", ar_step[setup_step]: "
);
Serial
.print(ar_step[setup_step]);
085
Serial
.println();
086
087
break
;
088
089
case
9:
090
Serial
.print(
"=debug (Run.Setup.3)="
);
091
Serial
.print(
" setup_step: "
);
Serial
.print(setup_step);
092
Serial
.print(
", term_real_new: "
);
Serial
.print(term_real_new);
093
Serial
.println();
094
095
break
;
096
097
case
10:
098
Serial
.print(
"=debug (Run.Setup.End)="
);
099
Serial
.print(
" setup_step: "
);
Serial
.print(setup_step);
100
Serial
.print(
", term_real_new: "
);
Serial
.print(term_real_new);
101
Serial
.print(
", ar_pow[setup_step]: "
);
Serial
.print(ar_pow[setup_step]);
102
Serial
.println();
103
104
break
;
105
}
106
}
107
}
файл Beep.ino :
01
//*************************************************************************************************
02
// процедура выводит на динамик звуки, сделана здесь, для удобства
03
// Num - номер программы
04
// 0 - нет звуков,
05
// 1 - включение контроллера,
06
// 2 - ошибка,
07
// 3 - старт нагрева,
08
// 4 - звук записи в EEPROM,
09
//*************************************************************************************************
10
void
Beep(
byte
Num) {
11
12
switch
(Num) {
13
case
0:
14
// нет звуков
15
noTone(beepCTRL);
16
break
;
17
case
1:
18
// включение контроллера
19
tone(beepCTRL, 1000);
20
delay(500);
21
tone(beepCTRL, 4000, 500);
22
break
;
23
24
case
2:
25
// ошибка,
26
tone(beepCTRL, 6000, 150);
27
break
;
28
29
case
3:
30
// старт нагрева,
31
tone(beepCTRL, 300, 1000);
32
break
;
33
34
case
4:
35
// запись в EEPROM,
36
tone(beepCTRL, 300, 100);
37
break
;
38
39
}
40
}
Калибровка моей печи
Схема
Подпишусь на тему. Интересно увидеть фотографии печки.
фото ниже, но пока еще есть ошибки в программе...
А для чего печка?
печь до 1100 с,
способов применения полно, начиная от обжига глины заколкой сталей и заканчивая ювелиркой
рабочий вариант выложил сюда http://arduino.ru/forum/proekty/kontroller-mufelnoi-pechi
сабж можно закрывать :)