Voltmetru Bluetooth bazat pe arduino. Voltmetru digital pe Arduino cu conectare la PC prin portul serial

Prezentat diagrama utila pentru cei cărora le place să experimenteze cu Arduino. Acesta este un voltmetru digital simplu care poate măsura în mod fiabil tensiunea DC în intervalul 0 - 30V. Placa Arduino, ca de obicei, poate fi alimentată de o baterie de 9V.

După cum probabil știți, intrările analogice ale Arduino pot fi folosite pentru a măsura tensiune DCîn intervalul 0 – 5V și acest interval poate fi mărit,
folosind două rezistențe ca divizor de tensiune. Divizorul va reduce tensiunea măsurată la nivelul intrărilor analogice Arduino. Și apoi programul va calcula valoarea reală a tensiunii.

Senzorul analogic de pe placa Arduino detectează prezența tensiunii la intrarea analogică și o convertește în formă digitală pentru procesare ulterioară de către microcontroler. În figură, tensiunea este furnizată la intrarea analogică (A0) printr-un simplu divizor de tensiune format din rezistențele R1 (100 kOhm) și R2 (10 kOhm).

Cu aceste valori de divizor, placa Arduino poate fi alimentată cu tensiune de la 0 la
55V. La intrarea A0 avem tensiunea măsurată împărțită la 11, adică 55V / 11=5V. Cu alte cuvinte, atunci când măsuram 55V la intrarea Arduino avem un maxim valoare admisibilă 5V. În practică, este mai bine să scrieți intervalul „0 - ​​30V” pe acest voltmetru, astfel încât să rămână
Marja de siguranta!

Note

Dacă citirile afișate nu coincid cu citirile unui voltmetru industrial (de laborator), atunci este necesar instrument de precizie Măsurați valorile rezistenței R1 și R2 și introduceți aceste valori în loc de R1=100000.0 și R2=10000.0 în codul programului. Apoi ar trebui să măsurați tensiunea reală dintre pinii de 5V și „Ground” ai plăcii Arduino cu un voltmetru de laborator. Rezultatul va fi o valoare mai mică de 5V, de exemplu, va fi 4,95V. Acest valoare reala trebuie inserat în linia de cod
vout = (valoare * 5,0) / 1024,0 în loc de 5,0.
De asemenea, încercați să utilizați rezistențe de precizie cu o toleranță de 1%.

Rezistoarele R1 și R2 oferă o anumită protecție împotriva tensiunilor de intrare crescute.Totuși, rețineți că orice tensiune de peste 55V poate deteriora placa Arduino. În plus, acest design nu oferă alte tipuri de protecție (împotriva supratensiunii, inversării polarității sau supratensiunii).

Program voltmetru digital

/*
Voltmetru DC
Un Arduino DVM bazat pe conceptul de divizor de tensiune
T.K.Hareendran
*/
#include
LiquidCrystal lcd (7, 8, 9, 10, 11, 12);
int analogInput = 0;
float vout = 0,0;
float vin = 0,0;
float R1 = 100000,0; // rezistența R1 (100K) -vezi text!
float R2 = 10000,0; // rezistența R2 (10K) – vezi text!
valoare int = 0;
void setup())(
pinMode(analogInput, INPUT);
lcd.begin(16, 2);
lcd.print(„VOLTMETRU DC”);
}
buclă goală ()
// citește valoarea la intrarea analogică
valoare = analogRead(analogInput);
vout = (valoare * 5,0) / 1024,0; // vezi textul
vin = vout / (R2/(R1+R2));
dacă (vin<0.09) {
vin=0.0;// declarație pentru a anula citirea nedorită!
}
lcd.setCursor(0, 1);
lcd.print(“INPUT V= “);
lcd.print(vin);
întârziere (500);
}

Schema schematică a voltmetrului Arduino

Lista componentelor

Placa Arduino Uno
Rezistor de 100 kOhm
Rezistor de 10 kOhm
rezistor de 100 ohmi
Rezistor trimmer de 10 kOhm
Afișaj LCD 16?2 (Hitachi HD44780)

