Что для этого нам понадобятся:
- Arduino Nano (или любой другой совместимый Arduino).
- OLED-дисплей 128×64 (обычно на контроллере SSD1306, подключается по I2C).
- Конденсатор, ёмкость которого будем измерять.
- Резистор известного номинала (например, 10 кОм или 100 кОм) для формирования RC-цепочки.
Принцип измерения ёмкости (RC-метод):
Мы будем использовать метод зарядки/разрядки конденсатора через резистор. Время зарядки (или разрядки) конденсатора в RC-цепи пропорционально его ёмкости и сопротивлению резистора.
- RC-постоянная времени (τ): Это время, за которое конденсатор зарядится примерно до 63.2% от приложенного напряжения или разрядится до 36.8% от начального напряжения. Формула: tau=RtimesC (где tau в секундах, R в Омах, C в Фарадах).
- Мы будем измерять время, за которое аналоговый вход Arduino достигает определённого порогового значения при зарядке конденсатора.
Схема подключения:
- OLED-дисплей:
- VCC -> Arduino 5V
- GND -> Arduino GND
- SDA -> Arduino A4 (для I2C)
- SCL -> Arduino A5 (для I2C)
- Конденсатор и Резистор (RC-цепь):
- Arduino Digital Pin 2 (или другой цифровой пин) -> Один конец Резистора (R)
- Другой конец Резистора (R) -> Один конец Конденсатора (C)
- Другой конец Конденсатора (C) -> Arduino GND
- Точка соединения Резистора (R) и Конденсатора (C) -> Arduino Analog Pin A0 (для измерения напряжения)
Необходимые библиотеки:
Вам понадобятся две библиотеки для работы с OLED-дисплеем SSD1306:
- Adafruit GFX Library (базовая графическая библиотека)
- Adafruit SSD1306 (драйвер для конкретного дисплея)
Их можно установить через «Менеджер библиотек» (Sketch -> Include Library -> Manage Libraries…) в Arduino IDE.
Программа для Arduino Nano:
#include <Wire.h> // Для связи по I2C (для OLED-дисплея)
#include <Adafruit_GFX.h> // Базовая графическая библиотека
#include <Adafruit_SSD1306.h> // Драйвер для SSD1306 OLED-дисплея
// Определяем размеры OLED-дисплея
#define SCREEN_WIDTH 128 // Ширина в пикселях
#define SCREEN_HEIGHT 64 // Высота в пикселях
// Объект дисплея (создаем экземпляр SSD1306)
// Параметры: (Ширина, Высота, &Wire - объект I2C, Reset-пин дисплея - обычно не используется для I2C, поэтому -1)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ---------- Пины для измерения конденсатора ----------
const int chargePin = 2; // Цифровой пин для зарядки/разрядки конденсатора
const int analogPin = A0; // Аналоговый пин для измерения напряжения на конденсаторе
// ---------- Параметры измерения ----------
const float R_VALUE_KOHM = 100.0; // Номинал резистора в кОм (например, 100 кОм)
// Чем больше резистор, тем дольше зарядка для больших ёмкостей
// Чем меньше резистор, тем быстрее зарядка для малых ёмкостей
const int VOLTAGE_THRESHOLD = 648; // Пороговое значение АЦП для измерения (примерно 63.2% от 1023, если питание 5В)
// 5В * 0.632 = 3.16В. Для 10-битного АЦП (0-1023), 3.16В/5В * 1023 = 646.6. Округлим до 647-648.
// Вы можете настроить этот порог для лучшей точности.
// ---------- Переменные для измерения ----------
unsigned long startTime;
unsigned long endTime;
float capacitance_uF; // Измеренная ёмкость в микрофарадах
void setup() {
Serial.begin(9600); // Инициализация последовательного порта для отладки
// Инициализация OLED-дисплея по адресу I2C 0x3C (или 0x3D).
// Проверьте адрес вашего дисплея, если он не работает.
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("Ошибка инициализации SSD1306!"));
for (;;) ; // Бесконечный цикл, если дисплей не найден
}
// Очистка буфера дисплея
display.clearDisplay();
display.setTextSize(1); // Размер текста (1x)
display.setTextColor(SSD1306_WHITE); // Цвет текста
display.setCursor(0, 0); // Установка курсора в начало
display.println("Измерение емкости...");
display.display(); // Вывод на дисплей
delay(2000);
}
void loop() {
// 1. Разрядка конденсатора:
pinMode(chargePin, OUTPUT); // Устанавливаем пин chargePin как выход
digitalWrite(chargePin, LOW); // Подключаем конденсатор к земле через chargePin для разрядки
delay(10); // Ждем короткое время для полной разрядки
// 2. Настройка пинов для измерения:
pinMode(chargePin, INPUT); // Отключаем chargePin (переводим в высокоимпедансное состояние)
// Это позволит пину "плавать" и заряжаться через резистор.
// Можно также установить его как INPUT_PULLUP, но для нашего метода лучше INPUT.
// 3. Запуск зарядки и измерение времени:
startTime = micros(); // Запоминаем текущее время в микросекундах
// Читаем аналоговый вход, пока напряжение не достигнет порога
while (analogRead(analogPin) < VOLTAGE_THRESHOLD) {
// Ждем, пока конденсатор зарядится
// Можно добавить небольшой delay(1) или yield() для предотвращения зависания
// при очень больших ёмкостях, если loop() должен выполнять другие задачи
}
endTime = micros(); // Запоминаем время, когда порог достигнут
// 4. Расчет ёмкости:
// Формула для RC-постоянной: tau = R * C
// Время зарядки до 63.2% (или нашего порога) = RC
// C = время / R
// C (Фарад) = (endTime - startTime) (сек) / R (Ом)
// Мы используем микросекунды и килоомы, поэтому:
// C (мкФ) = (endTime - startTime) (мкс) / (R_VALUE_KOHM * 1000 Ом/кОм)
// = (endTime - startTime) / R_VALUE_KOHM / 1000
// = (время_в_микросекундах / 1000) / R_VALUE_KOHM (что даст нФ)
// C (мкФ) = (время_в_микросекундах / 1000.0) / R_VALUE_KOHM (мкФ) * 1000 (нФ в мкФ)
// C (мкФ) = (время_в_микросекундах / 1000.0) / R_VALUE_KOHM
// Если R_VALUE_KOHM в кОм, а время в мкс, то C будет в нанофарадах (нФ).
// 1 нФ = 0.001 мкФ
// C (мкФ) = (время_в_мкс / 1000) / (R_VALUE_KOHM * 1000) (мкФ)
// Более точно: C (F) = delta_t (s) / R (Ohm)
// C (uF) = (delta_t (us) / 1,000,000) / (R_VALUE_KOHM * 1000) * 1,000,000
// C (uF) = delta_t (us) / (R_VALUE_KOHM * 1000)
// Более простая формула для uF:
// C (uF) = (endTime - startTime) / R_VALUE_KOHM; // Где время в микросекундах, R в килоомах.
// Это приближенная формула, работает хорошо для 63.2% зарядки.
// Если время в микросекундах (us), а R_VALUE_KOHM в кОм, то ёмкость будет в нФ.
// Для мкФ:
capacitance_uF = (float)(endTime - startTime) / R_VALUE_KOHM; // Это даст ёмкость в нанофарадах (нФ)
// (us / kOhm = nF)
// Переводим нФ в мкФ для более удобного отображения, если ёмкость большая
if (capacitance_uF >= 1000.0) { // Если ёмкость 1000 нФ и больше
capacitance_uF /= 1000.0; // Делим на 1000 для получения мкФ
Serial.print("Емкость: ");
Serial.print(capacitance_uF, 2); // 2 знака после запятой
Serial.println(" мкФ");
// Вывод на OLED
display.clearDisplay();
display.setTextSize(2); // Крупнее текст для значения
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print(capacitance_uF, 2); // Выводим значение
display.println(" uF");
display.setTextSize(1);
display.println(); // Пустая строка
display.println(" (microFarad)");
display.display();
} else {
Serial.print("Емкость: ");
Serial.print(capacitance_uF, 2);
Serial.println(" нФ");
// Вывод на OLED
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print(capacitance_uF, 2);
display.println(" nF");
display.setTextSize(1);
display.println(); // Пустая строка
display.println(" (nanoFarad)");
display.display();
}
delay(1000); // Задержка 1 секунда перед следующим измерением
}
Пояснения к коду:
- Подключение библиотек:
Wire.hдля I2C-связи,Adafruit_GFX.hиAdafruit_SSD1306.hдля работы с OLED-дисплеем. - Настройка OLED:
#define SCREEN_WIDTH 128и#define SCREEN_HEIGHT 64: Определяют разрешение дисплея.Adafruit_SSD1306 display(...): Создает объект для работы с дисплеем. Адрес0x3C(или0x3D) — стандартный для многих SSD1306. Если дисплей не работает, проверьте его I2C-адрес.
- Пины для измерения:
chargePin (пин 2): Используется для управления зарядкой/разрядкой конденсатора.analogPin (пин A0): Аналоговый вход для измерения напряжения на конденсаторе.
R_VALUE_KOHM:ОЧЕНЬ ВАЖНО! Укажите здесь точный номинал вашего резистора в килоомах (кОм). Чем точнее вы измерите этот резистор мультиметром, тем точнее будут измерения ёмкости.- Для ёмкостей в диапазоне нФ используйте резистор 100 кОм — 1 МОм.
- Для ёмкостей в диапазоне мкФ используйте резистор 10 кОм — 100 кОм.
VOLTAGE_THRESHOLD: Это порог, до которого мы ждем зарядки конденсатора.- Для зарядки до 63.2% от 5В (напряжение питания Arduino) это примерно 3.16В.
- Поскольку аналоговый вход Arduino имеет 10-битное разрешение (0-1023), 3.16В соответствует
(3.16 / 5.0) * 1023 ≈ 646.6. Я округлил до648для запаса.
setup():- Инициализация
Serialдля отладки (вывод данных в Serial Monitor). - Инициализация дисплея. Если дисплей не найден, программа остановится.
- Инициализация
loop():- Разрядка: Сначала
chargePinустанавливается какOUTPUTвLOW, чтобы полностью разрядить конденсатор. Это важно для точных измерений. - Подготовка к зарядке:
chargePinпереводится вINPUT(высокоимпедансное состояние), позволяя конденсатору заряжаться через резистор от напряжения наanalogPin. - Измерение времени:
micros()используется для измерения времени в микросекундах. Это обеспечивает достаточную точность для измерения небольших ёмкостей. - Цикл
while: Ждет, пока напряжение наanalogPinне достигнетVOLTAGE_THRESHOLD. - Расчет ёмкости:
capacitance_uF = (float)(endTime - startTime) / R_VALUE_KOHM;- Если
startTimeиendTimeв микросекундах, аR_VALUE_KOHMв килоомах, то результат будет в нанофарадах (нФ). Это происходит из-за того, что 1 нФ = 1 кОм * 1 нс, а у нас мкс и кОм, поэтому 1 мкс / 1 кОм = 1 нФ. - Затем код проверяет, если ёмкость больше 1000 нФ, то переводит её в микрофарады (мкФ) для более удобного отображения.
- Если
- Вывод на OLED и Serial: Результаты выводятся на дисплей и в Serial Monitor.
delay(1000): Задержка между измерениями.
- Разрядка: Сначала
Важные замечания и улучшения:
- Точность резистора: Точность измерения напрямую зависит от точности известного резистора. Используйте прецизионные резисторы или измерьте их фактическое сопротивление мультиметром.
- Диапазон измерений: Этот метод лучше всего работает для конденсаторов ёмкостью от нескольких нанофарад (нФ) до нескольких сотен микрофарад (мкФ).
- Для пикофарад (пФ) нужны более сложные схемы (например, с осциллятором или высокочастотным измерением).
- Для очень больших ёмкостей (тысячи мкФ) время зарядки будет очень долгим, и
micros()может переполниться (около 70 минут). Для таких ёмкостей лучше использоватьmillis()и другие методы.
- Помехи: Аналоговые измерения чувствительны к шумам. Убедитесь, что проводка короткая и надёжная.
- Сброс конденсатора: Перед каждым измерением убедитесь, что конденсатор полностью разряжен. Добавленный
digitalWrite(chargePin, LOW); delay(10);делает это. - Полярность электролитических конденсаторов: Электролитические конденсаторы имеют полярность. Подключайте их правильно, иначе они могут выйти из строя.
Этот код является хорошей отправной точкой. Загрузите его, подключите всё по схеме и попробуйте измерить несколько конденсаторов! Дайте знать, если возникнут вопросы.