Двухканальный цифровой вольтметр с графиком и шкалой на Arduino
🧾 Описание проекта
Этот проект представляет собой двухканальный цифровой вольтметр на базе Arduino, предназначенный для одновременного измерения входного и выходного напряжения, а также отображения максимального зафиксированного значения и реального графика изменения напряжения во времени.
Вольтметр отображает:
🟢 Входное напряжение (V In)
🔵 Выходное напряжение (V Out)
🔺 Максимальное выходное напряжение (V Max)
📉 График изменения выходного напряжения
📊 Вертикальную шкалу напряжения справа
Это отличный проект для начинающих радиолюбителей и разработчиков лабораторных блоков питания: он наглядно показывает работу стабилизаторов, поведение напряжения под нагрузкой и позволяет оценивать динамику процессов.
🔧 Используемые компоненты
⚙️ Схема подключения
🔌 Подключение компонентов
🖥️ OLED-дисплей:
GND → GND
VCC → 5V
SCL → A5
SDA → A4
🎛️ Измерение напряжений:
Arduino измеряет напряжения через аналоговые входы A0 и A1. Но напрямую подавать на них более 5 В опасно. Поэтому используются резистивные делители напряжения.
📥 Делитель для входного напряжения (V In → A0):
Верхний резистор: 40 кОм
Нижний резистор: 10 кОм
Входной сигнал подаётся на верхний резистор
Средняя точка подключается к A0
Позволяет измерять до 25 В
📤 Делитель для выходного напряжения (V Out → A1):
Верхний резистор: 40 кОм
Нижний резистор: 10 кОм
Средняя точка подключается к A1
Такой делитель даёт коэффициент ≈ 1/5, что позволяет измерять до 25 В
⚠️ Подбирайте резисторы с учётом нужного диапазона. Программа изначально рассчитана на вход 0–5 В, поэтому при использовании делителей нужно изменить формулу расчёта напряжения.
⚙️ Как работает программа
Программа построена на основе двух объектов класса VoltMeter, каждый из которых отвечает за измерение напряжения по одному из входов.
А также один экземпляр класса Oscilloscope (осциллограф)
📦 Смотри раздел "Скетч Arduino"
Основные этапы работы:
Измерение напряжений:
Выполняется analogRead() на пинах A0 и A1.
Полученные значения преобразуются в вольты: voltage = raw * (5.0 / 1023.0);
При необходимости можно умножать результат на коэффициент делителя, например voltage *= 2.0;
Отображение данных:
Все показания (V In, V Out, V Max) отображаются в верхней части дисплея крупным текстом.
Используется шрифт TextSize(1) для чёткости и экономии места.
Фиксация максимума:
В каждом измерении программа сравнивает текущее значение с предыдущим максимумом.
При нажатии на кнопку (подключенную к D2) максимум сбрасывается.
График напряжения:
Отдельный класс Oscilloscope сохраняет последние измерения в буфере.
В нижней части дисплея рисуется линия, отображающая изменение напряжения во времени.
График занимает 110 пикселей по горизонтали и не наезжает на шкалу.
Вертикальная шкала справа:
Сегментная шкала (10 делений) показывает текущий уровень выходного напряжения.
Обновляется при каждом цикле измерения.
🧠 Дисплей
Размещение основных блоков отображения на экране OLED дисплея
Отображение на дисплее
Программа строит интерфейс в несколько этапов:
Верхняя часть дисплея — отображает входное и максимальные значения напряжения
Средняя часть — напряжение на выходе блока питания.
Нижняя часть — график напряжения во времени, построенный с использованием массива graphBuffer[], в котором хранятся последние 128 измерений. Этот массив сдвигается каждый раз и отображается как ломаная линия, повторяя форму изменения напряжения.
Правая часть — визуальный уровень напряжения в виде сегментной шкалы, где каждый сегмент активен в зависимости от уровня сигнала.
Такой подход позволяет использовать OLED-дисплей максимально эффективно: информативно и красиво.
📜 Скетч Arduino
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int inputPin = A0; // Входное напряжение
const int outputPin = A1; // Выходное напряжение
const int resetButtonPin = 2; // Кнопка сброса максимума
#define GRAPH_HEIGHT 20
#define GRAPH_WIDTH 110 // Оставляем место справа под шкалу
uint8_t graphBuffer[GRAPH_WIDTH];
// Класс вольтметра
class VoltMeter {
private:
int pin;
float voltage;
float maxVoltage;
public:
VoltMeter(int analogInputPin) { // Кнструктор класса
pin = analogInputPin;
voltage = 0.0;
maxVoltage = 0.0;
}
void measure() { // Метод -измерение
int raw = analogRead(pin);
voltage = raw * (5.0 / 1023.0);
if (voltage > maxVoltage) {
maxVoltage = voltage;
}
}
void resetMax() { // Метод - сброс максимального значения
maxVoltage = voltage;
}
float getVoltage() { // Метод - получить измеренное напряжение
return voltage;
}
float getMax() { // Метод - получить максимальное напряжение
return maxVoltage;
}
};
// Класс осциллограф
class Oscilloscope {
public:
Oscilloscope() { // Кнструктор класса
// pin = analogInputPin;
}
void updateGraph(float voltage) {
for (int i = 0; i < GRAPH_WIDTH - 1; i++) {
graphBuffer[i] = graphBuffer[i + 1];
}
uint8_t newY = map(voltage * 100, 0, 500, 0, GRAPH_HEIGHT);
graphBuffer[GRAPH_WIDTH - 1] = newY;
}
void drawGraph() {
int baseY = SCREEN_HEIGHT - 1;
for (int x = 0; x < GRAPH_WIDTH - 1; x++) {
display.drawLine(x, baseY - graphBuffer[x], x + 1, baseY - graphBuffer[x + 1], SSD1306_WHITE);
}
}
void drawScale(float value) {
const int segments = 10;
const int startX = SCREEN_WIDTH - 10; // Правая сторона экрана
const int startY = 58;
const int segWidth = 8;
const int segHeight = 4;
const int gap = 2;
int activeSegments = map(value * 100, 0, 500, 0, segments);
for (int i = 0; i < segments; i++) {
int y = startY - i * (segHeight + gap);
if (i < activeSegments) {
display.fillRect(startX, y, segWidth, segHeight, SSD1306_WHITE);
} else {
display.drawRect(startX, y, segWidth, segHeight, SSD1306_WHITE);
}
}
}
};
VoltMeter vinMeter(inputPin); //Экземпляр класса вольтметр V In
VoltMeter voutMeter(outputPin); // Экземпляр класса вольтметр V Out
Oscilloscope oscill; //Экземпляр класса осциллограф
void setup() {
pinMode(resetButtonPin, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 28);
display.println("Digital Voltmeter");
display.display();
delay(1500);
}
void loop() {
vinMeter.measure();
voutMeter.measure();
if (digitalRead(resetButtonPin) == LOW) {
vinMeter.resetMax();
voutMeter.resetMax();
delay(300);
}
float vin = vinMeter.getVoltage();
float vout = voutMeter.getVoltage();
float vmax = voutMeter.getMax();
oscill.updateGraph(vout);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print("V In: ");
display.print(vin, 2);
display.println(" V");
display.setCursor(0, 10);
display.print("V Max: ");
display.print(vmax, 2);
display.println(" V");
display.setCursor(0, 20);
display.print("V Out: ");
display.print(vout, 2);
display.println(" V");
oscill.drawGraph();
oscill.drawScale(vout);
display.display();
delay(200);
}
🧠 Советы и доработки
✅ Добавить коэффициент делителя прямо в класс VoltMeter, чтобы учесть масштабирование.
💾 Сохранять максимум в EEPROM, чтобы он не сбрасывался при перезагрузке.
🧲 Добавить третью строку: ток или мощность, если есть токовый шунт.
📈 Изменить масштаб графика для отображения высокого напряжения.
⚡ Применение
Настройка и тестирование лабораторных блоков питания.
Измерение и контроль напряжения в проектах Arduino.
Демонстрация работы стабилизаторов напряжения.
Учебные и демонстрационные стенды.
Ответ на пост «Немного вечности»1
1960 год. В рабочем состоянии. Может шлифовать (снимать) не то что одну сотую миллиметра, а еще между этими сотыми есть 5 делений, понимаете?
я даже и не знаю как эти деления называются.
Работаю на нём и ему подобным
Немного вечности1
Амперметр Э30 образца 1953 года. Производства краснодарского завода измерительных приборов. В это время Юра Гагарин учится в саратовском индустриальном техникуме. Был ли жив Сталин - сказать сложно, точной датой изготовления не располагаю. В этом же году была испытана первая советская водородная бомба, закончилась Корейская война, был расстрелян Берия..
Согласно данных Википедии, данная серия приборов производилась с 1948 по 1966 год. До сих пор эксплуатируется, проходит поверку, радует глаз.
Что такое шунт и как на самом деле измеряется ток?
Сегодня мы с вами будем разбираться, как в электронике измеряют силу тока. Мы рассмотрим самый распространённый способ измерения тока с помощью шунта.
По пути выясним, что такое шунт, зачем он нужен, и почему амперметры на самом деле являются вольтметрами, измеряющими напряжение.
Что такое шунт?
Шунт – это специальный резистор, который устанавливается последовательно в цепи, где нужно измерить ток.
Его особенность заключается в низком сопротивлении, высокой точности, термостабильности и способности рассеивать мощность. Современные резисторы также могут использоваться в качестве шунтов, но об этом мы поговорим позже.
Как рассчитать ток в цепи?
Возникает вопрос: как резистор, подключенный последовательно в цепи, измеряет ток? Дело в законе Ома.
Допустим, у нас есть цепь, состоящая из лампочки и батарейки. Например, у нас 12-вольтовая батарейка и лампочка с сопротивлением 30 Ом.
Зная эти параметры, можем рассчитать ток по закону Ома. При напряжении 12 В и сопротивлении 30 Ом ток будет 0,4 А.
Если в цепь добавить ещё одну нагрузку с неизвестным сопротивлением, узнать ток станет сложнее.
В этом случае измеряем напряжение на известной лампочке и делим его на её сопротивление, получая ток.
В реальности конечно же лампа накаливания не может иметь стабильное сопротивление и при нагревании оно естественно будет изменяться.
Поэтому если вместо лампочки в схему установить шунт со стабильным, не зависящими от внешних факторов сопротивлением, то мы легко можем рассчитать ток во всей цепи измеряя лишь только падение напряжения на известном по сопротивлению участка.
Амперметр – это вольтметр!
Все амперметры на самом деле измеряют напряжение, а не ток. Они определяют падение напряжения на шунте.
Шкала амперметра размечена так, чтобы показывать ток, проходящий через цепь, измеряя падение напряжения на шунте.
Современные мультиметры используют аналогичный принцип: они измеряют падение напряжения на шунте с помощью микроконтроллера.
Из чего сделан шунт?
Шунт должен обладать стабильностью сопротивления в широком диапазоне температур. Шунты изготавливают из манганина и константана – сплавов, которые обеспечивают стабильное сопротивление.
В домашних условиях можно использовать медную или нихромовую проволоку для изготовления шунта, но специализированные шунты применяются в точной измерительной технике и для измерения больших токов.
Шунт защищает современную электронику
Шунты широко используются в современной электронике, особенно в импульсных блоках питания.
Они контролируют ток потребления и защищают устройства от короткого замыкания и перегрузок.
В современных схемах используются SMD резисторы с малым сопротивлением. Чем меньше сопротивление шунта, тем меньше его нагрев и тем сложнее измерить падение напряжения на нём.
Здесь помогают операционные усилители и компараторы, которые способны улавливать минимальные изменения напряжения.
Шунт + операционный усилитель
В модулях DC-DC преобразователей напряжения, которые регулируют ток, операционные усилители контролируют ток с помощью шунта.
Например, в микросхеме TL494 встроены операционные усилители, к которым можно подключить шунт для настройки уровня тока или защиты по току.
А кто если не шунт?
Измерить ток можно и бесконтактными методами, например, с использованием эффекта Холла или трансформаторов тока.
Такие методы применяются в современных бесконтактных токоизмерительных клещах.
Существует также оптический способ измерения тока, основанный на эффекте Фарадея.
Надеюсь, теперь вы лучше понимаете, как измеряется ток в электронике и почему шунты так важны в этом процессе.
Различного рода внешние шунты для внедрение в свои электронные проекты, можно приобрести на AliExpress.
Если понравился пост, не забудьте поставить плюсик и оставить комментарий, будет интересно узнать ваши рассуждения.