Буду признателен за помощь в реализации следующего алгоритма:
имеется одна кнопка и три реле.
необходимо по короткому нажатию кнопки включать реле P1, следующее короткое нажатие выключает P1 и включает реле P2, длинное нажатие выключает любое из предварительно включенных P1 либо P2 и включает на короткое время P3.
Желательно реализовать все это на ARDUINO mini.
Возможно что-то подобное уже кем-то было реализовано.
Если вы сами вообще ничего изучать/писать не хотите, то вам в раздел Ищу исполнителя.
Спасибо, буду иметь в виду что имеется и такая возможность.
В данном случае интересно было бы разобраться самому, разумеется с помощью сообщества.
Так что от сообщества нужно? Алгоритм вами описан - берите и пишите его, только уже на C++.
Заодно более “осязаемое” значение приобретет
Ну так начинай писать! И уже по написанному тобой коду задавай вопросы. Начни с обработчика кнопки. События кнопки просто выводи в сериал. Потом, вместо сериала, подключишь свои реле.
Надо с чего-то начинать. Внесу на рассмотрение:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
3000р и код у тебя
Вот, вроде, всё ничего, но как-то вот … не концептуально, что ли …
Так потому, что это “скелет”, на него еще надо “мясо нарастить”…
YaGPT так ответил
Спойлер
int buttonPin = 2; // цифровой вывод, к которому подключена кнопка
int relayPinP1 = 3; // цифровой выход, к которому подключен контакт реле P1
int relayPinP2 = 4; // цифровой выход, к которому подключены контакты реле P2
int relayPinP3 = 5; // цифровой вход, к которому подключается контакт катушки реле P3
boolean isButtonPressed = false; // флаг, указывающий, была ли нажата кнопка
void setup() {
pinMode(buttonPin, INPUT); // устанавливаем пин, к которому подключена кнопка, в режим входа
pinMode(relayPinP1, OUTPUT); // устанавливаем цифровой выход, к которому подключен P1 в режим выхода
pinMode(relayPinP2, OUTPUT); // устанавливаем P2 в режим выхода
digitalWrite(relayPinP3, HIGH); // включаем реле P3 на высокое напряжение
}
void loop() {
if (digitalRead(buttonPin) == HIGH) { // если кнопка нажата
isButtonPressed = true; // устанавливаем флаг нажатой кнопки
digitalWrite(relayPinP1, LOW); // выключаем P1
delay(100); // задержка 100 мс
digitalWrite(relayPinP2, HIGH); // включаем P2
delay(500); // задержка на 500 мс
} else if (isButtonPressed == true) { // иначе, если кнопка нажата,
digitalWrite(relayPinP2, LOW); // выключаем P2
digitalWrite(relayPinP3, LOW); // выключаем реле P3
isButtonPressed = false; // сбрасываем флаг нажатой кнопки
}
}
Другой вариант
int buttonPin = 2; // Пин подключения кнопки
int p1Pin = 3; // Пин включения реле P1
int p2Pin = 4; // Пин включения реле P2
int p3Pin = 5; // Пин включения реле P3
boolean isP1On = false; // Флаг включения реле P1
boolean isP2On = false; // Флаг включения реле P2
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Подключаем кнопку к пину с подтягивающим резистором
pinMode(p1Pin, OUTPUT);
pinMode(p2Pin, OUTPUT);
pinMode(p3Pin, OUTPUT);
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // Если кнопка нажата
if (isP1On) { // Если реле P1 уже включено
digitalWrite(p1Pin, LOW); // Выключаем P1
isP1On = false;
} else {
digitalWrite(p2Pin, LOW); // Включаем P2
isP2On = true;
}
} else if (digitalRead(buttonPin) == HIGH) { // Если кнопка отпущена
digitalWrite(p3Pin, HIGH); // Включаем на короткое время P3
delay(50); // Задержка 50 мс
digitalWrite(p3Pin, LOW); // Отключаем P3
}
}
Работает или нет - не знаю !!!
А так?
void loop() {
// put your main code here, to run repeatedly:
}
void setup() {
// put your setup code here, to run once:
}
Поддерживаю! Где инициализация Serial, во что рыбу заворачивать будем как программу отлаживать?
Куда ТС то пропал?
Двигаемся дальше:
Спойлер
/*
* Абзавём входные данные, а именно пины для КНОПКИ и ТРЁХ РЕЛЕ
*/
#define BUTTON_PIN 12 // Кнопка
#define RELE1_PIN 2 // Реле 1
#define RELE2_PIN 3 // Реле 2
#define RELE3_PIN 4 // Реле 3
void setup() {
// Крутая вставка от DetSimen для отладки
Serial.begin(9600);
stdout = fdevopen([](char ch, FILE* f)->int {return Serial.print(ch); }, NULL);
// puts("Program started...");
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
pinMode(RELE1_PIN, OUTPUT); // А пины реле на выход
pinMode(RELE2_PIN, OUTPUT);
pinMode(RELE3_PIN, OUTPUT);
// И зададим начальное значение - все реле выключены
digitalWrite(RELE1_PIN, LOW);
digitalWrite(RELE2_PIN, LOW);
digitalWrite(RELE3_PIN, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
}
Скетч использует 772 байт (2%) памяти устройства. Всего доступно 32768 байт.
Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
Вставь, правда, в самое начало setup() строки
Serial.begin(115200);
stdout = fdevopen([](char ch, FILE* f)->int {return Serial.print(ch); }, NULL);
puts("Program started...");
отлаживать будет проще, весь стандартный Сишный вывод (printf(), puts(), putchar()) будет идти в Serial искаропки.
P.S. Алехандро, можно это в Вики вставить, полезная штучка. (наерна)
Нихарашо абзывацца!
окаймить
#ifdef DEBUG
....
#endif
Едем дальше?
/*
* Абзавём входные данные, а именно пины для КНОПКИ и ТРЁХ РЕЛЕ
*/
#define BUTTON_PIN 12 // Кнопка
#define RELE1_PIN 2 // Реле 1
#define RELE2_PIN 3 // Реле 2
#define RELE3_PIN 4 // Реле 3
#define TIME_BOUNCE 70 // 70мс время "фильтрации" дребезга контактов
#define LONG_PRESS_TIME 2000 // 2 секунды время удержания кнопки
enum BUTTON_RESULT : uint8_t {
NOT_PRESS,
PRESS,
LONG_PRESS
};
BUTTON_RESULT current_button_res = NOT_PRESS;
void setup() {
// Крутая вставка от DetSimen для отладки
Serial.begin(9600);
stdout = fdevopen([](char ch, FILE* f)->int {return Serial.print(ch); }, NULL);
// puts("Program started...");
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
pinMode(RELE1_PIN, OUTPUT); // А пины реле на выход
pinMode(RELE2_PIN, OUTPUT);
pinMode(RELE3_PIN, OUTPUT);
// И зададим начальное значение - все реле выключены
digitalWrite(RELE1_PIN, LOW);
digitalWrite(RELE2_PIN, LOW);
digitalWrite(RELE3_PIN, LOW);
}
void loop() {
// С чего начать основную программу?
// А начну-ка с чтения состояния кнопки. ТС, как думаешь - это правильное решение?
uint8_t button_state = digitalRead(BUTTON_PIN); // Ну во, вот тут мы её и "уконтропупили".
// Теперь в переменной button_state содержится состояние кнопки
// LOW - если кнопка нажата, и HIGH - если кнопка не нажата
// Ещё нам понадобятся дополнительные переменные, оставим место тут для них
uint32_t _millis = millis(); // Запомним текущее значение миллисекунд
static uint32_t timeHoldBegin; // Время начала удержания кнопки
static uint32_t timeHold; // Длительность удержания кнопки
// А дальше нам нужно узнать - нажимал кто на кнопку? А если нажимал - то как долго удерживал?
if (!button_state) { // Если кнопка нажата
timeHold = _millis - timeHoldBegin; // Считаем длительность удержания
} else { // Еслди кнопку отпустили
timeHoldBegin = _millis; // Сбрасываем
timeHold = 0;
current_button_res = NOT_PRESS;
}
if (timeHold > TIME_BOUNCE && timeHold < LONG_PRESS_TIME) { // Если время удержание в интервале между временем подавления дребезга и удержанием
current_button_res = PRESS; // То нужно как-то "зарегистрировать нажатие"
}
if (timeHold > LONG_PRESS_TIME) { // Если время удержание больше времени удержаниея (2 сек)
current_button_res = LONG_PRESS; // То нужно как-то "зарегистрировать долгое удержание"
}
// Состояние кнопки узнали.
// А дальше пошла "жара" (то есть обработка нажатий)
switch (current_button_res) {
case PRESS: // Если кликнули один раз
// Обрабатываем короткие нажатия
break;
case LONG_PRESS: // Если долго держали
// Обрабатываем долгое удержание
break;
case NOT_PRESS: // Если кнопку не нажимали
// Ничего не делаем. Это просто для наглядности
break;
default:
break;
}
}
а не Serial.write(ch);
случаем?
print() принимает char, а write() - int
Чегой-то не хватает)))