Программирование кухонного блока вытяжки Krona на базе atmega328p

Добрый день форумчане. Не нашел похожую тему на форуме, поэтому создам свою. Собственно нашел в открытом доступе плату и код, доработал немного, развел, изготовил, собрал ПП (плата односторонняя) и залил прошивку на камушек atmega328р с помощью usbasp в среде Ардуино. Все работает, но есть косяк. Не могу понять что не так в коде, проблема заключается в следующем: при нажатии на первую кнопку скорости (вторая по порядку), (по порядку кнопки слева направо: 1 - свет; 2,3,4 - 3 скорости) включается вторая, при нажатии на вторую - третья, т.е. первая включает/отключает вторую скорость, вторая - третью. Получается первая не работает. Схема и плата на картинках.

#include <AnalogMultiButton.h>

#define BUTTONS_PIN A0
#define LED_LIGHT   5
#define LED_FAN1    6
#define LED_FAN2    7
#define LED_FAN3    8
#define CTRL_LIGHT  9
#define CTRL_FAN1   10
#define CTRL_FAN2   11
#define CTRL_FAN3   12

#define TIMER_ACTIVATION_DELAY 2500
#define TIMER_ACTIVATION_BLINK 500
#define TIMER_BLINK            1000
#define TIMER_BASE             600000

enum Channels {CHANNEL_LIGHT, CHANNEL_FAN1, CHANNEL_FAN2, CHANNEL_FAN3, CHANNELS_TOTAL};
const int BUTTONS_VALUES[CHANNELS_TOTAL] = {40, 343, 511, 613};

AnalogMultiButton buttons(BUTTONS_PIN, CHANNELS_TOTAL, BUTTONS_VALUES);

struct Output {
  const byte pin;
  unsigned long blink_timer;
  unsigned int blink_count;
  byte state;
  Output(byte pinv): pin(pinv), state(LOW), blink_timer(0), blink_count(0) {};
  void toggle(byte n_state) {state = n_state; digitalWrite(pin, state);};
  void on() {toggle(HIGH);};
  void off() {toggle(LOW); blink_count = 0;};
  void toggle() {toggle(state ? LOW : HIGH);};
  unsigned int blinking(unsigned long period) {
    unsigned long currentMillis = millis();
    if (currentMillis - blink_timer >= period) {
      blink_timer = currentMillis;
      toggle();
      blink_count++;
    }
    return blink_count/2;
  };
};

enum ChannelState {OFF, ON, TIMER_ACTIVATION, TIMER};

struct Channel {
  Output indicator;
  Output control;
  ChannelState state;
  unsigned long timer;
  unsigned int timer_multiply;
  
  Channel(byte led, byte ctrl): indicator(Output(led)), control(Output(ctrl)), state(OFF), timer(0) {
    pinMode(led, OUTPUT);
    pinMode(ctrl, OUTPUT);
  };
  void turnOn() {
    state = ON;
    indicator.on();
    control.on();
  };
  void turnOff() {
    state = OFF;
    indicator.off();
    control.off();
  };
  void timerActivation() {state = TIMER_ACTIVATION; indicator.blinking(TIMER_ACTIVATION_BLINK);};
  void startTimer() {state = TIMER; timer_multiply = indicator.blinking(TIMER_BLINK); control.on(); timer = millis();};
  void toggle() {
    if (state == OFF)
      turnOn();
    else 
      turnOff();
  };
  void tick() {
    unsigned long currentMillis = millis();
    if (timer > 0 && currentMillis - timer >= (timer_multiply * TIMER_BASE)) {
      timer = 0;
      turnOff();
    }
  };
  void update() {if (state > ON) {indicator.blinking(TIMER_BLINK); tick();}};
};

struct {
  Channel channels [CHANNELS_TOTAL] = {
    Channel(LED_LIGHT, CTRL_LIGHT),
    Channel(LED_FAN1, CTRL_FAN1),
    Channel(LED_FAN2, CTRL_FAN2),
    Channel(LED_FAN3, CTRL_FAN3)
  };
  void turnOffFans(byte j) {
    if (j != CHANNEL_LIGHT) {
      for (byte i = CHANNEL_FAN1; i < CHANNELS_TOTAL; i++) if (j != i) channels[i].turnOff();
    }
  };
} asply;

