Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • telefon Windows
  • Voltmetër sekret në Arduino - matja e tensionit të baterisë duke përdorur një mikrokontrollues. voltmetër bluetooth i bazuar në arduino

Voltmetër sekret në Arduino - matja e tensionit të baterisë duke përdorur një mikrokontrollues. voltmetër bluetooth i bazuar në arduino

Një skemë e dobishme është paraqitur për ata që duan të eksperimentojnë me Arduino. Ky është një voltmetër i thjeshtë dixhital që mund të matë me besueshmëri tensionin DC në intervalin 0 - 30 V. Bordi Arduino, si zakonisht, mund të mundësohet nga një bateri 9V.

Siç e dini ndoshta, hyrjet analoge të Arduino mund të përdoren për të matur tensionin DC në intervalin 0 - 5 V dhe kjo diapazon mund të rritet,
duke përdorur dy rezistorë si ndarës të tensionit. Ndarësi do të zvogëlojë tensionin e matur në nivelin e hyrjeve analoge të Arduino. Dhe pastaj programi do të llogarisë vlerën reale të tensionit.

Sensori analog në tabelën Arduino zbulon praninë e tensionit në hyrjen analoge dhe e shndërron atë në një formë dixhitale për përpunim të mëtejshëm nga mikrokontrolluesi. Në figurë, voltazhi aplikohet në hyrjen analoge (A0) përmes një ndarësi të thjeshtë tensioni të përbërë nga rezistorët R1 (100kΩ) dhe R2 (10kΩ).

Me këto vlera të pjesëtuesit, bordi Arduino mund të furnizohet me tension nga 0 në
55 V. Në hyrjen A0 kemi tensionin e matur të ndarë me 11, pra 55V / 11=5V. Me fjalë të tjera, kur matim 55V në hyrjen Arduino, kemi vlerën maksimale të lejueshme prej 5V. Në praktikë, është më mirë të shkruani diapazonin "0 - 30V" në këtë voltmetër në mënyrë që të qëndroni
Marzhi i sigurisë!

Shënime

Nëse leximet e ekranit nuk përputhen me leximet e një voltmetri industrial (laboratorik), atëherë është e nevojshme të matni rezistencën R1 dhe R2 me një instrument të saktë dhe të futni këto vlera në vend të R1=100000.0 dhe R2=10000.0 në program. kodi. Më pas duhet të matni tensionin real ndërmjet terminaleve 5V dhe "Ground" të tabelës Arduino me një voltmetër laboratori. Rezultati do të jetë një vlerë më e vogël se 5V, për shembull, doli 4.95V. Kjo vlerë reale duhet të futet në një rresht kodi
vout = (vlera * 5.0) / 1024.0 në vend të 5.0.
Gjithashtu, përpiquni të përdorni rezistenca precize me një tolerancë prej 1%.

Rezistencat R1 dhe R2 ofrojnë njëfarë mbrojtjeje kundër tensioneve të larta hyrëse.Megjithatë, kini parasysh se çdo tension mbi 55V mund të dëmtojë tabelën Arduino. Për më tepër, ky dizajn nuk ofron lloje të tjera mbrojtjeje (nga mbitensionet e energjisë, nga polariteti i kundërt ose mbitensioni).

Programi i voltmetrit dixhital

/*
Voltmetër DC
Një Arduino DVM bazuar në konceptin e ndarësit të tensionit
T.K.Hareendran
*/
#përfshi
LCD Crystal Liquid(7, 8, 9, 10, 11, 12);
int analogInput = 0;
float vout = 0.0;
float vin = 0,0;
noton R1 = 100000.0; // rezistenca e R1 (100K) -shiko tekstin!
noton R2 = 10000.0; // rezistenca e R2 (10K) - shikoni tekstin!
vlera int = 0;
konfigurimi i zbrazët ()(
pinMode (hyrje analoge, INPUT);
lcd.begin(16, 2);
lcd.print("VOLTMETER DC");
}
void loop()(
// lexoni vlerën në hyrjen analoge
vlera = analogLeximi(analogInput);
vout = (vlera * 5.0) / 1024.0; // shih tekstin
vin = vout / (R2/(R1+R2));
nëse (vin<0.09) {
vin=0.0;//deklaratë për të anuluar leximin e padëshiruar!
}
lcd.setCursor(0, 1);
lcd.print("INPUT V=");
printim LCD (vin);
vonesë (500);
}

Diagrami skematik i voltmetrit Arduino

Lista e komponentëve

Bordi i Arduino Uno
Rezistenca 100 kΩ
Rezistencë 10 kΩ
Rezistencë 100 ohm
Rezistencë prerëse 10 kΩ
Ekran LCD 16×2 (Hitachi HD44780)

