Rehberler · 11 dk okuma

Arduino Voltmetre Yapımı: 0–25 V Ölçme, LCD ve Kalibrasyon

Arduino voltmetre nasıl yapılır? Bölücüyle 0–25 V ölçme, direnç seçimi, zener koruma, kalibrasyon, LCD, INA219 wattmetre ve pil test cihazı.

Arduino voltmetre, iki direnç, bir analog giriş ve birkaç satır kodla 0–25 V arası doğru gerilimi ölçüp ekranda gösteren, yapımı bir akşam süren bir ölçü aletidir. Arduino'nun analog girişleri en fazla 5 V okuyabilir; daha yüksek gerilimi ölçmek için önce bir gerilim bölücüyle küçültür, sonra kodda aynı oranla geri büyütürsün. Akü izleme, güç kaynağı göstergesi, güneş paneli takibi ya da pil test cihazı gibi projelerin hepsi bu tek fikre dayanır.

Bu rehberde direnç değerlerini ölçüm aralığına göre nasıl seçeceğini, analog girişi aşırı gerilimden koruyan zener ve seri direnç düzenini, hazır 0–25 V voltaj sensörü modülünü, ölçümü multimetre seviyesine yaklaştıran referans gerilimi ayarını ve kalibrasyonu adım adım göreceksin. Ardından değeri I2C LCD ekranda gösterecek, aynı voltmetreyi ESP32 ve Raspberry Pi Pico'da kuracak, INA219 ile akım ekleyip wattmetreye dönüştürecek ve son olarak pilin gerçek kapasitesini mAh cinsinden ölçen bir test cihazı yapacaksın.

Dijital voltmetre
Arduino ile yapacağın voltmetre de bu panel tipi göstergeler gibi gerilimi iki ondalık basamakla gösterebilir.

Arduino voltmetre nasıl çalışır?

Arduino gerilimi doğrudan bilmez; analog girişteki gerilimi bir ADC (analog dijital dönüştürücü) ile referans gerilimine oranlar ve sonucu bir tam sayı olarak verir. Arduino Uno'nun ADC'si 10 bittir: 0 V için 0, referans gerilimi (varsayılan olarak 5 V) için 1023 okur. Pindeki gerilim Vpin = okunan × Vref / 1024 formülüyle bulunur. Girişte bir gerilim bölücü varsa ölçülen asıl gerilim Vgiriş = Vpin × (R1 + R2) / R2 olur. Yani voltmetrenin bütün doğruluğu üç şeye bağlıdır: Vref'in gerçek değeri, iki direncin oranı ve ADC'nin kendi hatası.

KartADCReferansPinde 1 basamak0–25 V bölücüyle 1 basamak
Arduino Uno, Nano, Pro Mini10 bit (0–1023)5 V (AVcc)4,88 mV24,4 mV (30 kΩ + 7,5 kΩ)
ESP3212 bit (0–4095)Yaklaşık 3,3 V (11 dB zayıflatma)Yaklaşık 0,8 mVYaklaşık 9 mV (100 kΩ + 10 kΩ)
Raspberry Pi Pico12 bit (read_u16 ile 0–65535)3,3 V (ADC_VREF)0,81 mV8,9 mV (100 kΩ + 10 kΩ)

0–25 V ölçmek için gerilim bölücü ve direnç seçimi

Ölçülecek gerilim üstteki direnç R1'den girer, iki direncin birleştiği orta nokta analog pine gider, alttaki R2 ise GND'ye bağlanır. Direnç seçerken önce en yüksek gerilimi belirle, sonra bu gerilimde pinde referansın biraz altında, örneğin Uno için yaklaşık 4,5 V kalacak bir oran seç. Hazır modüllerde kullanılan 30 kΩ ve 7,5 kΩ ikilisi oranı tam 5'e böler: 25 V girişte pinde 5,00 V olur. Değerleri de gelişigüzel seçme: toplam direnç çok küçükse bölücü ölçtüğün kaynaktan boşuna akım çeker, çok büyükse ADC'nin içindeki örnekleme kondansatörü dolamaz ve okuma kayar. ATmega328P'nin veri sayfası analog girişi süren kaynağın direncinin 10 kΩ'u geçmemesini önerir; bölücünün bu açıdan direnci R1 ile R2'nin paralel eşdeğeridir (30 kΩ ile 7,5 kΩ için 6 kΩ). Formülün ayrıntısını ve yük etkisini gerilim bölücü yazısında bulabilirsin.

Ölçüm aralığıArduino Uno (5 V): R1 + R2Tam aralıkta pinESP32 / Pico (3,3 V): R1 + R2Tam aralıkta pin
0–10 V12 kΩ + 10 kΩ4,55 V33 kΩ + 10 kΩ2,33 V
0–25 V30 kΩ + 7,5 kΩ (hazır modül)5,00 V100 kΩ + 10 kΩ2,27 V
0–30 V56 kΩ + 10 kΩ4,55 V120 kΩ + 10 kΩ2,31 V
0–50 V100 kΩ + 10 kΩ4,55 V220 kΩ + 10 kΩ2,17 V
Kendi aralığın için oranı elle hesaplamak yerine gerilim bölücü hesaplayıcısını kullanabilirsin. ESP32 ve Pico sütunlarında pin gerilimini bilerek 2,5 V'un altında tuttuk; ESP32'nin ADC'si üst uçta doğrusallığını kaybeder. Dirençler için %1 toleranslı metal film tercih et; %5'lik iki direnç oranı en kötü durumda yaklaşık %10 kaydırabilir.

Koruma: zener diyot, seri direnç ve kondansatör

