Arduino meet wisselspanning 220v. Analoge metingen met Arduino

Diagram van een zelfgemaakt apparaat op basis van Arduino Uno, dat is ontworpen om frequentie en spanning in een stopcontact te meten en de resultaten op het 1602A-display weer te geven. Het apparaat is zeer eenvoudig te vervaardigen, dankzij het gebruik van de kant-en-klare ARDUINO UNO-module.

Schematisch diagram

De indicator is een 1602A type LCD, het is standaard, gebaseerd op de HD44780-controller. De aanduiding 1602A betekent eigenlijk dat het op twee regels staat met 16 karakters per regel.

Het apparaat is gebaseerd op ARDUINO UNO, het is een relatief goedkope kant-en-klare module, - een kleine printplaat waarop de ATMEGA328-microcontroller zich bevindt, evenals al zijn "leidingen" die nodig zijn voor de werking, inclusief een USB-programmeur en een stroomvoorziening.

Het apparaat wordt gevoed via het lichtnet en meet bovenstaande parameters. De voeding dient tevens als sensor voor het verkrijgen van gegevens over de frequentie en spanning in het net. De stroombron is gemaakt op basis van een low-power kant-en-klare transformator T1, die twee identieke wikkelingen van elk 9V AC heeft.

Rijst. 1. Schematisch diagram van de frequentiemeter en spanningswaarden in het lichtnet, Arduino Uno en 1602A worden gebruikt.

Eén wikkeling wordt gebruikt om de voedingsspanning te verkrijgen. De wisselspanning daarvan gaat naar de gelijkrichtbrug op de diodes VD1-VD4. Condensator C3 verzacht de rimpel van de gelijkgerichte spanning.

Bij C3 wordt een constante spanning van ongeveer 12V verkregen, die wordt toegevoerd aan de connector voor het leveren van stroom aan het ARDUINO UNO-bord, aan de ingang van de 5V-spanningsstabilisator op dit bord, die het hele bord en de H1-indicator van stroom voorziet.

De andere secundaire wikkeling van de transformator dient als sensor voor het meten van de parameters van het elektriciteitsnet. De wisselspanning ervan via R1 wordt naar de pulsvormer gevoerd met de frequentie van het net, gemaakt op de VT1-transistor volgens het sleutelcircuit. Deze pulsen worden toegevoerd aan de digitale poort D10 van het ARDUINO UNO-bord.

De wisselspanning van het netwerk wordt gemeten met behulp van een gelijkrichter op de VD5-diode en condensator C2. De grootte van de wisselspanning in het netwerk wordt bepaald door de grootte van de constante spanning over deze condensator en wordt via een instelbare deler op de weerstanden R4 en R5 toegevoerd aan de analoge ingang A1 van het ARDUINO UNO-bord.

Programma

Het C++-programma met gedetailleerde opmerkingen wordt weergegeven in Tabel 1. Om de frequentie te meten, wordt de pulseln-functie gebruikt, die in microseconden de duur van de positieve of negatieve flank van de ingangspuls meet.

Tafel 1.

Rijst. 2. De broncode van het programma voor het meten van de frequentie- en spanningswaarden in het lichtnet.

Dus om de periode te bepalen, moet je de duur van de positieve en negatieve halve perioden optellen, en om de frequentie in hertz te weten te komen, moet je 1.000.000 delen door de berekende periode.

De meting van de duur van de periode bestaat uit twee delen, eerst worden de duur van de positieve en negatieve halve golven gemeten in de lijnen:

Htime = pulseln (10, HOOG);

Ltime = pulseln (10, LAAG);

Vervolgens wordt de volledige periode berekend in de regel:

Ttijd = Htijd + Ltijd;

En dan, de frequentie in een lijn berekenen:

frequentie = 1000000 / Ttijd;

De werking van het spanningsmeetprogramma is gebaseerd op het uitlezen van data van een analoge ingang en het berekenen van het meetresultaat. De uitgang van de analoge poort wordt omgezet in digitale vorm door de ADC van de microcontroller. Om het resultaat in eenheden van volt te krijgen, moet u het vermenigvuldigen met 5 (met de referentiespanning, dat wil zeggen met de voedingsspanning van de microcontroller) en delen door 1024.

Om een ​​spanning te kunnen meten van meer dan 5V, of beter gezegd, meer dan de voedingsspanning van de microcontroller, omdat de werkelijke spanning aan de uitgang van de 5-volt stabilisator op het ARDUINO UNO-bord kan verschillen van 5V, en meestal iets lager, je moet gewone resistieve verdelers gebruiken aan de ingang. Hier is het een spanningsdeler over weerstanden R5 en R4.

Daarnaast speelt het gebruik van een transformator een rol, evenals het verschil tussen de waarde van gelijkspanning en wisselspanning. Daarom wordt de oorspronkelijke delingsfactor van 0,016 opgeteld. Het lezen van gegevens van de analoge poort vindt plaats in de regel:

vout = analoog lezen (analoge invoer);

Vervolgens wordt de werkelijke spanning berekend, rekening houdend met de deelverhouding van de ingangsspanningsdeler:

volt = vout * 5,0 / 1024,0 / 0,016;

In deze regel is het getal 5.0 de spanning aan de uitgang van de stabilisator van het ARDUINO UNO-bord. Idealiter zou dit 5V moeten zijn, maar voor een nauwkeurige werking van de voltmeter moet deze spanning eerst worden gemeten.

Sluit een 12V voeding aan en meet de + 5V spanning op de POWER connector van het bord met een voldoende nauwkeurige voltmeter. Wat er zal gebeuren, voer dan deze regel in in plaats van 5.0, bijvoorbeeld als het 4.85V is, ziet de regel er als volgt uit:

volt = vout * 4,85 / 1024,0 / 0,016;