A ka raste kur dëshironi të kontrolloni tensionin ose ndonjë pikë në një qark, por nuk keni një voltmetër ose multimetër në dispozicion? Vraponi për të blerë? Është e gjatë dhe e shtrenjtë. Përpara se ta bëni këtë, si të bëni voltmetrin tuaj? Në fakt, me komponentë të thjeshtë, mund ta bëni vetë.

  • Në tutorial, ne përdorëm një tabelë të pajtueshme me Arduino - SunFounder Uno / Mars (http://bit.ly/2tkaMba)
  • Kabllo USB të dhënash
  • 2 potenciometra (50k)
  • LCD1602 - http://bit.ly/2ubNEfi
  • Breadboard - http://bit.ly/2slvfrB
  • Kërcim të shumëfishtë

Para se të lidhemi, le të kuptojmë fillimisht se si funksionon.

Përdorni tabelën SunFounder Uno për pjesën kryesore të përpunimit të të dhënave të voltmetrit, LCD1602 si ekran, një potenciometër për të rregulluar kontrastin LCD dhe tjetrën për të ndarë tensionin.

Kur rrotulloni një potenciometër të lidhur me tabelën Uno, rezistenca e potenciometrit ndryshon, duke ndryshuar kështu tensionin në të. Sinjali i tensionit do të dërgohet në bordin Uno përmes pinit A0, dhe Uno do të konvertojë sinjalin analog të marrë në formë dixhitale dhe do të shkruajë në LCD. Kështu që ju mund të shihni vlerën e tensionit në rezistencën e kapacitetit aktual.

LCD1602 ka dy mënyra funksionimi: 4-bit dhe 8-bit. Kur IO e MCU është e pamjaftueshme, mund të zgjidhni modalitetin 4-bit, i cili përdor vetëm kunjat D4 ~ D7.

Ndiqni tabelën për t'i lidhur ato.

Hapi 4: Lidhni potenciometrin me LCD1602

Lidhni kunjin e mesit të potenciometrit me pinin Vo në LCD1602 dhe cilindo nga kunjat e tjera me GND.

Lidhni kunjin e mesit të potenciometrit me pinin A0 të SunFounder Uno dhe njërën nga të tjerat në 5V ndërsa tjetra është me GND.

Hapi 6: Ngarkimi i kodit

Kodi si ky:

#përfshi /************************************************ ***** *****/ const int analogIn = A0;//potenciometër bashkëngjitni LCD-në A0 LiquidCrystal (4, 6, 10, 11, 12, 13);//LCd(RS,E,D4,D5 ,D6.D7) float val = 0;// përcaktoni variablin si vlerë=0 /******************************** ***** *****************/ void setup() ( Serial.begin(9600);//Inicializoni serialin lcd.begin(16, 2);/ / vendosni pozicionin e karaktereve në LCD si Linja 2, Kolona 16 lcd.print("Vlera e tensionit:");//print "Vlera e tensionit:" ) /**************** ***** ****************************************/ void loop() ( val = analogLexo (A0);//Lexo vlerën e potenciometrit në val val = val/1024*5.0;// Konverto të dhënat në vlerën përkatëse të tensionit në mënyrë matematikore Serial.print(val);//Print numrin e val në monitorin serik Serial.print ("V"); // printoni njësinë si V, shkurt për tension në monitorin serik LCD setCursor(6,1); // Vendoseni kursorin në rreshtin 1, kolona 6. Nga këtu duhet të shfaqen karakteret lcd.print(val);//Print numrin e v al në LCD lcd.print("V");//Më pas printoni njësinë si V, shkurt për tension në vonesën LCD(200); //Prisni për 200 ms)

Rrotulloni potenciometrin për të kontrolluar tensionin në LCD1602 në kohë reale.

Këtu është një e ndërlikuar. Pasi ekzekutova kodin, LCD tregoi simbole. Më pas rregullova kontrastin e ekranit (ndryshimi gradual nga e zeza në të bardhë) duke e rrotulluar potenciometrin në drejtim të akrepave të orës ose në të kundërt derisa ekrani t'i shfaqte qartë karakteret.

Merrni dy bateri për të matur tensionin e tyre: 1.5 V dhe 3.7 V. Shkëputni lidhjen e potenciometrit të dytë me pinin A0 dhe GND, që do të thotë heqja e potenciometrit nga qarku. Mbërtheni fundin e telit A0 në anodin e baterisë dhe qarkun GND në katodë. MOS i lidhni sërish në prizë përndryshe do të lidhni të shkurtër baterinë. Vlera 0V është lidhja e kundërt.

Pra, voltazhi i baterisë shfaqet në LCD. Mund të ketë ndonjë gabim midis vlerës dhe asaj nominale sepse bateria nuk është e ngarkuar plotësisht. Dhe kjo është arsyeja pse unë duhet të masë tensionin për të kuptuar nëse mund ta përdor baterinë apo jo.

PS: Nëse keni probleme me ekranin, shihni këtë FAQ për LCD - http://wiki.sunfounder.cc/index.php?title=LCD1602/I2C_LCD1602_FAQ.

Hyrjet analoge të tabelës Arduino.

Pllaka Arduino UNO përmban 6 hyrje analoge për matjen e sinjaleve të tensionit. Do të ishte më e saktë të thuhet se 6 dalje të tabelës mund të funksionojnë në modalitetin e daljeve diskrete dhe hyrjeve analoge.

Këto kunja janë të numëruara nga 14 deri në 19. Fillimisht janë vendosur si hyrje analoge dhe mund të quhen A0-A5. Në çdo kohë, ato mund të konfigurohen në mënyrën e daljeve diskrete.

pinMode (A3, OUTPUT); // vendosja e modalitetit të daljes diskrete për A3
digitalWrite (A3, LOW); // vendosja e prodhimit A3 të ulët

Për t'u kthyer në modalitetin e hyrjes analoge:

pinMode (A3, INPUT); // vendosja e modalitetit të hyrjes analoge për A3

Inputet analoge dhe rezistorët tërheqës.

Rezistorët tërheqës janë të lidhur me kunjat e hyrjes analoge, si dhe me kunjat dixhitale. Përfshirja e këtyre rezistorëve kryhet nga komanda

DigitalWrite (A3, LARTË); // aktivizoni rezistencën tërheqëse në hyrjen A3

Komanda duhet të zbatohet në një dalje të konfiguruar në modalitetin e hyrjes.

Duhet mbajtur mend se rezistenca mund të ndikojë në nivelin e sinjalit analog të hyrjes. Rryma nga furnizimi me energji 5V, përmes rezistencës tërheqëse, do të shkaktojë një rënie të tensionit në rezistencën e brendshme të burimit të sinjalit. Pra, është më mirë të fikni rezistencën.

Pllaka e konvertuesit analog në dixhital Arduino.

Matja aktuale e tensionit në hyrje kryhet nga një konvertues analog në dixhital (ADC) me një ndërprerës për 6 kanale. ADC ka një rezolucion prej 10 bit, që korrespondon me kodin e daljes së konvertuesit 0...1023. Gabimi i matjes nuk është më shumë se 2 njësi të shifrës më pak të rëndësishme.

Për të ruajtur saktësinë maksimale (10 shifra), është e nevojshme që rezistenca e brendshme e burimit të sinjalit të mos kalojë 10 kΩ. Kjo kërkesë është veçanërisht e rëndësishme kur përdorni ndarës të rezistencës të lidhur me hyrjet analoge të tabelës. Rezistenca e rezistorëve ndarës nuk mund të jetë shumë e madhe.

Funksionet e softuerit të hyrjes analoge.

int analogRead(port)

Lexon vlerën e tensionit në hyrjen analoge të specifikuar. Një tension i hyrjes që varion nga 0 në nivelin e referencës së tensionit (shpesh 5 V) konvertohet në një kod nga 0 në 1023.

Me një tension referimi prej 5 V, rezolucioni është 5 V / 1024 = 4,88 mV.

Duhen rreth 100 µs për t'u konvertuar.

int inputCode; // kodi i tensionit të hyrjes
float inputVoltage; // Tensioni i hyrjes në V

inputCod=analogLeximi(A3); // leximi i tensionit në hyrjen A3
InputVoltage= ((float)inputCod * 5. / 1024.); // kodi i konvertimit në tension (V)

Referenca (lloji) analoge e pavlefshme

Vendos tensionin e referencës për ADC. Ai përcakton tensionin maksimal të hyrjes analoge që ADC mund të konvertojë saktë. Vlera e tensionit të referencës përcakton gjithashtu koeficientin për shndërrimin e kodit në tension:

Tensioni i hyrjes = kodi ADC * voltazhi i referencës / 1024.

Argumenti tip mund të marrë vlerat e mëposhtme:

  • DEFAULT - voltazhi i referencës është i barabartë me tensionin e furnizimit të kontrolluesit (5 V ose 3,3 V). Për Arduino UNO R3 - 5 V.
  • INTERNAL - tension i brendshëm referencë 1.1 V për bordet me kontrollues ATmega168 dhe ATmega328, për ATmega8 - 2.56 V.
  • INTERNAL1V1 - Tension i brendshëm referencë 1,1 V për kontrollorët Arduino Mega.
  • INTERNAL2V56 - Tension i brendshëm referencë 2,56 V për kontrollorët Arduino Mega.
  • EXTERNAL – burim i jashtëm i tensionit referues, i lidhur me hyrjen AREF.

Referenca analoge (INTERNAL); // Tensioni i referencës është 1.1 V

Voltmetër me dy kanale në Arduino.

Si shembull i përdorimit të funksioneve të hyrjes analoge, le të krijojmë një projekt të thjeshtë voltmetër dixhital në Arduino. Pajisja duhet të matë tensionet në dy hyrje analoge të tabelës dhe të transferojë vlerat e matura në një kompjuter përmes një porti serik. Duke përdorur shembullin e këtij projekti, unë do të tregoj parimet e krijimit të sistemeve të thjeshta për matjen dhe mbledhjen e informacionit.

Ne vendosim që voltmetri të matë tensionin në intervalin prej të paktën 0 ... 20 V dhe të zhvillojë një qark për lidhjen e hyrjeve të voltmetrit me tabelën Arduino UNO.

Nëse e vendosim tensionin e referencës në 5 V, atëherë hyrjet analoge të tabelës do të masin tensionin në intervalin 0 ... 5 V. Dhe ne kemi nevojë për të paktën 0 ... 20 V. Pra, ne duhet të përdorim një ndarës i tensionit.

Tensioni në hyrje dhe në dalje të ndarësit janë të lidhura nga relacioni:

Uout = (Uin / (R1 + R2)) * R2

Raporti i transmetimit:

K = Uout / Uin = R2 / (R1 + R2)

Ne kemi nevojë për një fitim 1/4 (20V * 1/4 = 5V).

Për të ruajtur saktësinë maksimale (10 shifra), është e nevojshme që rezistenca e brendshme e burimit të sinjalit të mos kalojë 10 kΩ. Prandaj, ne zgjedhim rezistencën R2 të barabartë me 4.22 kOhm. Ne llogarisim rezistencën e rezistencës R1.

0,25 = 4,22 / (R1 + 4,22)
R1 \u003d 4,22 / 0,25 - 4,22 \u003d 12,66 kOhm

Gjeta rezistorë me një rezistencë prej 15 kOhm me vlerësimin më të afërt. Me rezistorë R1 = 15 kΩ dhe R2 = 4,22:

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

Qarku i voltmetrit i bazuar në Arduino do të duket kështu.

Dy ndarës të tensionit janë të lidhur me hyrjet analoge A0 dhe A1. Kondensatorët C1 dhe C2, së bashku me rezistorët ndarës, formojnë filtra me kalim të ulët që largojnë zhurmën me frekuencë të lartë nga sinjalet.

E montova këtë qark në një dërrasë buke.

E lidha hyrjen e parë të voltmetrit me një furnizim të rregulluar me energji elektrike dhe të dytin me furnizimin 3.3 V të bordit Arduino. Për të kontrolluar tensionin, lidha një voltmetër në hyrjen e parë. Mbetet për të shkruar programin.

Një program për matjen e tensionit duke përdorur një tabelë Arduino.

Algoritmi është i thjeshtë. E nevojshme:

  • lexoni kodin ADC dy herë në sekondë;
  • shndërroni atë në tension;
  • dërgoni vlerat e matura përmes portës serike në kompjuter;
  • Programi i monitorit të portit Arduino IDE shfaq vlerat e tensionit të marra në ekranin e kompjuterit.

Do të jap skicën e programit të plotë.

// programi i matjes së tensionit
// në hyrjet analoge A0 dhe A1

#përfshi

koha e periudhës së matjes
#define R1 15. // rezistenca R1
#define R2 4.22 // rezistenca R2


float u1, u2; // tensionet e matura

konfigurimi i zbrazët ()(
Serial.fillim(9600); //

MsTimer2::start(); // ndërprerje aktivizoj
}

void loop() (

// periudha 500 ms
nëse (Numërimi i kohës >= MEASURE_PERIOD) (
Numri i kohës=0;

//

// leximi i kodit të kanalit 2 dhe konvertimi në tension
u2= ((lundrues)analogLexo(A1)) * 5. / 1024. / R2 * (R1 + R2);

// transferimi i të dhënave përmes portës serike
Serial.print("U1 = "); Printim serik (u1, 2);
Serial.print(" U2 = "); Serial.println(u2, 2);
}
}

// ndërprerje përpunimi 1 ms
void timerInterrupt() (
TimeCount ++;
}

Më lejoni të shpjegoj linjën në të cilën kodi ADC konvertohet në tension:

// leximi i kodit të kanalit 1 dhe konvertimi në tension
u1= ((lundrues)analogLexo(A0)) * 5. / 1024. / R2 * (R1 + R2);

  • Lexohet kodi ADC: analogRead(A0) .
  • Konvertuar në mënyrë të qartë në formatin me pikë lundruese: (float) .
  • Shndërrohet në tension në hyrjen analoge: * 5. / 1024. Pika në fund të numrave tregon se ky është një numër me pikë lundruese.
  • Raporti i ndarësit merret parasysh: / R2 * (R1 + R2) .

Le të ngarkojmë programin në tabelë, të nisim monitorin e portit serial.

Dy shirita drejtimi tregojnë vlerat e tensioneve të matura. Gjithçka funksionon.

Matja e vlerës mesatare të sinjalit.

Le të lidhim kanalin e parë të voltmetrit tonë me një burim tensioni me një nivel të lartë valëzim. Një foto të tillë do ta shohim në monitor.

Vlerat e tensionit të kanalit të parë në ekranin e monitorit po dridhen dhe kërcejnë gjatë gjithë kohës. Dhe leximet e voltmetrit të kontrollit janë mjaft të qëndrueshme. Kjo është për shkak se voltmetri referencë mat vlerën mesatare të sinjalit, ndërsa bordi Arduino lexon mostra individuale çdo 500ms. Natyrisht, momenti i leximit të ADC bie në pika të ndryshme të sinjalit. Dhe në një nivel të lartë pulsimesh, amplituda në këto pika është e ndryshme.

Përveç kësaj, nëse sinjali lexohet në mostra të veçanta të rralla, atëherë çdo zhurmë impulsi mund të sjellë një gabim të rëndësishëm në matje.

Zgjidhja është marrja e disa mostrave të shpeshta dhe mesatarja e vlerës së matur. Për këtë:

  • në mbajtësin e ndërprerjeve, ne lexojmë kodin ADC dhe e përmbledhim atë me mostrat e mëparshme;
  • numëroni kohën mesatare (numri i mostrave mesatare);
  • kur arrihet numri i specifikuar i mostrave, ruajmë vlerën totale të kodeve ADC;
  • për të marrë vlerën mesatare, ne e ndajmë shumën e kodeve ADC me numrin e mostrave mesatare.

Një detyrë nga libri i matematikës së klasës së 8-të. Këtu është një skicë e programit, një voltmetër me vlerë mesatare me dy kanale.

// programi i matjes së tensionit të mesëm
// në hyrjet analoge A0 dhe A1

#përfshi

#define MEASURE_PERIOD 500 // koha e periudhës së matjes
#define R1 15. // rezistenca R1
#define R2 4.22 // rezistenca R2

int TimeCount; // numërues i kohës
shuma e gjatëU1, shumaU2; // variabla për përmbledhjen e kodeve ADC
disponueshmëria e gjatëU1, disponueshmëriaU2; // shuma e kodeve ADC (mesatarisht * 500)
boolean flagGati; // shenjë e gatishmërisë së të dhënave të matjes

konfigurimi i zbrazët ()(
Serial.fillim(9600); // inicializoni portin, shpejtësia 9600
MsTimer2::set(1, timerInterrupt); // ndërprerjet e kohëmatësit, periudha 1 ms
MsTimer2::start(); // ndërprerje aktivizoj
}

void loop() (

nëse (flamuri gati == e vërtetë) (
flagReady=false;
// konvertimi në tension dhe transferimi në një kompjuter
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);
}
}

