Кнопка в Arduino

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
Доброго времени суток. Чисто теоретический вопрос. Есть код, где кнопка постоянно опрашивается микроконтроллером нажата она или нет. Бывают коды, где кнопка опрашивается один раз, если изменила своё состояние. Вопрос такой. Если кнопка опрашивается постоянно, то микроконтроллер перегревается, устаёт или много памяти жрёт?
 

EugeneFrol

✩✩✩✩✩✩✩
17 Апр 2024
58
9
50
Нет. Обработка кнопки по прерыванию делается, если в теле цикла есть вызов функций, длительность выполнения которых очень большая.
В этот момент (без прерывания) нажатие кнопки программа просто не заметит.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,361
976
Если кнопка опрашивается постоянно, то микроконтроллер перегревается, устаёт или много памяти жрёт?
микроконтроллер, в отличии от процессора в ПК - всегда работает с одной скоростью. Соответственно, будет ли он постоянно опрашивать кнопку или просто бить баклуши в пустом цикле - "устанет" он одинаково

Обработка кнопки по прерыванию делается
Новичкам, ИМХО, лучше забыть про обработку кнопок в прерывании. Им это приносит больше проблем, чем пользы. Лучше учиться писать неблокирующий код, в котором кнопки будут успевать отрабатываться в основном цикле.
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
171
34
www.youtube.com
Прерывания это база. Это первое что нужно изучить, чтобы не мучать процессор говнокодом.
 

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
Интрига!!! Видимо речь о каком-то особом коде? А пацаны то не знают.
Обычный код, для вас может и слишком простой.
C++:
#define BUTTON_PIN 3
#define LED_PIN 5



void setup() {
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT);
    pinMode(LED_PIN,OUTPUT);



}

void loop() {
    static bool pState = false;
    bool state = digitalRead(BUTTON_PIN);
    if (pState != state) {  // состояние изменилось
        pState = state;     // запомнить новое
  {     
  digitalWrite(LED_PIN,HIGH);     
  }     
  if (pState = state);   
    
  else     
      
   {     
  digitalWrite(LED_PIN,LOW);     
  }           
        
        
        if (state) Serial.println("Кнопка нажата");
        else Serial.println("Кнопка отпущена");
    }
}
 

EugeneFrol

✩✩✩✩✩✩✩
17 Апр 2024
58
9
50
Ну-у. Это опрос в каждом цикле. А где - один раз при изменении состояния?
 

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
Умею так. Если знаешь иначе можешь показать, я не против.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,334
1,322
Москва
Бывают коды, где кнопка опрашивается один раз, если изменила своё состояние
Имеется ввиду по прерыванию ? Так можно, все будет зависеть от того, что надо получить от кнопки. Если по прерыванию подключить тики кнопки из библиотеки ГайверБатон, то тогда не будут работать события на удержание, т.к. кнопка тупо не будет менять свое состояние . Там есть ухищрения вроде автотика, но до проверки состояния еще добраться надо.
Можно вызывать все проверки кнопок по таймеру,если он, таймер, нигде больше не используется, то вполне можно сделать такое, тогда будет работать весь функционал библиотеки.
 
  • Лойс +1
Реакции: VictorArx

EugeneFrol

✩✩✩✩✩✩✩
17 Апр 2024
58
9
50
Самый простой пример выдал Гугл:
C++:
const int buttonPin = 2; // Пин, к которому подключена кнопка (должен быть пин прерывания: 2 или 3)
const int ledPin = 13;   // Пин светодиода (встроенный светодиод на большинстве плат)

volatile boolean buttonPressed = false; // Флаг, устанавливаемый в ISR

// Функция-обработчик прерывания
void handleButtonPress() {
  buttonPressed = true; // Устанавливаем флаг, что кнопка была нажата
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Используем внутренний подтягивающий резистор
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Нажмите кнопку!");

  // Прикрепляем прерывание:
  // FALLING - срабатывает при переходе от HIGH к LOW (кнопка нажата, если pullup)
  attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonPress, FALLING);
}

void loop() {
  if (buttonPressed) { // Проверяем флаг
    Serial.println("Кнопка нажата! Мигаю светодиодом...");
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
    buttonPressed = false; // Сбрасываем флаг, чтобы не срабатывало много раз подряд
  }
  // Здесь может быть другой код, который выполняется постоянно
  //, не мешая прерыванию
  // Serial.println("Основной цикл работает...");
  // delay(100);
}
 

SlavaZagaynov

★✩✩✩✩✩✩
27 Ноя 2019
171
34
www.youtube.com
Библиотека гайвер баттон очень хороша, пользуйтесь ей. Как минимум можно использовать одинарное, двойное и тройное нажание, остальные фиг запомнишь.
 

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
Доброго времени суток. Благодарю всех за участие в данной теме. При первом знакомстве с Arduino использовал такой код
void loop(){

if (digitalRead(buttonPinA) == HIGH)
{
digitalWrite(ledPinA, HIGH);
}
if (digitalRead(buttonPinA) == LOW)
{
digitalWrite(ledPinA, LOW);
}
Потом один ув. форумчанин сказал, что зачем постоянно делать опрос кнопки, когда можно один раз проверить изменилось ли состояние, поэтому я и привёл код выше. Теперь ещё и прерывание есть, буду изучать, надеюсь непонятки решу с вашей помошью, если не затруднит. Не увидел в последнем коде прерывание ISR, где именно эта аббревиатура написана в коде.
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,334
1,322
Москва
@VictorArx,конкретно в данном примере есть "тавтология",тут действительно есть лишний опрос, можно было бы сделать так:
C++:
if (digitalRead(buttonPinA) == HIGH)
{
digitalWrite(ledPinA, HIGH);
}
else
{
digitalWrite(ledPinA, LOW);
}
Потому как если пин не HIGH , то тогда он LOW. Возможно это имелось ввиду.
Опять же, можно запоминать последнее состояние кнопки , как ранее, но для того, что бы понять, что оно изменилось надо как то считать текущее состояние. Можно в прерывании по изменению состояния, но тогда кнопка должна быть свободна от дребезга(аппаратный фильтр).
 

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
С раннего утра начал изучать код о прерываниях и первый затык. Код из программирования Arduino и почему то диод не блинкает.
C++:
int pin = 13;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}
 

VictorArx

★★★✩✩✩✩
22 Мар 2021
644
102
@SlavaZagaynov, попробуй, очень даже можно. В гугле полно примеров. Специально для вас :
Чтобы логический вход не оставался в подвешенном состоянии при разомкнутом контакте кнопки и гарантировать на нем сигнал низкого уровня, его через резистор соединяют с землей.


Такой резистор называют подтягивающим: он обеспечивает подтяжку сигнала к земле (как в данном случае) или же к питанию, если устанавливается между логическим входом устройства и линией питания. Соответственно при подтяжке к питанию на логическом входе будет гарантирован высокий уровень сигнала.
 
Изменено: