Dvokanalni voltmetar s termometrom izveden kao shield za Arduino Uno. Mjeri dva istosmjerna napona do 40 V i temperaturu te sve prikazuje na malom OLED zaslonu.
Kako radi
Uređaj koristi 10-bitni A/D pretvornik Arduina. Za svako mjerenje očita se 16 uzoraka. Njihov se zbroj dijeli s 4, što softverskim oversamplingom daje 12-bitnu razlučivost. Pet takvih mjerenja zatim se usrednjuje i prikazuje na zaslonu, otprilike svakih 300 ms. Stvarno vrijeme jednog ciklusa prikazuje se u zadnjem retku zaslona.
Shema
Ulazni kanali
Mjereni napon dovodi se na stezaljke CH1+ i CH1−. Na ulazu je djelitelj napona od pet otpornika (100 kΩ prema 10 kΩ + 1 kΩ + 100 Ω + 10 Ω) s omjerom 10 : 1. Uz referentni napon od 4,096 V to daje mjerno područje do 40 V.
Izlaz djelitelja ide na kondenzator za filtriranje (1 µF) i zaštitne Schottkyjeve diode 1N5819 prema VCC-u i masi, a zatim na pin A1 Arduina. Drugi kanal izveden je jednako i spojen je na pin A2.
Upozorenje
Ulaz je predviđen samo za istosmjerni napon do 40 V. Viši napon može oštetiti Arduino unatoč zaštitnim diodama.
Referentni napon
Za referentni napon koristi se TL431, trimerom R16 podešen na 4,096 V. Spojen je na pin AREF Arduina preko kratkospojnika JP1.
Termometar
Temperatura se mjeri NTC termistorom od 47 kΩ (B = 3435). Termistor i otpornik od 47 kΩ u seriji čine djelitelj napona čiji izlazni napon ovisi o temperaturi. Izlaz djelitelja spojen je na pin A0, a skica iz izmjerenog napona izračunava otpor termistora te iz njega temperaturu pomoću B-jednadžbe.
Zaslon
OLED zaslon SSD1306 (0,96", 128×64) spojen je na +5 V i masu te signalnim linijama SDA i SCL na odgovarajuće pinove Arduina (I²C).
Skica za Arduino
Skica koristi biblioteku U8g2 za upravljanje zaslonom.
// *********************************************************
// Program: two chanel voltmeter with thermometer
// Date: 01/09/2018
// Version: 1.0
// Author: Elvis Baketa
// Description:
// *********************************************************
#include<Arduino.h>#include<Wire.h>#include<U8g2lib.h>// WHITE OLED LCD 0.96" 128X64 I2C
U8G2_SSD1306_128X64_NONAME_F_HW_I2Cu8g2(U8G2_R0,/* reset=*/U8X8_PIN_NONE);unsignedlongstartTime;unsignedlongfinishTime;intupdateDisplay=0;intsamples=16;floatresolution=4096.0;floatvoltageReference=4.096;floatseriesResistor=47000.00;intanalogValueCH0[16];intanalogValueCH1[16];intanalogValueCH2[16];unsignedintaverageAnalogValueCH0;unsignedintaverageAnalogValueCH1;unsignedintaverageAnalogValueCH2;floatvoltageCH0=0.000;floatvoltageCH1=0.000;floatvoltageCH2=0.000;floataverageVoltageCH1=0.000;floataverageVoltageCH2=0.000;floatresistance=0.000;floattemperature=0.000;floataverageTemperature=0.000;voidsetup(){// put your setup code here, to run once:
analogReference(EXTERNAL);u8g2.begin();}voidloop(){// put your main code here, to run repeatedly:
updateDisplay++;// read chanel one
for(inti=0;i<samples;i++){analogValueCH0[i]=analogRead(A0);delay(1);}for(intl=0;l<samples;l++){averageAnalogValueCH0+=analogValueCH0[l];}averageAnalogValueCH0/=4;voltageCH0=averageAnalogValueCH0*(voltageReference/resolution);averageAnalogValueCH0=0;// convert volts to resistance
resistance=voltageReference/voltageCH0-1;resistance=1/resistance;resistance=seriesResistor*resistance;// convert resistance to temperature in Kelvin
temperature=log(resistance/seriesResistor);temperature=temperature*(1/float(3435));temperature=temperature+(1/(25+273.15));temperature=1/temperature;// convert Kelvin to Celsius
// T(°C) = T(°K) - 273.15
temperature=temperature-273.15;averageTemperature+=temperature;// read chanel two
for(intj=0;j<samples;j++){analogValueCH1[j]=analogRead(A1);delay(1);}for(intm=0;m<samples;m++){averageAnalogValueCH1+=analogValueCH1[m];}averageAnalogValueCH1/=4;voltageCH1=averageAnalogValueCH1*(voltageReference/resolution);voltageCH1*=10;averageVoltageCH1+=voltageCH1;averageAnalogValueCH1=0;// read chanel three
for(intk=0;k<samples;k++){analogValueCH2[k]=analogRead(A2);delay(1);}for(intn=0;n<samples;n++){averageAnalogValueCH2+=analogValueCH2[n];}averageAnalogValueCH2/=4;voltageCH2=averageAnalogValueCH2*(voltageReference/resolution);voltageCH2*=10;averageVoltageCH2+=voltageCH2;averageAnalogValueCH2=0;if(updateDisplay>4){// display data
u8g2.clearBuffer();u8g2.setFont(u8g2_font_profont22_tf);averageTemperature/=updateDisplay;u8g2.setCursor(0,16);u8g2.print("T ");u8g2.print(averageTemperature);u8g2.print(char(176));u8g2.print("C");averageVoltageCH1/=updateDisplay;u8g2.setCursor(0,32);u8g2.print("CH1 ");u8g2.print(averageVoltageCH1);u8g2.print("V");averageVoltageCH2/=updateDisplay;u8g2.setCursor(0,48);u8g2.print("CH2 ");u8g2.print(averageVoltageCH2);u8g2.print("V");u8g2.setCursor(0,64);finishTime=millis()-startTime;u8g2.print(finishTime);u8g2.print(" ms");u8g2.sendBuffer();averageTemperature=0.000;averageVoltageCH1=0.000;averageVoltageCH2=0.000;updateDisplay=0;startTime=millis();}}