// ndërprerje përpunimi 1 ms
void timerInterrupt() (

TimeCount ++; // +1 numëruesi mesatar i mostrës
sumU1+= analogLeximi(A0); // përmbledhja e kodeve ADC
sumU2+= analogLeximi(A1); // përmbledhja e kodeve ADC

// duke kontrolluar numrin e mostrave mesatare
nëse (Numërimi i kohës >= MEASURE_PERIOD) (
Numri i kohës=0;
disponueshmëriaU1=shumaU1; // mbingarkesë e vlerës mesatare
avarageU2=shumaU2; // mbingarkesë e vlerës mesatare
shumaU1= 0;
shumaU2=0;
flagReady=e vërtetë; // rezultati i matjes së shenjës është gati
}
}

Formulës për konvertimin e kodit ADC në tension iu shtua /500, numri i mostrave. Ngarkoni, ekzekutoni monitorin e portit (Cntr + Shift + M).

Tani, edhe me një nivel të konsiderueshëm të valëzimit, leximet ndryshojnë me të qindtat. Kjo ndodh vetëm sepse tensioni nuk është i stabilizuar.

Numri i mostrave duhet të zgjidhet duke marrë parasysh:

  • numri i mostrave përcakton kohën e matjes;
  • sa më i madh të jetë numri i mostrave, aq më i vogël do të jetë ndikimi i interferencës.