Acest articol oferă o diagramă interesantă pentru cei cărora le place să experimenteze și Arduino. Dispune de un voltmetru digital simplu care poate măsura în siguranță tensiunea DC între 0 și 30 V. Placa Arduino în sine poate fi alimentată de o sursă standard de 9 V.



După cum știți, folosind intrarea analogică Arduino puteți măsura tensiunea de la 0 la 5 V (cu o tensiune de referință standard de 5 V). Dar această gamă poate fi extinsă folosind un divizor de tensiune.


Divizorul reduce tensiunea măsurată la un nivel acceptabil pentru intrarea analogică. Apoi, codul special scris calculează tensiunea reală.



Senzorul analogic din Arduino detectează tensiunea la intrarea analogică și o convertește într-un format digital care poate fi citit de microcontroler. Conectăm un divizor de tensiune format din rezistențele R1 (100K) și R2 (10K) la intrarea analogică A0. Cu aceste valori de rezistență, Arduino poate fi furnizat până la 55 V, deoarece coeficientul de divizare în acest caz este 11, deci 55V/11 = 5V. Pentru a fi siguri că măsurătorile sunt sigure pentru placă, este mai bine să măsurați tensiunea în intervalul de la 0 la 30 V.



Dacă citirile afișate nu se potrivesc cu citirile verificate ale voltmetrului, utilizați un multimetru digital de precizie pentru a găsi valorile exacte ale R1 și R2. În acest caz, în cod va trebui să înlocuiți R1=100000.0 și R2=10000.0 cu propriile valori. Apoi ar trebui să verificați sursa de alimentare măsurând tensiunea de pe placă între 5V și GND. Tensiunea poate fi de 4,95 V. Apoi, în codul vout = (valoare * 5,0) / 1024,0 trebuie să înlocuiți 5,0 cu 4,95. Este recomandabil să folosiți rezistențe de precizie cu o eroare de cel mult 1%. Amintiți-vă că tensiunea peste 55V poate deteriora placa Arduino!



#include LiquidCrystal lcd (7, 8, 9, 10, 11, 12); int analogInput = 0; float vout = 0,0; float vin = 0,0; float R1 = 100000,0; // rezistența R1 (100K) float R2 = 10000,0; // rezistența R2 (10K) int valoare = 0; void setup())( pinMode(analogInput, INPUT); lcd.begin(16, 2); lcd.print("DC VOLTMETER"); ) void loop())( // citește valoarea analogică = analogRead(analogInput) ); vout = (valoare * 5,0) / 1024,0; vin = vout / (R2/(R1+R2)); if (vin<0.09) { vin=0.0;// обнуляем нежелательное значение } lcd.setCursor(0, 1); lcd.print("INPUT V= "); lcd.print(vin); delay(500); }


Elemente folosite:


Placa Arduino Uno
Rezistor 100 KOhm
Rezistor 10 KOhm
rezistor de 100 ohmi
Potențiometru 10KOhm
Display LCD 16×2

Intrări analogice ale plăcii Arduino.

Placa Arduino UNO conține 6 intrări analogice concepute pentru a măsura semnalele de tensiune. Ar fi mai corect să spunem că cei 6 pini ai plăcii pot funcționa atât în ​​moduri de ieșire discretă, cât și de intrare analogică.

Acești pini sunt numerotați de la 14 la 19. Sunt configurați inițial ca intrări analogice și pot fi accesați folosind numele A0-A5. Ele pot fi configurate în modul de ieșire discretă în orice moment.

pinMode(A3, OUTPUT); // setarea modului de ieșire discretă pentru A3
digitalWrite(A3, LOW); // setarea ieșirii A3 la un nivel scăzut

Pentru a reveni la modul de intrare analogică:

pinMode(A3, INPUT); // setarea modului de intrare analogic pentru A3

Intrări analogice și rezistențe pull-up.

Rezistoarele de tragere sunt conectate la pinii de intrare analogici, precum și la pinii discreti. Aceste rezistențe sunt pornite folosind comanda

digitalWrite(A3, HIGH); // porniți rezistența de tragere la intrarea A3

Comanda trebuie aplicată unui pin configurat în modul de intrare.

