Энкодер и светодиоды

allname
Offline
Зарегистрирован: 20.10.2015

Здравствуйте форумчане, задача у меня такая: Есть энкодер с кнопкой, ардуино и уже сломанный мозг. На ардуино (мега 2560) отведено 25 выходов под светодиоды. Светодиоды мигают последовательно от первого до цатого

Например так 

digitalWrite(led1, LOW);
  delay (200);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  delay (200);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, LOW);
  delay (200);
  digitalWrite(led3, HIGH);

Присутствует задержка в каждом последующем зажигании светодиода, в данном случае 0.2с. Дак вот надо энкодером выставлять эту задержку от 0.1с до 9.9с (значение буду выводить на 2х разрядный 7мисегментный индикатор) и с кнопки на энкодере запускать процесс мигания. Помогите разобраться с этим.

P.s. С индикатором все без проблем, весь гемор только в том как энкодером менять эту задержку и хранить где то эту переменную, что-бы во время нажатия кнопки ардуина воспользовалась этим значением переменной.

vvadim
Offline
Зарегистрирован: 23.05.2012

ваши делеи будут полностью тормозить работу энкодера.

для начала избавтесь от них, используйте millis()

allname
Offline
Зарегистрирован: 20.10.2015

Дак энкодер нужен только чтобы выставить этот делэй

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Вам уже написали - забудьте за delay. Используйте millis, вот пример. Энкодером можно менять перменную interval.

nkk
nkk аватар
Offline
Зарегистрирован: 18.03.2016

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

Имеется три светодиода и величины, которые нужно на них выводить, то есть зажигать их комбинациями:

volatile byte ledCadCurr;
void setup() {
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
}
void srtLedCad(byte ledCadNew) {
  if (ledCadNew != ledCadCurr) {
    ledCadCurr = ledCadNew;
    PORTC &= 0b111111000; // Сбрасываем PС0-2.
    if (ledCadNew > 65) {
      else if (ledCadNew <  70) PORTC |= 0b00000001;
      else if (ledCadNew <  80) PORTC |= 0b00000011;
      else if (ledCadNew <  90) PORTC |= 0b00000010;
      else if (ledCadNew < 100) PORTC |= 0b00000110;
      else if (ledCadNew < 115) PORTC |= 0b00000100;
      else if (ledCadNew < 125) PORTC |= 0b00000101;
      else                      PORTC |= 0b00000111;
    }
  }
}

Подскажите, можно ли в этом коде еще что-то оптимизировать, чтобы он выполнялся за меньшее количество тактов? Например, будет ли прирост производительности, если вместо
if () ...; else if () ...;
написать
if () { ... return;}
if () { ... return;}

Функция srtLedCad будет вызываться из обработчика прерываний, а в loop() в это время происходит чтение из последовательного порта, будут ли теряться данные. Раньше небыло прерываний и данные терялись, пока скорость не опустил до 9600.

Весь код, без этих изменений можно посмотреть тут - https://gist.github.com/ircphp/b25f979855252b0e630c - это GPS-треккер, который читает из датчика и пишет на SD-карту, при инициализации мигает светодиодом (PD6) если карта не вставлена или если GPS-датчик не "раздуплился", потом пишет до нажатия на кнопку (PD7). Так как устройство будет висеть на велике, хочу еще индицировать каденс с помощью трёх светодиодов.