Burimi kryesor i ndërhyrjes në sinjalet analoge është rrjeti 50 Hz. Prandaj, është e dëshirueshme të zgjidhni një kohë mesatare që është shumëfish i 10 ms - koha e gjysmë ciklit të rrjetit me një frekuencë prej 50 Hz.

Optimizimi i llogaritjeve.

Llogaritjet e pikave lundruese thjesht gllabërojnë burimet e një mikrokontrollues 8-bit. Çdo operacion me pikë lundruese kërkon denormalizimin e mantisës, funksionimin me pikë fikse, normalizimin e mantisës, korrigjimin e eksponentit... Dhe të gjitha operacionet me numra 32 bit. Prandaj, është e nevojshme të minimizohet përdorimi i llogaritjeve me pikë lundruese. Unë do t'ju tregoj se si ta bëni këtë në mësimet e ardhshme, por le të paktën të optimizojmë llogaritjet tona. Efekti do të jetë i rëndësishëm.

Në programin tonë, konvertimi i kodit ADC në tension shkruhet si më poshtë:

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

Sa llogaritje ka dhe të gjitha janë me pikë lundruese. Por shumica e llogaritjeve janë operacione me konstante. Pjesa e linjës:

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

(float)avarageU1 * 0.00004447756

Vetë përpiluesit inteligjentë i njohin llogaritjet me konstante dhe i llogarisin ato në kohën e kompilimit. Kisha një pyetje se sa i zgjuar është përpiluesi i Andruino. Vendosi të kontrollojë.

