Тайме обратного хода для паяльной станции
- Войдите на сайт для отправки комментариев
Доброго времени суток!
Собрал таймер кухонный по этой схеме http://mk90.blogspot.fr/2009_06_01_archive.html
Работает замечательно. Но он не подходит для моих нужд. Я новичок не шар. в программировании. Умею только повторять чужие проекты.
Нашел в скетче чтобы первоначальное время было не 0000 а свое. Мне нужно чтобы он астоматически стартовал без нажатия на кнопки и при старте на какой нибудь вывод подавал лог 1. после окончания таймера лог.0 для включения реле.
Данное устройство нужно чтобы автоматически выключать паяльную станцию чтобы не горели жала. у меня дорогие паяльные станция фирмы PACE и OKI.
вот. скетч. что тут нужно переделать. заранее спасибо!
/* кухонный таймер */
#define SEG_NUM 4 // total digits in a display
#define BUTT_NUM 2 // total buttons number
#define delayms 1 // time for displaying one digit, ms
#define p_buzz 8
// управление дисплеем
byte latch[SEG_NUM] = {0,0,0,0}; // защелка состояний
boolean flash_all = true; // мигание
boolean flash_dots = false;
byte s_pin[SEG_NUM]; // пины общих катодов
byte l_pin[8]; // мап пинов на сегменты знакоместа
byte d_map[10]; // память знакогенератора
// State Machines
typedef enum { E_WAIT=0, E_SETUP, E_STARTED, E_ALARMED} fsm_type;
fsm_type state = E_WAIT;
typedef enum { NO_EVENT=0, KEY1_PRESSED, KEY2_PRESSED, KEY12_PRESSED, KEYS_CHANGED} key_press_type;
int key_event = NO_EVENT;
byte b_pins[BUTT_NUM] = {10,9};
boolean b_changed[BUTT_NUM] = {false,false};
int b_state[BUTT_NUM] = {HIGH,HIGH};
// машина состояний таймера
word timer_delay = 0; // задержка, на которую программируется таймер
boolean started = false; // таймер запущен
boolean alarmed = false; // включен акустический сигнал
unsigned long t_start; // засечка времени старта
unsigned long t_stop; // засечка времени останова
// машина состояния кнопок
unsigned long button_timeout; // засечка последнего времени изменения кнопок
void setup() {
s_pin[0] = 4;
s_pin[1] = 5;
s_pin[2] = 6;
s_pin[3] = 7;
l_pin[0] = 3; // a
l_pin[1] = 17; // b
l_pin[2] = 19; // c
l_pin[3] = 15; // d
l_pin[4] = 14; // e
l_pin[5] = 2; // f
l_pin[6] = 18; // g
l_pin[7] = 16; // dot
for (byte i=0;i<SEG_NUM;i++) {
pinMode(s_pin[i],OUTPUT);
digitalWrite(s_pin[i],LOW);
}
for (byte i=0;i<8;i++) pinMode(l_pin[i],OUTPUT);
d_map[0] = 0b00000010; // 0
d_map[1] = 0b10011110; // 1
d_map[2] = 0b00100100; // 2
d_map[3] = 0b00001100; // 3
d_map[4] = 0b10011000; // 4
d_map[5] = 0b01001000; // 5
d_map[6] = 0b01000000; // 6
d_map[7] = 0b00011110; // 7
d_map[8] = 0b00000000; // 8
d_map[9] = 0b00001000; // 9
// кнопки
for (byte i=0;i<BUTT_NUM;i++) {
pinMode(b_pins[i],INPUT);
digitalWrite(b_pins[i],HIGH); // enable pull-up R
}
//
pinMode(p_buzz,OUTPUT);
digitalWrite(p_buzz,LOW);
// Serial.begin(38400);
}
void set_digit(byte d) {
byte i=0;
for (byte mask=0x80;mask!=1;mask>>=1)
digitalWrite(l_pin[i++],(d_map[d]&mask) ? HIGH : LOW );
}
void indicate() {
if (!flash_all || (flash_all && (millis() % 1000UL > 200))) {
digitalWrite(l_pin[7], (!flash_dots || (flash_dots && (millis() % 1000UL > 500))) ? LOW : HIGH);
for (byte k=0;k<SEG_NUM;k++) {
digitalWrite(s_pin[k],HIGH);
set_digit(latch[k]);
delay(delayms);
digitalWrite(s_pin[k],LOW);
}
}
}
void set_display(unsigned long secs) {
latch[3] = secs % 10;
if (secs > 9) {
latch[2] = (secs % 60) / 10;
}
else latch[2] = 0;
if (secs > 59) {
latch[1] = (secs / 60) % 10;
}
else latch[1] = 0;
if (secs > (60*10 -1) ) {
latch[0] = secs / 600;
} else latch[0] = 0;
}
void update_time() {
unsigned long t_now = millis();
if (state == E_STARTED) {
if (t_now >= t_stop) {
set_display(timer_delay);
flash_all = true;
flash_dots = false;
alarmed = true;
state = E_ALARMED;
} else set_display((t_stop - t_now) / 1000UL);
} else set_display(timer_delay);
}
void update_alarm() {
digitalWrite(p_buzz, (alarmed && (millis() % 2000UL > 999)) ? HIGH : LOW);
}
int get_key_event() {
for (int i=0;i<BUTT_NUM;i++) {
b_changed[i]=false;
int bread = digitalRead(b_pins[i]);
if (bread != b_state[i]) {
b_changed[i]=true;
b_state[i]=bread;
}
}
if (b_changed[0] || b_changed[1]) {
if ( (b_state[0] == LOW) && (b_state[1] == LOW)) return KEY12_PRESSED;
else if ( (b_state[0] == LOW) && b_changed[0]) return KEY1_PRESSED;
else if ( (b_state[1] == LOW) && b_changed[1]) return KEY2_PRESSED;
else return KEYS_CHANGED;
} else
return NO_EVENT;
}
void update_buttons() {
int evt = get_key_event();
switch (evt) {
case NO_EVENT: {
if (state == E_SETUP) {
if ( timer_delay && ((millis() - button_timeout) > 5000) ) {
t_start = millis();
t_stop = t_start + (unsigned long)timer_delay*1000UL;
flash_all = false;
flash_dots = true;
started = true;
state = E_STARTED;
}
}
return;
} break;
case KEY1_PRESSED: {
if (state == E_WAIT) state = E_SETUP;
button_timeout = millis();
if (state == E_SETUP)
timer_delay+=(timer_delay>599?600:60);
} break;
case KEY2_PRESSED: {
if (state == E_WAIT) state = E_SETUP;
button_timeout = millis();
if (state == E_SETUP) {
if (timer_delay < 60) timer_delay = 0;
else timer_delay-=(timer_delay>(15*60-1)?300:60);
}
} break;
case KEY12_PRESSED: {
if (state == E_WAIT) state = E_SETUP;
button_timeout = millis();
if (state == E_SETUP) {
timer_delay=0;
}
} break;
case KEYS_CHANGED: {
if (state == E_WAIT) state = E_SETUP;
button_timeout = millis();
if (state == E_ALARMED) {
alarmed = false;
state = E_WAIT;
}
} break;
}
}
void loop() {
indicate();
update_time();
update_alarm();
update_buttons();
}
Сдесь ставится первоначальное время
word timer_delay = 0; // задержка, на которую программируется таймер
Друг, ну ты хоть расскажи, разобрался ли с автозапуском таймера этого кода? А то я уже неделю в этот код втыкаюсь над этой же задачей. Чую ещё чуть чуть и Си уже выучу..))
И ещё хочу разобраться как изменить этот скетч так, чтобы можно было использовать экран с общим катодом, а не с общим анодом.
Разобрался я с автозапуском!
Добавил условие (строки 155-161), что таймер стартует через 10 секунд после подачи питания, но не будет автостартовать если контроллер проработал без сброса больше 30 сек ( т.е. автостарт работает только первый раз)
switch (evt) { case NO_EVENT: { if (state == E_WAIT && millis() > 10000UL && millis() < 30000UL) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; if (state == E_SETUP) { if ( timer_delay && ((millis() - button_timeout) > 5000) ) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; } } } return;С замыканием реле при окончании времени разобрался пока очень просто - использовал выход для пищалки. теперь при окончании времени на D8 просто появляется лог1 и будет она там, пока не нажмётся кнопка или не сбросится питание.
void update_alarm() { digitalWrite(p_buzz, (alarmed /* && (millis() % 2000UL > 999)*/) ? HIGH : LOW); }Но это временная мера, т.к. пищалка мне всётаки нужна, причём чтоб попискивала она каждую секунду, но я думаю взять для этих нужд выход который мигает точками на экране или продублировать этот кусок кода на другой выход под пищалку.
Ну и осталось разобраться с подключением дисплеев с общим катодом
Sky-DiGGeR, Доброго времени суток!
С кодом я не разобрался. Только почему прога стартует через 10 секунд не понятно? Нужно сократить время хотя бы до 3-х секунд. 10 это много
Еще вопрос. Под рукойнет ардуино т.к. на работе нахожусь. Прога работает так я правильно понял: при подаче питания проходит 10 секунд и начинается обратный отсчет. на D8 появляется лог. 1 для включения реле. после оканчания отсчета чтобы запустить нужно нажать на резет или переподать напругу
Нужно сократить время хотя бы до 3-х секунд. 10 это много
мне надо было именно столько , можешь подправить тут 10000 на 3000, и будет стартовать через 3 сек.
if (state == E_WAIT && millis() > 10000UL && millis() < 30000UL) {Прога работает так я правильно понял: при подаче питания проходит 10 секунд и начинается обратный отсчет. на D8 появляется лог. 1 для включения реле. после оканчания отсчета чтобы запустить нужно нажать на резет или переподать напругу
Нет, на D8 появляется лог 1 только после отработки времени обратного отсчёта и висит там пока таймер мигает всеми цифрами в ожидании команды. В принципе сделать так чтобы пока работает таймер, на D8 висела лог1, тоже не сложно:
void update_alarm() { digitalWrite(p_buzz, (started ) ? HIGH : LOW); // лог1 пока таймер запущен }но тогда надо ещё добавить одну строку в секции void update_time()
void update_time() { unsigned long t_now = millis(); if (state == E_STARTED) { if (t_now >= t_stop) { set_display(timer_delay); flash_all = true; flash_dots = false; alarmed = true; started = false; state = E_ALARMED; } else set_display((t_stop - t_now) / 1000UL); } else set_display(timer_delay); }такой вариант я не проверял натурно, но логически всё должно работать )
Спасибо за труд! Завтра притащу ардуино и проверю.
Такие штуки хочу еще установить на лампочки освещения и на элетромоторы насосов. От забывчивости. Но их буду делать без дисплея и кнопок. буду использовать только выход и пущу на симистор.
Вообще, если тебе надо просто задержку выключения органзовать после умпульсного включения питания, например по кнопке без фиксации и не нужны никакие дисплеи с цифирками, то это очень легко и быстро организуется на таймере NE555. Схем в инете море, собираются на коленке за 15 минут и настройка задержки простым подбором R C , по формуле 1.1 * R (МОм) * С (мкФ) = t (сек)
Про NE555 я знаю. На нем много че собирал. Она она мне не подходит. в некоторых местах мне нужна все же индикация процесса. Прошивать прогу буду в мега 8 контроллеры. памяти должно хватить. Их уже заказал на алиэкспрессе
Проверил код. Все работает! Сам стартует через 10 секунд. На D8 появляется после старта 4,5вольт лог 1.
Но вот не разобрался с автостартом так и. чтобы он стартовал не через 10 секунд а через 3.
Чтобы стартовала через 3 сек, вот тут:
switch (evt) { case NO_EVENT: { if (state == E_WAIT && millis() > 10000UL && millis() < 30000UL) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; if (state == E_SETUP) { if ( timer_delay && ((millis() - button_timeout) > 5000) ) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; } } } return;Надо сделать вот так:
switch (evt) { case NO_EVENT: { if (state == E_WAIT && millis() > 3000UL && millis() < 30000UL) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; if (state == E_SETUP) { if ( timer_delay && ((millis() - button_timeout) > 5000) ) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; } } } return;Еще олин вопрос. После отсчитывания временя чтобы он не показывал установленное а 0000 показывал что нужно менять?
Все разобрался с временем автозапуска: if (state == E_WAIT && millis() > 1000UL && millis() < 30000UL) {
тут 1000 поставил 1 секунду
Все отлично работает. Жаль только буззера нет по окончании работы
Собрал 3 устройства.
Один на защиту насоса на гидроаккумулятор. поставил на 3.5 минут.
ВТорой. На душевую кабинку и тепличку на 30 минут.
Третий в баню. на 14 минут.
Добрый день!
Добрые люди, от Вас снова нужна помощь.
Купил я приблуду TM1637 СВЕТОДИОДНЫЙ Дисплей Модуль Для arduino 7 Сегмент 4 Бит https://ru.aliexpress.com/item/Free-shipping-4-digital-display-with-adjustable-brightness-LED-module-clock-Point-Accessories-Blocks-for-arduino/32243608784.html?spm=2114.13010608.0.0.WWDPGf&detailNewVersion=&categoryId=541
Хочу на таймер поставить этот дисплей. т.к. он по 2 проводам управляется. Помогите с кодом плиз. С меня пиво!
Еще одна хотелочка. Чтобы по окончании отсчета раз 5 пропищала пищалка. у меня есть со встроенным генератором на 5В. На любую свободную ногу
/* кухонный таймер */ #define SEG_NUM 4 // total digits in a display #define BUTT_NUM 2 // total buttons number #define delayms 1 // time for displaying one digit, ms #define p_buzz 8 // управление дисплеем byte latch[SEG_NUM] = {0,0,0,0}; // защелка состояний boolean flash_all = true; // мигание boolean flash_dots = false; byte s_pin[SEG_NUM]; // пины общих катодов byte l_pin[8]; // мап пинов на сегменты знакоместа byte d_map[10]; // память знакогенератора // State Machines typedef enum { E_WAIT=0, E_SETUP, E_STARTED, E_ALARMED} fsm_type; fsm_type state = E_WAIT; typedef enum { NO_EVENT=0, KEY1_PRESSED, KEY2_PRESSED, KEY12_PRESSED, KEYS_CHANGED} key_press_type; int key_event = NO_EVENT; byte b_pins[BUTT_NUM] = {10,9}; boolean b_changed[BUTT_NUM] = {false,false}; int b_state[BUTT_NUM] = {HIGH,HIGH}; // машина состояний таймера word timer_delay = 900; // задержка, на которую программируется таймер boolean started = false; // таймер запущен boolean alarmed = false; // включен акустический сигнал unsigned long t_start; // засечка времени старта unsigned long t_stop; // засечка времени останова // машина состояния кнопок unsigned long button_timeout; // засечка последнего времени изменения кнопок void setup() { s_pin[0] = 4; s_pin[1] = 5; s_pin[2] = 6; s_pin[3] = 7; l_pin[0] = 3; // a l_pin[1] = 17; // b l_pin[2] = 19; // c l_pin[3] = 15; // d l_pin[4] = 14; // e l_pin[5] = 2; // f l_pin[6] = 18; // g l_pin[7] = 16; // dot for (byte i=0;i<SEG_NUM;i++) { pinMode(s_pin[i],OUTPUT); digitalWrite(s_pin[i],LOW); } for (byte i=0;i<8;i++) pinMode(l_pin[i],OUTPUT); d_map[0] = 0b00000010; // 0 d_map[1] = 0b10011110; // 1 d_map[2] = 0b00100100; // 2 d_map[3] = 0b00001100; // 3 d_map[4] = 0b10011000; // 4 d_map[5] = 0b01001000; // 5 d_map[6] = 0b01000000; // 6 d_map[7] = 0b00011110; // 7 d_map[8] = 0b00000000; // 8 d_map[9] = 0b00001000; // 9 // кнопки for (byte i=0;i<BUTT_NUM;i++) { pinMode(b_pins[i],INPUT); digitalWrite(b_pins[i],HIGH); // enable pull-up R } // pinMode(p_buzz,OUTPUT); digitalWrite(p_buzz,LOW); // Serial.begin(38400); } void set_digit(byte d) { byte i=0; for (byte mask=0x80;mask!=1;mask>>=1) digitalWrite(l_pin[i++],(d_map[d]&mask) ? HIGH : LOW ); } void indicate() { if (!flash_all || (flash_all && (millis() % 1000UL > 200))) { //1000UL > 200 digitalWrite(l_pin[7], (!flash_dots || (flash_dots && (millis() % 1000UL > 500))) ? LOW : HIGH); for (byte k=0;k<SEG_NUM;k++) { digitalWrite(s_pin[k],HIGH); set_digit(latch[k]); delay(delayms); digitalWrite(s_pin[k],LOW); } } } void set_display(unsigned long secs) { latch[3] = secs % 10; if (secs > 9) { latch[2] = (secs % 60) / 10; } else latch[2] = 0; if (secs > 59) { latch[1] = (secs / 60) % 10; } else latch[1] = 0; if (secs > (60*10 -1) ) { latch[0] = secs / 600; } else latch[0] = 0; } void update_time() { unsigned long t_now = millis(); if (state == E_STARTED) { if (t_now >= t_stop) { set_display(timer_delay); flash_all = true; flash_dots = false; alarmed = true; started = false; //////// state = E_ALARMED; } else set_display((t_stop - t_now) / 1000UL); } else set_display(timer_delay); } /// A L A R M void update_alarm() { // digitalWrite(p_buzz, (alarmed /* && (millis() % 2000UL > 999)*/) ? HIGH : LOW); digitalWrite(p_buzz, (started ) ? HIGH : LOW); // лог1 пока таймер запущен } int get_key_event() { for (int i=0;i<BUTT_NUM;i++) { b_changed[i]=false; int bread = digitalRead(b_pins[i]); if (bread != b_state[i]) { b_changed[i]=true; b_state[i]=bread; } } if (b_changed[0] || b_changed[1]) { if ( (b_state[0] == LOW) && (b_state[1] == LOW)) return KEY12_PRESSED; else if ( (b_state[0] == LOW) && b_changed[0]) return KEY1_PRESSED; else if ( (b_state[1] == LOW) && b_changed[1]) return KEY2_PRESSED; else return KEYS_CHANGED; } else return NO_EVENT; } void update_buttons() { int evt = get_key_event(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// switch (evt) { // АВТОСТАРТ case NO_EVENT: { if (state == E_WAIT && millis() > 1000UL && millis() < 30000UL) { // ТУТ ЗАДЕРЖКА 10000UL && millis() < 30000UL) 10СЕК., ТУТ СТАРТ СРАЗУ 1000UL && millis() < 30000UL t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; //1000 не трогать это значение flash_all = false; flash_dots = true; started = true; state = E_STARTED; } if (state == E_SETUP) { if ( timer_delay && ((millis() - button_timeout) > 5000) ) { t_start = millis(); t_stop = t_start + (unsigned long)timer_delay*1000UL; flash_all = false; flash_dots = true; started = true; state = E_STARTED; } } return; } break; case KEY1_PRESSED: { if (state == E_WAIT) state = E_SETUP; button_timeout = millis(); if (state == E_SETUP) timer_delay+=(timer_delay>599?600:60); } break; case KEY2_PRESSED: { if (state == E_WAIT) state = E_SETUP; button_timeout = millis(); if (state == E_SETUP) { if (timer_delay < 60) timer_delay = 0; else timer_delay-=(timer_delay>(15*60-1)?300:60); } } break; case KEY12_PRESSED: { if (state == E_WAIT) state = E_SETUP; button_timeout = millis(); if (state == E_SETUP) { timer_delay=0; } } break; case KEYS_CHANGED: { if (state == E_WAIT) state = E_SETUP; button_timeout = millis(); if (state == E_ALARMED) { alarmed = false; state = E_WAIT; } } break; } } void loop() { indicate(); update_time(); update_alarm(); update_buttons(); }Добрый день!
Как переделать программу по общие аноды??? дисплеи кончились с катодами :(