Bölücü doğru hesaplansa bile yanlış prob, güç kaynağındaki bir sıçrama ya da yanlışlıkla 25 V yerine 48 V'a dokunmak pindeki gerilimi 5 V'un üstüne çıkarabilir. ATmega328P'nin pinleri en fazla besleme + 0,5 V'a dayanır. Pinin içinde 5 V'a ve GND'ye giden koruma diyotları vardır, ama bunlar yalnızca küçük akımlara dayanır. İyi haber şu: bölücünün üst direnci zaten akımı sınırlar. 30 kΩ'luk R1 ile 50 V'a dokunsan bile pine en fazla yaklaşık 1,5 mA akar. Bu akımı daha da küçültmek ve fazla gerilimi güvenle yutmak için aşağıdaki katmanları ekleyebilirsin.

  • Seri direnç: Bölücünün orta noktası ile analog pin arasına 4,7–10 kΩ bir direnç koy. Aşırı gerilimde pinin iç diyotlarına giden akım mikroamper seviyesine iner.
  • 100 nF kondansatör: Analog pin ile GND arasına bağla. Seri direnç yüzünden artan kaynak direncini telafi eder, çünkü ADC örnekleme anında gereken yükü bu kondansatörden alır. Üstelik gürültüyü ve kısa sıçramaları da süzer.
  • 5,1 V zener diyot: 1N4733A ya da BZX55C5V1 gibi bir zeneri katodu pine, anodu GND'ye gelecek şekilde bağla. Gerilim 5,1 V'u aşmaya çalışınca zener iletime geçer ve fazlasını GND'ye akıtır.
  • Zener kaçağına dikkat: Zener, kırılma geriliminin biraz altından itibaren küçük bir akım çekmeye başlar ve bu akım yüksek dirençli bölücüde ölçümü aşağı çeker. Zener kullanıyorsan pinin en yüksek değerini 4 V civarında tut ya da zener yerine pinden 5 V hattına giden bir Schottky diyot (BAT85) kullan.
  • Ters kutup: Probları ters bağlarsan pine eksi gerilim gelir. Seri direnç akımı sınırlar; ek güvenlik için anodu GND'ye, katodu pine gelecek şekilde ikinci bir Schottky diyot ekleyebilirsin.
Bu voltmetre yalnızca DC ve düşük gerilim (en fazla birkaç on volt) içindir. 220 V şebekeyi iki dirençle ölçmeye kalkma: hem hayati tehlike vardır hem de Arduino'nun GND'si şebekeye bağlanmış olur. Şebeke gerilimi için galvanik yalıtımlı ZMPT101B gibi bir trafo modülü kullanılır. Ayrıca ölçtüğün kaynağın eksisi ile Arduino'nun GND'si mutlaka birleşik olmalı; ortak toprak yoksa okunan değer anlamsızdır.

Hazır voltaj sensörü modülü (0–25 V)

Lehim yapmak istemiyorsan piyasada "voltage sensor" adıyla satılan küçük kırmızı ya da mavi modülü kullanabilirsin. İçinde sihirli bir şey yoktur: tam olarak 30 kΩ ve 7,5 kΩ'luk iki dirençten oluşan bir bölücü, bir vida klemensi ve üç pinli bir başlık bulunur. Oran 5 olduğu için 5 V'luk bir Arduino ile 0–25 V, 3,3 V'luk bir kartla ise en fazla 16,5 V ölçebilirsin. Ancak 3,3 V kartlarda 25 V'a dokunmak pine 5 V uygular ve kartı bozar; ESP32 ve Pico için yukarıdaki tablodaki kendi bölücünü kurmak daha güvenlidir. Modülde koruma diyotu yoktur, bu yüzden önceki bölümdeki zener ya da Schottky önlemi burada da geçerlidir.

Modül ucuGöreviArduino UnoESP32 (kendi bölücün)Raspberry Pi Pico (kendi bölücün)
VCC (vida klemensi)Ölçülecek kaynağın artısıKaynağın +R1'in üst ucuR1'in üst ucu
GND (vida klemensi)Ölçülecek kaynağın eksisiKaynağın −Kaynağın − ve GNDKaynağın − ve GND
SBölünmüş sinyalA0GPIO 34 (ADC1)GP26 (ADC0, pin 31)
+Çoğu modülde boşturBağlama--
−Modülün GND'siGNDGNDGND (ör. pin 33)

Adım adım: Arduino ile ilk voltmetre

  1. Modülün S pinini A0'a, − pinini GND'ye bağla. Kendi bölücünü kuruyorsan 30 kΩ'u kaynak tarafına, 7,5 kΩ'u GND tarafına koy ve orta noktayı A0'a götür.
  2. Arduino'yu USB'ye tak, multimetreyle 5V pini ile GND arasını ölç ve değeri not et. USB'den gelen gerilim çoğu zaman 4,7–5,1 V arasındadır.
  3. Aşağıdaki kodda VREF sabitine ölçtüğün değeri yaz ve kodu yükle.
  4. Ölçeceğin kaynağı modülün vida klemensine bağla: artı VCC'ye, eksi GND'ye. İlk deneme için 9 V'luk bir pil ya da ayarlı bir güç kaynağı idealdir.
  5. Seri Monitör'ü 9600 baud'da aç. Ekranda gerilimi gör ve aynı anda multimetreyle kaynağın uçlarını ölçüp iki değeri karşılaştır.
C++ (Arduino IDE)
1// Arduino voltmetre: 0-25 V gerilim sensörü modülü / Arduino voltmeter: 0-25 V voltage sensor module
2// Modül S -> A0, modül - -> GND / module S -> A0, module - -> GND
3// Ölçülen kaynak modülün VCC ve GND klemensine / measured source goes to the module's VCC and GND terminals
4const int SENSE_PIN = A0;
5const float VREF = 5.00;       // 5V pininde ölçtüğün gerilim / voltage you measured on the 5V pin
6const float R1 = 30000.0;      // üst direnç (ohm) / top resistor (ohms)
7const float R2 = 7500.0;       // alt direnç (ohm) / bottom resistor (ohms)
8const float CAL = 1.000;       // kalibrasyon: gerçek / okunan / calibration: real / measured
9const int SAMPLES = 32;        // ortalama için örnek sayısı / samples to average
10
11float readVoltage() {
12  analogRead(SENSE_PIN);                    // ilk okumayı at / discard the first reading
13  unsigned long sum = 0;
14  for (int i = 0; i < SAMPLES; i++) {
15    sum += analogRead(SENSE_PIN);
16    delayMicroseconds(500);
17  }
18  float adc = (float)sum / SAMPLES;         // 0-1023 arası ortalama / average between 0 and 1023
19  float vPin = adc * VREF / 1024.0;         // pindeki gerilim / voltage at the pin
20  return vPin * (R1 + R2) / R2 * CAL;       // bölücüden önceki gerilim / voltage before the divider
21}
22
23void setup() {
24  Serial.begin(9600);
25}
26
27void loop() {
28  float v = readVoltage();
29  if (v < 0.05) v = 0.0;                    // boşta gürültüyü sıfırla / zero the noise when idle
30  Serial.print(F("Gerilim / Voltage: "));
31  Serial.print(v, 2);
32  Serial.println(F(" V"));
33  delay(500);
34}