Trebuie reținut că rezistorul poate afecta nivelul semnalului analogic de intrare. Curentul de la sursa de alimentare de 5V, prin rezistorul de tragere, va provoca o scădere de tensiune pe rezistența internă a sursei de semnal. Deci este mai bine să deconectați rezistența.

Convertor analog-digital al plăcii Arduino.

Măsurarea tensiunii reale la intrări este efectuată de un convertor analog-digital (ADC) cu un comutator pentru 6 canale. ADC-ul are o rezoluție de 10 biți, care corespunde codului de la ieșirea convertorului 0...1023. Eroarea de măsurare nu este mai mare de 2 unități din cifra cea mai puțin semnificativă.

Pentru a menține acuratețea maximă (10 biți), este necesar ca rezistența internă a sursei de semnal să nu depășească 10 kOhm. Această cerință este deosebit de importantă atunci când se utilizează divizoare de rezistență conectate la intrările analogice ale plăcii. Rezistența rezistențelor divizor nu poate fi prea mare.

Funcții software de intrare analogică.

int analogRead(port)

Citește valoarea tensiunii la intrarea analogică specificată. Tensiunea de intrare variază de la 0 la nivelul tensiunii de referință (adesea 5 V) care se transformă într-un cod de la 0 la 1023.

Cu o tensiune de referință de 5 V, rezoluția este de 5 V / 1024 = 4,88 mV.

Conversia durează aproximativ 100 μs.

int inputCod; // codul tensiunii de intrare
Tensiune de intrare float; // tensiune de intrare în V

inputCod= analogRead(A3); // citirea tensiunii la intrarea A3
inputVoltage= ((float)inputCod * 5. / 1024.); // conversia codului în tensiune (V)

void analogReference(tip)

Setează tensiunea de referință pentru ADC. Acesta definește tensiunea maximă de intrare analogică pe care ADC-ul o poate converti corect. Valoarea tensiunii de referință determină, de asemenea, factorul de conversie cod-la-tensiune:

Tensiune de intrare = cod ADC * tensiune de referință / 1024.

Argumentul tip poate lua următoarele valori:

  • IMPLICIT – tensiunea de referință este egală cu tensiunea de alimentare a controlerului (5 V sau 3,3 V). Pentru Arduino UNO R3 – 5 V.
  • INTERN – tensiune de referință internă 1,1 V pentru plăci cu controlere ATmega168 și ATmega328, pentru ATmega8 – 2,56 V.
  • INTERNAL1V1 – tensiune de referință internă de 1,1 V pentru controlerele Arduino Mega.
  • INTERNAL2V56 – tensiune de referință internă de 2,56 V pentru controlerele Arduino Mega.
  • EXTERN – sursă externă de tensiune de referință, conectată la intrarea AREF.

analogReference(INTERN); // tensiunea de referință este de 1,1 V

Voltmetru cu două canale pe Arduino.

Ca exemplu de utilizare a funcțiilor de intrare analogică, să creăm un proiect pentru un voltmetru digital simplu pe Arduino. Dispozitivul trebuie să măsoare tensiunile la două intrări analogice ale plăcii și să transmită valorile măsurate către computer printr-un port serial. Folosind acest proiect ca exemplu, voi arăta principiile creării sistemelor simple de măsurare și colectare a informațiilor.

Să decidem că voltmetrul ar trebui să măsoare tensiunea în intervalul de cel puțin 0...20 V și să dezvoltăm un circuit pentru conectarea intrărilor voltmetrului la placa Arduino UNO.

Dacă setăm tensiunea de referință la 5 V, atunci intrările analogice ale plăcii vor măsura tensiunea în intervalul 0...5 V. Și avem nevoie de cel puțin 0...20 V. Aceasta înseamnă că trebuie să folosim un divizor de tensiune.

Tensiunea la intrarea și ieșirea divizorului este legată de relația:

Uieșire = (Uinput / (R1 + R2)) * R2

Raport de transmisie:

K = Uieșire / Uintrare = R2 / (R1 + R2)

Avem nevoie de un raport de transfer de 1/4 (20 V * 1/4 = 5 V).

