Выходной сдвиговый регистр

Senovik
Offline
Зарегистрирован: 06.10.2018

Всем привет!

Начал изучение платформы Ардуино по разным лёгким упражнениям и не могу разобраться с выходным сдвиговым регистром. Помогите, пожалуйста)

Суть - имеется кнопка, регистр и семисегментый цифровой индикатор. Задача - при нажатии на кнопку менять цифру на следующую.

Написан такой код:

//  Обработка нажатия кнопки
  if (buttwasUp && !digitalRead(butt)) {
    delay(10);
    if (!digitalRead(butt)) {
      clicks = (clicks + 1) % 10;
    }
  }
  buttwasUp = digitalRead(butt);

//  Выводим результат
  digitalWrite(latch_pin, LOW);
  shiftOut(data_pin, clock_pin, LSBFIRST, Segments[clicks]);
  digitalWrite(latch_pin, HIGH);

 Всё работает прекрасно. Нажимаю кнопку - цифры крутятся. Могу нажимать медленно, быстро, всё замечательно.

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

//  Обработка нажатия кнопки
  if (buttwasUp && !digitalRead(butt)) {
    delay(10);
    if (!digitalRead(butt)) {
      clicks = (clicks + 1) % 10;
      //  Выводим результат
      digitalWrite(latch_pin, LOW);
      shiftOut(data_pin, clock_pin, LSBFIRST, Segments[clicks]);
      digitalWrite(latch_pin, HIGH);
    }
  }
  buttwasUp = digitalRead(butt);

То есть, просто переместил работу с регистром внутрь обработки кнопки. 

С моей точки зрения, логически ничего не поменялось. Я нажимаю кнопку - меняется зачение на семисегментнике.

Однако на практике в таком варианте кнопка начала "глючить". Пропускать нажатия, не реагировать. Из двух-трёх нажатий может увидеть только одно.

Помогите, пожалуйста, понять, в чём проблема?

И еще один вопрос, как работает регистр при резете? Заметил, что рандомно подаётся напряжение на разные ноги (и в процессе перезарузки на семисегментнике может быть что угодно, даже восьмёрка, то бишь все ноги под напряжением). В дальнейшем хотел повесить на регистр помпу, но наверное это не лучшая идея, если при перезагрузке она может на несколько секунд самопроизвольно включиться?

Senovik
Offline
Зарегистрирован: 06.10.2018

Поспешил с постом, разобрался сам)

Похоже запись в регистр занимает время и при одном проходе digitalRead с кнопки успевают поменяться, а программа на это не рассчитана) 

Поменял на такой вариант (заменил два digitalRead на один - до вывода цифры на индикатор) и всё заработало прекрасно:

  //  Обработка нажатия кнопки
  buttisUp = digitalRead(butt);
  if (buttwasUp && !buttisUp) {
    delay(10);
    buttisUp = digitalRead(butt);
    Serial.println("Нажали");
    if (!buttisUp) {
      clicks = (clicks + 1) % 10;
      Serial.print("Переключили на ");
      Serial.println(clicks);
      //  Выводим результат
      digitalWrite(latch_pin, LOW);
      shiftOut(data_pin, clock_pin, LSBFIRST, Segments[clicks]);
      digitalWrite(latch_pin, HIGH);
    }
  }
  buttwasUp = buttisUp;

 Можете подсказать, почему так?) Ну и второй вопрос ещё актуален - правильно ли на регистр подключать не светодиоды, а помпы/моторы и тд (то есть устройства, непроизвольное включение которых может привести к каким-то последствиям)? Или лучше этого избежать?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Оптроном избегайте.....

SLKH
Offline
Зарегистрирован: 17.08.2015

Senovik пишет:

Ну и второй вопрос ещё актуален - правильно ли на регистр подключать не светодиоды, а помпы/моторы и тд (то есть устройства, непроизвольное включение которых может привести к каким-то последствиям)? Или лучше этого избежать?

Например, ардуина после всяких инициализаций/настроек/обнулений (в т.ч. выходного регистра) подает команду на включение питания исполнительных механизмов.