Узкоспециализированная самоделка для электромонтёра ОПС - "Умный Пробник"
ВНИМАНИЕ! В данной статье используется контакт с сетями 220В! Будьте осторожны и соблюдайте технику безопасности при работе с напряжением 220В!
После очередной попытки проверить фазу отвёрткой-пробником, понял что батарейки там кончились(пробник 5в1), да и мультиметр подвёл - крона "села" и он перестал включаться...
Мне это всё надоело и я решил сделать устройство, которое бы удовлетворяло моим потребностям в нахождении фазы, в поиске скрытой проводки, в измерении резисторов(ходовых при работе ОПС), в измерении светодиодов - и всё это без постоянных замен батареек.
И на свет родилось это (просьба не пинать - я сделал из того, что было под рукой...принтера, к сожалению, нет)
Мозгом прибора выступил "народный" Wemos D1 mini. Дисплей - 0.96" OLED (используется очень часто в самоделках), щупом выступил тот самый щуп, который был у меня(пришлось укоротить). Ну и по мелочи: резисторы, транзисторы, кнопки, переключатели, плата зарядки, акб.
Что умеет прибор:
Проверка фазы\нуля (до 220В) - при "фазе" издаёт непрерывный сигнал(присутствует гальваническая развязка).
Омметр: Проверка резисторов от 1kΩ до 200kΩ (имеется отдельные входы на торце для подключения).
Бесконтактный поиск скрытой проводки (с графической шкалой уровня сигнала, отображением цифры уровня, и потрескиванием с меняющимся тоном при приближении к проводу).
Проверка светодиодов с отображением напряжения падения.
Прозвонка провода на обрыв: При сопротивлении ниже 150 Ом прибор пишет «ЦЕПЬ: ОК» и издает непрерывный сигнал.
Обновление по Wi-Fi (OTA): Упрощает корректировку и настройку прибора либо обновление функций.
Автономность работы: во включенном режиме - 9 часов, в выключенном - пока не сядет li-ion батарея от саморазряда. Учитывая, что замеры, в среднем, происходят не более 2х минут и прибор отключают, то прибор заряжать нужно будет не чаще раза в полгода, год.
Если кого-то заинтересовал данный проект - ниже будут списки с необходимыми деталями и сам скетч под Arduino IDE
Необходимые детали:
Wemos D1 mini (ESP8266) - 1шт.
Дисплей: OLED 0.96" I2C - 1шт.
Динамик с планшета или смартфона на 4-8 Ом - 1шт.
Транзистор BC547- 2шт.
Диоды 1N4148 - 2шт.
Резистор 2.2 МОм (0.25Вт или выше) - 1шт.
Резистор 1 МОм - 1шт.
Резистор (эталон для омметра): 10 кОм - 1шт.
Резистор (для динамика): 100 Ом - 1шт.
Аккумулятор: Li-Po или Li-ion (по размеру вашего корпуса) - 1шт.
Модуль зарядки: TP4056 с разъемом Type-C (с защитой АКБ) - 1шт.
Выключатель: Сдвижной тумблер (SPDT) - 1 шт.
Кнопка: Тактовая кнопка любого, удобного вам, размера - 1шт.
Разъемы для резисторов: любой разъём "мама" - 2шт.
Тыльный контакт: Небольшая металлическая пластина (для касания пальцем) - 1шт.Ещё необходимо поверх щупа, на ту часть, которая внутри корпуса, через изоляцию(термоусадка например) намотать 10-15 витков провода. Один конец этой обмотки оставьте свободным (никуда не подключайте!)., а второй конец припаяйте в точку на плате Wemos, куда приходит защитный резистор 2.2 МОм).
Схема соединения на словах: Щуп к резистору 2.2 МОм а от резистора к базе транзистора BC547.
Коллектор транзистора BC547 к пину 3.3V на Wemos.
Эмиттер транзистора BC547 к пину A0 на Wemos.
Пин A0 на Wemos к резистору 10 кОм а от резистора к GND.
Пин A0 к резистору 1 МОм а от резистора к GND).
Анод первого диода к базе BC547, а катод к 3.3V Wemos.
Анод второго диода к GND, а катод к базе BC547.
Разъем первый к пину 3.3V Wemos.
Разъем второй к пину A0 Wemos.
Контакт (пластина) напрямую к GND.
Дисплей : VCC на 3.3V Wemos.
Дисплей: GND на GND Wemos.
Дисплей: SCL на пин D1 (GPIO5).
Дисплей: SDA на пин D2 (GPIO4).
Тактовая кнопка: одна ножка к пин D3 (GPIO0), а вторая к земле GND.
Динамик: Эмиттер транзистора с землёй GND, базу с D5 через резистор 1k, коллектор с минусом динамика, плюс динамика к +5V платы Wemos.
Резистор 2.2 МОм должен быть припаян максимально близко к самому металлическому щупу и затянут в термоусадку.
Все точки "GND" должны быть соединены между собой!
При монтаже высоковольтных резисторов (2.2 МОм) убедитесь, что между их выводами и другими частями схемы достаточное расстояние (не менее 5-7 мм), чтобы исключить пробой по поверхности платы.
Скетч(код) для Arduino IDE:
#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();
}
Не забываем скачать библиотеки, объявленные в начале кода: U8g2 (автор: oliver), WiFiManager (автор: tzapu), ядро ESP8266 (уже при начале прошивки выбираем LOLIN(WEMOS) D1 R2 & mini)
в MMU выбираем 16Kb+48kb IRAM, частоту проца 160Mhz
Спасибо за внимание и заранее простите за возможные орфографические ошибки.
UPD:
Видео работы основных режимов https://drive.google.com/file/d/1HaYfwVFuJ-eJx0kla1pdLG4uP5T...
