Необходимо включить насос через 3 минутыпосле того как одна из трех кнопок нажата(удерживается,сухой контакт) и отключить насос через 1 минутуесли ни одна кнопка не нажата.P.S. для теплого пола. 3 минуты задержки нужны для открытия сервопривода на коллекторе и 1 минута на закрытие
/*насос*/
unsigned long mill; // переменная под millis()
//-------кнопки---------------------
const byte Btn1Pin =/*пин*/2;
const byte Btn2Pin =/*пин*/3;
const byte Btn3Pin =/*пин*/4;
//-------насос---------------------
const byte pumpPin =/*пин*/13;
byte state = 0; /*0 выкл /1 вкл /2 собирается выкл/3 собирается вкл*/
const unsigned long timeON = 180000;
const unsigned long timeOFF = 60000;
unsigned long pastPump;
void stand(byte s) { /*установить в состояние*/
state = s;
pastPump = mill;
switch (s) {
case 0:/*0 выкл*/
digitalWrite(pumpPin, LOW);
break;
case 1:/*1 вкл*/
digitalWrite(pumpPin, HIGH);
break;
}
}
void initPump() { /* инициализация воткнуть в setup*/
pinMode(Btn1Pin, OUTPUT);
stand(0);
}
void runPump() { /*воткнуть в loop*/
if (state == 2 && mill - pastPump >= timeON ) stand(0);
if (state == 3 && mill - pastPump >= timeOFF) stand(1);
}
void ONtime() { /*вкл с задержкой*/
if (state == 1)return;
if (state == 3)return;
stand(3);
}
void OFFtime() { /*выкл с задержкой*/
if (state == 0)return;
if (state == 2)return;
stand(2);
}
//--------------main--------------
void setup() {
pinMode(Btn1Pin, INPUT_PULLUP);
pinMode(Btn2Pin, INPUT_PULLUP);
pinMode(Btn3Pin, INPUT_PULLUP);
initPump();
}
void loop() {
mill = millis();
bool Btn1 = digitalRead(Btn1Pin);
bool Btn2 = digitalRead(Btn2Pin);
bool Btn3 = digitalRead(Btn3Pin);
if (!Btn1 || !Btn2 || !Btn3) { /*если одна из кнопок нажата*/
ONtime(); /*то включить насос с задержкой 3 мин*/
}
if (Btn1 && Btn2 && Btn3) { /*если все кнопки отжаты */
OFFtime(); /*то отключить насос с задержкой 1 мин*/
}
runPump() ;
}
/*Скетч использует 1384 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 18 байт (0%) динамической памяти, оставляя 2030 байт для локальных переменных. Максимум: 2048 байт.
*/
Так скетч Блинкер. Задаете программу и мигает по программе. Нажали кнопку включилось. еще раз нажали выключилось. Можно хоть на мигать различными ногами и по своей программе.
/**/
unsigned long mill;
typedef void (*pDo)() ;// тип -функция обработчик
//------------------------------------
typedef struct { /*формат записи программы*/
byte maxTick; // количество миганий
unsigned long OnTick; // сколько нужно светить
unsigned long OffTick; // сколько "держать паузу
} Tick_t;
enum {sStop = 0, sStart, sOnTick, sOffTick, sPause};
class Cl_Blinker {
protected:
byte pin;/*нога*/
Tick_t *prog;
unsigned long past, interval;
const unsigned long pause = 1000;/*длительность паузы между сериями*/
byte iTick, iPeriod, maxTick, maxPeriod;
byte state;
void stand(byte s) {
state = s;
past = mill;
switch (state) {
case sStop:
digitalWrite(pin, LOW);
break;
case sStart:
iTick = 0;
iPeriod = 0;
maxTick = prog[iPeriod].maxTick;
state = sOnTick;
case sOnTick:
interval = prog[iPeriod].OnTick;
digitalWrite(pin, HIGH);
break;
case sOffTick:
interval = prog[iPeriod].OffTick;
digitalWrite(pin, LOW);
break;
case sPause:
interval = pause;
break;
}
}
public:
Cl_Blinker(byte p, Tick_t *pr, byte s)
: pin(p), prog(pr), maxPeriod(s) {}
void init() {
pinMode(pin, OUTPUT);
stand(sStop);
}
void run() {
if (state == sOnTick && mill - past >= interval) stand(sOffTick);
if (state == sOffTick && mill - past >= interval) {
iTick++;
if (iTick >= maxTick) {
iPeriod++;
if (iPeriod >= maxPeriod) {
stand(sPause);
return;
}
else {
iTick = 0;
maxTick = prog[iPeriod].maxTick;
stand(sOnTick);
}
}
else stand(sOnTick);
}
if (state == sPause && mill - past >= interval) stand(sStart);
}
void start() {
stand(sStart);
}
void stop() {
stand(sStop);
}
};
//------Cl_Btn----------------------
// класс кнопка
class Cl_Btn {
protected:
const byte pin;
pDo Do1, Do2; //обработчик 1 и 2
bool bounce = 0;
bool btn = 1, oldBtn;
unsigned long past;
byte stand = 0;
void tick() {
if (stand == 0) {
stand = 1;
Do1();
}
else {
stand = 0;
Do2();
}
}
public:
/*конструктор*/
Cl_Btn(byte pin_, pDo D1, pDo D2)
: pin(pin_), Do1(D1), Do2(D2) {}
/*инициализация-вставить в setup()*/
void init() {
pinMode(pin, INPUT_PULLUP);
tick();
}
/*работа-вставить в loop()*/
void run() {
bool newBtn = digitalRead(pin);
if (!bounce && newBtn != btn) {
bounce = 1;
past = mill;
}
if (bounce && mill - past >= 10) {
bounce = 0 ;
oldBtn = btn;
btn = newBtn;
if (!btn && oldBtn) tick();
}
}
};
//------Компоновка-------------------------------
Tick_t prog[] = {
/* maxTick OnTick OffTick*/
{3, 100 , 100}, // 3 коротких
{3, 500 , 100}, // 3 длиных
{3, 100 , 100}, // 3 коротких
};
byte step = sizeof(prog) / sizeof(Tick_t); // вычисляем сколько у нас всего "комманд".
Cl_Blinker Blinker(/*пин*/13,/*программа*/prog,/*количество*/step);
void Do1Btn1() {
Blinker.start();
}
void Do2Btn1() {
Blinker.stop();
}
Cl_Btn Btn1(/*пин*/2,/*обработчик 1*/Do1Btn1,/*обработчик 2*/Do2Btn1);
//---------Main----------------------------
void setup() {
Blinker.init();
Btn1.init();
}
void loop() {
mill = millis();
Blinker.run();
Btn1.run();
}
/*Скетч использует 1910 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 74 байт (3%) динамической памяти, оставляя 1974 байт для локальных переменных. Максимум: 2048 байт.
*/
Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
По коду, voidstand(bytes) выполняет 5 действий (причем 2 из них совпадают) в зависимости от параметра, а два из этих действий обернуты в отдельный вызов в стр55-62. Это явно надумано. Делаем просто 4 функции voidstandOFF() voidstandRed() ..... и массив указателей на них, заполненный по порядку их включения. И паузы тоже в массив. В результате стр.50-53 приятно ужимаются почти в одну и их кол-во перестает зависить от числа режимов. И тогда любые хотелки типа мигания зеленого легко добавляются причем почти без правки кода, только добавлением в массив указателей на функции и массив пауз. А совсем уж по уму держать один массив структур.
Logik, здесь используется цифровой автомат. И решается через цифровой автомат. Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Logik пишет:
Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
Это все можно организовать дополнительным классом. Просто расписав алгоритм работы и состояния системы. Как и частоту мигания . А так же вывод сколько секунд осталось до переключения.
Пух, ну вот КАК тебе удается нести херню, вроде бы, с виду правильными словами? Я вот когда несу, у меня слова неправильные, а у тебя дар. Я прям завидую.
Спасибо вам за тему! Очень полезная. Вы советовали книгу вначале темы. И там как мне показалось указано, что нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17. Однако ваш код работает.
class Cl_Btn {
13
byte pin; // номер ноги на кнопке
14
void (* Do)();// указатель на обработчик
15
bool btn, btn_old;
16
bool bounce = 0; // антидребезговый флаг
17
uint32_t past = 0 ;
18
public:
19
// конструктор класса
20
Cl_Btn( byte _pin, void (* _Do)()): pin(_pin), Do(_Do) {}
21
// метод setup()
22
void setup() {
23
pinMode(pin, INPUT_PULLUP);// подключить кнопку 1 с подтяжкой
24
btn = digitalRead(pin); // прочитать реальное значение на выводе};
25
}
26
// метод loop()
27
void loop() {
28
if (! bounce && btn != digitalRead(pin)) { // если прошел фронт изм на выводн
29
bounce = 1; // выставить флаг
30
past = millis(); // сделать временую засветку
31
}
32
else if ( bounce && millis() - past >= 5 ) { // если прошло антидребезговое время
33
bounce = 0; // то снять флаг
34
btn_old = btn ;
35
btn = digitalRead(pin) ; // прочитать реальное значение на выводе
36
if (btn_old && ! btn) Do();
37
}
38
}
39
};
freeman86, а вот здесь вылез факт о котором новички не догадываются. Они считают что Си/Си++ уже не развивается и не меняется. А последняя редакция Си произошла в 2017 году. А книга о Си написана еще до этих изменений.
нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17.
Без крайней нужды этого лучше не делать. А если делать, то точно знать что именно Вы делаете. Там очень много тонкостей, и очень многое может пойти не так. Инициализация в конструкторе - значительно проще и надёжнее.
вот тут по ссылке бит инверсии. Не понимаю, в чем преимущество такого варианты перед led = !led? И как понимать синтаксис led ^ inv, в таблице я оператор ^ не нашел, только ^=.
Теперь по программе. Есть реле (светодиоды и т д) . Некоторые срабатывают при HIGH, другие по LOW. Можно написать для них два класса. Но можно написать универсальный, где ввести в консруктор дополнитнльную переменную inv. Если inv - LOW , то это срабатывание при HIGH. И обратно. То есть использование оператора ^ упрощает и сокращает код. И в конце концов делает "универсальный класс".
В большинстве случаев, это неважно, там разница маленькая, но методологически это неправильно.
а так сойдёт?
void loop() {
if (uint32_t m = millis() - past > 100) {
*_pnt = map(analogRead(_pin), 0, 1023, 0, 31000);// 31 Ампер
past = m; //millis(); // Измеряем раз в 100 миллисекунд
}
}
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Не нужно разбрасывать свой вопрос одновременно по нескольким темам.
А вот скетч
Так скетч Блинкер. Задаете программу и мигает по программе. Нажали кнопку включилось. еще раз нажали выключилось. Можно хоть на мигать различными ногами и по своей программе.
Светофор через цифровой автомат.
Это картинка не подходит для программирования.Попробуем немного изменить.
Вот получился скетч.
Нипонял, а где мигание зеленого за 3сек до переключения на желтый и где одновременное горение желтого и красного перед переключением на зеленый?
По коду,
void
stand(
byte
s)
выполняет 5 действий (причем 2 из них совпадают) в зависимости от параметра, а два из этих действий обернуты в отдельный вызов в стр55-62. Это явно надумано. Делаем просто 4 функцииvoid
stand
OFF
(
)
void
stand
Red(
)
..... и массив указателей на них, заполненный по порядку их включения. И паузы тоже в массив. В результате стр.50-53 приятно ужимаются почти в одну и их кол-во перестает зависить от числа режимов. И тогда любые хотелки типа мигания зеленого легко добавляются причем почти без правки кода, только добавлением в массив указателей на функции и массив пауз. А совсем уж по уму держать один массив структур.Logik, здесь используется цифровой автомат. И решается через цифровой автомат. Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Logik, здесь используется цифровой автомат
таниужели! Ого как! )))) Может добавить знак "Осторожно, цифровой автомат!" ;)
Если начать оптимизировать, то точно сведется к черному ящику и нефиг лезть туда, где и так все работает.
Я и не предлагал Вам от цифрового автомата отказыватся. Эта штука годная. Но похоже Вам нравится одиночество в этой теме. Продолжайте.
Пух, ну вот КАК тебе удается нести херню, вроде бы, с виду правильными словами? Я вот когда несу, у меня слова неправильные, а у тебя дар. Я прям завидую.
))))
Это потому что у него нетрадиционное виденье поддерживается крепостью веры.
Зато когда вижу типа такого
понимаю что в китайском коде некоторые китайцам и фору дать могут.
https://vk.com/wall-51126445?q=Arduino
За тему большое спасибо!
Для новичков или подзабывших про программаж на С/С++ очень полезно.
freeman86, а вот здесь вылез факт о котором новички не догадываются. Они считают что Си/Си++ уже не развивается и не меняется. А последняя редакция Си произошла в 2017 году. А книга о Си написана еще до этих изменений.
https://www.youtube.com/watch?v=eSwrisPYrXE
нельзя при создании класса присваивать значение переменным в этом классе. Строки 16 и 17.
Без крайней нужды этого лучше не делать. А если делать, то точно знать что именно Вы делаете. Там очень много тонкостей, и очень многое может пойти не так. Инициализация в конструкторе - значительно проще и надёжнее.
Еще вопросы по дальнейшему коду, если не возражаете. Я все сам переписываю и загружаю в плату )
http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-ch...
вот тут по ссылке бит инверсии. Не понимаю, в чем преимущество такого варианты перед led = !led? И как понимать синтаксис led ^ inv, в таблице я оператор ^ не нашел, только ^=.
Шаблоны для тех кто не знал, а потом случилось несчастье забыл. Код отсюда #10
Класс
И через шаблон
А на мой вопрос по поводу бита инверсии и led ^ inv ответите? )
freeman86,Возьмем таблицу операторов в Си. https://msdn.microsoft.com/ru-ru/library/126fe14k.aspx ^ Побитовое исключающее ИЛИ led здесь bool- то есть два значения. Это по синтасису.
Теперь по программе. Есть реле (светодиоды и т д) . Некоторые срабатывают при HIGH, другие по LOW. Можно написать для них два класса. Но можно написать универсальный, где ввести в консруктор дополнитнльную переменную inv. Если inv - LOW , то это срабатывание при HIGH. И обратно. То есть использование оператора ^ упрощает и сокращает код. И в конце концов делает "универсальный класс".
Шаблоны для тех кто не знал, а потом случилось несчастье забыл. Код отсюда #10
И через шаблон
Квон, тебе не надоело с напыщенностью усталого ментора постить код с детскими ошибками?
Лови пример для твоего класса с шаблоном:
А теперь объясни мне. Все пуши завершились успешно, так какая же зараза стырила первые две буквы выводной строки? Куда они делись?
И это кстати, не единственная ошибка в этом коротеньком куске говнокода. Вторая, правда, не детская, а скорее идеологическая. Показать?
для твоего класса с шаблоном:
А код без шаблонов что, лучше? Те же самые детские ошибки. Но ТС не очень адекватно реагирует на сообщения об ошибках, так что я уж давно помалкиваю.
Чёт квон не спешит ошибки править. Решил кинуть своих читателей, которые надеются найти у него решение своих проблем :(((
В большинстве случаев, это неважно, там разница маленькая, но методологически это неправильно.
а так сойдёт?
Смотря для какой цели. Попробуй после второй строки m попечатать и посмотри, устроит тебя или не очень :-)
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Скажите пожалуйста, а как сделать так, чтоб этот код, описанный в посте #18, на выходе выдавал, скажем, 3 импульса по 2 секунды с интервалом между импульсами в 5 секунд?
Не нужно разбрасывать свой вопрос одновременно по нескольким темам.
Ответил в соседней.
Кроме того, похожий вопрос обвсуждался здесь: http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/imitatsiya-bortovykh-ognei-samoleta