Kod her ölçümde 32 okumanın ortalamasını alır; ADC'nin ±1 basamaklık titremesi böylece büyük ölçüde kaybolur ve son hane sakinleşir. İlk okumanın atılmasının sebebi, ADC'nin örnekleme kondansatörünün bir önceki kanaldan kalan yükü taşımasıdır. 0,05 V altını sıfıra yuvarlamak, kaynak bağlı değilken ekranda 0,02–0,04 V gibi rastgele değerler görmeni engeller. Çözünürlüğün 24,4 mV olduğunu unutma: ekranda iki ondalık görsen de son hane 0,02–0,03 V'luk adımlarla değişir. Daha ince çözünürlük istiyorsan aralığı daralt; 0–10 V bölücüyle bir basamak 10,7 mV'a iner.

Referans gerilimi ve kalibrasyon

Arduino voltmetrelerin çoğunun "yanlış ölçtüğü" söylenir, ama hatanın asıl kaynağı genellikle referanstır. Kodda 5,00 V yazarken kart USB'den 4,80 V alıyorsa her okuma %4 yüksek çıkar: 12,00 V'luk aküyü 12,50 V gösterirsin. Bilgisayardan dizüstüne, bir USB kablodan diğerine bu gerilim değişir; harici adaptörle beslediğinde ise kartın regülatörü devreye girer ve değer yine farklı olur. Bu sorunu çözmenin üç yolu vardır: 5V pinini ölçüp koda yazmak, sabit bir iç referans kullanmak ya da kartın kendi besleme gerilimini her ölçümde yeniden hesaplamak.

