Хочу выложить проект, но вот куда?
- Войдите на сайт для отправки комментариев
Ср, 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 :
файл Screen_out.ino :
//************************************************************************************************* // процедура выводит все параметры и оформление на экран // anime - вызывает перерисовку анимации в зависимости он значения переменных time_anime, time_anime_new, step_anime // face - вызывает перерисовку надписей и прочих статических значений в зависимости от текущего режима контролера // force - параметр для явного обновления всего экрана вне зависимости от остальных параметров // true - полностью обновляет все параметры // false - обновляет только измененые параметры //************************************************************************************************* void screen_out(boolean anime, boolean face, boolean force) { byte ii; // строка 1: // текущая температура выводится всегда в колонках 12,13,14,15 // оформление текущей температувы выводится всегда в колонках 10,11,16 term_real_display = OutNumber(term_real_display, term_real_new, 11, 0, 4, force); if (force || face) { PrintLcd("t:", 9, 0); PrintLcd("c", 15, 0); } //------------------------------------------------------- if (mode == STATUS_STOP) { // строка 1: // анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9 if (force || face) { PrintLcd("=STOP= ", 0, 0); } // строка 2: // установленая температура выводится в колонках 12,13,14,15 // оформление выводим в колонки 1,2,3,4,5 // оформление установленой температувы выводится в колонки 6,7,8,9,10,11,16 term_set_display = OutNumber(term_set_display, term_set_new, 11, 1, 4, force); if (force || face) { PrintLcd(" ", 0, 1); PrintLcd("SET T:", 5, 1); PrintLcd("c", 15, 1); } // установка курсора во вторую строку редактируемого поля if (edit_term == 0) { if (FlagCursor == true) { lcd.noBlink(); FlagCursor = false; } } else { lcd.setCursor(10 + edit_term, 1); if (FlagCursor != true) { lcd.blink(); FlagCursor = true; } } } //------------------------------------------------------- else if (mode == STATUS_RUN) { // строка 1: // очистим поле для анимации в колонках 1,2,3,4,5,6,7,8,9 if (force || face) { PrintLcd(" ", 0, 0); } // анимацию выводим в первую строку if (anime == true) { // делаем шаг анимации if (step_anime < 3) { step_anime = step_anime + 1; } else { step_anime = 0; } // выводим текущий шак на экран if (step_anime == 0) { PrintLcd("|", 0, 0); } else if (step_anime == 1) { PrintLcd("/", 0, 0); } else if (step_anime == 2) { PrintLcd("-", 0, 0); } else { PrintLcd("-", 0, 0); } } // строка 2: // установленая температура выводится в колонках 12,13,14,15 // оформление выводим в колонки 1,2,3,4,5 // оформление установленой температувы выводится в колонки 6,7,8,9,10,11,16 term_set_display = OutNumber(term_set_display, term_set_new, 11, 1, 4, force); if (force || face) { PrintLcd(" ", 0, 1); PrintLcd(" T:", 5, 1); PrintLcd("c", 15, 1); } } //------------------------------------------------------- else if (mode == STATUS_SETUP) { // строка 1: // анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9 if (force || face) { PrintLcd(" =SETUP= ", 0, 0); } // строка 2: if (force || face) { PrintLcd(" ", 0, 1); for (byte ii=0; ii <= 9; ii++) { if (ar_setup[ii] == 0) { PrintLcd("_", ii + 3, 1); } else if (ar_setup[ii] == 1) { PrintLcd("o", ii + 3, 1); } else if (ar_setup[ii] == 2) { PrintLcd("O", ii + 3, 1); } ar_setup_scr[ii] = 0; } } else { for (byte ii=0; ii <= 9; ii++) { if (ar_setup_scr[ii] == 1) { if (ar_setup[ii] == 0) { PrintLcd("_", ii + 3, 1); } else if (ar_setup[ii] == 1) { PrintLcd("o", ii + 3, 1); } else if (ar_setup[ii] == 2) { PrintLcd("O", ii + 3, 1); } } ar_setup_scr[ii] = 0; } } // установка курсора во вторую строку редактируемого поля if (edit_term == 0) { if (FlagCursor == true) { lcd.noBlink(); FlagCursor = false; } } else { lcd.setCursor(2 + edit_term, 1); if (FlagCursor != true) { lcd.blink(); FlagCursor = true; } } } //------------------------------------------------------- else if (mode == STATUS_SETUP_RUN) { // строка 1: // очистим поле для анимации в колонках 1,2,3,4,5,6,7,8,9 if (force || face) { PrintLcd(" SETUP ", 0, 0); } // анимацию выводим в первую строку if (anime == true) { // делаем шаг анимации if (step_anime < 3) { step_anime = step_anime + 1; } else { step_anime = 0; } // выводим текущий шак на экран if (step_anime == 0) { PrintLcd("|", 0, 0); } else if (step_anime == 1) { PrintLcd("/", 0, 0); } else if (step_anime == 2) { PrintLcd("-", 0, 0); } else { PrintLcd("-", 0, 0); } } // строка 2: if (force || face) { PrintLcd(" ", 0, 1); for (byte ii=0; ii <= 9; ii++) { if (ar_setup[ii] == 0) { PrintLcd("_", ii + 3, 1); } else if (ar_setup[ii] == 1) { PrintLcd("o", ii + 3, 1); } else if (ar_setup[ii] == 2) { PrintLcd("O", ii + 3, 1); } ar_setup_scr[ii] = 0; } } else { for (byte ii=0; ii <= 9; ii++) { if (ar_setup_scr[ii] == 1) { if (ar_setup[ii] == 0) { PrintLcd("_", ii + 3, 1); } else if (ar_setup[ii] == 1) { PrintLcd("o", ii + 3, 1); } else if (ar_setup[ii] == 2) { PrintLcd("O", ii + 3, 1); } } ar_setup_scr[ii] = 0; } } } //------------------------------------------------------- else if (mode == STATUS_ERROR) { // строка 1: // анимацию не выводим, вместо анимации выводим оформление в колонках 1,2,3,4,5,6,7,8,9 if (force || face) { PrintLcd("=ERROR= ", 0, 0); } // строка 2: // температура ошибки выводится в колонках 12,13,14,15 // оформление выводим в колонки 1,2,3,4,5 // оформление температуры ошибки температувы выводится в колонки 6,7,8,9,10,11,16 term_set_display = OutNumber(Error_Term, Error_Term, 3, 1, 4, force); if (force || face) { PrintLcd(" T:", 0, 1); PrintLcd("c", 15, 1); } } }файл Run.ino :
//************************************************************************************************* // процедура расчитывает разогрев и включает, отключает нагрузку //************************************************************************************************* void Run(unsigned long time_loop_new) { int temp_pow; int i; int i1; //-------------------------------------------------------------------- if (mode == STATUS_RUN) { if (step_run == 0) { // ожидание стабилизации температуры, предотвращает перегрев нагревателей при открытом муфеле off_Relay(); if (getDelayTime(time_heat_start, time_loop_new) < TIME_STAB) { if ( (term_real_new > (term_setup_max + TERM_GRADIENT * 2)) || (term_real_new < (term_setup_max - TERM_GRADIENT * 2))) { // температура скачет time_heat_start = time_loop_new; } } else { step_run = 1; } } else if (step_run == 1) { // разогрев с мощностью 100% if (term_real_new < (term_set - r_term)) { on_off_heat(10000, r_dt * 1000, time_loop_new); } else { time_heat_start = time_loop_new; time_setup_t1 = time_loop_new; step_run = 2; } } else if (step_run == 2) { // ожидание остывания до текущей температуры if (term_real_new >= term_set) { off_Relay(); } else { time_heat_start = time_loop_new; time_setup_t1 = time_loop_new; step_run = 3; } } else if (step_run == 3) { // поддержание температуры if (term_real_new > (term_set + TERM_GRADIENT)) { // явный перегрев, идем к предыдущему шагу step_run = 2; } else if ( (getDelayTime(time_heat_start, time_loop_new) < (1000.0 * r_dt)) // не закончен малый цикл on-off отсчитаного от времени включения реле || (getDelayTime(time_setup_t1, time_loop_new) < (1000.0 * r_step))) { // или не прошло время перебега on_off_heat(100 * r_pow + rk_pow, r_dt * 1000, time_loop_new); } else { // тут все равно попали мы в диапазон или нет, все равно вносим корректор... temp_pow = 1.0 * (term_set / term_real_new) * (100 * r_pow + rk_pow); rk_pow = (100 * r_pow) - temp_pow; time_setup_t1 = time_loop_new; on_off_heat(100 * r_pow + rk_pow, r_dt * 1000, time_loop_new); LogSerial(5); } } else { off_Relay(); } } //-------------------------------------------------------------------- else if (mode == STATUS_SETUP_RUN) { // выбор полки калибровки // надо проверить может мы отстали... проверяем всегда, без учета степов for (byte i=setup_step; i <= 9; i++) { setup_step = i; if (ar_setup[setup_step] != 2) { break; // все нормально, можно идти дальше (выходим из цикла) } } if (setup_step == 9) { if (ar_setup[setup_step] == 2) { // это конец калибровки, переходим в режим SETUP mode = STATUS_SETUP; edit_term = 0; off_Relay(); Beep(1); // после изменения режима нужно полностью обновить экран screen_out(true, true, true); LogSerial(2); return; } } // полка выбрана, идем дальше теперь собственно этапы калибровки if (step_run == 1) { // этап 1. - разогрев до температуры полки if (term_real_new < ar_temp[setup_step]) { // до температуры калибровки еще не дошли, греем дальше и запоминаем время on_off_heat(10000, ar_dt[setup_step] * 1000, time_loop_new); time_setup_t1 = time_loop_new; } else { off_Relay(); step_run = 2; LogSerial(7); } } else if (step_run == 2) { // этап 2. - ожидание потолка перебега off_Relay(); if (term_real_new >= (term_setup_max-1)) { // идет перебег, нагрев нужно выключить, и запомнить температуру (-1 это на дребезг темппературы) if (term_real_new > term_setup_max) { term_setup_max = term_real_new; time_setup_t2 = time_setup_t1; } } else { // начали остывать, температура опустилась ниже максимума на 2 градуса, реальное время - середина между time_setup_t2 и time_setup_t1 // пишем результаты if (ar_tep[setup_step] != (term_setup_max - ar_temp[setup_step])) { ar_tep[setup_step] = term_setup_max - ar_temp[setup_step]; Set_tep(setup_step, ar_tep[setup_step]); // пишем температуру перебега } i = getDelayTime(time_setup_t1, time_loop_new) / 1000; i1 = getDelayTime(time_setup_t2, time_loop_new) / 1000; i = (i + i1) / 2; if (ar_step[setup_step] != i) { ar_step[setup_step] = i; Set_step(setup_step, ar_step[setup_step]); } ar_setup[setup_step] = 1; ar_setup_scr[setup_step] = 1; Set_setup(setup_step, ar_setup[setup_step]); pow_setup_max = 100; pow_setup_min = 0; pow_setup = 0; step_run = 3; LogSerial(8); } } else if (step_run == 3) { // этап 3. - остывание ниже градиента off_Relay(); if (term_real_new <= (ar_temp[setup_step] - TERM_GRADIENT)) { // остыли, будущую мощность выберем как среднюю между pow_setup_max и pow_setup_min pow_setup = (pow_setup_min + pow_setup_max) / 2; // запомним время перехода в 4 режим time_setup_t1 = time_loop_new; // нагрев был выключен, значит запуск этапа 4 нужно начинать со старта mode_heat = true; time_heat_start = time_loop_new; on_Relay(); step_run = 4; LogSerial(9); } } else if (step_run == 4) { // этап 4. - нагреваем с выбраной ранее мощностью if (term_real_new > (ar_temp[setup_step] + TERM_GRADIENT)) { // явный перегрев, идем к предыдущему шагу off_Relay(); pow_setup_max = pow_setup; step_run = 3; } else if ( (getDelayTime(time_heat_start, time_loop_new) < (1000.0 * ar_dt[setup_step])) // не закончен малый цикл on-off отсчитаного от времени включения реле || (getDelayTime(time_setup_t1, time_loop_new) < (2000.0 * ar_step[setup_step]))) { // или не прошло двойное время перебега on_off_heat(pow_setup * 100, ar_dt[setup_step] * 1000, time_loop_new); } else if ( ((pow_setup_max - pow_setup_min) == 1) // разница между режимами перегрева и негорева 1%, дальше оптимизировать нечего || (term_real_new >= (ar_temp[setup_step] - TERM_GRADIENT))) { // или мы попали в диапазон градиента // мощность подобрана правильно // этап 2 завершен, пишем результаты if (ar_pow[setup_step] != (pow_setup)) { ar_pow[setup_step] = pow_setup; if (ar_pow[setup_step] > 100) {ar_pow[setup_step] = 100;} Set_pow(setup_step, ar_pow[setup_step]); } ar_setup[setup_step] = 2; ar_setup_scr[setup_step] = 1; Set_setup(setup_step, ar_setup[setup_step]); step_run = 1; // по сколько этот этап мы прошли, следующий идем с первого шага LogSerial(10); } else { // это недогрев, меняем параметры и продолжаем pow_setup_min = pow_setup; pow_setup = (pow_setup_min + pow_setup_max) / 2; time_setup_t1 = time_loop_new; step_run = 3; } } else { off_Relay(); } } //-------------------------------------------------------------------- else { off_Relay(); } }файл other.ino :
// --------------------------------------------------------- // вспомогательные процедуры // --------------------------------------------------------- //************************************************************************************************* // процедура включает и выключает нагрев в зависимости от необходимой мощности // p - относительной мощность сотые доли % (допустимые значения от 0 до 10 000) // dt - общее время одного цикла вкл/выкл (в мсек, допустимые значения от 0 до 32 767), это время делется пропорционально параметра "p" // 100% мощность этого времени не должно приводить к перебегу температуры выше разумной погрешности, // по этому общее время одного цикла должно расчитыватся заранее. // t - текущее время //************************************************************************************************* void on_off_heat(int p, int dt, unsigned long t) { unsigned long t1 = 1; if (p >= 9900) { // 99% мощности считаем как 100% в целях сохранения ресурса реле mode_heat = true; time_heat_start = t; on_Relay(); } else if (p <= 100) { // 1% мощности считаем 0% в целях сохранения ресурса реле mode_heat = false; time_heat_stop = t; off_Relay(); } else if (mode_heat == true) { // идет нагрев, нужно проверить может стоит остановится t1 = t1*dt/100*p/100; if (getDelayTime(time_heat_start, t) >= t1) { mode_heat = false; time_heat_stop = t; off_Relay(); } } else if (mode_heat == false) { // идет охлаждение, нужно проверить может стоит запустится t1 = t1*dt/100*(100-p/100); if (getDelayTime(time_heat_stop, t) >= t1) { mode_heat = true; time_heat_start = t; on_Relay(); } } } void on_Relay() { //Serial.println("on reley"); digitalWrite(heatCTRL, HIGH); } void off_Relay() { //Serial.println("off reley"); digitalWrite(heatCTRL, LOW); } //************************************************************************************************* // процедура выводит на экран число и возвращает новое значение // num - текущее значение числа // new_num - новое значение числа // col - номер позиции в строке экрана для вывода // line - номер строки экрана для вывода // count - количество символов на экране для вывода // force - параметр для явного обновления //************************************************************************************************* int OutNumber(int num, int new_num, byte col, byte line, byte count, boolean force) { String stringOne; int str_l; if (force || (new_num != num)) { num = new_num; stringOne = String(num); str_l = count - stringOne.length(); for (int i=1; i <= str_l; i++){ stringOne = String(" ") + stringOne; } PrintLcd(stringOne, col, line); } return num; } //************************************************************************************************* // процедура возвращает значение нажатой клавиши на клавиатуре //************************************************************************************************* int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } else if (buttonValue >= 800){ return BUTTON_NONE; } return BUTTON_NONE; } //************************************************************************************************* // процедура сравнивает два времени и возвращает разницу в виде числа, учитывает переход времени через 0 // start_time - начальное время // end_time - конечное время // // !!!! процедура чуствительна к разрядности исполняемого кода !!!! // !!!! процедура может работать неправильно при двойном переходе времени через 0 !!!! //************************************************************************************************* unsigned long getDelayTime(unsigned long start_time, unsigned long end_time) { unsigned long result; if (start_time <= end_time) { result = end_time - start_time; } else { result = 4294967295 - end_time + start_time; } return result; } //************************************************************************************************* // процедура увеличивает или умеьшает значение разряда числа // num - начальное число // count - максимальная разрядность числа // nb - номер разряда, считам с лево на право, например: num=2, count=4, nb=2 считаем разряд указаный "X" 0X02. Результат увеличения будет число 102. // inc - флаг увеличение/уменьшения, если true - то увеличиваем //************************************************************************************************* int ChangeValue(int num, int count, int nb, boolean inc) { int result; String stringOne; int str_l; int sim; // сначала добьем нулями разрядность stringOne = String(num); str_l = count - stringOne.length(); for (int i=1; i <= str_l; i++){ stringOne = String("0") + stringOne; } // теперь изменяем нужный разряд sim = int(stringOne.charAt(nb-1)); if ((inc == true) && (sim < 57)) { sim = sim + 1; } else if ((inc == false) && (sim > 48)) { sim = sim - 1; } // запаковываем обратно в число stringOne.setCharAt(nb-1, char(sim)); result = stringOne.toInt(); return result; } //************************************************************************************************* // процедура выводит на экран заранее подготовленую строку, при этом выключает режим "Blink" // str - строка или String для вывода // col - номер позиции в строке экрана для вывода // line - номер строки экрана для вывода //************************************************************************************************* void PrintLcd(String str, int col, int line) { if (FlagCursor == true) { lcd.noBlink(); FlagCursor = false; } lcd.setCursor(col, line); lcd.print(str); } //************************************************************************************************* // процедура читает из энерго независимой памяти двухбйтовое число // num - идентификатор памяти (номер двухбайтного слова) //************************************************************************************************* int ReadInt(int num) { byte a; byte b; int result; a = int(EEPROM.read(num * 2)); b = int(EEPROM.read(num * 2 + 1)); result = a * 255 + b; return result; } //************************************************************************************************* // процедура записывает в энерго независимую память двухбйтовое число // num - идентификатор памяти (номер двухбайтного слова) // value - записываемое значение //************************************************************************************************* void WriteInt(int num, int value) { byte a; byte b; b = value % 255; a = (value - b) / 255; EEPROM.write(num * 2, a); EEPROM.write(num * 2 + 1, b); Beep(4); // сделано для выявления безконтрольной записи и снижения ресурса EEPROM } //************************************************************************************************* // процедура проверяет новую установленую температуру и сохраняет ее //************************************************************************************************* void set_term_set() { if (term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; } if (term_set_new != term_set) { // применяем новую температуру и запоминаем ее term_set = term_set_new; Set_term_set(term_set); } } //************************************************************************************************* // две процедуры, для получения данных с термопары //************************************************************************************************* double readCelsius() { uint16_t v; digitalWrite(thermoCS, LOW); _delay_ms(1); v = spiread(); v <<= 8; v |= spiread(); digitalWrite(thermoCS, HIGH); if (v & 0x4) { // uh oh, no thermocouple attached! //return NAN; return -101; } v >>= 3; return v*0.25; } byte spiread() { int i; byte d = 0; for (i=7; i>=0; i--) { digitalWrite(thermoCLK, LOW); _delay_ms(1); if (digitalRead(thermoDO)) { //set the bit to 0 no matter what d |= (1 << i); } digitalWrite(thermoCLK, HIGH); _delay_ms(1); } return d; } //************************************************************************************************* // процедура получает апромиксированое значение по температуре из эталонных массивов // NumParam - номер массива, 1 - ar_pow, 2 - ar_tep, 3 - ar_dt, 4 - ar_step // Term - температура к которой нужно получить значение //************************************************************************************************* int GetParamProc(byte NumParam, int Term){ int ir = 0; byte ii; byte i1; byte i2; // найдем индексы i1 = 0; for (byte ii=0; ii <= 9; ii++) { if (ar_temp[ii] > Term) { ii = ii - 1; break; } } if (ii <= 0) { i1 = 0; i2 = 1; } else if (ii >=9) { i1 = 8; i2 = 9; } else { i1 = ii; i2 = ii + 1; } // в i1 и i2 лежат индексы для массивов, начинаем апромиксацию 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]); } 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]); } 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]); } 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]); } return ir; } //************************************************************************************************* // процедуры, для записи и получении всех данных EEPROM // собраны здесь для единообразного адресного хранения и визуализации карты использования EEPROM, // адреса в двух байтовом виде (1 - это два байта с физическим адресом 2 и 3) //************************************************************************************************* // ------------------- чтение ------------------- int Get_signature() { return ReadInt(0); } // 0 - сигнатура int Get_term_set() { return ReadInt(1); } // 1 - установленая температура // 2...9 - резерв int Get_temp(int Num) { return ReadInt(Num+10); } // 10..19 - массив калибровочных температур int Get_pow(int Num) { return ReadInt(Num+20); } // 20..29 - массив мощности поддержания температуры int Get_tep(int Num) { return ReadInt(Num+30); } // 30..39 - массив температур инерционности int Get_dt(int Num) { return ReadInt(Num+40); } // 40..49 - массив времени цикла on/off int Get_step(int Num) { return ReadInt(Num+50); } // 50..59 - массив времени инерционности int Get_setup(int Num){ return ReadInt(Num+60); } // 60..69 - массив флагов калибровки // 70..99 - резерв // 100..511 - свободно // ------------------- запись ------------------- int Set_signature(int value) { WriteInt(0, value); } // 0 - сигнатура int Set_term_set(int value) { WriteInt(1, value); } // 1 - установленая температура // 2...9 - резерв void Set_temp(int Num, int value) { WriteInt(Num+10, value); } // 10..19 - массив калибровочных температур void Set_pow(int Num, int value) { WriteInt(Num+20, value); } // 20..29 - массив мощности поддержания температуры void Set_tep(int Num, int value) { WriteInt(Num+30, value); } // 30..39 - массив температур инерционности void Set_dt(int Num, int value) { WriteInt(Num+40, value); } // 40..49 - массив времени цикла on/off void Set_step(int Num, int value) { WriteInt(Num+50, value); } // 50..59 - массив времени инерционности void Set_setup(int Num, int value) { WriteInt(Num+60, value); } // 60..69 - массив флагов калибровки // 70..99 - резерв // 100..511 - свободнофайл OnKeyUp.ino :
//************************************************************************************************* // обработчик вызывается при отпускании кнопки клавиатуры // key - кнопка которая была отпущена // pressing - время которое кнопка была нажата //************************************************************************************************* void OnKeyUp (int key, unsigned long pressing) { int i ; if (key == BUTTON_SELECT) { // реализуем переход режима работы контроллера // ******************** переход в режим RUN ******************** if (mode == STATUS_STOP && pressing < BUTTON_TIME_LONG) { // перед стартом применим (и сохраним) установленую температуру set_term_set(); mode = STATUS_RUN; // иницилизируем дефолтные параметры расчета r_pow = GetParamProc(1, term_set); r_term = GetParamProc(2, term_set); r_dt = GetParamProc(3, term_set); r_step = GetParamProc(4, term_set); // дополнительные коэффициенты (плюсуются к основным) step_run = 0; time_heat_start = millis(); rk_pow = 0; LogSerial(6); Beep(3); } // ******************** переход в режим SETUP ******************** else if ( (mode == STATUS_STOP && pressing >= BUTTON_TIME_LONG) || (mode == STATUS_SETUP_RUN)) { mode = STATUS_SETUP; off_Relay(); edit_term = 0; } // ******************** переход в режим STOP ******************** else if ( (mode == STATUS_ERROR) || (mode == STATUS_RUN) || (mode == STATUS_SETUP && pressing < BUTTON_TIME_LONG)) { mode = STATUS_STOP; off_Relay(); edit_term = 0; Error_Term = 0; Error_Number = 0; } // ******************** переход в режим SETUP_RUN ******************** else if ((mode == STATUS_SETUP) && (pressing >= BUTTON_TIME_LONG)) { // перед калибровкой применим (и сохраним) установленую линейку порогов for (byte i=0; i <= 9; i++) { if (Get_setup(i) != ar_setup[i]) { Set_setup(i, ar_setup[i]); } } mode = STATUS_SETUP_RUN; step_run = 1; term_setup_max = 0; pow_setup_max = 100; edit_term = 0; setup_step = 0; Beep(3); } // после изменения режима нужно полностью обновить экран screen_out(true, true, true); } else if (key == BUTTON_RIGHT) { if (mode == STATUS_STOP) { // переключаем редактируемый разряд установленой температуры if (edit_term >= 4) { edit_term = 0; } else { edit_term = edit_term + 1; } if (term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; } screen_out(false, false, false); } else if (mode == STATUS_SETUP) { if (edit_term >= 10) { edit_term = 0; } else { edit_term = edit_term + 1; } screen_out(false, false, false); } } else if (key == BUTTON_LEFT) { if (mode == STATUS_STOP) { // переключаем редактируемый разряд установленой температуры if (edit_term == 0) { edit_term = 4; } else { edit_term = edit_term - 1; } if (term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; } screen_out(false, false, false); } else if (mode == STATUS_SETUP) { if (edit_term == 0) { edit_term = 10; } else { edit_term = edit_term - 1; } screen_out(false, false, false); } } else if (key == BUTTON_UP) { if ((mode == STATUS_STOP) && (edit_term != 0)) { // мы редактируем текущий разряд установленой температуры term_set_new = ChangeValue(term_set_new, 4, edit_term, true); if (term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; } } else if (mode == STATUS_SETUP) { switch (ar_setup[edit_term - 1]) { case 0: ar_setup[edit_term - 1] = 2; break; case 1: ar_setup[edit_term - 1] = 2; break; case 2: ar_setup[edit_term - 1] = 0; break; } ar_setup_scr[edit_term - 1] = 1; } } else if (key == BUTTON_DOWN) { if ((mode == STATUS_STOP) && (edit_term != 0)) { // мы редактируем текущий разряд установленой температуры term_set_new = ChangeValue(term_set_new, 4, edit_term, false); if (term_set_new > TERM_LIMIT) { term_set_new = TERM_LIMIT; } } else if (mode == STATUS_SETUP) { switch (ar_setup[edit_term - 1]) { case 0: ar_setup[edit_term - 1] = 2; break; case 1: ar_setup[edit_term - 1] = 0; break; case 2: ar_setup[edit_term - 1] = 0; break; } ar_setup_scr[edit_term - 1] = 1; } } }файл LogSerial.ino :
//************************************************************************************************* // процедура выводит в порт лог глобальных переменных, собрано здесь для удобства включения/отключения // и уменьшения текстов основной программы, Num - номер вызова лога //************************************************************************************************* void LogSerial(byte Num) { int i; // if (false) { if (true) { switch (Num) { case 0: Serial.print("=debug (setup.Start)="); Serial.println(); break; case 1: Serial.print("=debug (setup.FORMAT)="); Serial.println(); break; case 2: Serial.print("=debug (setup.ActualTable)="); Serial.println(); for (byte i=0; i <= 9; i++) { Serial.print("i: "); Serial.print(i); Serial.print(", ar_temp: "); Serial.print(ar_temp[i]); Serial.print(", ar_pow: "); Serial.print(ar_pow[i]); Serial.print(", ar_tep: "); Serial.print(ar_tep[i]); Serial.print(", ar_dt: "); Serial.print(ar_dt[i]); Serial.print(", ar_step: "); Serial.print(ar_step[i]); Serial.print(", ar_setup: "); Serial.print(ar_setup[i]); Serial.println(); } break; case 3: Serial.print("=debug (setup.setup)= Complete."); Serial.println(); break; case 4: Serial.print("=debug (Run.RunStep_1)="); Serial.print(" term_set: "); Serial.print(term_set); Serial.print(", term_real_new: "); Serial.print(term_real_new); Serial.println(); break; case 5: Serial.print("=debug (Run.RunStep_2)="); Serial.print(", rk_pow: "); Serial.print(rk_pow); Serial.println(); break; case 6: Serial.print("=debug (OnKeyUp.Start)="); Serial.print(" term_set: "); Serial.print(term_set); Serial.print(", r_pow: "); Serial.print(r_pow); Serial.print(", r_term: "); Serial.print(r_term); Serial.print(", r_dt: "); Serial.print(r_dt); Serial.print(", r_step: "); Serial.print(r_step); Serial.println(); break; case 7: Serial.print("=debug (Run.Setup.1)="); Serial.print(" setup_step: "); Serial.print(setup_step); Serial.print(", term_real_new: "); Serial.print(term_real_new); Serial.println(); break; case 8: Serial.print("=debug (Run.Setup.2)="); Serial.print(" setup_step: "); Serial.print(setup_step); Serial.print(", ar_tep[setup_step]: "); Serial.print(ar_tep[setup_step]); Serial.print(", ar_step[setup_step]: "); Serial.print(ar_step[setup_step]); Serial.println(); break; case 9: Serial.print("=debug (Run.Setup.3)="); Serial.print(" setup_step: "); Serial.print(setup_step); Serial.print(", term_real_new: "); Serial.print(term_real_new); Serial.println(); break; case 10: Serial.print("=debug (Run.Setup.End)="); Serial.print(" setup_step: "); Serial.print(setup_step); Serial.print(", term_real_new: "); Serial.print(term_real_new); Serial.print(", ar_pow[setup_step]: "); Serial.print(ar_pow[setup_step]); Serial.println(); break; } } }файл Beep.ino :
//************************************************************************************************* // процедура выводит на динамик звуки, сделана здесь, для удобства // Num - номер программы // 0 - нет звуков, // 1 - включение контроллера, // 2 - ошибка, // 3 - старт нагрева, // 4 - звук записи в EEPROM, //************************************************************************************************* void Beep(byte Num) { switch (Num) { case 0: // нет звуков noTone(beepCTRL); break; case 1: // включение контроллера tone(beepCTRL, 1000); delay(500); tone(beepCTRL, 4000, 500); break; case 2: // ошибка, tone(beepCTRL, 6000, 150); break; case 3: // старт нагрева, tone(beepCTRL, 300, 1000); break; case 4: // запись в EEPROM, tone(beepCTRL, 300, 100); break; } }Калибровка моей печи
Схема
Подпишусь на тему. Интересно увидеть фотографии печки.
фото ниже, но пока еще есть ошибки в программе...
А для чего печка?
печь до 1100 с,
способов применения полно, начиная от обжига глины заколкой сталей и заканчивая ювелиркой
рабочий вариант выложил сюда http://arduino.ru/forum/proekty/kontroller-mufelnoi-pechi
сабж можно закрывать :)