Vervolgens worden de meetresultaten weergegeven op het LCD-scherm. De spanning wordt ingevoerd in de eerste regel van het display en de frequentie in de tweede. De eenheden worden aangeduid als "V" en "Hz". Wat de frequentiemeting betreft, is aanpassing helemaal niet nodig. Maar om de spanning te meten, moet u het apparaat kalibreren volgens de voorbeeldige aanpassing van de weerstand R5.

Karavkin V. RK-10-17.

Dit artikel biedt een interessant diagram voor degenen die graag experimenteren en Arduino... Het introduceert een eenvoudige digitale voltmeter die veilig gelijkspanningen van 0 tot 30 V kan meten. Het Arduino-bord zelf kan worden gevoed vanuit een standaard 9 V.



Zoals je weet, kan de Arduino analoge ingang spanningen meten van 0 tot 5V (met een standaard 5V referentie). Maar dit bereik kan worden uitgebreid door een spanningsdeler te gebruiken.


De verdeler reduceert de gemeten spanning tot een acceptabel niveau voor de analoge ingang. De speciaal geschreven code berekent vervolgens de werkelijke spanning.



Een analoge sensor in de Arduino detecteert de spanning op de analoge ingang en zet deze om naar een digitaal formaat dat de microcontroller kan uitlezen. Op analoge ingang A0 sluiten we een spanningsdeler aan die gevormd wordt door de weerstanden R1 (100K) en R2 (10K). Met dergelijke weerstandswaarden kan de Arduino gevoed worden tot 55V, aangezien de deelverhouding in dit geval 11 is, dus 55V/11 = 5V. Om er zeker van te zijn dat de metingen veilig zijn voor het bord, meet u het beste de spanning in het bereik van 0 tot 30 V.



Als het display niet overeenkomt met dat van een geverifieerde voltmeter, moet een digitale precisiemultimeter worden gebruikt om de exacte waarden voor R1 en R2 te vinden. In dit geval moet u in de code R1 = 100000.0 en R2 = 10000.0 vervangen door uw eigen waarden. Dan is het de moeite waard om het vermogen te controleren door de spanning op het bord te meten tussen 5V en GND. De spanning kan 4,95 V zijn. Dan moet je in de code vout = (waarde * 5,0) / 1024,0 5,0 vervangen door 4,95. Het is raadzaam om precisieweerstanden te gebruiken met een fout van niet meer dan 1%. Onthoud dat spanningen boven 55V het Arduino-bord kunnen beschadigen!



#erbij betrekken LiquidCrystal-lcd (7, 8, 9, 10, 11, 12); int analoge ingang = 0; float vout = 0,0; vlotter vin = 0,0; vlotter R1 = 100000.0; // weerstand R1 (100K) vlotter R2 = 10000.0; // weerstand R2 (10K) int-waarde = 0; void setup () (pinMode (analogInput, INPUT); lcd.begin (16, 2); lcd.print ("DC VOLTMETER");) void loop () (// lees analoge waarde waarde = analogRead (analogInput); vout = (waarde * 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); }


Gebruikte elementen:


Arduino Uno-bord
100K ohm weerstand
10K weerstand
100 ohm weerstand
Potentiometer 10Kohm
LCD-scherm 16 × 2
  • zelfstudie

Invoering

Dag iedereen! Na de voltooiing van de cyclus op de sensoren, waren er vragen over een ander plan voor het meten van de parameters van het verbruik van huishoudelijke en niet erg elektrische apparaten. Wie verbruikt hoeveel, hoe wat aan te sluiten om te meten, wat zijn de subtiliteiten enzovoort. Het is tijd om alle kaarten in dit gebied te onthullen.
In deze serie artikelen zullen we kijken naar het onderwerp van het meten van elektriciteitsparameters. Er zijn in feite een zeer groot aantal van deze parameters, waarover ik u geleidelijk in kleine series zal proberen te vertellen.
Tot nu toe staan ​​er drie afleveringen op de planning:
  • Meting van elektriciteit.
  • Kracht, kwaliteit.
  • Apparaten voor het meten van de parameters van elektriciteit.
Tijdens het ontleden lossen we bepaalde praktische problemen op microcontrollers op totdat het resultaat is bereikt. Natuurlijk zal het grootste deel van deze cyclus gewijd zijn aan het meten van wisselspanning en kan nuttig zijn voor iedereen die graag de elektrische apparaten van hun slimme huis wil bedienen.
Op basis van de resultaten van de hele cyclus maken we een soort slimme elektriciteitsmeter met internettoegang. Hele fervente liefhebbers van het aansturen van de elektrische apparaten van hun smart home kunnen op basis van bijvoorbeeld MajorDomo alle mogelijke assistentie verlenen bij de uitvoering van het communicatiegedeelte. Laten we OpenSource smart home als het ware beter maken.
In deze serie behandelen we de volgende vragen in twee delen:
  • Aansluiting van stroom- en spanningssensoren in gelijkstroomapparaten, evenals enkelfasige en driefasige wisselstroomcircuits;
  • Meting van effectieve waarden van stroom en spanning;
  • Meting van de arbeidsfactor;
  • Volledig, actief en reactief vermogen;
  • Elektriciteitsverbruik;
Hieronder vindt u de antwoorden op de eerste twee vragen van deze lijst. Ik ga bewust niet in op de kwestie van de nauwkeurigheid van meetindicatoren en uit deze serie verheug ik me alleen over de resultaten die zijn verkregen met een nauwkeurigheid van plus of min bastschoenen. In de derde reeks zal ik hier zeker een apart artikel aan wijden.

1. Sensoren aansluiten