YöntemKodArtısıDikkat edilecek
Varsayılan (AVcc)analogReference(DEFAULT)Kurulum gerektirmez, 0–5 V tam aralıkBesleme ne kadar oynarsa ölçüm de o kadar oynar
İç 1,1 V referansanalogReference(INTERNAL)Beslemeden bağımsız ve kararlıDeğeri karttan karta 1,0–1,2 V arasında; bölücü oranı yaklaşık 23 olmalı (ör. 220 kΩ + 10 kΩ)
Dış referans (AREF)analogReference(EXTERNAL)LM4040 gibi hassas referansla en iyi doğrulukAREF'e gerilim uygulamadan önce bu satır çalışmalı, yoksa iç referansla kısa devre olur
Besleme ölçümü (readVcc)Aşağıdaki kodEk parça yok, USB ya da pil değişse de doğru kalırYalnız AVR kartlarda (Uno, Nano, Pro Mini) çalışır; 1,1 V değerini bir kez kalibre et
C++ (Arduino IDE)
1// Kendi besleme gerilimini ölçen voltmetre (ATmega328P: Uno, Nano, Pro Mini)
2// Voltmeter that measures its own supply (ATmega328P: Uno, Nano, Pro Mini)
3const int SENSE_PIN = A0;
4const float R1 = 30000.0;      // üst direnç / top resistor
5const float R2 = 7500.0;       // alt direnç / bottom resistor
6long bandgapMv = 1100;         // iç referans (mV), kalibrasyonla düzelt / internal reference (mV), fix by calibration
7
8long readVccMv() {
9  // Referans AVcc, ölçülen kanal iç 1,1 V / reference AVcc, measured channel is the internal 1.1 V
10  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
11  delay(2);                                  // referans otursun / let the reference settle
12  ADCSRA |= _BV(ADSC);                       // dönüşümü başlat / start a conversion
13  while (bit_is_set(ADCSRA, ADSC)) {}        // bitmesini bekle / wait until it finishes
14  unsigned int raw = ADCW;                   // 10 bit sonuç / 10-bit result
15  return bandgapMv * 1024L / raw;            // Vcc = 1,1 V x 1024 / okunan / Vcc = 1.1 V x 1024 / reading
16}
17
18float readVoltage(float vcc) {
19  analogRead(SENSE_PIN);                     // kanal değişti, ilk okumayı at / channel changed, discard first
20  unsigned long sum = 0;
21  for (int i = 0; i < 32; i++) sum += analogRead(SENSE_PIN);
22  float vPin = (sum / 32.0) * vcc / 1024.0;
23  return vPin * (R1 + R2) / R2;
24}
25
26void setup() {
27  Serial.begin(9600);
28}
29
30void loop() {
31  float vcc = readVccMv() / 1000.0;
32  float v = readVoltage(vcc);
33  Serial.print(F("Vcc: "));
34  Serial.print(vcc, 3);
35  Serial.print(F(" V   Giris / Input: "));
36  Serial.print(v, 2);
37  Serial.println(F(" V"));
38  delay(500);
39}
  1. İç referansı kalibre et: readVcc kodunu çalıştır, Seri Monitör'deki Vcc değerini multimetreyle 5V pininde ölçtüğün değerle karşılaştır. Yeni bandgapMv = 1100 × ölçülen / gösterilen. Örneğin kart 5,12 V gösterir, multimetre 4,98 V ölçerse 1100 × 4,98 / 5,12 ≈ 1070 yaz.
  2. Tek noktalı kalibrasyon: Ölçüm aralığının üst kısmına yakın bilinen bir gerilim bağla (ör. 12 V). CAL = multimetrenin değeri / Arduino'nun değeri. Bu katsayı direnç toleransından gelen oran hatasını da düzeltir.
  3. İki noktalı kalibrasyon: Düşük gerilimlerde sabit bir kayma görüyorsan, biri düşük (ör. 2 V), biri yüksek (ör. 20 V) iki noktada ölç. Eğim = (M2 − M1) / (A2 − A1), kayma = M1 − eğim × A1; sonuç gerçek = eğim × okunan + kayma olur (M multimetrenin, A Arduino'nun değeri).
  4. Kontrol et: Kalibrasyondan sonra aralığın ortasında üçüncü bir gerilimle sonucu doğrula. Uno ile dikkatli kurulmuş bir voltmetre 0–25 V aralığında %1'in altında hatayla ölçer.

LCD ekranlı dijital voltmetre

I2C 2x16 LCD ekran
Arkasındaki I2C modülü sayesinde 16x2 LCD yalnızca dört kabloyla bağlanır: GND, VCC, SDA ve SCL.

Voltmetreyi bilgisayardan bağımsız hale getirmek için değeri bir I2C LCD ekrana yazdırman yeterli. LCD'nin GND'sini GND'ye, VCC'sini 5V'a, SDA'yı A4'e, SCL'yi A5'e bağla. Kütüphane Yöneticisi'nden LiquidCrystal I2C (Frank de Brabander) kütüphanesini kur. Ekranın adresi çoğunlukla 0x27, bazı modüllerde 0x3F'tir. Aşağıdaki kod üst satırda anlık gerilimi, alt satırda ise açılıştan beri görülen en düşük ve en yüksek değeri gösterir; bu sayede örneğin bir motor çalışırken aküde oluşan gerilim düşümünü de yakalarsın.

C++ (Arduino IDE)
1// LCD ekranlı dijital voltmetre (0-25 V, min/maks) / Digital voltmeter with LCD (0-25 V, min/max)
2// LCD: SDA -> A4, SCL -> A5, VCC -> 5V, GND -> GND; sensör S -> A0 / sensor S -> A0
3#include <Wire.h>
4#include <LiquidCrystal_I2C.h>
5
6LiquidCrystal_I2C lcd(0x27, 16, 2);   // adres 0x27 ya da 0x3F / address 0x27 or 0x3F
7
8const int SENSE_PIN = A0;
9const float VREF = 5.00;              // 5V pininde ölçülen / measured on the 5V pin
10const float RATIO = (30000.0 + 7500.0) / 7500.0;   // = 5,0
11const float CAL = 1.000;              // kalibrasyon katsayısı / calibration factor
12
13float vMin = 99.99;
14float vMax = 0.0;
15
16float readVoltage() {
17  analogRead(SENSE_PIN);
18  unsigned long sum = 0;
19  for (int i = 0; i < 32; i++) sum += analogRead(SENSE_PIN);
20  float v = (sum / 32.0) * VREF / 1024.0 * RATIO * CAL;
21  return v < 0.05 ? 0.0 : v;
22}
23
24void printField(float value) {
25  char buf[8];
26  dtostrf(value, 5, 2, buf);          // sabit genişlik: " 9.87" / fixed width: " 9.87"
27  lcd.print(buf);
28}
29
30void setup() {
31  lcd.init();
32  lcd.backlight();
33  lcd.print(F("Voltmetre 0-25V"));
34  delay(1000);
35  lcd.clear();
36}
37
38void loop() {
39  float v = readVoltage();
40  if (v > 0.5) {                      // boştayken min/maks güncelleme / don't update min/max when idle
41    if (v < vMin) vMin = v;
42    if (v > vMax) vMax = v;
43  }
44
45  lcd.setCursor(0, 0);
46  lcd.print(F("V: "));
47  printField(v);
48  lcd.print(F(" V      "));
49
50  lcd.setCursor(0, 1);
51  lcd.print(F("L"));
52  printField(vMin > 99.0 ? 0.0 : vMin);
53  lcd.print(F("  H"));
54  printField(vMax);
55  lcd.print(F("  "));
56  delay(300);
57}

ESP32 ile voltmetre

ESP32 3,3 V ile çalışır ve pinleri 3,6 V'u aşan gerilime dayanmaz, bu yüzden 0–25 V için 100 kΩ + 10 kΩ'luk bölücü kullan: 25 V girişte pinde 2,27 V olur. Bölücüyü ADC1 pinlerinden birine (GPIO 32–39) bağla; ADC2 pinleri Wi-Fi açıkken çalışmaz. ESP32'nin ADC'si 12 bittir ama uçlarda doğrusal değildir: 0,15 V'un altını neredeyse hiç göremez ve 2,5 V'un üstünde hatası artar. analogReadMilliVolts() fonksiyonu üretimde yongaya yazılan kalibrasyon verisini kullanarak ham değerden çok daha doğru bir milivolt sonucu verir. Kalan kaymayı gidermek için kod, önceki bölümde anlatılan iki noktalı kalibrasyonu GAIN ve OFFSET sabitleriyle uygular.

C++ (Arduino IDE)
1// ESP32 voltmetre: 100k + 10k bölücü ile 0-25 V / ESP32 voltmeter: 0-25 V with a 100k + 10k divider
2// Kaynak + -> 100k -> GPIO 34 -> 10k -> GND, kaynak - -> GND / source + -> 100k -> GPIO 34 -> 10k -> GND
3const int SENSE_PIN = 34;                 // ADC1_CH6, Wi-Fi açıkken de çalışır / works with Wi-Fi on
4const float RATIO = (100000.0 + 10000.0) / 10000.0;   // = 11,0
5const float GAIN = 1.000;                 // iki noktalı kalibrasyon: eğim / two-point calibration: slope
6const float OFFSET = 0.00;                // iki noktalı kalibrasyon: kayma (V) / two-point calibration: offset (V)
7
8float readVoltage() {
9  uint32_t mv = 0;
10  for (int i = 0; i < 64; i++) {
11    mv += analogReadMilliVolts(SENSE_PIN);   // fabrika kalibrasyonlu mV / factory-calibrated mV
12  }
13  float vPin = mv / 64.0 / 1000.0;           // pindeki gerilim (V) / voltage at the pin (V)
14  float v = vPin * RATIO * GAIN + OFFSET;
15  return v < 0.10 ? 0.0 : v;
16}
17
18void setup() {
19  Serial.begin(115200);
20  analogReadResolution(12);                  // 0-4095
21}
22
23void loop() {
24  float v = readVoltage();
25  Serial.printf("Gerilim / Voltage: %.2f V\n", v);
26  delay(500);
27}

Raspberry Pi Pico ile voltmetre (MicroPython)

Raspberry Pi Pico'da analog girişler GP26, GP27 ve GP28'dir. ESP32 ile aynı 100 kΩ + 10 kΩ bölücüyü GP26'ya bağla. MicroPython'da read_u16() 12 bitlik sonucu 0–65535 aralığına ölçeklenmiş olarak verir. Pico'nun ADC referansı 3,3 V hattından süzülerek gelir; daha doğru ölçüm için ADC_VREF (pin 35) ile GND arasını multimetreyle ölçüp VREF sabitine yaz. Kodda bir bonus da var: standart Pico'da GP29 (ADC3), kartın besleme girişi VSYS'i 1/3 oranında bölen dahili bir bölücüye bağlıdır. Böylece hiçbir ek parça kullanmadan Pico'yu besleyen pilin gerilimini de okursun. Pico W ve Pico 2 W'de GP29 kablosuz yongayla paylaşıldığı için bu satır o kartlarda doğrudan çalışmaz.

MicroPython
1# Raspberry Pi Pico voltmetre (MicroPython) / Raspberry Pi Pico voltmeter (MicroPython)
2# Kaynak + -> 100k -> GP26 -> 10k -> GND / source + -> 100k -> GP26 -> 10k -> GND
3from machine import ADC
4import time
5
6sense = ADC(26)            # GP26 = ADC0 (pin 31)
7vsys = ADC(29)             # GP29 = VSYS / 3 (yalnız standart Pico / standard Pico only)
8VREF = 3.3                 # ADC_VREF; multimetreyle ölçüp düzelt / measure and correct with a multimeter
9RATIO = (100000 + 10000) / 10000    # = 11.0
10GAIN = 1.000               # iki noktalı kalibrasyon: eğim / two-point calibration: slope
11OFFSET = 0.00              # iki noktalı kalibrasyon: kayma (V) / two-point calibration: offset (V)
12
13
14def pin_voltage(adc, samples=64):
15    total = 0
16    for _ in range(samples):
17        total += adc.read_u16()            # 0-65535
18    return total / samples * VREF / 65535  # pindeki gerilim / voltage at the pin
19
20
21while True:
22    v_in = pin_voltage(sense) * RATIO * GAIN + OFFSET
23    if v_in < 0.05:
24        v_in = 0.0
25    v_sys = pin_voltage(vsys) * 3          # VSYS = GP29 x 3
26    print("Giris / Input: {:.2f} V   VSYS: {:.2f} V".format(v_in, v_sys))
27    time.sleep(0.5)

Akım ekleyip wattmetre yapmak: ACS712 ya da INA219

ACS712 akım sensörü modülü
ACS712 akımı Hall etkisiyle ölçer; ölçülen devre ile Arduino arasında elektriksel yalıtım sağlar.

Gerilimi ölçen bir voltmetreye akım ölçümü eklediğinde gücü de bulursun: P = V × I. 12 V'luk bir akü 1,5 A çekiyorsa güç 18 W'tır. Gücü zamanla toplarsan enerjiyi elde edersin: 18 W'lık yük 2 saat çalışırsa 36 Wh harcar. Bunun için iki yaygın seçenek var. ACS712 analog çıkışlıdır, AC akımı da ölçer ve yalıtım sağlar; mevcut voltmetreye ikinci bir analog kanal olarak eklenir. INA219 ise gerilimi ve akımı aynı yongada, 12 bit hassasiyetle ölçen ve I2C ile haberleşen bir DC güç ölçerdir; tek başına hazır bir wattmetredir.

ÖzellikVoltaj modülü + ACS712 (5A)INA219 modülü
Gerilim aralığı0–25 V (bölücüye bağlı)0–26 V (yonganın içinde)
Akım aralığı±5 A±3,2 A (0,1 Ω şönt ile)
Akım çözünürlüğüUno'da yaklaşık 26 mA0,1 mA
AC akımÖlçerÖlçmez
Bağlantıİki analog pinI2C (SDA, SCL), adres 0x40
En uygun işMotor, şebeke tarafı akım ve yalıtım gereken yerlerPil, güneş paneli, USB cihaz gibi küçük DC güç ölçümü
C++ (Arduino IDE)
1// INA219 + I2C LCD ile wattmetre: V, A, W ve Wh / Wattmeter with INA219 + I2C LCD: V, A, W and Wh
2// Kaynak + -> INA219 VIN+ ; INA219 VIN- -> yük + ; yük - -> kaynak - -> Arduino GND
3// Source + -> INA219 VIN+ ; INA219 VIN- -> load + ; load - -> source - -> Arduino GND
4#include <Wire.h>
5#include <Adafruit_INA219.h>
6#include <LiquidCrystal_I2C.h>
7
8Adafruit_INA219 ina219;               // varsayılan adres 0x40 / default address 0x40
9LiquidCrystal_I2C lcd(0x27, 16, 2);
10
11float energyWh = 0.0;
12unsigned long lastMs = 0;
13
14void printField(float value, int width, int decimals) {
15  char buf[10];
16  dtostrf(value, width, decimals, buf);
17  lcd.print(buf);
18}
19
20void setup() {
21  Serial.begin(9600);
22  lcd.init();
23  lcd.backlight();
24  if (!ina219.begin()) {              // modül bulunamadı / module not found
25    lcd.print(F("INA219 yok!"));
26    while (true) delay(10);
27  }
28  // ina219.setCalibration_16V_400mA();  // küçük akımlar için daha hassas / finer for small currents
29  lastMs = millis();
30}
31
32void loop() {
33  float busV = ina219.getBusVoltage_V();           // VIN- ile GND arası / between VIN- and GND
34  float shuntMv = ina219.getShuntVoltage_mV();     // şönt üzerindeki düşüm / drop across the shunt
35  float loadV = busV + shuntMv / 1000.0;           // kaynağın gerilimi / source voltage
36  float currentA = ina219.getCurrent_mA() / 1000.0;
37  float powerW = loadV * currentA;
38
39  unsigned long now = millis();
40  energyWh += powerW * (now - lastMs) / 3600000.0; // W x saat = Wh / W x hours = Wh
41  lastMs = now;
42
43  lcd.setCursor(0, 0);
44  printField(loadV, 5, 2);  lcd.print(F("V "));
45  printField(currentA, 6, 3); lcd.print(F("A  "));
46  lcd.setCursor(0, 1);
47  printField(powerW, 6, 2); lcd.print(F("W "));
48  printField(energyWh, 6, 2); lcd.print(F("Wh"));
49
50  Serial.print(loadV, 2);    Serial.print(F(" V, "));
51  Serial.print(currentA, 3); Serial.print(F(" A, "));
52  Serial.print(powerW, 2);   Serial.print(F(" W, "));
53  Serial.print(energyWh, 3); Serial.println(F(" Wh"));
54  delay(500);
55}

INA219 akımı, VIN+ ile VIN− arasındaki 0,1 Ω'luk şönt dirençteki küçük gerilim düşümünden hesaplar; bu yüzden modül devreye seri ve kaynağın artı tarafına (yüksek taraf) bağlanır. Bus gerilimi VIN− ile GND arasında ölçüldüğü için kod, şönt düşümünü ekleyerek kaynağın gerçek gerilimini bulur. Varsayılan kalibrasyon 32 V ve 2 A içindir; yalnızca birkaç yüz miliamper ölçeceksen setCalibration_16V_400mA() satırını açarak ölçüm aralığını 400 mA'e daraltabilir ve küçük akımlarda doğruluğu artırabilirsin. Enerji, her döngüde geçen süre ile o anki gücün çarpımı toplanarak bulunur; Arduino'yu kapatınca sıfırlanır, kalıcı olması için değeri belli aralıklarla EEPROM'a yazabilirsin. ACS712 ile aynı hesabı yapan koda ACS712 yazısındaki güç ve enerji bölümünden bakabilirsin.

Pil test cihazı: kapasiteyi (mAh) ölçen voltmetre

18650 Li-ion pil
Bir 18650 hücrenin etiketindeki kapasite ile gerçek kapasitesi çoğu zaman farklıdır; test cihazı bunu ortaya çıkarır.

Bir pilin gerilimine bakmak, içinde ne kadar enerji kaldığını tam söylemez; dolu ama yorgun bir hücre de 4,1 V gösterebilir. Gerçek kapasiteyi bulmanın yolu pili bilinen bir yük üzerinden boşaltmak ve akımı zamanla toplamaktır: mAh = Σ (akım × süre). Bu devrede yükü bir MOSFET açıp kapatır, Arduino da pilin ve yük direncinin alt ucunun gerilimini saniyede bir ölçer. İki gerilim arasındaki fark yük direncine bölünerek akım bulunur. Pil kesme gerilimine inince MOSFET kapanır ve sonuç ekrana yazılır. Kod başlangıçta ayrıca pilin yüksüz ve yüklü gerilimini karşılaştırarak iç direncini hesaplar; iç direnç yükseldikçe pil yüksek akımda daha çok çöker.

ParçaBağlantıNot
Pil +10 kΩ üzerinden A0; ayrıca yük direncinin üst ucuA0 ile GND arasına 100 nF koy
Yük direnci 4,7 ΩPil + ile MOSFET drain arasıEn az 5 W (tercihen 10 W) taş direnç; 18650 ile yaklaşık 0,9 A akar ve ısınır
MOSFET drainYük direncinin alt ucu; 10 kΩ üzerinden A1A1 ile GND arasına da 100 nF koy
MOSFET sourceGNDPilin eksisi de buraya bağlanır
MOSFET gate220 Ω üzerinden D9; 100 kΩ ile GND'yeIRLZ44N gibi lojik seviyeli bir MOSFET kullan
C++ (Arduino IDE)
1// Pil kapasite test cihazı: mAh, Wh ve iç direnç / Battery capacity tester: mAh, Wh and internal resistance
2// Pil + -> 10k -> A0 ; pil + -> 4,7 ohm yük -> MOSFET drain ; drain -> 10k -> A1
3// Battery + -> 10k -> A0 ; battery + -> 4.7 ohm load -> MOSFET drain ; drain -> 10k -> A1
4// MOSFET source -> GND ; gate <- D9 (220 ohm), gate -> 100k -> GND ; pil - / battery - -> GND
5const int BAT_PIN = A0;
6const int DRAIN_PIN = A1;
7const int LOAD_PIN = 9;
8const float VREF = 5.00;        // 5V pininde ölçülen / measured on the 5V pin
9const float R_LOAD = 4.7;       // yük direnci, multimetreyle ölç / load resistor, measure it
10const float CUTOFF_V = 3.00;    // Li-ion 3,00 V ; alkalin AA / alkaline AA 0,90 V
11
12float mAh = 0.0;
13float wh = 0.0;
14unsigned long lastMs = 0;
15unsigned long startMs = 0;
16bool running = false;
17
18float readPin(int pin) {
19  analogRead(pin);                          // kanal değişti, ilk okumayı at / discard first reading
20  unsigned long sum = 0;
21  for (int i = 0; i < 32; i++) sum += analogRead(pin);
22  return (sum / 32.0) * VREF / 1024.0;
23}
24
25float loadCurrent(float vBat) {
26  return (vBat - readPin(DRAIN_PIN)) / R_LOAD;   // dirençteki gerilim / R / voltage across R / R
27}
28
29void setup() {
30  Serial.begin(9600);
31  pinMode(LOAD_PIN, OUTPUT);
32  digitalWrite(LOAD_PIN, LOW);              // yük kapalı / load off
33  delay(1000);
34
35  float vOpen = readPin(BAT_PIN);           // yüksüz gerilim / open-circuit voltage
36  if (vOpen < CUTOFF_V + 0.1) {
37    Serial.println(F("Pil zayif ya da takili degil / Battery low or missing"));
38    return;
39  }
40  digitalWrite(LOAD_PIN, HIGH);             // yükü aç / load on
41  delay(1000);
42  float vLoad = readPin(BAT_PIN);
43  float amps = loadCurrent(vLoad);
44  Serial.print(F("Bos / Open: "));
45  Serial.print(vOpen, 3);
46  Serial.print(F(" V  Yuklu / Loaded: "));
47  Serial.print(vLoad, 3);
48  Serial.print(F(" V  Ic direnc / Internal R: "));
49  Serial.print((vOpen - vLoad) / amps * 1000.0, 0);
50  Serial.println(F(" mOhm"));
51
52  running = true;
53  startMs = lastMs = millis();
54}
55
56void loop() {
57  if (!running) return;
58  unsigned long now = millis();
59  if (now - lastMs < 1000) return;          // saniyede bir ölç / measure once per second
60
61  float hours = (now - lastMs) / 3600000.0;
62  lastMs = now;
63  float vBat = readPin(BAT_PIN);
64  float amps = loadCurrent(vBat);
65  mAh += amps * 1000.0 * hours;             // akım x süre / current x time
66  wh += vBat * amps * hours;
67
68  Serial.print((now - startMs) / 1000);
69  Serial.print(F(" s  "));
70  Serial.print(vBat, 3);
71  Serial.print(F(" V  "));
72  Serial.print(amps, 3);
73  Serial.print(F(" A  "));
74  Serial.print(mAh, 0);
75  Serial.println(F(" mAh"));
76
77  if (vBat <= CUTOFF_V) {                   // kesme gerilimi / cut-off voltage
78    digitalWrite(LOAD_PIN, LOW);
79    running = false;
80    Serial.print(F("Bitti / Done: "));
81    Serial.print(mAh, 0);
82    Serial.print(F(" mAh, "));
83    Serial.print(wh, 2);
84    Serial.println(F(" Wh"));
85  }
86}

4,7 Ω'luk yükle bir 18650 hücre yaklaşık 0,9 A'den başlayıp 0,65 A'e doğru azalan bir akımla boşalır; 2500 mAh'lik sağlam bir hücrenin testi yaklaşık üç saat sürer. Li-ion için kesme gerilimini 3,0 V'un altına indirme, aksi halde hücre zarar görür. Alkalin AA pil test ediyorsan CUTOFF_V'yi 0,9 V yap; aynı yükle yaklaşık 0,3 A çekilir. Sonucu etiketteki değerle ve pil ömrü hesaplayıcısıyla karşılaştırabilirsin. Yeni bir 18650'nin bu yöntemle ölçülen iç direnci yuva ve kablo dahil genellikle 0,15 Ω'un altındadır; 0,3 Ω'u geçen bir hücre yüksek akım isteyen işlerde kullanılmamalıdır. Kapasite birimlerinin anlamı için mAh ve pil kapasitesi yazısına göz at.

Li-ion hücreleri hiçbir zaman kısa devre etme ve yük direncini yanıcı bir yüzeye koyma; 4 W civarında ısı üreten direnç 80–100 °C'ye çıkabilir. Testi gözetimsiz bırakma ve şişmiş ya da ezilmiş hücreleri test etmeye kalkma.

Arduino voltmetre ile proje fikirleri

  • Akü izleme ve düşük gerilim alarmı: Karavan ya da güneş sistemindeki 12 V aküyü izle, gerilim 11,8 V'un altına inince bir buzzer öttür.
  • Güneş paneli kaydedici: Panelin gerilimini ve INA219 ile akımını dakikada bir SD karta yaz, günlük üretimi Wh cinsinden çıkar.
  • Ayarlı güç kaynağı göstergesi: LM2596 modülünün çıkışına voltmetre ve INA219 ekleyerek tezgah üstü güç kaynağına dönüştür.
  • Uzaktan akü takibi: ESP32 ile ölçtüğün gerilimi MQTT ile Home Assistant'a gönder ya da düşük gerilimde Telegram'dan mesaj al.
  • 18650 paket kontrolü: TP4056 ile şarj ettiğin hücrelerin kapasitesini test et, benzer kapasiteli hücreleri eşleştirerek dengeli bir paket kur.
  • Büyük rakamlı gösterge: Değeri LCD yerine 7 segment display ya da OLED ekran üzerinde, uzaktan okunacak büyüklükte göster.

Sık yapılan hatalar ve çözümleri

BelirtiOlası sebepÇözüm
Okuma sürekli %2–5 yüksek ya da düşükKodda VREF 5,00 V ama kart farklı bir gerilimle besleniyor5V pinini ölçüp VREF'e yaz ya da readVcc yöntemini kullan
Değer durmadan zıplıyorKaynağın eksisi Arduino GND'sine bağlı değil ya da hat gürültülüOrtak GND bağla, ortalama al, pine 100 nF ekle
Yüksek gerilimde hep aynı değerde takılıyorPin referansa ulaştı, ADC 1023'te doyduÖlçüm aralığını büyüt, bölücü oranını artır
Üst kısımda okuma eğiliyor, doğrusal değilZener kaçak akımı ya da ESP32 ADC'nin üst ucuPini 4 V (ESP32'de 2,5 V) altında tut ya da Schottky kullan
ESP32'de Wi-Fi açılınca okuma 0 ya da sabitBölücü bir ADC2 pinine bağlıGPIO 32–39 arasındaki ADC1 pinlerinden birini kullan
INA219 eksi akım gösteriyorVIN+ ve VIN− ters bağlanmışKaynak artısı VIN+'ya, yükün artısı VIN−'ye gelmeli
LCD aydınlık ama yazı yokYanlış I2C adresi ya da kontrast ayarıI2C tarayıcıyla adresi bul, arkadaki trimpotu çevir
Yeni kurduğun bir bölücüyü Arduino'ya bağlamadan önce kaynağı aç ve orta noktadaki gerilimi multimetreyle ölç. Değer hesapladığına yakınsa ve referansın altındaysa pine bağlamak güvenlidir. Bu on saniyelik kontrol, ters takılmış iki direncin kartını yakmasını önler.

