#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
SSD1306AsciiWire oled;
// Пины подключения RC8000
#define DATA_PIN 2
#define PON_PIN 3
#define LED_PIN 13
byte lastState = HIGH;
unsigned long fallTime = 0;
unsigned long lastPulseTime = 0;
String bitHistory = "";
//
//
// --- ГРАФИКА Welcome, boot screen---
void runBootSequence() {
oled.clear();
// --- Экран 1: Приветствие ---
oled.set2X();
oled.setCursor(0, 1);
oled.println(F("RD&P Lab "));
oled.set1X();
oled.setCursor(0, 3);
oled.println(F(" with"));
oled.set2X();
oled.setCursor(0, 5);
oled.println(F(" Gemini"));
oled.set1X();
// Анимация ИИ
oled.setCursor(0, 7); oled.println(F(" [O_o]")); delay(1000);
oled.setCursor(0, 7); oled.println(F(" [o_O]")); delay(1000);
oled.setCursor(0, 7); oled.println(F(" [O_o]")); delay(1000);
// --- Экран 2: Загрузка ---
oled.clear();
oled.set2X();
oled.setCursor(0, 2);
oled.println(F("W-MONITOR"));
oled.set1X();
oled.setCursor(0, 4);
oled.println(F(" DCF77"));
oled.setCursor(0, 7);
// Ограничил цикл до 21 (максимальная ширина экрана в символах), чтобы не было переноса
for (int i = 0; i < 21; i++) {
oled.print(F("|"));
delay(100);
}
delay(500);
oled.clear();
}
//
//
void setup() {
pinMode(PON_PIN, OUTPUT);
digitalWrite(PON_PIN, LOW); // Включаем модуль
pinMode(DATA_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
// Инициализация легковесного экрана
Wire.begin();
oled.begin(&Adafruit128x64, 0x3C);
oled.setFont(System5x7); // Идеальный терминальный шрифт
oled.clear();
oled.println(F("W-MONITOR DCF77"));
oled.println(F("BOOTING ..."));
delay(1500);
}
void loop() {
byte currentState = digitalRead(DATA_PIN);
digitalWrite(LED_PIN, !currentState);
if (currentState == LOW && lastState == HIGH) {
fallTime = millis();
unsigned long timeSinceLastPulse = fallTime - lastPulseTime;
if (timeSinceLastPulse > 1500 && lastPulseTime != 0) {
drawTerminal("SYNC MARKER", 0, -1);
}
lastPulseTime = fallTime;
}
else if (currentState == HIGH && lastState == LOW) {
unsigned long duration = millis() - fallTime;
if (duration > 50) {
int bitValue = -1;
if (duration >= 60 && duration <= 140) bitValue = 0;
else if (duration >= 160 && duration <= 250) bitValue = 1;
drawTerminal("PULSE", duration, bitValue);
}
}
lastState = currentState;
}
// Новая легкая функция отрисовки без буфера
void drawTerminal(String eventType, unsigned long duration, int bitVal) {
// Не стираем весь экран (oled.clear()), а просто перезаписываем нужные строки
// Это уберет любое мерцание!
// Шапка (Строки 0 и 1)
oled.setCursor(0, 0);
oled.print(F("W-MONITOR DCF77 \nTGT FREQ: 77.500 кHz "));
// Разделитель (Строка 2)
oled.setCursor(0, 2);
oled.print(F("---------------------"));
// Обновляем историю
if (bitVal == 0 || bitVal == 1) bitHistory += String(bitVal);
else if (eventType == "SYNC MARKER") bitHistory += "[M]";
else if (eventType == "NOISE" && duration > 0) bitHistory += "e";
if (bitHistory.length() > 20) bitHistory.remove(0, bitHistory.length() - 20);
// Бегущая строка (Строка 4)
oled.setCursor(0, 4);
oled.print(F("> "));
oled.print(bitHistory);
// Добиваем пробелами конец строки, чтобы затереть старые символы
oled.print(F(" "));
// Осциллограф (Строка 6)
oled.setCursor(0, 6);
if (bitVal == 0) {
oled.print(F(" _____ ")); oled.print(duration); oled.print(F(" ms "));
}
else if (bitVal == 1) {
oled.print(F(" _|||_ ")); oled.print(duration); oled.print(F(" ms "));
}
else if (eventType == "SYNC MARKER") {
oled.print(F(" _[M]_ "));
}
else {
oled.print(F(" _err_ ")); oled.print(duration); oled.print(F(" ms "));
}
}