Kam shkruar një program të shkurtër. Kryen një cikël prej 10,000 kalimesh dhe më pas transmeton në kompjuter kohën e ekzekutimit të këtyre 10,000 cikleve. ato. ju lejon të shihni kohën e ekzekutimit të operacioneve të vendosura në trupin e lakut.

// kontrolli i optimizimit të llogaritjes

int x= 876;
noton y;
numërim int i panënshkruar;
kohë e gjatë e panënshkruarAktuale, kohëPara;

konfigurimi i zbrazët ()(
Serial.fillim(9600);
}

void loop() (
numëro++;
// y= (lundrues)x / 500. * 5. / 1024. / 4.22 * (15. + 4.22);
// y= (lundrues)x * 0.00004447756;

nëse (numërimi >= 10000) (
numërim=0;
kohaRurrent=millis();
Serial.println(kohAktuale - KohaPara);
kohaPara = kohaAktuale;
}
}

Në variantin e parë, kur operacionet me pikë lundruese komentohen dhe nuk ekzekutohen në lak, programi dha një rezultat prej 34 ms.

ato. 10,000 cikle boshe përfundojnë në 34 ms.

Pastaj hapa rreshtin:

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

përsërit llogaritjet tona. Rezultati 10,000 kalime në 922 ms ose