In de laatste cyclus over spannings- en stroomsensoren had ik het over de soorten sensoren, maar niet over hoe ze te gebruiken en waar ze moesten worden geplaatst. Het is tijd om het te repareren
DC-sensoren aansluiten
Het is duidelijk dat de hele cyclus gewijd zal zijn aan AC-systemen, maar we zullen ook snel DC-circuits doornemen, omdat dit ons van pas kan komen bij het ontwikkelen van DC-voedingen. Neem bijvoorbeeld een klassieke PWM buck-converter:


Fig 1. Buck-converter met PWM
Het is onze taak om een ​​gestabiliseerde uitgangsspanning te leveren. Bovendien is het op basis van informatie van de stroomsensor mogelijk om de bedrijfsmodus van de smoorspoel L1 te regelen, waardoor verzadiging wordt voorkomen, en ook om de stroombeveiliging van de omzetter te implementeren. En eerlijk gezegd zijn er geen speciale mogelijkheden om sensoren te installeren.
Een spanningssensor in de vorm van een resistieve verdeler R1-R2, die de enige is die op gelijkstroom kan werken, is geïnstalleerd aan de uitgang van de omzetter. Een gespecialiseerde converter-microschakeling heeft in de regel een feedback-ingang en stelt alles in het werk om ervoor te zorgen dat een bepaald spanningsniveau, voorgeschreven in de documentatie voor de microschakeling, aan deze ingang verschijnt (3). Bijvoorbeeld 1,25V. Als onze uitgangsspanning overeenkomt met dit niveau - alles is in orde - passen we de uitgangsspanning direct op deze ingang toe. Zo niet, stel dan de deler in. Als we een uitgangsspanning van 5V moeten leveren, dan moet de deler een delingsfactor van 4 geven, dus bijvoorbeeld R1 = 30k, R2 = 10k.
De stroomsensor wordt meestal tussen de voeding en de omvormer en op de microschakeling geïnstalleerd. Door het potentiaalverschil tussen de punten 1 en 2, en met een bekende weerstand, kunnen de weerstanden Rs de huidige waarde van de stroom van onze smoorspoel bepalen. Het installeren van een stroomsensor tussen de bronnen en de belasting is geen goed idee, omdat de filtercondensator door de weerstand wordt afgesneden van de impulsstroomverbruikers. Het installeren van een weerstand in de breuk van de gemeenschappelijke draad is ook een goed voorteken - er zullen twee grondniveaus zijn waarmee het nog steeds een plezier is om te sleutelen.
Problemen met spanningsverlies kunnen worden voorkomen door contactloze stroomsensoren te gebruiken, zoals hall-sensoren:


Fig 2. Contactloze stroomsensor
Er is echter een lastigere manier om stroom te meten. Inderdaad, de spanning daalt op precies dezelfde manier over de transistor en er vloeit dezelfde stroom door als de inductantie. Daarom kunt u door de spanningsval erover ook de huidige waarde van de stroom bepalen. Eerlijk gezegd, als je kijkt naar de interne structuur van converter-microschakelingen, bijvoorbeeld van Texas Instruments, dan komt deze methode net zo vaak voor als de vorige. De nauwkeurigheid van deze methode is zeker niet de hoogste, maar dit is ruim voldoende om de huidige cutoff te laten werken.


Fig 3. Transistor als stroomsensor
We doen hetzelfde in andere circuits van vergelijkbare converters, of het nu gaat om boost of om te inverteren.
Het is echter noodzakelijk om de forward- en flyback-converters van de transformator afzonderlijk te vermelden.


Fig 4. Aansluiting van stroomsensoren in flyback-omvormers
Ze kunnen ook een externe weerstand of een transistor in zijn rol gebruiken.
Dit voltooit de aansluiting van sensoren op DC / DC-converters. Als u suggesties heeft voor andere opties, vul ik het artikel graag aan.
1.2 Sensoren aansluiten op eenfasige wisselstroomcircuits
In AC-circuits hebben we een veel grotere selectie van mogelijke sensoren. Laten we verschillende opties bekijken.
Het eenvoudigst is om een ​​resistieve spanningsdeler en een stroomshunt te gebruiken.


Fig 5 Aansluiting van weerstandssensoren
Ze heeft echter een aantal belangrijke nadelen:
Ten eerste zullen we ofwel een significante signaalamplitude leveren van de huidige shunt, nadat we er een grote hoeveelheid vermogen aan hebben toegewezen, of we zullen tevreden zijn met een kleine signaalamplitude en deze vervolgens versterken. En ten tweede creëert de weerstand een potentiaalverschil tussen de nulleider van het netwerk en de nulleider van het apparaat. Als het apparaat geïsoleerd is, maakt het niet uit, als het apparaat een aardklem heeft, lopen we het risico zonder signaal van de stroomsensor te zitten, omdat we het zullen kortsluiten. Misschien is het de moeite waard om sensoren te proberen die op andere principes werken.
We gebruiken bijvoorbeeld stroom- en spanningstransformatoren, of een hall-effect stroomsensor en een spanningstransformator. Er zijn veel meer mogelijkheden om met apparatuur te werken, aangezien de nuldraad geen verliezen heeft en het belangrijkste is dat er in beide gevallen een galvanische scheiding van de meetapparatuur is, wat vaak van pas kan komen. Houd er echter rekening mee dat transformatorstroom- en spanningssensoren een beperkte frequentierespons hebben en als we de harmonische samenstelling van vervormingen willen meten, dan is dit voor ons geen feit.


