#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WiFiManager.h>
#define NOTE_E7 2637
#define NOTE_C7 2093
#define NOTE_G7 3136
#define NOTE_G6 1568
float avgRaw = 1024.0;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
const int BTN_PIN = D3;
const int BUZZ_PIN = D5;
const int SENSOR_PIN = A0;
const float R_REF = 11400.0; // Указать точное значение резистора 10k (в данном случае 11.4k)
bool isSleeping = false;
bool otaMode = false;
uint32_t lastActivity = 0;
int currentMode = 0;
void configModeCallback (WiFiManager *myWiFiManager) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x12_t_cyrillic);
u8g2.drawUTF8(0, 12, "РЕЖИМ НАСТРОЙКИ");
u8g2.drawUTF8(0, 42, "SmartProbe-Config");
u8g2.setCursor(0, 60); u8g2.print("IP: "); u8g2.print(WiFi.softAPIP());
u8g2.sendBuffer();
}
int getP2P() {
int minV = 1024, maxV = 0;
uint32_t start = millis();
while (millis() - start < 28) {
int v = analogRead(SENSOR_PIN);
if (v < minV) minV = v;
if (v > maxV) maxV = v;
}
return (maxV - minV);
}
void wakeUp() {
if (isSleeping) {
u8g2.setPowerSave(0);
for(int i=0; i<255; i+=5) { u8g2.setContrast(i); delay(2); }
u8g2.setContrast(255);
isSleeping = false;
}
lastActivity = millis();
}
void setup() {
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
pinMode(BTN_PIN, INPUT_PULLUP);
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_6x12_t_cyrillic);
if (digitalRead(BTN_PIN) == LOW) {
otaMode = true;
WiFi.forceSleepWake(); delay(10);
WiFi.mode(WIFI_STA);
u8g2.clearBuffer(); u8g2.drawUTF8(0, 20, "ОБНОВЛЕНИЕ ПО Wi-Fi"); u8g2.sendBuffer();
WiFiManager wm;
wm.setAPCallback(configModeCallback);
wm.setConfigPortalTimeout(180);
if (!wm.autoConnect("SmartProbe-Config")) { ESP.restart(); }
ArduinoOTA.setHostname("SmartProbe-V4");
ArduinoOTA.setPassword("1"); // Пароль при обновлении по "воздуху" - Запомни или измени на свой
ArduinoOTA.begin();
u8g2.clearBuffer(); u8g2.drawUTF8(0, 35, "ЖДУ ПРОШИВКУ...");
u8g2.setCursor(0, 55); u8g2.print("IP: "); u8g2.print(WiFi.localIP());
u8g2.sendBuffer();
}
if (!otaMode) {
pinMode(BUZZ_PIN, OUTPUT);
for (int i = 0; i <= 128; i += 8) {
u8g2.clearBuffer(); u8g2.drawLine(i, 0, i, 64);
if (i > 30) u8g2.drawUTF8(15, 30, "УМНЫЙ");
if (i > 70) u8g2.drawUTF8(15, 50, "ПРОБНИК v4 [Wi-Fi]");
u8g2.sendBuffer();
}
int mel[] = { NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, NOTE_G6 };
int tem[] = { 100, 100, 80, 100, 80, 100, 100, 80, 150, 280, 200 };
for (int i = 0; i < 11; i++) {
if (mel[i] == 0) {
delay(tem[i]);
} else {
tone(BUZZ_PIN, mel[i], tem[i]);
delay(tem[i] * 1.35);
}
}
noTone(BUZZ_PIN); lastActivity = millis();
}
}
void loop() {
if (otaMode) { ArduinoOTA.handle(); return; }
int raw = analogRead(SENSOR_PIN);
int p2p = getP2P();
if (digitalRead(BTN_PIN) == LOW || p2p > 50 || (currentMode == 1 && raw > 20)) { wakeUp(); }
if (!isSleeping && (millis() - lastActivity > 1800000)) { u8g2.setPowerSave(1); isSleeping = true; }
if (isSleeping) return;
if (digitalRead(BTN_PIN) == LOW) {
currentMode++; if (currentMode > 2) currentMode = 0;
tone(BUZZ_PIN, 1000 + (currentMode * 500), 100);
while(digitalRead(BTN_PIN) == LOW) delay(10);
lastActivity = millis();
}
u8g2.clearBuffer(); u8g2.setFont(u8g2_font_6x12_t_cyrillic);
u8g2.drawUTF8(0, 10, currentMode == 0 ? "РЕЖИМ: ЩУП" : (currentMode == 1 ? "РЕЖИМ: ПОИСК ПРОВОДА" : "РЕЖИМ: LED"));
u8g2.drawHLine(0, 12, 128);
if (currentMode == 0) {
if (p2p > 40) {
avgRaw = 1024.0;
if (p2p > 800) {
u8g2.drawUTF8(5, 45, "ФАЗА! ~220V"); tone(BUZZ_PIN, 1000);
} else {
u8g2.drawUTF8(5, 45, "НОЛЬ / ПУСТО"); noTone(BUZZ_PIN);
}
}
else {
(raw > 960)
if (raw > 960) {
avgRaw = 1024.0;
u8g2.drawUTF8(5, 45, "НОЛЬ / ПУСТО");
noTone(BUZZ_PIN);
}
else {
if (avgRaw > 1000) avgRaw = (float)raw;
avgRaw = (avgRaw * 0.8) + (raw * 0.2);
float r_un = R_REF * ((1024.0 / avgRaw) - 1.0);
if (r_un > 400000.0) {
u8g2.drawUTF8(5, 45, "НОЛЬ / ПУСТО");
noTone(BUZZ_PIN);
}
else if (r_un < 150) {
u8g2.drawUTF8(5, 45, "ЦЕПЬ: ОК");
u8g2.setCursor(70, 45); u8g2.print((int)r_un); u8g2.print(" Om");
tone(BUZZ_PIN, 2000);
} else {
noTone(BUZZ_PIN); u8g2.setCursor(5, 45); u8g2.print("R: ");
if (r_un > 950) {
u8g2.print(r_un / 1000.0, 1); u8g2.print(" kOm");
} else {
u8g2.print((int)r_un); u8g2.print(" Om");
}
}
}
}
}
else if (currentMode == 1) {
u8g2.drawUTF8(5, 45, "СИГНАЛ: "); u8g2.setCursor(65, 45); u8g2.print(p2p);
int noiseFloor = 31;
if (p2p > noiseFloor) {
tone(BUZZ_PIN, 400 + (p2p - noiseFloor) * 80, 15);
delay(map(constrain(p2p, noiseFloor, 45), noiseFloor, 45, 200, 5));
} else { noTone(BUZZ_PIN); }
}
else {
float v = (raw * 3.3) / 1024.0;
if (v > 0.5 && v < 3.1) {
u8g2.drawUTF8(5, 30, "СВЕТОДИОД ПОДКЛЮЧЕН");
u8g2.setCursor(5, 45);
u8g2.print("V падения: "); u8g2.print(v, 2); u8g2.print(" V");
} else {
u8g2.drawUTF8(5, 45, "ОЖИДАНИЕ LED...");
}
noTone(BUZZ_PIN);
}
u8g2.drawFrame(0, 56, 128, 8);
int barWidth;
if (currentMode == 1) {
barWidth = map(constrain(p2p, 30, 45), 30, 45, 0, 124);
} else {
barWidth = map(constrain(p2p, 750, 1024), 750, 1024, 0, 124);
}
u8g2.drawBox(2, 58, barWidth, 4);
u8g2.sendBuffer();
}