(922 - 34) / 10,000 = 88,8 µs.

ato. Kjo linjë e llogaritjeve të pikës lundruese kërkon 89 µs për të përfunduar. Mendova se do të kishte më shumë.

Tani e mbylla këtë rresht me një koment dhe hapa rreshtin tjetër, shumëzuar me një konstante të parallogaritur:

y= (lundrues)x * 0.00004447756;

Rezultati 10,000 kalime në 166 ms ose

(166 - 34) / 10,000 = 13,2 µs.

Rezultat i mahnitshëm. Kemi kursyer 75,6 µs për rresht. E përfundoi pothuajse 7 herë më shpejt. Ne kemi 2 rreshta të tillë, por mund të ketë shumë më tepër në program.

Përfundim - llogaritjet me konstante duhet të bëhen vetë në kalkulator dhe të përdoren në programe si koeficientë të gatshëm. Përpiluesi Arduino nuk do t'i llogarisë ato në fazën e përpilimit. Në rastin tonë, ne duhet të bëjmë këtë:

#define ADC_U_COEFF 0.00004447756 // Kodi ADC në faktorin e konvertimit të tensionit

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

Opsioni optimal i shpejtësisë është transferimi i kodit ADC në kompjuter, dhe bashkë me të të gjitha llogaritjet me pikë lundruese. Në këtë rast, një program i specializuar duhet të marrë të dhëna në kompjuter. Monitoruesi i portit nga Arduino IDE nuk do të funksionojë.

Unë do të flas për mënyra të tjera për të optimizuar programet Arduino në mësimet e ardhshme sipas nevojës. Por pa zgjidhur këtë çështje, është e pamundur të zhvillohen programe komplekse në një mikrokontrollues 8-bit.

Ekziston një mësim tjetër në sit

Me interes të gjerë për tifozët e pajisjeve të programueshme elektronike të bëra në shtëpi janë asambletë shumëfunksionale Arduino që ju lejojnë të zbatoni ide interesante.

Avantazhi kryesor i qarqeve të gatshme Arduino qëndron në parimin unik bllok-modular: çdo tabelë mund të shtohet me ndërfaqe shtesë, duke zgjeruar pafundësisht mundësitë për krijimin e projekteve të ndryshme.

Modulet Arduino ndërtuar mbi një mikrokontrollues universal me ngarkuesin e vet, i cili e bën të lehtë ndezjen e tij me kodin e nevojshëm të programit, pa përdorimin e pajisjeve shtesë. Programimi kryhet në gjuhën standarde C++.

Një nga shembujt më të thjeshtë të përdorimit të Arduino mund të jetë zbatimi mbi bazën e këtij montimi të një voltmetri DC me precizion të lartë me një gamë matjeje nga 0 në 30 V.

Hyrjet analoge të Arduino janë projektuar për një maksimum prej pesë volt DC, prandaj, përdorimi i tyre në tensione që tejkalojnë këtë vlerë është i mundur me një ndarës tensioni.


Diagrami i lidhjes së Areduino përmes ndarësit të tensionit

Një ndarës i tensionit përbëhet nga dy rezistorë të lidhur në seri. Ajo llogaritet sipas formulës:

Prizë e jashtme USB në radion e makinës

Ideja