Afb. 6 Aansluiting van transformator en naderingssensoren voor stroom en spanning
1.3 Sensoren aansluiten op meerfasencircuits van wisselstroomnetwerken
In meerfasige netwerken is ons vermogen om stroomsensoren aan te sluiten iets minder. Dit komt door het feit dat het helemaal niet zal werken om de huidige shunt te gebruiken, omdat het potentiaalverschil tussen de faseshunts binnen honderden volts zal fluctueren en ik ken geen enkele controller voor algemeen gebruik waarvan de analoge ingangen bestand zijn tegen zo'n bespotting.
Een manier om stroomshunts te gebruiken is natuurlijk - voor elk kanaal is het noodzakelijk om een ​​galvanisch geïsoleerde analoge ingang te maken. Maar het is veel gemakkelijker en betrouwbaarder om andere sensoren te gebruiken.
In mijn kwaliteitsanalysator gebruik ik resistieve spanningsdelers en externe hall-effectstroomsensoren.

Figuur 7 Stroomsensoren in een driefasig netwerk
Zoals u op de afbeelding kunt zien, gebruiken we een vierdraadsverbinding. Natuurlijk kunt u in plaats van hall-effectstroomsensoren stroomtransformatoren of Rogowski-loops nemen.
In plaats van resistieve verdelers kunnen spanningstransformatoren worden gebruikt voor zowel vierdraads- als driedraadssystemen.
In het laatste geval zijn de primaire wikkelingen van de spanningstransformatoren verbonden met een delta en de secundaire met een ster, waarvan het gemeenschappelijke punt het gemeenschappelijke punt van het meetcircuit is


Afbeelding 8: Gebruik van spanningstransformatoren in een driefasig netwerk

2 RMS-waarde van stroom en spanning


Het is tijd om het probleem van het meten van onze signalen op te lossen. Allereerst is de effectieve waarde van stroom en spanning voor ons van praktisch belang.
Laat me je herinneren aan het materiaal uit de sensorcyclus. Met behulp van de ADC van onze microcontroller zullen we met regelmatige tussenpozen de momentane spanningswaarde registreren. Voor de meetperiode hebben we dus een reeks gegevens over het niveau van de momentane spanningswaarde (voor stroom is alles hetzelfde).


Fig 9. Reeks momentane spanningswaarden
Het is onze taak om de effectieve waarde te berekenen. Laten we eerst de integrale formule gebruiken:
(1)
In een digitaal systeem moet je jezelf beperken tot een bepaalde hoeveelheid tijd, dus gaan we naar de som:
(2)
Waar is de bemonsteringsperiode van ons signaal en is het aantal monsters voor de meetperiode. Ergens hier, in de video, begin ik het spel over gelijkheid van gebieden te wrijven. Ik had die dag moeten slapen. =)
In de MSP430FE4252-microcontrollers, die worden gebruikt in enkelfasige Mercury-elektriciteitsmeters, worden 4096 metingen gedaan voor een meetperiode van 1, 2 of 4 seconden. We zullen in de toekomst vertrouwen op T = 1c en N = 4096. Bovendien zullen we met 4096 punten per seconde snelle Fourier-transformatiealgoritmen kunnen gebruiken om het harmonische spectrum tot de 40e harmonische te bepalen, zoals vereist door GOST. Maar daarover meer in de volgende serie.
Laten we het algoritme voor ons programma schetsen. We moeten zorgen voor een stabiele start van de ADC elke 1/8192 seconde, aangezien we twee kanalen hebben en we deze gegevens afwisselend zullen meten. Stel hiervoor de timer in en het onderbrekingssignaal zal de ADC automatisch opnieuw opstarten. Alle ADC's kunnen dit.
We zullen het toekomstige programma op arduino schrijven, aangezien velen het bij de hand hebben. We hebben tot nu toe een puur academisch belang.
Met een 16MHz-systeemkwartsfrequentie en een 8-bits timer (zodat het leven niet als honing lijkt), moeten we ervoor zorgen dat de werkingsfrequentie van ten minste elke timeronderbreking met een frequentie van 8192Hz wordt gegarandeerd.
We zijn verdrietig over het feit dat 16 MHz niet als geheel is verdeeld zoals we nodig hebben, en de uiteindelijke frequentie van de timer is 8198 Hz. Sluit onze ogen voor een fout van 0,04% en lees nog steeds 4096 samples per kanaal.
We zijn verdrietig over het feit dat de overflow-interrupt in Arduino bezig is met timing (verantwoordelijk voor millis en vertraging, dus dit zal niet meer normaal werken), dus gebruiken we de vergelijkings-interrupt.
En ineens realiseren we ons dat het signaal bipolair is en dat de msp430fe4252 er perfect mee omgaat. We zijn tevreden met een unipolaire ADC, dus assembleren we een eenvoudige bipolaire-naar-unipolaire converter op een operationele versterker:


Fig 10 Bipolaire naar unipolaire omzetter
Bovendien is het onze taak om ervoor te zorgen dat onze sinusoïde oscilleert ten opzichte van de helft van de referentiespanning - dan trekken we de helft van het bereik af of activeren we de optie in de ADC-instellingen en krijgen we ondertekende waarden.
De Arduino heeft een 10-bit ADC, dus we trekken de helft af van het niet-ondertekende resultaat in het bereik van 0-1023 en krijgen -512-511.
We controleren het in LTSpiceIV geassembleerde model en zorgen ervoor dat alles werkt zoals het hoort. In de video zijn we bovendien experimenteel overtuigd.


Fig 11 simulatie resultaat. Groen is het bronsignaal, blauw is de output

Arduino-schets voor één kanaal