void setup() {}

void loop() {
  buttons.update();
  
  for (byte i = 0; i < CHANNELS_TOTAL; i++) {

    if (buttons.isPressed(i)) {
      if (buttons.isPressedAfter(i, TIMER_ACTIVATION_DELAY))
        asply.channels[i].timerActivation();
      else
        asply.channels[i].indicator.on();
    }

    if (buttons.onReleaseAfter(i, TIMER_ACTIVATION_DELAY)) {
      if (asply.channels[i].state != TIMER) {
        asply.turnOffFans(i);
        asply.channels[i].startTimer();
      }
    } else if (buttons.onRelease(i)) {
      asply.turnOffFans(i);
      asply.channels[i].toggle();
    }
    
    asply.channels[i].update();
  }

  delay(10);
}


Вычесть единичку из номера канала.

При включении реле не щелкают сами?

Можно поподробнее, какая строка, я сам еще учусь и как работает здесь большая часть кода мне не понятно, пытаюсь понять, сюда за разъяснениями и обратился.

Все щелкает, все работает. Такое ощущение что загводка именно где то в том, о чем написал Komandir.

Диоды загораются так же не правильно ?

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

А что происходит при нажатии кнопки включения света ?

Я думаю это не верно - первым должен идти 0 ! В примере к библиотеке там идёт 0, так как первая кнопка замыкается на GND без резистора !

Включается/отключается свет. Горит первый светодиод. А вот скорость какая то не работает. Еще раз уточню: при нажатии второй кнопки горит вкл светодиод на третьей, при нажатии на 3 кнопку вкл светодиод на 4, скорость при этом повышается и похожа на макс. возможную. Самая мин. скорость видимо не срабатывает.

Тут вы правы, резистора у первой кнопки нет, к слову у оригинальной платы вообще не было резисторов на кнопках. Кстати пин подписан как buttons input на первую кнопку без резистора. Попробую Ваше предложение вечером, спасибо.

Еще на схеме:
PB1=9- управляет реле подписанное как FAN3
PB2=10- управляет реле подписанное как FAN2
PB3=11- управляет реле подписанное как FAN1
PB4=12- управляет реле подписанное как Light
А в скетче:

Эти значения у вас опытным путём получены ?

Скетч я не трогал вроде бы насколько помню, нашел в инете. На что это влияет?

Если бы я знал что это за значения)

Это значения в порту A0 при нажатии кнопок.

void loop() {
  Serial.println(analogRead(A0));
}

Нажимайте кнопки и смотрите какое число выводится - его и заносите в нужное место в массиве.
Где то у вас попуталась нумерация !

Это мне получается вытащить микруху из схемы воткнуть в ардуинку подключить кнопки к портам и тыкать, смотря значения? А нужное место в массиве это как? Что-то нужно делать с микрухой (ставить внешнее тактирование там например)?

У вас плата без вывода отладки через Serial ??? Сильно не заморачивайтесь - там особо точные значения не нужны. Просто это бы дало понимание того где у вас какая кнопка в итоговой плате !
Тогда измеряйте напряжение на пине A0 при нажатии каждой кнопки ! При нажатии кнопки включения света должно быть напряжении около 0 и потом подниматься для FAN1 и далее FAN2 и самое высокое для FAN3.
Когда узнаем реальную нумерацию кнопок на плате - подгоним нумерацию управляющих выводов для светодиодов и реле …

1 лайк

Вот и обратись к автору. Никто наугад без оборудования в руках в этом не разберется.

Serial нету. Ну я хотел сделать как заводскую, фото разведенной платы приложено. Не фоткал саму плату так как устройство уже собрано, + там ничего нового не будет, все тоже самое как на фотке разведенной платы только с припаянными компонентами, на схеме могут быть ошибки. Про микроконтроллер спрашивал так как он в каретке/кроватке стоит и его можно снять. Хорошо, попробую.