Ideja pajisjet për matjen e tensionit, rrymës, kapacitetit, shkarkimit dhe ndoshta ngarkimit u ngritën shumë kohë më parë dhe jo vetëm me mua. Mund të gjeni mjaft lodra të quajtura USB Tester (Doktor) për testimin e pajisjeve të ndryshme USB. Unë jam i interesuar për një pajisje disi më të gjithanshme, e pavarur nga ndërfaqja, por e krijuar thjesht për tensione dhe rryma të caktuara. Për shembull, 0 - 20.00v, 0 - 5.00a, 0 - 99.99Ah. Sa për funksionet, unë e shoh kështu

  • Shfaqja e tensionit dhe rrymës aktuale, domethënë një metër volt-amper. Në parim, ju mund të reflektoni menjëherë fuqinë.
  • Llogaritja dhe shfaqja e kapacitetit të akumuluar. Në amp-orë dhe ka shumë të ngjarë në vat-orë.
  • Shfaqja e kohës së procesit
  • Dhe, ka shumë të ngjarë, pragjet e mbylljes së tensionit të poshtëm dhe të sipërm të konfigurueshëm (kufijtë e shkarkimit dhe ngarkimit)

Zhvillimi

Për të zbatuar llogaritjet dhe matjet, na duhet një kontrollues. E mbaja mend këtë ide si pjesë e njohjes sime me Arduino, kështu që Atmega328 e thjeshtë popullore do të jetë kontrolluesi dhe do të programohet në mjedis. Arduino. Nga pikëpamja inxhinierike, zgjedhja ndoshta nuk është më e mira - kontrolluesi për detyrën është pak i trashë, dhe ADC-ja e tij nuk mund të quhet matës, por ... do të përpiqemi.

  • Ne nuk do të bashkojmë shumë në këtë projekt. Si bazë, ne do të marrim modulin e gatshëm Arduino Pro Mini, pasi kinezët janë gati t'i furnizojnë me pakicë për 1,5 dollarë.
  • Pajisja e ekranit do të jetë një ekran 1602 - 1,5 dollarë më shumë. Unë kam një opsion me një modul të ndërfaqes I2C, por në këtë projekt nuk është shumë i nevojshëm (0,7 dollarë).
  • Për zhvillim, ne kemi nevojë për një dërrasë buke. Në rastin tim, ky është një BreadBoard i vogël $1.
  • Natyrisht, do t'ju nevojiten tela dhe një numër rezistencash të vlerësimeve të ndryshme. Për një ekran 1602 pa I2C, nevojitet gjithashtu zgjedhja e kontrastit - bëhet me një rezistencë të ndryshueshme prej 2 - 20 kOhm.
  • Për të zbatuar një ampermetër, keni nevojë për një shunt. Si përafrim i parë, mund të jetë një rezistencë 0,1 ohm, 5 vat.
  • Për të zbatuar mbylljen automatike, ju nevojitet një stafetë me kontakte të krijuara për rrymën maksimale të pajisjes dhe një tension të barabartë me tensionin e furnizimit. Për të kontrolluar stafetën, ju nevojitet një transistor npn dhe një diodë mbrojtëse.
  • Pajisja do të mundësohet nga një furnizim i jashtëm me energji elektrike, padyshim të paktën 5V. Nëse furnizimi me energji elektrike ndryshon shumë, atëherë do të kërkohet gjithashtu një stabilizues integral i tipit 7805 - ai do të përcaktojë tensionin e stafetës.
  • Kur Arduino Pro Mini do të kërkojë një konvertues USB-TTL për të ndezur firmuerin.
  • Për ta konfiguruar do t'ju duhet një multimetër.

Voltmetër

Unë jam duke zbatuar një voltmetër të thjeshtë me një interval prej rreth 0 - 20v. Kjo vërejtje është e rëndësishme, sepse ADC e kontrolluesit tonë ka një kapacitet prej 10 bit (1024 vlera diskrete), kështu që gabimi do të jetë së paku 0.02 V (20 / 1024). Për të zbatuar harduerin, na duhet një hyrje analoge e kontrolluesit, një ndarës nga një palë rezistencash dhe një lloj daljeje (ekrani është në një version të përfunduar, një port serik mund të përdoret për korrigjimin e gabimeve).

Parimi i matjes së ADC është të krahasohet tensioni në hyrjen analoge me referencën VRef. Dalja ADC është gjithmonë numër i plotë - 0 korrespondon me 0V, 1023 korrespondon me tensionin VRef. Matja zbatohet nga një seri leximesh të njëpasnjëshme të tensionit dhe mesatarizimi gjatë periudhës ndërmjet përditësimeve të vlerës në ekran. Zgjedhja e tensionit të referencës është e rëndësishme sepse është e paracaktuar me tensionin e furnizimit, i cili mund të mos jetë i qëndrueshëm. Kjo nuk na përshtatet aspak - ne do të marrim si bazë një burim të brendshëm referimi të qëndrueshëm me një tension prej 1.1 V, duke e inicializuar atë duke e quajtur AnalogReference(INTERNAL). Pastaj do të kalibrojmë vlerën e tij sipas leximeve të multimetrit.

