#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#include <IRremote.hpp>
// OLED
#define OLED_SDA 21
#define OLED_SCL 22
Adafruit_SSD1306 display(128, 64, &Wire, -1);
// RTC
TwoWire RTCWire = TwoWire(1);
RTC_DS1307 rtc;
// IR
#define IR_PIN 14
// Joystick
#define JOY_X 34 // HORZ
#define JOY_Y 35 // VERT
// 7-seg segmenty
int segA = 23;
int segB = 19;
int segC = 18;
int segD = 5;
int segE = 4;
int segF = 2;
int segG = 15;
// Digity
int dig1 = 33;
int dig2 = 32;
// Snake premenné
struct Segment {
int x;
int y;
};
Segment snake[100];
int snakeLength = 1;
int foodX = 20;
int foodY = 20;
int score = 0;
bool gameRunning = false;
// Farba hada (simulácia veľkosťou bloku)
int snakeBlockSize = 4;
// Tabuľka číslic (CA logika: LOW = svieti)
byte digits[10][7] = {
{LOW, LOW, LOW, LOW, LOW, LOW, HIGH}, // 0
{HIGH, LOW, LOW, HIGH, HIGH, HIGH, HIGH}, // 1
{LOW, LOW, HIGH, LOW, LOW, HIGH, LOW}, // 2
{LOW, LOW, LOW, LOW, HIGH, HIGH, LOW}, // 3
{HIGH, LOW, LOW, HIGH, HIGH, LOW, LOW}, // 4
{LOW, HIGH, LOW, LOW, HIGH, LOW, LOW}, // 5
{LOW, HIGH, LOW, LOW, LOW, LOW, LOW}, // 6
{LOW, LOW, LOW, HIGH, HIGH, HIGH, HIGH}, // 7
{LOW, LOW, LOW, LOW, LOW, LOW, LOW}, // 8
{LOW, LOW, LOW, LOW, HIGH, LOW, LOW} // 9
};
void setup() {
Serial.begin(115200);
Wire.begin(OLED_SDA, OLED_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED error!");
while(1);
}
// RTC init na druhej zbernici
RTCWire.begin(25, 26); // SDA=25, SCL=26
if (!rtc.begin(&RTCWire)) {
Serial.println("RTC error!");
while(1);
}
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// IR init
IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK);
Serial.println("IR prijimac pripraveny");
// Joystick
pinMode(JOY_X, INPUT);
pinMode(JOY_Y, INPUT);
// 7-seg init
int segments[] = {segA, segB, segC, segD, segE, segF, segG};
for (int i = 0; i < 7; i++) {
pinMode(segments[i], OUTPUT);
digitalWrite(segments[i], HIGH);
}
pinMode(dig1, OUTPUT);
pinMode(dig2, OUTPUT);
digitalWrite(dig1, HIGH);
digitalWrite(dig2, HIGH);
// Uvítacie okno
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.println("HADIK");
display.setTextSize(1);
display.setCursor(20, 50);
display.println("Stlac 1 na ovladaci");
display.display();
snake[0].x = 64;
snake[0].y = 32;
}
void loop() {
// IR ovladac – start/stop/farba
if (IrReceiver.decode()) {
uint32_t code = IrReceiver.decodedIRData.decodedRawData;
Serial.println(code, HEX);
if (code == 0xCF30FF00) { // "1" start
gameRunning = true;
score = 0;
snakeLength = 1;
snake[0].x = 64;
snake[0].y = 32;
foodX = random(10, 118);
foodY = random(10, 54);
}
if (code == 0xE718FF00) { // "2" toggle pause/resume
gameRunning = !gameRunning;
if (!gameRunning) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 25);
display.println("PAUZA");
display.display();
}
}
if (code == 0x857AFF00) { // "3" zmena farby
if (snakeBlockSize == 4) snakeBlockSize = 6;
else snakeBlockSize = 4;
}
IrReceiver.resume();
}
if (gameRunning) {
playSnake();
}
}
// Funkcia hry Snake
void playSnake() {
int xVal = analogRead(JOY_X);
int yVal = analogRead(JOY_Y);
if (xVal > 3000) snake[0].x += 2; // doprava
else if (xVal < 1000) snake[0].x -= 2; // doľava
if (yVal < 1000) snake[0].y -= 2; // hore
else if (yVal > 3000) snake[0].y += 2; // dole
// posun tela vždy
for (int i = snakeLength - 1; i > 0; i--) {
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
// kolízia s jedlom
if (abs(snake[0].x - foodX) < 4 && abs(snake[0].y - foodY) < 4) {
score++;
if (snakeLength < 100) snakeLength++;
foodX = random(10, 118);
foodY = random(10, 54);
}
// OLED vykreslenie
display.clearDisplay();
// vykreslenie hada podľa veľkosti bloku
for (int i = 0; i < snakeLength; i++) {
display.fillRect(snake[i].x, snake[i].y, snakeBlockSize, snakeBlockSize, SSD1306_WHITE);
}
// jedlo
display.fillCircle(foodX, foodY, 2, SSD1306_WHITE);
// čas z RTC
DateTime now = rtc.now();
display.setTextSize(1);
display.setCursor(80, 0);
display.printf("%02d:%02d:%02d", now.hour(), now.minute(), now.second());
display.display();
// skóre na 7-seg
showNumber(score);
}
// 7-seg funkcie
void showNumber(int num) {
int tens = num / 10;
int ones = num % 10;
digitalWrite(dig1, LOW);
digitalWrite(dig2, HIGH);
setSegments(tens);
delay(2);
digitalWrite(dig1, HIGH);
digitalWrite(dig2, LOW);
setSegments(ones);
delay(2);
}
void setSegments(int digit) {
int segments[] = {segA, segB, segC, segD, segE, segF, segG};
for (int i = 0; i < 7; i++) {
digitalWrite(segments[i], digits[digit][i]);
}
}