Pentru a menține acuratețea maximă (10 biți), este necesar ca rezistența internă a sursei de semnal să nu depășească 10 kOhm. Prin urmare, alegem rezistorul R2 egal cu 4,22 kOhm. Se calculează rezistența rezistenței R1.

0,25 = 4,22 / (R1 + 4,22)
R1 = 4,22 / 0,25 – 4,22 = 12,66 kOhm

Am găsit rezistențe cu o rezistență de 15 kOhm cu cea mai apropiată valoare. Cu rezistențe R1 = 15 kOhm și R2 = 4,22:

5 / (4,22 / (15 + 4,22)) = 22,77 V.

Circuitul voltmetrului bazat pe Arduino va arăta astfel.

Două divizoare de tensiune sunt conectate la intrările analogice A0 și A1. Condensatorii C1 și C2, împreună cu rezistențele de divizare, formează filtre trece-jos care elimină zgomotul de înaltă frecvență din semnale.

Am asamblat acest circuit pe o placă.

Am conectat prima intrare a voltmetrului la o sursă de alimentare reglată, iar a doua la sursa de alimentare de 3,3 V a plăcii Arduino. Pentru a monitoriza tensiunea, am conectat un voltmetru la prima intrare. Rămâne doar să scrieți programul.

Un program pentru măsurarea tensiunii folosind o placă Arduino.

Algoritmul este simplu. Necesar:

  • citiți codul ADC de două ori pe secundă;
  • convertiți-l în tensiune;
  • trimiteți valorile măsurate prin portul serial către un computer;
  • programul de monitorizare a portului Arduino IDE afișați valorile tensiunii obținute pe ecranul computerului.

Vă voi oferi imediat o schiță completă a programului.

// program de măsurare a tensiunii
// pe intrările analogice A0 și A1

#include

timpul perioadei de măsurare
#define R1 15. // rezistența rezistenței R1
#define R2 4.22 // rezistența rezistenței R2


plutitor u1, u2; // tensiuni măsurate

void setup() (
Serial.begin(9600); //

MsTimer2::start(); // activare întrerupere
}

void loop() (

// perioada 500 ms
dacă (timeCount >= MEASURE_PERIOD) (
timeCount= 0;

//

// citirea codului canalului 2 și conversia la tensiune
u2= ((float)analogRead(A1)) * 5. / 1024. / R2 * (R1 + R2);

// transfer de date prin port serial
Serial.print("U1 = "); Serial.print(u1, 2);
Serial.print(" U2 = "); Serial.println(u2, 2);
}
}

// întrerupe procesarea 1 ms
void timerInterrupt() (
timeCount++;
}

Permiteți-mi să explic linia în care codul ADC este convertit în tensiune:

// citirea codului canalului 1 și conversia la tensiune
u1= ((float)analogRead(A0)) * 5. / 1024. / R2 * (R1 + R2);

  • Codul ADC este citit: analogRead(A0) .
  • Convertit explicit în format virgulă mobilă: (float) .
  • Convertit la tensiune la intrarea analogică: * 5. / 1024. Punctul de la sfârșitul numerelor indică faptul că acesta este un număr în virgulă mobilă.
  • Se ia în considerare coeficientul de transmisie divizor: / R2 * (R1 + R2).

Să încărcăm programul pe placă și să lansăm monitorul portului serial.

Două bare de rulare arată valorile tensiunilor măsurate. Totul merge.

Măsurarea valorii medii a semnalului.

Să conectăm primul canal al voltmetrului nostru la o sursă de tensiune cu un nivel ridicat de ondulare. Vom vedea această poză pe monitor.

Valorile tensiunii primului canal de pe ecranul monitorului trec și sar în mod constant. Și citirile voltmetrului de control sunt destul de stabile. Acest lucru se datorează faptului că voltmetrul de referință măsoară valoarea medie a semnalului, în timp ce placa Arduino citește mostre individuale la fiecare 500 ms. Desigur, momentul citirii ADC scade în diferite puncte ale semnalului. Și la un nivel ridicat de pulsații, amplitudinea în aceste puncte este diferită.

În plus, dacă semnalul este citit în eșantioane rare și separate, atunci orice zgomot de impuls poate introduce o eroare semnificativă în măsurare.

