Загрузка данных


#include <Arduino.h>

// 74HC595
const byte DATA_PIN  = 8;   // SDI
const byte CLOCK_PIN = 7;   // SFTCLK
const byte LATCH_PIN = 4;   // LCHCLK

// Кнопки
const byte BTN_MUL   = 2;
const byte BTN_RESET = 3;

// Начальное значение
const uint32_t START_VALUE = 138;
uint32_t value = START_VALUE;

// Предел для 4-разрядного индикатора
const uint32_t MAX_VALUE = 9999;

// Дребезг
const unsigned long DEBOUNCE_MS = 40;

struct ButtonState {
  bool lastRead = HIGH;
  bool stable = HIGH;
  unsigned long lastChange = 0;
};

ButtonState mulBtn;
ButtonState resetBtn;

// Таблица сегментов для common anode
const byte SEG_CA[10] = {
  0xC0, // 0
  0xF9, // 1
  0xA4, // 2
  0xB0, // 3
  0x99, // 4
  0x92, // 5
  0x82, // 6
  0xF8, // 7
  0x80, // 8
  0x90  // 9
};

// Выбор разрядов
const byte DIGIT_SEL[4] = {
  0x01,
  0x02,
  0x04,
  0x08
};

byte digits[4] = {0, 0, 0, 0};

void send595(byte firstByte, byte secondByte) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, firstByte);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, secondByte);
  digitalWrite(LATCH_PIN, HIGH);
}

void splitToDigits(uint16_t n) {
  for (byte i = 0; i < 4; i++) {
    digits[i] = n % 10;
    n /= 10;
  }
}

void refreshDisplay() {
  uint16_t shown = (uint16_t)(value % 10000UL);
  splitToDigits(shown);

  for (byte pos = 0; pos < 4; pos++) {
    byte seg = SEG_CA[digits[3 - pos]];
    byte dig = DIGIT_SEL[pos];
    send595(seg, dig);
    delayMicroseconds(800);
  }
}

bool buttonPressed(ButtonState &btn, byte pin) {
  bool reading = digitalRead(pin);

  if (reading != btn.lastRead) {
    btn.lastChange = millis();
    btn.lastRead = reading;
  }

  if (millis() - btn.lastChange > DEBOUNCE_MS) {
    if (reading != btn.stable) {
      btn.stable = reading;
      if (btn.stable == LOW) return true;
    }
  }

  return false;
}

void setup() {
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);

  pinMode(BTN_MUL, INPUT_PULLUP);
  pinMode(BTN_RESET, INPUT_PULLUP);

  digitalWrite(LATCH_PIN, HIGH);
}

void loop() {
  refreshDisplay();

  if (buttonPressed(mulBtn, BTN_MUL)) {
    value *= 3;

    if (value > MAX_VALUE) {
      value = START_VALUE;
    }
  }

  if (buttonPressed(resetBtn, BTN_RESET)) {
    value = START_VALUE;
  }
}