Поворотник для велика, на Digispark ATtiny85

Zaur.

✩✩✩✩✩✩✩
15 Апр 2020
17
1
Всем здарова! Хотел сделать поворотники для велика, на Digispark. У каждого светодиода есть своя кнопка. Нажимаешь на правою мигает правый светодиод, на левую кнопку левый. Но что-то не получилось(. Я нажимая на любую из 2х кнопок а моргают все 2 светодиода. Библеотека OneButtone.
Принцип работы. Нажимаешь кнопку 1 раз ждёшь когда включится светодиод, и нажимаешь быстро 2 раза, и он моргает.

Скетч:
C++:
#include "OneButton.h"

typedef enum {
  ACTION_OFF1,  // Выключить сведотдиод1
  ACTION_ON1, // Включить светодиод1
  ACTION_FAST1, // Быстро моргать1
  ACTION_ON2, // Включить светодиод2
  ACTION_OFF2, // Выключить сведотдиод2
  ACTION_FAST2, // Быстро моргать2
}

MyActions;

OneButton button1(3, true); //Кнопка1 подключена к 3 пину
OneButton button2(4, true); //Кнопка2 подключена к 4 пину

MyActions nextAction1 = ACTION_OFF1; //Выключенный светодиод
MyActions nextAction2 = ACTION_OFF2; //Выключенный светодиод

void setup() {
  pinMode(2, OUTPUT); // Светодиод подключен к 2 пину
  pinMode(1, OUTPUT); // Светодиод подключен к 1 пуну
  button1.attachDoubleClick(DoubleClickFunction1);
  button1.attachClick(ClickFunction1);
  button2.attachClick(ClickFunction2);
  button2.attachDoubleClick(DoubleClickFunction2);
}

void loop() {
  unsigned long now1 = millis();
  unsigned long now2 = millis();

  button1.tick();
  button2.tick();

  delay(10);

  if (nextAction1 == ACTION_OFF1) {
    // ничего не делать
    digitalWrite(1, LOW);
  } else if (nextAction1 == ACTION_ON1) {
    // Включить светодиод
    digitalWrite(1, HIGH);
  }
  else if (nextAction1 == ACTION_FAST1) {
    // Быстро моргать
    if (now1 % 200 < 100) { // Частота моргания
      digitalWrite(1, LOW);
    } else {
      digitalWrite(1, HIGH);
    } // if
  } // if

  if (nextAction2 == ACTION_OFF2) {
    // // Ничего неделать
    digitalWrite(2, LOW);
  } else if (nextAction2 == ACTION_ON2) {
    // Включить светодиод
    digitalWrite(2, HIGH);
  } else if (nextAction2 == ACTION_FAST2) {
    // Быстро моргать
    if (now2 % 200 < 100){ // Частота моргания
      digitalWrite(2, LOW);
    } else {
      digitalWrite(2, HIGH);
    } // if
  } // if
} //loop

void ClickFunction1() {
  if (nextAction1 == ACTION_OFF1)
    nextAction1 = ACTION_ON1;
  else
    nextAction1 = ACTION_OFF1;
} // myClickFunction

void DoubleClickFunction1() {
  if (nextAction1 == ACTION_ON1) {
    nextAction1 = ACTION_FAST1;

  } else if (nextAction1 == ACTION_FAST1) {
    nextAction1 = ACTION_ON1;
  } // if
} // DoubleClickFunction


void ClickFunction2() {
  if (nextAction2 == ACTION_OFF2)
    nextAction2 = ACTION_ON2;
  else
    nextAction2 = ACTION_OFF2;
} // ClickFunction

void DoubleClickFunction2() {
  if (nextAction2 == ACTION_ON2) {
    nextAction2 = ACTION_FAST2;
  } else if (nextAction2 == ACTION_FAST2) {
  } // if
} // DoubleClickFunction
 
Изменено:

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
сделай на мультивибраторе из пары транзисторов

в следущий раз оборачивай код в тег для кода с подсветкой, иначе его никто читать не будет
 

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

★★★★★★★
14 Авг 2019
4,188
1,280
Москва
А почему такое сложное включение ? Вообще поворотник должен минимально отвлекать от езды. если есть пара кнопок (а она есть), то 1-ое нажатие включает поворот, второе выключает.
Скетч гляну.
 

Zaur.

✩✩✩✩✩✩✩
15 Апр 2020
17
1
Спасибо за замечание! Теперь он включается по 1 нажатию и выключается тоже по одному нажатию.

Скетч:
C++:
#include "OneButton.h"

typedef enum {
  ACTION_OFF1,  // Выключить сведотдиод1
  ACTION_ON1, // Включить светодиод1
  ACTION_FAST1, // Быстро моргать1
  ACTION_ON2, // Включить светодиод2
  ACTION_OFF2, // Выключить сведотдиод2
  ACTION_FAST2, // Быстро моргать2
}

MyActions;

OneButton button1(3, true); //Кнопка1 подключена к 3 пину
OneButton button2(4, true); //Кнопка2 подключена к 4 пину

MyActions nextAction1 = ACTION_OFF1; //Выключенный светодиод
MyActions nextAction2 = ACTION_OFF2; //Выключенный светодиод

void setup() {
  pinMode(2, OUTPUT); // Светодиод подключен к 2 пину
  pinMode(1, OUTPUT); // Светодиод подключен к 1 пуну
  button1.attachClick(ClickFunction1);
  button2.attachClick(ClickFunction2);
}

void loop() {
  unsigned long now1 = millis();
  unsigned long now2 = millis();

  button1.tick();
  button2.tick();

  delay(10);

  if (nextAction1 == ACTION_OFF1) {
    // ничего не делать
    digitalWrite(1, LOW);
  } else if (nextAction1 == ACTION_ON1) {
    // Включить светодиод
    digitalWrite(1, HIGH);
  }
  else if (nextAction1 == ACTION_FAST1) {
    // Быстро моргать
    if (now1 % 200 < 100) { // Частота моргания
      digitalWrite(1, LOW);
    } else {
      digitalWrite(1, HIGH);
    } // if
  } // if

  if (nextAction2 == ACTION_OFF2) {
    // // Ничего неделать
    digitalWrite(2, LOW);
  } else if (nextAction2 == ACTION_ON2) {
    // Включить светодиод
    digitalWrite(2, HIGH);
  } else if (nextAction2 == ACTION_FAST2) {
    // Быстро моргать
    if (now2 % 200 < 100){ // Частота моргания
      digitalWrite(2, LOW);
    } else {
      digitalWrite(2, HIGH);
    } // if
  } // if
} //loop

void ClickFunction1() {
  if (nextAction1 == ACTION_OFF1) {
    nextAction1 = ACTION_ON1;
    nextAction1 = ACTION_FAST1;

  } else if (nextAction1 == ACTION_FAST1) {
    nextAction1 = ACTION_OFF1;
  } // if
} // myClickFunction


void ClickFunction2() {
  if (nextAction2 == ACTION_OFF2) {
    nextAction2 = ACTION_ON2;
    nextAction2 = ACTION_FAST2;

  } else if (nextAction2 == ACTION_FAST2) {
    nextAction2 = ACTION_OFF2;
  } // if
} // DoubleClickFunction
 

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

★★★★★★★
14 Авг 2019
4,188
1,280
Москва
У меня такое впечатление, что немного перемудрил с кодом. Или еще что то хочешь сделать , кроме поворотов. типа габаритов.
Что не нравиться:
C++:
if (nextAction1 == ACTION_OFF1) {
    digitalWrite(1, LOW);
  }
Если условие выполняется, то все время, 50 000 раз в секунду будет выключаться светодиод на 1-ом пине. Выключать выключенное, это не критично, но я стараюсь избегать таких мест.

Сейчас скетч работает корректно?
 

Zaur.

✩✩✩✩✩✩✩
15 Апр 2020
17
1
У меня такое впечатление, что немного перемудрил с кодом. Или еще что то хочешь сделать , кроме поворотов. типа габаритов.
Что не нравиться:
C++:
if (nextAction1 == ACTION_OFF1) {
    digitalWrite(1, LOW);
  }
Если условие выполняется, то все время, 50 000 раз в секунду будет выключаться светодиод на 1-ом пине. Выключать выключенное, это не критично, но я стараюсь избегать таких мест.

Сейчас скетч работает корректно?
Извините я вас не понял, вы можете скинуть исправленный скетч скетч сюда?
Я просто новичок
 

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

★★★★★★★
14 Авг 2019
4,188
1,280
Москва
Я не правил ничего. Просто есть места, которые можно подредактировать
Выше показал одно из них
Если у тебя ACTION_OFF1, т.е. светодиод выключен, то ты его выключаешь каждый раз при прохождении цикла loop , а он может совершаться 50 000 рвз в секунду.. На самом деле я ошибся, он тут будет совершаться не более 100 раз в секунду, т.к. в цикле есть delay(10). Так что скорее всего раз 90 в секунду. Но действие повторяется.
Я бы в цикле оставил только мигание,. а включение и выключение можно делать в функции нажатия кнопки.
 

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
А программно как-то можно это сделать?
можно, но зачем?
я себе подобную купил давно, платка на паре смд транзисторов туда должна влезть
 

Zaur.

✩✩✩✩✩✩✩
15 Апр 2020
17
1
можно, но зачем?
я себе подобную купил давно, платка на паре смд транзисторов туда должна влезть
Я учусь писать скетчи, мне это на пользу будет
 
  • Лойс +1
Реакции: MrBob

kalobyte

★★★✩✩✩✩
1 Янв 2020
726
146
ну тогда смотри тут
https://alexgyver.ru/gyverbutton

будет намного проще и понятней
у тебя сейчас гора кода, где легко запутаться