Soluția este să luați mai multe probe frecvente și să faceți o medie a valorii măsurate. Pentru aceasta:

  • în manipulatorul de întreruperi citim codul ADC și îl însumăm cu mostrele anterioare;
  • numărați timpul de mediere (numărul de probe de mediere);
  • când se atinge numărul specificat de mostre, salvăm valoarea totală a codurilor ADC;
  • Pentru a obține valoarea medie, împărțiți suma codurilor ADC la numărul de eșantioane de mediere.

Problemă dintr-un manual de matematică de clasa a VIII-a. Iată o schiță a programului, un voltmetru de valoare medie cu două canale.

// program de măsurare a mediei tensiuni
// pe intrările analogice A0 și A1

#include

#define MEASURE_PERIOD 500 // timpul perioadei de măsurare
#define R1 15. // rezistența rezistenței R1
#define R2 4.22 // rezistența rezistenței R2

int timeCount; // contor de timp
lung sumU1, sumU2; // variabile pentru însumarea codurilor ADC
medie lungăU1, medieU2; // suma codurilor ADC (valoare medie * 500)
steag boolean Gata; // indicator al gradului de pregătire al datelor de măsurare

void setup() (
Serial.begin(9600); // inițializați portul, viteza 9600
MsTimer2::set(1, timerInterupt); // cronometrul întrerupe, perioadă 1 ms
MsTimer2::start(); // activare întrerupere
}

void loop() (

dacă (flagReady == adevărat) (
flagReady= fals;
// conversie la tensiune și transfer pe computer
Serial.print("U1 = ");
Serial.print((float)avarageU1 / 500. * 5. / 1024. / R2 * (R1 + R2), 2);
Serial.print(" U2 = ");
Serial.println((float)avarageU2 / 500. * 5. / 1024. / R2 * (R1 + R2), 2);
}
}

// întrerupe procesarea 1 ms
void timerInterrupt() (

timeCount++; // +1 contor de probă medie
sumU1+= analogRead(A0); // însumând codurile ADC
sumU2+= analogRead(A1); // însumând codurile ADC

// verificarea numărului de probe de mediere
dacă (timeCount >= MEASURE_PERIOD) (
timeCount= 0;
medieU1= sumaU1; // suprasarcină de valoare medie
medieU2= sumaU2; // suprasarcină de valoare medie
sumU1= 0;
sumaU2= 0;
flagReady= adevărat; // rezultatul măsurării semnului este gata
}
}

În formula de conversie a codului ADC în tensiune, a fost adăugat /500 - numărul de mostre. Încărcați, lansați monitorul portului (Cntr+Shift+M).

Acum, chiar și cu un nivel semnificativ de pulsație, citirile se modifică cu sutimi. Acest lucru se datorează faptului că tensiunea nu este stabilizată.

Numărul de probe trebuie ales luând în considerare:

  • numărul de probe determină timpul de măsurare;
  • Cum număr mai mare probe, cu atât influența zgomotului va fi mai mică.

Principala sursă de interferență în semnalele analogice este rețeaua de 50 Hz. Prin urmare, este recomandabil să alegeți un timp de mediere care este un multiplu de 10 ms – timpul de jumătate de ciclu al unei rețele de 50 Hz.

Optimizarea calculelor.

Calculele cu virgulă mobilă pur și simplu consumă resursele unui microcontroler pe 8 biți. Orice operațiune în virgulă mobilă necesită denormalizarea mantisei, operarea în virgulă fixă, normalizarea mantisei, corectarea comenzii... Și toate operațiunile cu 32 numere de cifre. Prin urmare, este necesar să se minimizeze utilizarea calculelor în virgulă mobilă. Vă voi spune cum să faceți acest lucru în lecțiile următoare, dar să ne optimizăm cel puțin calculele. Efectul va fi semnificativ.

În programul nostru, conversia codului ADC în tensiune este scrisă după cum urmează:

(float)medieU1 / 500. * 5. / 1024. / R2 * (R1 + R2)

Sunt atât de multe calcule aici, toate cu virgulă mobilă. Dar majoritatea calculelor sunt operații cu constante. O parte a liniei:

