#include <Arduino.h>
/* ================= ПІНИ ================= */
#define DATA_PIN PA7
#define CLOCK_PIN PA5
#define LATCH_PIN PA6
#define BTN_PIN PB0
/* ================= ЗМІЙКА =================
0 – CW
1 – CCW
2 – STOP
*/
uint8_t snakeMode = 0;
uint8_t snakePos = 0;
/* ================= СЕГМЕНТИ ================= */
const uint8_t segDigits[10] = {
0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110,
0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111
};
uint8_t displayBuf[4] = {8, 0, 0, 0};
/* ================= 74HC595 ================= */
void shiftSend(uint16_t data) {
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data >> 8);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, data & 0xFF);
digitalWrite(LATCH_PIN, HIGH);
}
/* ================= ЗАДАЧА 1: ІНДИКАТОР ================= */
void taskDisplay() {
static uint8_t digit = 0;
uint16_t data = (1 << digit) << 8;
data |= segDigits[displayBuf[digit]];
shiftSend(data);
digit = (digit + 1) % 4;
}
/* ================= ЗАДАЧА 2: ЗМІЙКА ================= */
void taskSnake() {
if (snakeMode == 2) return;
for (int i = 0; i < 4; i++) displayBuf[i] = 0;
displayBuf[snakePos] = 8;
if (snakeMode == 0) {
snakePos = (snakePos + 1) % 4;
} else {
snakePos = (snakePos == 0) ? 3 : snakePos - 1;
}
}
/* ================= ЗАДАЧА 3: КНОПКА ================= */
void taskButton() {
static uint8_t prev = HIGH;
uint8_t cur = digitalRead(BTN_PIN);
if (prev == HIGH && cur == LOW) {
snakeMode++;
if (snakeMode > 2) snakeMode = 0;
}
prev = cur;
}
/* ================= ЗАДАЧА 4: UART ================= */
float readTemp() {
return 20.0 + (millis() % 1000) / 100.0;
}
float readVref() {
return 1.10 + (millis() % 100) / 500.0;
}
void taskUART() {
static String rx = "";
while (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
rx.trim();
rx.toUpperCase();
if (rx == "T MCU?") {
Serial.print("T MCU=");
Serial.print(readTemp(), 1);
Serial.println("C");
}
else if (rx == "V REF?") {
Serial.print("V REF=");
Serial.print(readVref(), 2);
Serial.println(" V");
}
else if (rx == "ALL SENS?") {
Serial.print("T MCU=");
Serial.print(readTemp(), 1);
Serial.println("C");
Serial.print("V REF=");
Serial.print(readVref(), 2);
Serial.println(" V");
}
else if (rx.length()) {
Serial.println("ERROR");
}
rx = "";
} else rx += c;
}
}
/* ================= ДИСПЕТЧЕР ================= */
struct Task {
void (*func)();
uint32_t period;
uint32_t lastRun;
};
Task tasks[] = {
{ taskDisplay, 2, 0 },
{ taskSnake, 300, 0 },
{ taskButton, 50, 0 },
{ taskUART, 1, 0 }
};
const uint8_t TASK_COUNT = sizeof(tasks) / sizeof(Task);
/* ================= SETUP ================= */
void setup() {
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
Serial.begin(115200);
Serial.println("TASK DISPATCHER READY");
}
/* ================= LOOP ================= */
void loop() {
uint32_t now = millis();
for (uint8_t i = 0; i < TASK_COUNT; i++) {
if (now - tasks[i].lastRun >= tasks[i].period) {
tasks[i].lastRun = now;
tasks[i].func();
}
}
}