Në diagramin në të majtë - një variant me kontroll të drejtpërdrejtë të ekranit (ai thjesht kontrollohet - shihni skicën standarde LiquidCrystal\HelloWorld). Në të djathtë është opsioni I2C, të cilin do ta përdor më tej. I2C ju lejon të kurseni tela (të cilat në versionin e zakonshëm janë 10, pa llogaritur dritën e prapme). Por kjo kërkon një modul shtesë dhe inicializim më kompleks. Në çdo rast, shfaqja e simboleve në modul duhet së pari të kontrollohet dhe të rregullohet kontrasti - për këtë, thjesht duhet të shfaqni çdo tekst pas inicializimit. Kontrasti rregullohet nga rezistenca R1, ose një rezistencë e ngjashme e modulit I2C.

Hyrja është një ndarës 1:19, i cili lejon, në Vref = 1.1, të marrë një tension maksimal prej rreth 20 V (zakonisht një kondensator + diodë zener vendoset paralelisht me hyrjen për mbrojtje, por kjo nuk është ende e rëndësishme për ne. ). Rezistorët kanë një përhapje, dhe Vref referencë e kontrolluesit gjithashtu, kështu që pas montimit, duhet të matni tensionin (të paktën furnizimin me energji elektrike) paralelisht me pajisjen tonë dhe një multimetër referencë dhe zgjidhni Vref në kod derisa leximet të përputhen. Vlen gjithashtu të përmendet se çdo ADC ka një tension të kompensuar zero (i cili prish leximet në fillim të diapazonit), por ne nuk do të thellohemi ende në këtë.

Do të jetë gjithashtu e rëndësishme të ndani furnizimin dhe "tokën" matëse. ADC-ja jonë ka një rezolucion pak më të keq se 1mV, gjë që mund të jetë problematike nëse lidhet gabimisht, veçanërisht në një tabelë. Meqenëse instalimet elektrike të tabelës së modulit tashmë janë bërë dhe ne kemi mbetur me zgjedhjen e kunjave. Moduli ka disa kunja "tokë", kështu që duhet të sigurohemi që furnizimi me energji i modulit të vijë nga një "tokë", dhe matjet nga një tjetër. Në fakt, unë përdor gjithmonë pinin e tokës më afër hyrjeve analoge për ndryshime.

Për kontrollin I2C, përdoret një variant i bibliotekës LiquidCrystal_I2C - në rastin tim, tregohet një pikë specifike e modulit I2C (kinezët prodhojnë module me kontrolle të ndryshme). Vërej gjithashtu se I2C në Arduino përfshin përdorimin e kunjave A4, A5 - në tabelën Pro Mini ato nuk janë në skaj, gjë që është e papërshtatshme për prototipimin në BreadBoard.

Burimi

#përfshi #përfshi // Voltmetër i thjeshtë me ekran i2c 1602. V 16.11 // Cilësimet për ekranin i2c 1602 me pinout të personalizuar #define LCD_I2C_ADDR 0x27 #define BACKLIGHT 3 #define LCD_EN 2 #define LCD_RW 1 #define LCD_RW 1 #define LCD_RW 1 #define define LCD_D6 6 #define LCD_D7 7 LiquidCrystal_I2C LCD(LCD_I2C_ADDR,LCD_EN,LCD_RW,LCD_RS,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Koha e rifreskimit, ms (200-2000) #define REFRESH_TIME 330 // Hyrja analoge #define PIN_VOLT A0 // Tensioni i brendshëm i referencës (zgjidh) konst float VRef = 1,10; // Raporti i ndarësit rezistues në hyrje (Rh + Rl) / Rl. NË<-[ Rh ]--(analogInPin)--[ Rl ]--|GND const float VoltMult = (180.0 + 10.0) / 10.0; float InVolt, Volt; void setup() { analogReference(INTERNAL); // Инициализация дисплея lcd.begin (16, 2); lcd.setBacklightPin(BACKLIGHT, POSITIVE); lcd.setBacklight(HIGH); // включить подсветку lcd.clear(); // очистить дисплей lcd.print("Voltage"); } void loop() { unsigned long CalcStart = millis(); int ReadCnt = 0; InVolt = 0; // Чтение из порта с усреднением while ((millis() - CalcStart) < REFRESH_TIME) { InVolt += analogRead(PIN_VOLT); ReadCnt++; } InVolt = InVolt / ReadCnt; // Смещение 0 для конкретного ADC (подобрать или отключить) if (InVolt >0.2) Involt += 3; // Konverto në volt (Vlera: 0..1023 -> (0..VRef) shkallëzuar nga Mult) Volt = InVolt * VoltMult * VRef / 1023; // Shfaq të dhënat lcd.setCursor(0, 1); LCD.print(Volt); lcd.print("V"); )

Artikujt kryesorë të lidhur