void setup () (autoadcsetup (); DDRD | = (1<

Het programma is geschreven in de Arduino IDE voor de ATmega1280-microcontroller. Op mijn debug-bord worden de eerste 8 kanalen gerouteerd voor de interne behoeften van het bord, dus het ADC8-kanaal wordt gebruikt. Het is mogelijk om deze schets te gebruiken voor een bord met een ATmega168, maar je moet wel het juiste kanaal selecteren.
Binnen de interrupts jongleren we met een paar servicepinnen om duidelijk de werkende digitaliseringsfrequentie te zien.
Een paar woorden over waar de factor 102 vandaan kwam. Bij de eerste start werd een signaal met verschillende amplitudes geleverd door de generator, werd de werkelijke spanningswaarde afgelezen van de oscilloscoop en werd de berekende waarde in absolute ADC-eenheden van de console gehaald .

Umax, V Urms, B geteld
3 2,08 212
2,5 1,73 176
2 1,38 141
1,5 1,03 106
1 0,684 71
0,5 0,358 36
0,25 0,179 19

Als we de waarden van de derde kolom delen door de waarden van de tweede, krijgen we een gemiddelde van 102. Dit wordt onze "kalibratie" -factor. Wel zie je dat de nauwkeurigheid sterk daalt bij afnemende spanning. Dit komt door de lage gevoeligheid van onze ADC. In feite zijn 10 cijfers voor nauwkeurige berekeningen catastrofaal klein en als de spanning in het stopcontact op deze manier kan worden gemeten, zal het werken, dan is het plaatsen van een 10-bit ADC om de stroom die door de belasting wordt verbruikt te meten een misdaad tegen de metrologie .

We zullen op dit punt onderbreken. In het volgende deel gaan we in op de andere drie vragen van deze serie en gaan we soepel verder met het maken van het apparaat zelf.

De gepresenteerde firmware, evenals andere firmware voor deze serie (aangezien ik video's sneller maak dan het voorbereiden van artikelen), is te vinden in de repository op GitHub.

Als je je erg zorgen maakt over het verbruik van elektrische energie en je wilt echt de boosdoener achterhalen, dan is dit jouw dag. We zullen een stroomsensor samenstellen en een eenvoudige logica schrijven om de invoerwaarden te verwerken om de waarden om te zetten in kilowatt / h.

Voor de montage heb ik een Arduino nano-bord gebruikt (niemand stoort je om dezelfde code te gebruiken voor ESP- of STM-kaarten), LCD-schermafscherming, 56 Ohm-weerstand, 100 kOhm-weerstanden, 10 mKf-condensator, CT-stroomsensor - Talema AC103 (met nominale meting 30A en maximaal 75A).

Wat is een stroomsensor?


De stroomsensor is een magnetisch circuit met een opening en een compensatiewikkeling, evenals een ingebouwde Hall-sensor en een besturingskaart. De Hall-sensor bevindt zich in de opening van het magnetische circuit en reageert op het magnetische veld dat door de spoel wordt gegenereerd. Hoe sterker het magnetische veld, hoe sterker de Hall-effectsensor een signaal genereert, dat door de besturingskaart wordt versterkt.
Stroomsensoren worden gebruikt om wisselstroom en gelijkstroom te meten. De onze - CT-Talema AC103 - voor AC.

Laten we ons apparaat volgens het diagram samenstellen:


Het LCD-scherm heeft al pinnen voor het aansluiten van onze analoge poorten om het signaal te meten - en dat is handig.
Er moet een enkelfasige invoerkabel door de stroomsensor worden gevoerd. vaak komt niet alle spanning naar de nuldraad - sommige kunnen door de grond gaan.


Vergeet niet dat we de belastingsweerstand R3 moeten kalibreren. De formule voor het berekenen van R = V / I - R = 2,5 / 0,042 = 59,5 Ohm waarbij 2,5 de referentiespanning op het bord is en 42 mA het verbruik van het bord. Daarom nemen we de dichtstbijzijnde weerstand bij nominale waarde - 56 ohm.
Om de hoofdvoedingsspanning te verdelen over de referentie 5/2, moet u twee identieke weerstanden R1 en R2 leveren.

Het enige dat overblijft is om de voorbeeldcode naar de Arduino te uploaden:

// Michael Klements // The DIY Life // 27 oktober 2014 #include int huidigePin = 1; // Wijs CT-invoer toe aan pin 1 dubbele kilo = 0; int piekvermogen = 0; LiquidCrystal-lcd (8, 9, 4, 5, 6, 7); // Wijs LCD-schermpinnen toe, volgens de vereisten van het LCD-schild void setup () (lcd.begin (16,2); // kolommen, rijen.use 16,2 voor een 16x2 LCD, enz. lcd.clear (); lcd .setCursor (0,0); // zet cursor op kolom 0, rij 0 (de eerste rij) lcd.print ("Running");) void loop () (int current = 0; int maxCurrent = 0; int minCurrent = 1000; voor (int i = 0; i<=200 ; i++) //Monitors and logs the current input for 200 cycles to determine max and min current { current = analogRead(currentPin); //Reads current input and records maximum and minimum current if(current >= maxCurrent) maxCurrent = stroom; anders als (huidige<= minCurrent) minCurrent = current; } if (maxCurrent <= 517) { maxCurrent = 516; } double RMSCurrent = ((maxCurrent - 516)*0.707)/11.8337; //Calculates RMS current based on maximum value int RMSPower = 220*RMSCurrent; //Calculates RMS Power Assuming Voltage 220VAC, change to 110VAC accordingly if (RMSPower >peakPower) (peakPower = RMSPower;) kilo = kilo + (RMSPower * (2.05 / 60/60/1000)); // Bereken gebruikte kilowattuur vertraging (2000); lcd.wissen (); lcd.setCursor (0,0); // Toont alle huidige gegevens lcd.print (RMSCurrent); lcd.print ("A"); lcd.setCursor (10,0); lcd.print (RMSPower); lcd.print ("W"); lcd.setCursor (0,1); lcd.print (kilo); lcd.print ("kWh"); lcd.setCursor (10,1); lcd.print (piekvermogen); lcd.print ("W"); )

De laatste hand aan onze setup is kalibratie. Dit kan het beste worden gedaan met een bekende vermogensreferentiebelasting ingeschakeld. Krachtige gloeilampen zijn hier zeer geschikt voor. Laten we een lamp van 100 watt nemen. We zetten het tarief aan en berekenen de correctiefactor:
Dubbele RMSCurrent = ((maxCurrent - 516) * 0.707) / 11.8337 waarbij 11.8337 de aangepaste coëfficiënt is om afwijkingen in metingen te compenseren.

Analoge ingangen van het Arduino-bord.

Het Arduino UNO-bord bevat 6 analoge ingangen voor het meten van de signaalspanning. Het zou juister zijn om te zeggen dat 6 pinnen van het bord kunnen werken in de modus van zowel discrete pinnen als analoge ingangen.

Deze pinnen zijn genummerd van 14 tot en met 19. Ze zijn aanvankelijk geconfigureerd als analoge ingangen en zijn toegankelijk met de namen A0-A5. Ze kunnen op elk moment worden geconfigureerd voor discrete output-modus.

pinMode (A3, UITGANG); // discrete uitvoermodus instellen voor A3
digitalWrite (A3, LAAG); // lage status instellen op uitgang A3

Om terug te keren naar de analoge ingangsmodus:

pinMode (A3, INGANG); // de analoge ingangsmodus instellen voor A3

Analoge ingangen en pull-up weerstanden.

Optrekweerstanden zijn aangesloten op de pinnen van de analoge ingangen, evenals op de discrete pinnen. Het opnemen van deze weerstanden wordt uitgevoerd door het commando

digitalWrite (A3, HOOG); // activeer pull-up weerstand naar A3

De opdracht moet worden toegepast op de uitgang die is geconfigureerd in de invoermodus.

Houd er rekening mee dat de weerstand het niveau van het analoge ingangssignaal kan beïnvloeden. De stroom van de 5V-voeding door de pull-up-weerstand veroorzaakt een spanningsval over de interne weerstand van de signaalbron. Het is dus beter om de weerstand los te koppelen.

Analoog-naar-digitaal omzetter van het Arduino-bord.

De daadwerkelijke meting van de spanning op de ingangen wordt uitgevoerd door een analoog-naar-digitaal omzetter (ADC) met een 6-kanaals schakelaar. De ADC heeft een resolutie van 10 bits, wat overeenkomt met de code op de converteruitgang 0 ... 1023. Meetfout is niet meer dan 2 eenheden van het minst significante cijfer.

Om maximale nauwkeurigheid (10 cijfers) te behouden, is het noodzakelijk dat de interne weerstand van de signaalbron niet groter is dan 10 kΩ. Deze vereiste is vooral belangrijk bij het gebruik van weerstandsverdelers die zijn aangesloten op de analoge ingangen van het bord. De weerstand van de delerweerstanden mag niet te hoog zijn.

Analoge input software functies.

int analoog lezen (poort)

Leest de spanningswaarde op de gespecificeerde analoge ingang. Een ingangsspanning variërend van 0 tot het referentiespanningsniveau (vaak 5 V) wordt omgezet in een code van 0 tot 1023.

Bij een 5 V referentie is de resolutie 5 V / 1024 = 4,88 mV.

De conversietijd is ongeveer 100 µs.

int invoercode; // ingangsspanningscode:
vlotter ingangsspanning; // ingangsspanning in V

inputCod = analoog lezen (A3); // uitleesspanning op ingang A3
inputVoltage = ((float) inputCod * 5. / 1024.); // herberekening van de code in spanning (V)

ongeldig analoogReferentie (type)

Stelt de referentiespanning in voor de ADC. Het definieert de maximale waarde van de analoge ingangsspanning die de ADC correct kan omzetten. De waarde van de referentiespanning bepaalt ook de conversiefactor van de code in spanning:

Ingangsspanning = ADC-code * referentiespanning / 1024.

Het argument type kan de volgende waarden aannemen:

  • STANDAARD - de referentiespanning is gelijk aan de voedingsspanning van de controller (5 V of 3,3 V). Voor Arduino UNO R3 - 5 V.
  • INTERN is een interne 1,1 V-referentie voor kaarten met ATmega168- en ATmega328-controllers, voor ATmega8 - 2,56 V.
  • INTERNAL1V1 is de interne 1.1V-referentie voor de Arduino Mega-controllers.
  • INTERNAL2V56 - Interne 2,56V referentie voor Arduino Mega controllers.
  • EXTERN - externe spanningsreferentie, aangesloten op de AREF-ingang.

analogeReferentie (INTERN); // de referentiespanning is 1,1 V

Tweekanaals voltmeter op Arduino.

Laten we als voorbeeld van het gebruik van de analoge ingangsfuncties een project maken voor een eenvoudige digitale voltmeter op Arduino. Het apparaat moet spanningen meten op twee analoge ingangen van het bord, en de gemeten waarden via een seriële poort naar een computer sturen. Aan de hand van dit project als voorbeeld zal ik de principes laten zien van het creëren van eenvoudige systemen voor het meten en verzamelen van informatie.

Laten we besluiten dat de voltmeter de spanning in het bereik van minimaal 0 ... 20 V moet meten en een circuit ontwikkelen om de voltmeter-ingangen aan te sluiten op het Arduino UNO-bord.

Als we de referentiespanning gelijk stellen aan 5 V, dan meten de analoge ingangen van het bord de spanning in het bereik van 0 ... 5 V. En we hebben minimaal 0 ... 20 V nodig. Dus we moeten gebruiken een spanningsdeler.

De spanning aan de ingang en uitgang van de verdeler is gerelateerd aan de verhouding:

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

Overdrachtsverhouding:

K = Uuit / Uinput = R2 / (R1 + R2)

We hebben een versterking nodig van 1/4 (20V * 1/4 = 5V).

Om maximale nauwkeurigheid (10 cijfers) te behouden, is het noodzakelijk dat de interne weerstand van de signaalbron niet hoger is dan 10 kΩ. Daarom kiezen we de weerstand R2 gelijk aan 4,22 kOhm. We berekenen de weerstand van de weerstand R1.

0,25 = 4,22 / (R1 + 4,22)
R1 = 4,22 / 0,25 - 4,22 = 12,66 kΩ

Ik vond weerstanden van 15 kOhm met de dichtstbijzijnde waarde. Met weerstanden R1 = 15 kΩ en R2 = 4,22:

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

Het voltmetercircuit op basis van Arduino ziet er als volgt uit.

Op de analoge ingangen A0 en A1 zijn twee spanningsdelers aangesloten. Condensatoren C1 en C2 vormen samen met de delerweerstanden laagdoorlaatfilters die hoogfrequente ruis uit de signalen verwijderen.

Ik heb dit circuit op een breadboard gemonteerd.

Ik heb de eerste ingang van de voltmeter aangesloten op een gereguleerde voeding en de tweede op de 3,3 V-voeding van het Arduino-bord. Om de spanning te regelen, heb ik een voltmeter aangesloten op de eerste ingang. Het blijft om het programma te schrijven.

Een programma voor het meten van spanning met behulp van een Arduino-bord.

Het algoritme is eenvoudig. Vereist:

  • lees de ADC-code twee keer per seconde;
  • zet het om in spanning;
  • meetwaarden via een seriële poort naar een computer sturen;
  • het Arduino IDE-poortmonitorprogramma om de verkregen spanningswaarden op het computerscherm weer te geven.

Ik zal in één keer een volledige schets van het programma geven.

// spanning meetprogramma
// op analoge ingangen A0 en A1

#erbij betrekken

meetperiode tijd:
#definieer R1 15. // de weerstand van de weerstand R1
#definieer R2 4.22 // weerstand van weerstand R2


zweven u1, u2; // gemeten spanningen

ongeldige setup () (
Serieel.begin (9600); //

MsTimer2 :: start (); // onderbreking inschakelen
}

lege lus () (

// periode 500 ms
if (timeCount> = MEASURE_PERIOD) (
tijdtelling = 0;

//

// kanaal 2-code lezen en converteren naar spanning
u2 = ((float) analogRead (A1)) * 5. / 1024. / R2 * (R1 + R2);

// seriële gegevensoverdracht
Serieafdruk ("U1 ="); Serieafdruk (u1, 2);
Serieafdruk ("U2 ="); Serieel.println (u2, 2);
}
}

// interruptafhandeling 1ms
ongeldige timerInterupt () (
timeCount ++;
}

Laat me de regel uitleggen waarin de ADC-code wordt omgezet in spanning:

// kanaal 1-code lezen en converteren naar spanning
u1 = ((float) analogRead (A0)) * 5. / 1024. / R2 * (R1 + R2);

  • De ADC-code wordt gelezen: analogRead (A0).
  • Expliciet geconverteerd naar floating point formaat: (float).
  • Omgerekend naar spanning op de analoge ingang: * 5. / 1024. De punt aan het einde van de cijfers geeft aan dat dit een getal met drijvende komma is.
  • Er wordt rekening gehouden met de overdrachtsverhouding van de deler: / R2 * (R1 + R2).

Laten we het programma in het bord laden, de seriële poortmonitor starten.

De twee lopende staven geven de gemeten spanningen weer. Alles werkt.

Meting van de gemiddelde waarde van een signaal.

Laten we het eerste kanaal van onze voltmeter aansluiten op een spanningsbron met een hoge rimpel. We zullen zo'n beeld op de monitor zien.

De spanningswaarden van het eerste kanaal op het beeldscherm schokken en springen de hele tijd. En de aflezingen van de controle voltmeter zijn vrij stabiel. Dit komt omdat de referentie-voltmeter het gemiddelde van het signaal meet, terwijl het Arduino-bord elke 500 ms individuele samples leest. Uiteraard valt het moment van uitlezen van de ADC in verschillende punten van het signaal. En met een hoog niveau van rimpeling is de amplitude op deze punten anders.

Bovendien, als het signaal in afzonderlijke zeldzame monsters wordt gelezen, kan elke impulsruis een significante fout in de meting introduceren.

De oplossing is om een ​​paar frequente monsters te nemen en de gemeten waarde te middelen. Voor deze:

  • in de interrupt-handler lezen we de ADC-code en voegen deze toe aan de vorige voorbeelden;
  • het tellen van de middelingstijd (het aantal middelingsmonsters);
  • bij het bereiken van het gespecificeerde aantal monsters - sla de totale waarde van de ADC-codes op;
  • om de gemiddelde waarde te verkrijgen, wordt de som van de ADC-codes gedeeld door het aantal middelingsmonsters.

Probleem uit het wiskundeboek van groep 8. Hier is een schets van het programma, een tweekanaals gemiddelde voltmeter.

// gemiddelde spanning meetprogramma
// op analoge ingangen A0 en A1

#erbij betrekken

#define MEASURE_PERIOD 500 // meetperiode tijd:
#definieer R1 15. // de weerstand van de weerstand R1
#definieer R2 4.22 // weerstand van weerstand R2

int timeCount; // tijdteller
lange sumU1, sumU2; // variabelen voor het optellen van ADC-codes
lange gemiddeldeU1, gemiddeldeU2; // som van ADC-codes (gemiddelde waarde * 500)
booleaanse vlagGereed; // gereedheidsindicator meetgegevens

ongeldige setup () (
Serieel.begin (9600); // initialiseer de poort, snelheid 9600
MsTimer2 :: set (1, timerInterupt); // timer onderbreekt, periode 1 ms
MsTimer2 :: start (); // onderbreking inschakelen
}

lege lus () (

if (flagReady == waar) (
flagReady = onwaar;
// conversie naar spanning en overdracht naar computer
Serieafdruk ("U1 =");
Serial.print ((float) avarageU1 / 500. * 5. / 1024. / R2 * (R1 + R2), 2);
Serieafdruk ("U2 =");
Serial.println ((float) avarageU2 / 500. * 5. / 1024. / R2 * (R1 + R2), 2);
}
}

// interruptafhandeling 1ms
ongeldige timerInterupt () (

timeCount ++; // +1 gemiddelde steekproefteller
sumU1 + = analoog lezen (A0); // optelling van ADC-codes
sumU2 + = analoog lezen (A1); // optelling van ADC-codes

// controleer het aantal middelingsmonsters
if (timeCount> = MEASURE_PERIOD) (
tijdtelling = 0;
gemiddeldeU1 = somU1; // gemiddelde overbelasting
gemiddeldeU2 = somU2; // gemiddelde overbelasting
somU1 = 0;
somU2 = 0;
flagReady = waar; // teken dat het meetresultaat klaar is
}
}

In de formule voor het herberekenen van de ADC-code in de spanning, werd / 500 toegevoegd - het aantal monsters. Laden, start de poortmonitor (Cntr + Shift + M).

Nu, zelfs met een aanzienlijk niveau van rimpeling, veranderen de metingen met honderdsten. Dit komt alleen omdat de spanning niet gestabiliseerd is.

Het aantal monsters moet worden gekozen rekening houdend met:

  • het aantal monsters bepaalt de meettijd;
  • hoe groter het aantal samples, hoe minder het effect van ruis zal zijn.

De belangrijkste storingsbron in analoge signalen is het 50 Hz-netwerk. Daarom is het raadzaam om de middelingstijd te selecteren die een veelvoud is van 10 ms - de halve cyclustijd van het netwerk met een frequentie van 50 Hz.

Optimalisatie van berekeningen.

Computing met drijvende komma verslindt gewoon de bronnen van een 8-bits microcontroller. Elke drijvende-kommabewerking vereist mantisse-denormalisatie, vaste-puntbewerking, mantisse-normalisatie, ordercorrectie ... En alle bewerkingen met 32-bits getallen. Daarom is het noodzakelijk om het gebruik van drijvende-kommaberekeningen tot een minimum te beperken. Hoe je dit doet, vertel ik je in de volgende lessen, maar laten we in ieder geval onze berekeningen optimaliseren. Het effect zal aanzienlijk zijn.

In ons programma wordt de conversie van de ADC-code naar spanning als volgt geschreven:

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

Hoeveel berekeningen zijn er, en alles is een drijvende komma. Maar de meeste berekeningen zijn bewerkingen met constanten. Een deel van de lijn:

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

(float) gemiddeldeU1 * 0.00004447756

Slimme compilers herkennen zelf berekeningen met constanten en berekenen deze tijdens het compileren. Ik vroeg me af hoe slim de Andruino-compiler is. Ik besloot het te controleren.

Ik heb een kort programma geschreven. Het voert een lus van 10.000 lussen uit en stuurt vervolgens de tijd naar de computer voor die 10.000 lussen. Die. hiermee kunt u de uitvoeringstijd zien van de bewerkingen die zich in de hoofdtekst van de lus bevinden.

// berekening optimalisatie check

intx = 876;
zweven y;
niet-ondertekende int telling;
niet-ondertekend lange tijdCurrent, timePrev;

ongeldige setup () (
Serieel.begin (9600);
}

lege lus () (
tel ++;
// y = (zwevend) x / 500. * 5. / 1024. / 4.22 * (15. + 4.22);
// y = (zwevend) x * 0.00004447756;

als (telling> = 10000) (
aantal = 0;
timeCurrent = millis ();
Serial.println (timeCurrent - timePrev);
timePrev = tijdCurrent;
}
}

In de eerste variant, wanneer de drijvende-kommabewerkingen in de lus worden uitgecommentarieerd en niet uitgevoerd, retourneerde het programma het resultaat van 34 ms.

Die. 10.000 inactieve cycli worden voltooid in 34 ms.

Toen opende ik de regel:

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

herhaalt onze berekeningen. Resultaat van 10.000 passages in 922 ms of

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

Die. deze lijn van drijvende-kommaberekening duurt 89 µs. Ik dacht dat er meer zou zijn.

Nu sloot ik deze regel met een opmerking en opende de volgende, vermenigvuldigd met een vooraf berekende constante:

y = (zwevend) x * 0.00004447756;

Resultaat van 10.000 passages in 166 ms of

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

Verbazingwekkend resultaat. We hebben 75,6 microseconden per regel bespaard. We voltooiden het bijna 7 keer sneller. We hebben 2 van dergelijke lijnen, maar er kunnen er veel meer in het programma staan.

Conclusie - berekeningen met constanten moeten zelf op de rekenmachine worden gedaan en in programma's worden toegepast als kant-en-klare coëfficiënten. De Arduino-compiler berekent ze niet in de compilatiefase. In ons geval moet u dit doen:

#define ADC_U_COEFF 0.00004447756 // ADC-code naar spanning conversiefactor

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

De optimale optie in termen van snelheid is om de ADC-code naar de computer over te dragen, en daarmee alle berekeningen met drijvende komma. In dit geval moet een gespecialiseerd programma gegevens op de computer ontvangen. De poortmonitor van de Arduino IDE zal niet werken.

Ik zal het hebben over andere manieren om Arduino-programma's te optimaliseren in toekomstige lessen, indien nodig. Maar zonder dit probleem op te lossen, is het onmogelijk om complexe programma's op een 8-bits microcontroller te ontwikkelen.

Er is weer een les op de site verschenen (