/ 500. * 5. / 1024. / R2 * (R1 + R2)

(float)avarageU1 * 0,00004447756

Compilatoarele inteligente recunosc calculele cu constante și le calculează în etapa de compilare. Am o întrebare despre cât de inteligent este compilatorul lui Andruino. Am decis să verific.

Am scris un scurt program. Efectuează un ciclu de 10.000 de treceri și apoi transmite timpul de execuție a acelor 10.000 de cicluri către computer. Acestea. vă permite să vedeți timpul de execuție al operațiilor plasate în corpul buclei.

// verificarea optimizării calculelor

int x= 876;
float y;
unsigned int număr;
nesemnat lung timeCurrent, timePrev;

void setup() (
Serial.begin(9600);
}

void loop() (
numără++;
// y= (float)x / 500. * 5. / 1024. / 4.22 * (15. + 4.22);
// y= (float)x * 0,00004447756 ;

dacă (număr >= 10000) (
număr = 0;
timeCurrent= milis();
Serial.println(timeCurrent - timePrev);
timePrev= timeCurrent;
}
}

În prima opțiune, când operațiunile în virgulă mobilă din buclă sunt comentate și nu sunt executate, programul a produs un rezultat de 34 ms.

Acestea. 10.000 de bucle goale sunt finalizate în 34 ms.

Apoi am deschis linia:

y= (float)x / 500. * 5. / 1024. / 4.22 * (15. + 4.22);

repetă calculele noastre. Rezultat de 10.000 de treceri în 922 ms sau

(922 – 34) / 10.000 = 88,8 µs.

Acestea. această linie de calcule cu virgulă mobilă durează 89 µs pentru a fi finalizată. Am crezut că vor fi mai multe.

Acum am închis această linie cu un comentariu și am deschis-o pe următoarea, înmulțind cu o constantă precalculată:

y= (float)x * 0,00004447756;

Rezultat de 10.000 de treceri în 166 ms sau

(166 – 34) / 10.000 = 13,2 µs.

Rezultat uimitor. Am economisit 75,6 μs pe linie. L-am finalizat de aproape 7 ori mai repede. Avem 2 astfel de linii, dar pot fi mult mai multe în program.

Concluzie - calculele cu constante trebuie făcute singur pe un calculator și utilizate în programe ca coeficienți gata pregătiți. Compilatorul Arduino nu le va calcula în etapa de compilare. În cazul nostru ar trebui să facem asta:

#define ADC_U_COEFF 0,00004447756 // factor de conversie a codului ADC la tensiune

Serial.print((float)avarageU1 * ADC_U_COEFF, 2);

Opțiunea optimă pentru performanță este transferul codului ADC pe computer și, împreună cu acesta, toate calculele în virgulă mobilă. În acest caz, computerul trebuie să primească date program de specialitate. Monitorul portului de la Arduino IDE nu va funcționa.

Voi vorbi despre alte modalități de optimizare a programelor Arduino în lecțiile viitoare, după cum este necesar. Dar fără a rezolva această problemă este imposibil de dezvoltat programe complexe pe un microcontroler pe 8 biți.