Arduino voltmetre, ölçme mantığını öğrenmenin en iyi yollarından biridir: iki direnç, bir formül ve biraz kalibrasyonla multimetreye yakın sonuçlar alırsın; akım sensörü eklediğinde wattmetre, MOSFET eklediğinde pil test cihazı olur. BlueGrays uygulamasındaki "LCD Ekran ile Dijital Voltmetre" projesinde aynı devreyi adım adım devre şeması ve hazır koduyla kurabilir, oradan akü izleme ve güç ölçümü projelerine geçebilirsin.

Sıkça sorulan sorular

Arduino ile kaç volta kadar gerilim ölçülebilir?

Analog pine doğrudan en fazla 5 V (ESP32 ve Pico'da 3,3 V) bağlanabilir. Gerilim bölücüyle bu sınır istediğin kadar büyütülebilir: 30 kΩ + 7,5 kΩ ile 25 V, 100 kΩ + 10 kΩ ile 50 V ölçülür. Ancak birkaç on voltun üzerinde güvenlik ve yalıtım önemli hale gelir; şebeke gerilimi bu yöntemle ölçülmez.

Arduino voltmetre neden yanlış ölçüyor?

En sık sebep referans gerilimidir: kodda 5,00 V yazar ama kart USB'den 4,7–4,9 V alır ve bütün ölçümler aynı oranda kayar. Diğer sebepler %5 toleranslı dirençler, ortak GND eksikliği ve yüksek dirençli bölücüdür. 5V pinini multimetreyle ölçüp koda yazmak ya da readVcc yöntemini kullanmak ve bilinen bir gerilimle CAL katsayısını ayarlamak sorunu çözer.

0–25 V voltaj sensörü modülü ESP32 ile kullanılır mı?

Kullanılabilir ama dikkatli olmalısın. Modül oranı 5 olduğu için ESP32 ile en fazla 16,5 V ölçebilirsin; 25 V'a dokunursan pine 5 V gelir ve ESP32 zarar görür. ESP32 için 100 kΩ + 10 kΩ'luk kendi bölücünü kurmak hem güvenli hem de ADC'nin doğrusal bölgesinde kaldığı için daha doğrudur.

Arduino ile 220 V AC gerilim ölçülür mü?

Gerilim bölücüyle kesinlikle ölçülmemelidir; hem hayati tehlike vardır hem de Arduino şebekeye bağlanmış olur. Şebeke gerilimi için içinde küçük bir trafo bulunan ve galvanik yalıtım sağlayan ZMPT101B gibi modüller kullanılır. Bu modüllerin çıkışı alternatif olduğu için kodda RMS hesabı yapılır.

Arduino ile eksi (negatif) gerilim ölçülebilir mi?

Doğrudan ölçülemez; analog pin GND'nin altına inen gerilimi okuyamaz ve zarar görebilir. Çözüm, ölçülen sinyali bir dirençle 5 V'a doğru kaydırmaktır: örneğin iki eşit dirençle sinyal ve 5 V arasında bir orta nokta oluşturursan −5 V ile +5 V arası 0–5 V'a taşınır. Daha hassas işler için op-amp ile seviye kaydırma kullanılır.

Arduino voltmetre multimetre kadar hassas olur mu?

Kalibre edilmiş bir Uno voltmetresi 0–25 V aralığında %1'in altında hatayla ölçer; bu çoğu hobi işi için yeterlidir ve ucuz multimetrelere yakındır. 10 bitlik ADC yüzünden çözünürlük 25 V aralıkta yaklaşık 24 mV ile sınırlıdır. Daha iyi sonuç için ADS1115 gibi 16 bitlik harici bir ADC, %0,1 toleranslı dirençler ve hassas bir referans kullanılabilir.

Tüm projeleri gör
Ldr İle Işık Şiddeti Okuma
#11Başlangıç

Ldr İle Işık Şiddeti Okuma

Odanın ne kadar aydınlık olduğunu sayıyla görmek ister misin? Işığa duyarlı küçük bir parça olan LDR ortam ışığını ölçer ve Arduino bu değeri yarım saniyede bir bilgisayar ekranına yazar. Elinle üstün

4.6(81)
139
ESP32 LDR Modülü ile Işık Şiddeti Okuma
#113Başlangıç

ESP32 LDR Modülü ile Işık Şiddeti Okuma

LDR modülünün ham ADC değerini ve karanlık/aydınlık referanslarına göre hesaplanan göreli ışık yüzdesini Serial Monitor'da gerçek zamanlı izleme. Bu yüzde lux ölçümü değildir. Modülün kalibrasyon mantığını öğretir. Proje 10'un öncesinde yapılması ideal; çünkü eşik değerini belirlemek için kullanılır.

4.6(36)
55
LCD Ekran ile Dijital Voltmetre
#56Orta
Premium

LCD Ekran ile Dijital Voltmetre

Pilin ya da adaptörün ne kadar gerilim verdiğini kendi yaptığın ölçü aletiyle öğren. İki dirençten oluşan bir bölücü yüksek gerilimi kartın okuyabileceği seviyeye indirir, Arduino da gerçek değeri hes

4.5(27)
36
NTC ve 2x16 Lcd Ekran İle Sıcaklık Ölçümü
#44Başlangıç
Premium

NTC ve 2x16 Lcd Ekran İle Sıcaklık Ölçümü

Ortamın sıcaklığını küçük bir boncuk gibi görünen sensörle ölç. NTC adlı bu parça ısındıkça elektriği daha kolay geçirir; Arduino bu değişimi okuyup bir formülle santigrat dereceye çevirir ve iki satı

4.5(33)
44
I2C İle LCD Ekran Kullanımı
#32Başlangıç
Premium

I2C İle LCD Ekran Kullanımı

Arduino'ya kendi ekranını kazandır ve ilk mesajını yazdır. İki satırlık LCD ekran yalnızca birkaç kabloyla bağlanır; önce üst satıra bir selam, ardından alt satıra ikinci bir yazı gelir, ekran temizle

4.8(53)
70
ESP32 I2C LCD Ekran (16x2)
#119Orta
Premium

ESP32 I2C LCD Ekran (16x2)

Bu projede 16x2 karakter LCD ekranı I2C protokolü üzerinden ESP32'ye bağlayarak metin görüntülüyoruz. I2C sayesinde sadece 2 data pini (SDA ve SCL) ile ekranı kontrol edebiliyoruz; klasik paralel bağlantıdaki 6+ pin israfı ortadan kalkıyor. Kod ilk satıra sabit bir mesaj, ikinci satıra ise her saniye artan bir sayaç yazdırıyor. Ayrıca başlangıçta I2C tarayıcı çalıştırarak ekranın adresini Serial Monitor'a yazdırıyoruz (genelde 0x27 veya 0x3F).

4.9(23)
40
LCD Ekran Kullanarak Mesafe Ölçme
#31İleri
Premium

LCD Ekran Kullanarak Mesafe Ölçme

Cetvelsiz mesafe ölçen bir alet: elini sensörün önünde ileri geri götür, sayı değişsin. HC-SR04 ses dalgası gönderip yankısını dinler, Arduino da aradaki uzaklığı santimetre olarak hesaplayıp iki satı

4.6(45)
59
ESP32 Potansiyometre ile LED Parlaklık (Analog → PWM)
#115Orta
Premium

ESP32 Potansiyometre ile LED Parlaklık (Analog → PWM)

Bu projede bir potansiyometre ile LED parlaklığını analog olarak kontrol ediyoruz. ESP32'nin ADC pini potansiyometreden gelen 0-3.3V gerilimi okur, ardından bu değer PWM (Pulse Width Modulation) sinyaline çevrilerek LED'e gönderilir. Böylece potansiyometreyi çevirdikçe LED kademeli olarak parlar ve söner. Arduino Core 3.0+ ile analogWrite() doğrudan kullanılabilir; ESP32-S2/S3'te ADC çözünürlüğü 12-bit'e sabitlenir.

4.5(19)
32