πŸ’‘ Π¦ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ Π’ΠΎΠ»ΡŒΡ‚ΠΌΠ΅Ρ‚Ρ€ Π½Π° Arduino с OLED-дисплССм ΠΈ Π“Ρ€Π°Ρ„ΠΈΠΊΠΎΠΌ

Π²ΠΎΠ»ΡŒΡ‚ΠΌΠ΅Ρ‚Ρ€ arduino

πŸ“˜ ОписаниС

Π­Ρ‚ΠΎΡ‚ простой ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ позволяСт ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ Π²ΠΎΠ»ΡŒΡ‚ΠΌΠ΅Ρ‚Ρ€ Π½Π° Π±Π°Π·Π΅ Arduino, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΠΉ:

  • Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ напряТСниС Π½Π° Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ Π²Ρ…ΠΎΠ΄Π΅ (Π΄ΠΎ 5 Π’) Ссли Π±Π΅Π· дСлитСля
  • максимальноС зафиксированноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ НапряТСния
  • ΡˆΠΊΠ°Π»Ρƒ Π² Π²ΠΈΠ΄Π΅ сСгмСнтов (ΠΊΠ°ΠΊ ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ‚ΠΎΡ€ уровня)
  • ΠΆΠΈΠ²ΠΎΠΉ Π³Ρ€Π°Ρ„ΠΈΠΊ измСнСния напряТСния Π² Π½ΠΈΠΆΠ½Π΅ΠΉ части экрана

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΊΠ½ΠΎΠΏΠΊΠ° сброса максимального значСния, Π° Π½Π° OLED 128Γ—64 дисплСС для Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ отобраТСния ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π³Ρ€Π°Ρ„ΠΈΠΊ.

β˜‘οΈ Telegram Канал —-


πŸ“‹ ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹

НазваниСКол-Π²ΠΎΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅
Arduino Uno/Nano1Π›ΡŽΠ±Π°Ρ стандартная ΠΏΠ»Π°Ρ‚Π°
OLED-дисплСй 128×64 I2C1АдрСс ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 0x3C
Кнопка1ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π° ΠΊ ΠΏΠΈΠ½Ρƒ D2 ΠΈ GND
РСзистор (10 кОм)1Для подтяТки, ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· INPUT_PULLUP
ΠŸΡ€ΠΎΠ²ΠΎΠ΄Π°, макСтная платаДля ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²

βš™οΈ Π‘Ρ…Π΅ΠΌΠ° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

Π’ΠΎΠ»ΡŒΡ‚ΠΌΠ΅Ρ‚Ρ€ Π½Π° Arduino
Пин ArduinoΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚
A0Π˜Π·ΠΌΠ΅Ρ€ΡΠ΅ΠΌΠΎΠ΅ напряТСниС
A4 (SDA)OLED SDA
A5 (SCL)OLED SCL
D2Кнопка (Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π²ΠΎΠ΄ Π½Π° GND)
5V, GNDΠŸΠΈΡ‚Π°Π½ΠΈΠ΅ OLED ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ

πŸ“Ž Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

  • ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ напряТСния с Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ Π΄ΠΎ 0.01 Π’
  • Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ максимального значСния
  • Кнопка для сброса максимума
  • БСгмСнтированная шкала уровня (аналоговая индикация)
  • Π Π΅Π°Π»Π’Π°ΠΉΠΌ Π³Ρ€Π°Ρ„ΠΈΠΊ напряТСния (ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈ-осциллограф)

🧠 ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ€Π°Π±ΠΎΡ‚Ρ‹

  • НапряТСниС считываСтся с ΠΏΠΈΠ½Π° A0 с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ analogRead()
  • Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ прСобразуСтся Π² Π²ΠΎΠ»ΡŒΡ‚Ρ‹ ΠΈ отобраТаСтся
  • Π’ массивС graphBuffer[] ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ послСдниС значСния
  • На основС этого массива строится Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ Π³Ρ€Π°Ρ„ΠΈΠΊ
  • Кнопка сбрасываСт максимум (Π°Π½Ρ‚ΠΈΠ΄Ρ€Π΅Π±Π΅Π·Π³ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Ρ‡Π΅Ρ€Π΅Π· delay(300))

πŸ” Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° (ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ)