O altă lecție a apărut pe site (

Există momente în care doriți să verificați tensiunea sau un anumit punct dintr-un circuit, dar nu aveți un voltmetru sau un multimetru la îndemână? Fugi să cumperi? Este lung și scump. Înainte să faci asta, ce zici de a construi singur un voltmetru? De fapt, cu ajutorul componente simple o poți face singur.

  • În lecție am folosit o placă compatibilă cu Arduino - SunFounder Uno/Mars (http://bit.ly/2tkaMba)
  • cablu de date USB
  • 2 potențiometre (50k)
  • LCD1602 - http://bit.ly/2ubNEfi
  • Placă de dezvoltare - http://bit.ly/2slvfrB
  • Mai multe săritori

Înainte de a vă conecta, să vedem mai întâi cum funcționează.

Utilizați placa SunFounder Uno pentru partea principală a procesării datelor voltmetrului, LCD1602 ca ecran, un potențiometru pentru a regla contrastul LCD și altul pentru a împărți tensiunea.

Când rotiți potențiometrul conectat la placa Uno, rezistența potențiometrului se schimbă, modificând astfel tensiunea pe el. Semnalul de tensiune va fi trimis la placa Uno prin pinul A0, iar Uno va converti cel primit semnal analogîn formă digitală și înregistrări pe ecranul LCD. În acest fel, puteți vedea valoarea tensiunii la rezistența capacității curente.

LCD1602 are două moduri de operare: 4 biți și 8 biți. Când MCU IO este insuficient, puteți alege modul pe 4 biți, care utilizează doar pinii D4 ~ D7.

Urmați tabelul pentru a le conecta.

Pasul 4: Conectați potențiometrul la LCD1602

Conectați pinul din mijloc al potențiometrului la pinul Vo de pe LCD1602 și oricare dintre ceilalți pini la GND.

Conectați pinul din mijloc al potențiometrului la pinul A0 de la SunFounder Uno și unul dintre ceilalți la 5V, în timp ce celălalt la GND.

Pasul 6: Încărcați codul

Acest cod:

#include /*********************************************** ******* *****/ const int analogIn = A0;//potențiometrul atașat la A0 LiquidCrystal lcd(4, 6, 10, 11, 12, 13);//lcd(RS,E,D4) ,D5,D6.D7) float val = 0;// definiți variabila ca valoare=0 /**************************** ******* *****************/ void setup() ( Serial.begin(9600);//Inițializați seria lcd.begin(16, 2) ;//setează poziția caracterelor de pe LCD ca linia 2, coloana 16 lcd.print("Valoarea tensiunii:");//printează "Valoarea tensiunii:" ) /*********** ******* **********************************/ bucla void() ( val = analogRead (A0);//Citiți valoarea potențiometrului la val val = val/1024*5.0;// Convertiți datele la valoarea tensiunii corespunzătoare într-un mod matematic Serial.print(val);//Imprimați numărul de val pe monitorul serial Serial.print ("V"); // tipăriți unitatea ca V, prescurtare pentru tensiune pe monitorul serial lcd.setCursor(6,1);//Plasați cursorul la linia 1, coloana 6. Din aici caracterele vor fi afișate lcd.print(val);//Tipărește numărul de val pe LCD lcd.print("V");//Apoi imprimă unitatea ca V, scurt pentru tensiune pe LCD delay( 200); // Asteapta pentru 200 ms)

Rotiți potențiometrul pentru a verifica tensiunea de pe LCD1602 în timp real.

Iată un lucru complicat. După ce am rulat codul, ecranul LCD arăta caractere. Am ajustat apoi contrastul ecranului (modificare treptată de la negru la alb) rotind potențiometrul în sensul acelor de ceasornic sau în sens invers acelor de ceasornic până când ecranul a afișat clar caracterele.

Luați două baterii pentru a le măsura tensiunea: 1,5 V și 3,7 V. Decuplați conexiunea celui de-al doilea potențiometru la pinul A0 și GND, ceea ce înseamnă scoaterea potențiometrului din circuit. Fixați capătul firului A0 la anodul bateriei și circuitul GND la catod. NU le conectați înapoi sau veți primi scurt circuit pe baterie. O valoare de 0V este o conexiune inversă.

Deci, tensiunea bateriei este afișată pe afișajul LCD. Este posibil să existe o eroare între valoare și valoarea nominală, deoarece bateria nu este încărcată complet. Și de aceea trebuie să măsoare tensiunea pentru a înțelege dacă pot folosi bateria sau nu.

PS: Dacă aveți probleme cu afișarea pe afișaj - consultați această Întrebări frecvente pentru afișajele LCD - http://wiki.sunfounder.cc/index.php?title=LCD1602/I2C_LCD1602_FAQ.

Date inițiale și revizuire

Deci, în acest moment avem un voltmetru cu tensiune constantă cu o limită de 0..20V (vezi partea anterioară). Acum îi adăugăm un ampermetru de 0..5a. Pentru a face acest lucru, modificăm ușor circuitul - va deveni un circuit de trecere, adică are atât o intrare, cât și o ieșire.

Am scos partea referitoare la afișajul de pe LCD - nu se va schimba. Practic de bază element nou- Șunt Rx la 0,1 Ohm. Lanțul R1-C1-VD1 servește la protejarea intrării analogice. Este logic să instalați același lucru la intrarea A0. Din moment ce presupunem destule curenți mari, există cerințe de instalare - linii de înaltă tensiune trebuie realizat cu un fir suficient de gros și conectat direct la bornele de șunt (cu alte cuvinte, lipite), altfel citirile vor fi departe de realitate. Există și o notă despre curent - în principiu, o tensiune de referință de 1,1 V vă permite să o înregistrați pe șunt Curenți de 0,1 Ohm până la 11 amperi cu o precizie puțin mai slabă decât 0,01a, dar când o astfel de tensiune scade pe Rx, puterea eliberată va depăși 10 W, ceea ce nu este deloc distractiv. Pentru a rezolva problema, puteți folosi un amplificator cu un câștig de 11 folosind un amplificator operațional de înaltă calitate și un șunt de 10 mOhm (0,01 Ohm). Dar deocamdată nu ne vom complica viața și pur și simplu ne vom limita curentul la 5A (în acest caz, puterea Rx poate fi selectată de ordinul a 3-5 W).

În această etapă, mă aștepta o surpriză - s-a dovedit că ADC-ul controlerului avea un offset de zero destul de mare - aproximativ -3mV. Adică, ADC pur și simplu nu vede semnale mai mici de 3 mV, iar semnalele de un nivel puțin mai ridicat sunt vizibile cu o inexactitate caracteristică de -3 mV, ceea ce strica liniaritatea la începutul intervalului. O căutare rapidă nu a dat referințe evidente la o astfel de problemă (un offset zero este normal, dar ar trebui să fie semnificativ mai mic), așa că este foarte posibil ca aceasta să fie o problemă cu o anumită instanță Atmega 328. Soluția pe care am ales-o a fost dublu - în tensiune - un pas de software la începutul intervalului (afișajul începe la 0,06 volți), pentru curent - un rezistor de tragere la magistrala de 5V. Rezistorul este indicat printr-o linie punctată.

Sursă

Versiunea completă a acestui volt-ampermetru (în versiunea I2C) poate fi descărcată din linkul de la sfârșitul articolului.În continuare voi arăta modificările în cod sursa. Citirea adăugată a intrării analogice A1 cu aceeași medie ca și pentru voltmetru. În esență, acesta este același voltmetru, doar fără divizor și obținem amperi folosind formula lui Ohm: I = U/Rx (de exemplu, dacă scăderea de tensiune pe Rx = 0,01 V, atunci curentul este de 0,1 A). Am introdus și constanta de câștig curent AmpMult - pentru viitor. Constanta AmpRx cu rezistența de șunt va trebui probabil să fie potrivită pentru a ține cont de inexactitatea rezistenței de șunt. Ei bine, din moment ce acesta este deja un volt-ampermetru și mai rămâne spațiu pe afișajul 1602, rămâne să afișați consumul curent de putere în wați, obținând o funcționalitate suplimentară simplă.

.... // Intrare analogică #define PIN_VOLT A0 #define PIN_AMP A1 // Tensiune de referință internă (selectare) const float VRef = 1,10; // Coeficient divizor rezistiv de intrare (Rh + Rl) / Rl. IN 0,2) InVolt += 3; // Convertiți în volți (In: 0..1023 -> (0..VRef) scalat de Mult) float Volt = InVolt * VoltMult * VRef / 1023; float Amp = InAmp * VRef / AmpMult / AmpRx / 1023 ; // Pentru a ține cont de căderea pe șunt, decomentați 2 linii //float RxVolt = InAmp * VRef / 1023 / AmpMult; // Volt -= RxVolt; float Watt = Volt * Amperi; // Date de ieșire lcd.setCursor (8, 0); lcd.print (Watt); lcd.print("W"); lcd.setCursor(0, 1); lcd.print (Volt); lcd.print("V"); lcd.setCursor(8, 1); lcd.print(Amp); lcd.print("A"); )

Legături

  • Biblioteca LiquidCrystal_I2C, care vă permite să setați pinout-ul