На вот эти вопросы ответить сможешь?
Я не люблю “менять коней на переправе” (изменять задачу по середине её решения).
На вот эти вопросы ответить сможешь?
Я не люблю “менять коней на переправе” (изменять задачу по середине её решения).
Еще раз предлагаю - напишу за 20 евро в крипте. Биткоин, USDT, Бинанс - что угодно. Или ты принципиально хочешь бесплатно? Вполне понимаю, но тогда - не я.
Подходит.
Далее в лс пожалуйста.
Всем спасибо.
А ТС быстро сдался.
Видимо
В данном случае интересно было бы разобраться самому
не сильно то и интересно…
/*
Абзавём входные данные, а именно пины для КНОПКИ и ТРЁХ РЕЛЕ
*/
#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 секунды время удержания кнопки
#define SHORT_TIME 3000
enum BUTTON_RESULT : uint8_t {
NOT_PRESS,
PRESS,
LONG_PRESS
};
BUTTON_RESULT current_button_res = NOT_PRESS;
const uint8_t RELE_PINS[] = {RELE1_PIN, RELE2_PIN, RELE3_PIN}, r_count = sizeof(RELE_PINS) / sizeof(RELE_PINS[0]);
uint8_t cur_rele = 0;
void releOff () {
for (uint8_t i = 0; i < r_count; i++) {
digitalWrite(RELE_PINS[i], LOW);
}
}
void setup() {
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
for (uint8_t i = 0; i < r_count; i++) {
pinMode(RELE_PINS[i], OUTPUT); // А пины реле на выход
}
// И выключим их все
releOff();
}
void loop() {
uint8_t button_state = digitalRead(BUTTON_PIN); // Ну во, вот тут мы её и "уконтропупили".
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: // Если кликнули один раз
releOff();
if (cur_rele < (r_count - 1)) {
digitalWrite(RELE_PINS[cur_rele], HIGH);
}
cur_rele = (cur_rele++) % r_count;
break;
case LONG_PRESS: // Если кномпу долго удерживали
releOff();
digitalWrite(RELE_PINS[r_count - 1], HIGH);
delay(SHORT_TIME);
digitalWrite(RELE_PINS[r_count - 1], LOW);
cur_rele = 0;
break;
case NOT_PRESS: // Если кнопку не нажимали
// Ничего не делаем. Это просто для наглядности
break;
default:
break;
}
}
Скетч использует 1396 байт (4%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 23 байт (1%) динамической памяти, оставляя 2025 байт для локальных переменных. Максимум: 2048 байт.
Ну вот не дал человеку заработать 20 ойро !
Да прям? )
Там у ТС еще пару раз ТЗ поменяется.
Этот код под первоначальное из первого сообщения и “додуманное” мною до логического завершения.
А у меня “по ходу пьесы” вопрос возник.
Если в setup вот такой код:
void releOff () {
for (uint8_t i = 0; i < r_count; i++) {
digitalWrite(RELE_PINS[i], LOW);
}
}
void setup() {
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
for (uint8_t i = 0; i < r_count; i++) {
pinMode(RELE_PINS[i], OUTPUT); // А пины реле на выход
}
// И выключим их все
releOff();
}
То скетч занимает 1396 байт, а если вот такой:
void setup() {
// Теперь настроим пины
pinMode(BUTTON_PIN, INPUT_PULLUP); // На вход и подтянуть к +питания (экономим на резисторах для "подтяжки")
for (uint8_t i = 0; i < r_count; i++) {
pinMode(RELE_PINS[i], OUTPUT); // А пины реле на выход
// И выключим их все
digitalWrite(RELE_PINS[i], LOW);
}
}
То на 16 байт меньше - 1380 байт. Почему так?
Почему так?
Блин, вот, не первый же раз замужем! Даже неудобно говорить, чтобы код полностью приводил. Если у меня предположение, но без полного кода - пальцем в небо.
По вашему лишний цикл в код отображается “бесплатно” ?
без полного кода - пальцем в небо.
Как же без него? Он чуть выше.
По вашему лишний цикл в код отображается “бесплатно” ?
Отчего же?
Но я всегда думал, что процедурный подход позволяет сокращать код, а не увеличивать его. Функция releOff() используется в нескольких местах.
Что происходит во время вызова функции?
А ленивый компилятор решил, нахер прыгать я ещё буду по адресам, заinline
л и нафиг.
Что происходит во время вызова функции?
PUSHится то что будет “испорчено”, организуется окно в стеке под локальные переменные (если нужно), …, POPается всё что было запушено. Плюс сами CALL и RET дают до 6 байт …
6 байт, но не 16.
К тому же digitalWrite() тоже функция. По сути я заменил одну функцию другой, но объем увеличился.
Не понимать.
У меня 1.8.19 и другие цифры:
С релеофф 1396
Без релеофф и c digitalWrite внутри цикла 1408
BOOM - спасибо большое.
Я не совсем уверен, но думаю, все дело в размере функции.
Если она довольно компактная, то оптимизатор вполне может её заинлайнить.
может её заинлайнить
Он может и цикл развернуть, благо, он там маленький. Над смотреть код. Не понимаю, почему этого до сих пор не сделано.
Почему так?
Потому, что код разный.
Не понимать.
Посмотри листинг.