1. Π§Ρ‚Π΅Π½ΠΈΠ΅ напряТСния ΠΈ расчёт

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΎΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ Π²Ρ…ΠΎΠ΄ A0 ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ analogRead(), которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ 0 Π΄ΠΎ 1023, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ Π½Π°ΠΏΡ€ΡΠΆΠ΅Π½ΠΈΡŽ ΠΎΡ‚ 0 Π΄ΠΎ 5 Π’. Π—Π°Ρ‚Π΅ΠΌ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ прСобразуСтся Π² Π²ΠΎΠ»ΡŒΡ‚Ρ‹ ΠΏΠΎ Ρ„ΠΎΡ€ΠΌΡƒΠ»Π΅:

voltage = raw * (5.0 / 1023.0);

МаксимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сохраняСтся Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ maxVoltage. Если Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ максимума β€” ΠΎΠ½ΠΎ пСрСзаписываСтся. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π½Π° экранС всСгда отобраТаСтся ΠΏΠΈΠΊΠΎΠ²ΠΎΠ΅ напряТСниС с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° послСднСго сброса.

2. ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π° дисплСС

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° строит интСрфСйс Π² нСсколько этапов:

  • ВСрхняя Ρ‡Π°ΡΡ‚ΡŒ дисплСя β€” ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ ΠΈ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Π΅ значСния напряТСния Π² Π²ΠΈΠ΄Π΅ тСкста.
  • БрСдняя Ρ‡Π°ΡΡ‚ΡŒ β€” Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ напряТСния Π² Π²ΠΈΠ΄Π΅ сСгмСнтной ΡˆΠΊΠ°Π»Ρ‹, Π³Π΄Π΅ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ сСгмСнт Π°ΠΊΡ‚ΠΈΠ²Π΅Π½ Π² зависимости ΠΎΡ‚ уровня сигнала.
  • НиТняя Ρ‡Π°ΡΡ‚ΡŒ β€” Π³Ρ€Π°Ρ„ΠΈΠΊ напряТСния Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, построСнный с использованиСм массива graphBuffer[], Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ хранятся послСдниС 128 ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ. Π­Ρ‚ΠΎΡ‚ массив сдвигаСтся ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΈ отобраТаСтся ΠΊΠ°ΠΊ ломаная линия, повторяя Ρ„ΠΎΡ€ΠΌΡƒ измСнСния напряТСния.

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ OLED-дисплСй максимально эффСктивно: ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΠ²Π½ΠΎ ΠΈ красиво.

🧠 ДисплСй

Π Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ основных Π±Π»ΠΎΠΊΠΎΠ² отобраТСния Π½Π° экранС OLED дисплСя

OLED ДисплСй

🧾 Код скСтча

#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 analogPin = A0;
const int resetButtonPin = 2;

#define GRAPH_HEIGHT 20
#define GRAPH_WIDTH  128
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;
    }
};

VoltMeter voltmeter(analogPin);

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 = 0;
  const int startY = 22;
  const int segWidth = 10;
  const int segHeight = 5;
  const int gap = 2;

  int activeSegments = map(value * 100, 0, 500, 0, segments);
  for (int i = 0; i < segments; i++) {
    int x = startX + i * (segWidth + gap);
    if (i < activeSegments) {
      display.fillRect(x, startY, segWidth, segHeight, SSD1306_WHITE);
    } else {
      display.drawRect(x, startY, segWidth, segHeight, SSD1306_WHITE);
    }
  }
}

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() {
  voltmeter.measure();

  if (digitalRead(resetButtonPin) == LOW) {
    voltmeter.resetMax();
    delay(300);
  }

  float voltage = voltmeter.getVoltage();
  float maxVoltage = voltmeter.getMax();
  updateGraph(voltage);

  display.clearDisplay();

  display.setCursor(0, 0);
  display.print("Voltage: ");
  display.print(voltage, 2);
  display.println(" V");

  display.setCursor(0, 10);
  display.print("Max:     ");
  display.print(maxVoltage, 2);
  display.println(" V");

  drawScale(voltage);
  drawGraph();

  display.display();
  delay(200);
}

πŸ“¦ Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ

  • Максимально допустимоС напряТСниС Π½Π° A0: 5 Π’! Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ, Ссли измСряСтС большС напряТСниС.
  • МоТно ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π΄ΠΎΠ±Π°Π²ΠΈΠ²:
    • EEPROM для сохранСния максимума
    • Автонастройку ΠΌΠ°ΡΡˆΡ‚Π°Π±Π° Π³Ρ€Π°Ρ„ΠΈΠΊΠ°
    • Π—ΡƒΠΌ Π½Π° Π³Ρ€Π°Ρ„ΠΈΠΊ ΠΈΠ»ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ срСдних Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ

πŸ”— БвязанныС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρ‹

Author: admin

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *