220V nätverksspänningssensor för Arduino. Skapa en Arduino-kontrollerad laddare

Om du är mycket orolig för förbrukningen av elektrisk energi och verkligen vill lista ut den skyldige, är det här din dag. Vi kommer att montera en strömsensor och skriva enkel logik för att bearbeta ingångsvärdena för att omvandla värdena till kilowatt/timme.

För montering använde jag en bräda Arduino nano(ingen hindrar dig från att använda samma kod för ESP- eller STM-kort), LCD-skärm, 56 Ohm motstånd, 100 kOhm motstånd, 10 uF kondensator, CT-strömsensor - Talema AC103 (med ett nominellt mått på 30A och max. av 75A).

Vad är en strömsensor?


Strömgivaren är en magnetisk krets med ett gap och en kompensationslindning, samt en inbyggd Hall-givare och styrkort. Hall-sensorn placeras i gapet i magnetkretsen och reagerar på magnetfältet som skapas av spolen. Ju starkare spänningen magnetiskt fält, ju starkare Hall-sensorn producerar en signal, som förstärks av styrkortet.
Strömsensorer finns tillgängliga för mätning växelström Och likström. Vår - CT-Talema AC103 - för alternerande.

Låt oss montera vår enhet enligt diagrammet:


LCD-skärmen har redan stift för att ansluta våra analoga portar för signalmätning - och det är bekvämt.
Den enda fasingångskabeln måste föras genom strömsensorn pga Ofta når inte all spänning den neutrala ledningen - en del kan gå igenom jordning.


Glöm inte att vi behöver kalibrera belastningsmotståndet R3. Beräkningsformel R = V / I - R = 2,5 / 0,042 = 59,5 Ohm där 2,5 är referensspänningen på kortet, och 42mA är kortets förbrukning. Därför accepterar vi det närmaste motståndet i nominellt värde - 56 Ohm.
För att dela nätspänningen till referensen 5/2 måste du installera två identiska motstånd R1 och R2.

Allt som återstår är att ladda upp exempelkoden till Arduino:

//Michael Klements //The DIY Life //27 oktober 2014 #inkludera int currentPin = 1; //Tilldela CT-ingång till stift 1 dubbelkilo = 0; int peakPower = 0; LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Tilldela LCD-skärmstift, enligt kraven på LCD-skärmen void setup() ( lcd.begin(16,2); // kolumner, rader. använd 16,2 för en 16x2 LCD, etc. lcd.clear(); lcd .setCursor(0,0); // ställ in markören på kolumn 0, rad 0 (den första raden) lcd.print("Kör" ) void loop() ( int ström = 0; int maxström = 0; int minström = 1000 ; för (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 >= maxström) maxström = ström; annat om (aktuell<= 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; ) kilos = kilos + (RMSPower * (2.05/60/60/1000)); //Beräkna använda kilowattimmars fördröjning (2000); lcd.clear(); lcd.setCursor(0,0); // Visar all aktuell data lcd.print(RMSCurrent); lcd.print("A"); lcd.setCursor(10,0); lcd.print(RMSPower); lcd.print("W"); lcd.setCursor(0,1); lcd.print(kilos); lcd.print("kWh"); lcd.setCursor(10,1); lcd.print(peakPower); lcd.print("W"); )

Den sista touchen av vår installation kommer att vara kalibrering. Det är bäst att utföra det med en referensbelastning med känd ström påslagen. Kraftfulla glödlampor är väl lämpade för detta. Låt oss ta en 100 Watt lampa. Vi slår på tavlan och beräknar korrektionsfaktorn:
Dubbel RMSCurrent = ((maxCurrent - 516) * 0,707) /11,8337 där 11,8337 är den valda koefficienten för att kompensera för avvikelser i mätningar.

Ett användbart diagram presenteras för dem som gillar att experimentera med Arduino. Detta är en enkel digital voltmeter som på ett tillförlitligt sätt kan mäta DC-spänning i området 0 - 30V. Arduino-kortet kan som vanligt drivas av ett 9V-batteri.

Som du säkert vet kan Arduinos analoga ingångar användas för att mäta DC-spänning i intervallet 0 - 5V och detta intervall kan ökas,
använder två motstånd som spänningsdelare. Avdelaren kommer att minska den uppmätta spänningen till nivån för Arduinos analoga ingångar. Och sedan kommer programmet att beräkna det verkliga spänningsvärdet.

Den analoga sensorn på Arduino-kortet känner av närvaron av spänning vid den analoga ingången och omvandlar den till digital form för vidare bearbetning av mikrokontrollern. I figuren tillförs spänning till den analoga ingången (A0) genom en enkel spänningsdelare bestående av motstånden R1 (100 kOhm) och R2 (10 kOhm).

Med dessa delarvärden kan Arduino-kortet förses med spänning från 0 till
55V. På ingång A0 har vi den uppmätta spänningen dividerad med 11, dvs 55V / 11=5V. Med andra ord, när vi mäter 55V vid Arduino-ingången har vi ett maximalt tillåtet värde på 5V. I praktiken är det bättre att skriva intervallet "0 - 30V" på denna voltmeter så att den förblir
Säkerhetsmarginal!

Anteckningar

Om displayavläsningarna inte sammanfaller med avläsningarna från en industriell (laboratorie) voltmeter, är det nödvändigt att mäta värdet på motstånden R1 och R2 med ett exakt instrument och infoga dessa värden istället för R1=100000.0 och R2=10000.0 i programkoden. Sedan bör du mäta den verkliga spänningen mellan 5V- och "Jord"-stiften på Arduino-kortet med en laboratorievoltmeter. Resultatet blir ett värde mindre än 5V, till exempel blir det 4,95V. Detta verkliga värde ska infogas i kodraden
vout = (värde * 5,0) / 1024,0 istället för 5,0.
Försök också använda precisionsmotstånd med 1 % tolerans.

Motstånd R1 och R2 ger visst skydd mot ökade inspänningar Kom dock ihåg att alla spänningar över 55V kan skada Arduino-kortet. Dessutom ger denna design inte andra typer av skydd (mot spänningsöverspänningar, polaritetsomkastning eller överspänning).

Program för digital voltmeter

/*
DC voltmeter
En Arduino DVM baserad på spänningsdelarkoncept
T.K.Hareendran
*/
#omfatta
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int analogInput = 0;
float vout = 0,0;
float vin = 0,0;
float R1 = 100000,0; // motstånd på R1 (100K) -se text!
flottör R2 = 10000,0; // motstånd på R2 (10K) – se text!
int värde = 0;
void setup())(
pinMode(analogInput, INPUT);
lcd.begin(16, 2);
lcd.print(“DC VOLTMETER”);
}
void loop()
// läs värdet på analog ingång
värde = analogRead(analogInput);
vout = (värde * 5,0) / 1024,0; // se text
vin = vout/(R2/(Rl+R2));
om (vin<0.09) {
vin=0.0;//påstående för att upphäva oönskad läsning!
}
lcd.setCursor(0, 1);
lcd.print(“INPUT V= “);
lcd.print(vin);
fördröjning(500);
}

Schematiskt diagram av Arduino-voltmeter

Lista över komponenter

Arduino Uno-bräda
100 kOhm motstånd
10 kOhm motstånd
100 ohm motstånd
10kOhm trimmermotstånd
LCD-skärm 16?2 (Hitachi HD44780)

Som du vet kan ATmega drivas från ett brett spektrum av spänningar, så det kan förbli "i drift" även i händelse av en gradvis batteriurladdning, uttryckt i en minskning av spänningen. Denna situation inom robotik är mer än standard, du behöver inte leta långt efter ett exempel: låt oss ta Voyager-projektet. Detta är en robotrymdfarkost som lanseras bortom solsystemet och därför berövad förmåga att mata från solpaneler. Den är utrustad med radioisotop termiska generatorer (kärnbatterier), som vid lanseringen producerade 30V / 470W, men varje år tappar de 0,78% av sin effekt. Följaktligen återstår för närvarande cirka 60% av originalet, och det är nödvändigt att slå på forskningsundersystemen en efter en för att inte överbelasta generatorerna.

I Arduino kan du inte bara koppla Vcc till det analoga stiftet direkt - som standard är AREF ansluten till Vcc och du kommer alltid att få ett maxvärde på 1023, oavsett vilken spänning du använder. Att ansluta till AREF en spänningskälla med en tidigare känd, stabil spänning hjälper, men detta är ett extra element i kretsen.

Du kan också ansluta Vcc till AREF via diod: Spänningsfallet över dioden är känt i förväg, så att beräkna Vcc är inte svårt. Men med en sådan krets genom en diod ström flyter konstant, förkortar batteritiden, vilket inte heller är särskilt bra.

Hur tar man sig ur situationen utan att lägga till nya element i kretsen och utan att minska batteritiden? Det visar sig att det finns en utgång, och den interna 1,1V referensspänningskällan i ATmega kommer att hjälpa oss (i dokumentationen kallas den för en bandgapsreferens), vilket inte beror på Vcc. Detta resulterar i följande formel:

V_BAT=(1.1*1024)/analogRead(14);

där V_BAT är Vcc-spänningen i volt, och analogRead(14) är resultatet av ADC:n som läses direkt från kanal 14.

Arduino tillåter endast avläsningar från kanaler 0-7 (bli inte förvånad om du bara hittar Diecimila eller Duemilanove 0-5 , ta Seeeduino till exempel ;)

För att göra det möjligt att skicka data till andra kanaler, inklusive 14, måste du byta mask i Arduinos kärnbibliotek. För att göra detta, öppna filen hårdvara\cores\arduino\wiring_analog.c och hitta raden där:

ADMUX = (analog_referens

ersätt den med:

ADMUX = (analog_referens

Efter det kan du skriva denna skiss:

uint16_t raw_bandgap = 0; // internt bandgap värde
float volt_battery = 0,0;

tomhet uppstart (){
Serial.begin(57600);
}

tomhet slinga (){
// Läs av batterispänning
analogReference(DEFAULT); // använd Vcc som AREF
// tomgångsavläsning efter byte av AREF (se 23.5.2 i manualen)
raw_bandgap = analogRead(14); // mät det interna bandgapvärdet
volt_battery = (1,1 * 1024) / raw_bandgap; // beräkna Vcc
Seriell .print(volt_battery);
Serial.println("v_bat");
fördröjning(1000);
}

Den som vill veta spänningen på batteriet bör tänka på det med en regulator(typ L7805CV), vi mäter spänning Vout regulator och om tillgänglig ingångsdiod– vi måste ta hänsyn till spänningen som faller över den.

Så här ser de beräknade värdena ut i Seeeduino, vid övergången från 5V till 3,3V:

Min voltmeter visar dock lägre värden. Men ändå fungerar skissen ;)

UPD: Jag hittade exempel där 1.05 används istället för konstanten 1.1. Resultatet är mycket närmare voltmeteravläsningarna, jag letar efter en teoretisk grund som kan förklara detta faktum...

En enkel lösning för säkerhets- och automationssystem!

BM8039D, MP8036, MA3401

Finns tillgängliga

Köp i bulk

Denna modul är designad specifikt för enheter från Master Kit-katalogen BM8039D, MP8036, MA3401, etc. Men det kan framgångsrikt användas med alla hemautomations- och larmsystem.

Enheten har opto-galvanisk isolering, vilket gör det möjligt att ansluta modulen direkt till mikrokontrollerns utgång.

Modulen kommer att vara användbar för användarprojekt baserade på mikrokontroller och Arduino och Raspberry.

Specifikationer

Matningsspänning (V) 220
Antal inbyggda styrreläer (st) 1
Effekttyp variabel
Antal ingångar (st) 1
Antal utgångar (st) 1
Rekommenderad drifttemperatur (°C) -30...+60
Längd (mm) 42
Bredd (mm) 25
Höjd (mm) 17
Vikt, inte mer (g) 20
Omkopplingsspänning (V) 220
Ansluten lasteffekt, max (W) 1
Vikt 38

Egenheter

  • Opto-galvanisk isolering. Isolationsspänning 1500V
  • Möjlighet till direktanslutning till mikrokontrollern.
  • Möjlighet att styra reläspolar med effekt upp till 1 W.
  • Omkopplingsspänning upp till 350V

Funktionsprincip

Om det finns 220V växelspänning vid modulens ingång, sluter reläkontakterna. Tack vare användningen av ett opto-relä kan modulen anslutas direkt till mikrokontrollerns styrledningar.

Enhetsdesign

Modulen är utformad som en inbyggd sensor. Modulen har små mått på 40x25x15 mm. Vid behov kan modulen fungera som en transformatorlös strömkälla, med en driftspänning på 5V/12V och en ström på upp till 80 mA.

Schema

Förbindelse

Leveransens innehåll

  • MP220V-modul - 1 st.
  • Instruktioner - 1 st.

Vad krävs för montering

  • För att ansluta behöver du: tråd, skruvmejsel, sidoskärare.

Förberedelse för användning

  • Vänd multimetern till motståndsmätningsläge. Anslut sonderna till modulens styrledning.
  • Anslut nätsladden med en kontakt till "IN 220V"-uttagen.
  • Anslut kontakten till 220V-nätet.
  • Indikatorn på tavlan ska lysa och multimetern ska visa 0 Ohm.
  • Kontrollen är klar. Njut av din användning

villkor

  • Temperatur -30C till +50C.
  • Relativ luftfuktighet 20-80% utan kondens.

Med några tillägg.

En föga känd egenskap hos Arduino och många andra AVR-chips är förmågan att mäta den interna 1,1 V referensspänningen. Denna funktion kan användas till ökande noggrannhet Arduino-funktioner - analogRead använder sig av standardreferensspänning på 5 V (på plattformar med en matningsspänning på 5 V) eller 3,3 V (på plattformar med en matningsspänning på 3,3 V).Det kan hon också vara används för att mäta Vcc appliceras på chipet, tillhandahållande kontrollmedel batterivolt utan användning dyrbara analoga stift.

Motivering

Det finns åtminstone åtminstone två skäl för att mäta matningsspänning vår Arduino (Vcc). En av dem är vårt batteridrivna projekt om vi vill övervaka batterispänningsnivån. Dessutom, när batterieffekten (Vcc) inte kan vara 5,0 volt (till exempel en 3-cells 1,5 V-strömkälla) och vi vill göra analoga mätningar mer exakta - måste vi använda antingen en intern 1,1 V referensspänning eller en extern referensspänningskälla . Varför?

Det är vanligt att man vid användning av analogRead() antar att regulatorns analoga matningsspänning är 5,0 volt, när det i verkligheten kanske inte alls är fallet (exempelvis är en strömförsörjning från 3 element 1,5 V). Den officiella Arduino-dokumentationen kan till och med leda oss till detta felaktiga antagande. Faktum är att strömmen inte nödvändigtvis är 5,0 volt oavsett strömnivån, denna ström tillförs chipets Vcc. Om vår strömförsörjning inte är stabiliserad eller om vi kör på batteri kan denna spänning variera en hel del. Här är ett kodexempel som illustrerar detta problem:

Dubbel Vcc = 5,0; // inte nödvändigtvis sant int värde = analogRead(0); / läs avläsningarna från A0 dubbel volt = (värde / 1023,0) * Vcc; // endast sant om Vcc = 5,0 volt För att mäta spänningen korrekt krävs en korrekt referensspänning. De flesta AVR-chips ger tre spänningsreferenser:

  • 1,1 V från den interna källan, i dokumentationen passerar den som en bandgap-referens (några av dem är 2,56 V, till exempel ATMega 2560). Valet görs av funktionen analogReference() med parametern INTERNAL: analogReference(INTERNAL) ;
  • extern referensspänningskälla, märkt AREF på arduino. Välj: analogReference(EXTERNAL);
  • Vcc är strömförsörjningen till själva styrenheten. Välj: analogReference(DEFAULT).

I Arduino kan du inte bara koppla Vcc till det analoga stiftet direkt - som standard är AREF ansluten till Vcc och du kommer alltid att få ett maxvärde på 1023, oavsett vilken spänning du använder. Att ansluta till AREF en spänningskälla med en tidigare känd, stabil spänning hjälper, men detta är ett extra element i kretsen.

Du kan också ansluta Vcc till AREF via diod: Spänningsfallet över dioden är känt i förväg, så att beräkna Vcc är inte svårt. Men med en sådan krets genom en diod ström flyter konstant, förkortar batteritiden, vilket inte heller är särskilt bra.

En extern spänningsreferens är den mest exakta, men kräver ytterligare hårdvara. Intern ION är stabil men inte exakt +/- 10 % avvikelse. Vcc är helt opålitligt i de flesta fall. Att välja en intern spänningsreferens är billigt och stabilt, men för det mesta skulle vi vilja mäta mer spänning än 1,1V, så att använda Vcc är det mest praktiska, men potentiellt minst exakt. I vissa fall kan det vara väldigt opålitligt!

Hur man gör det

Många AVR-chips inklusive ATmega- och ATtiny-serierna tillhandahåller ett sätt att mäta intern referensspänning. Varför är detta nödvändigt? Anledningen är enkel - genom att mäta den interna spänningen kan vi bestämma värdet på Vcc. Här är hur:

  1. Ställ in standardspänningsreferens: analogReference(DEFAULT); . Vi använder Vcc som källa.
  2. Ta ADC-avläsningar för den interna 1,1 V-källan.
  3. Beräkna Vcc-värdet baserat på 1,1 V-mätningen med hjälp av formeln:

Vcc * (ADC-avläsning) / 1023 = 1,1 V

Vad som följer:

Vcc = 1,1 V * 1023 / (ADC-avläsning)

Vi sätter ihop allt och vi får koden:

long readVcc() ( // Läs 1.1V-referens mot AVcc // ställ in referensen till Vcc och mätningen till den interna 1.1V-referensen #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADVMUX (REFS0) |. _BV(MUX1) | #elif definierad(__AVR_ATtiny44__) (__AVR_ATtiny45__) | annars ADMUX = _BV(MUX2) |_BV(MUX1); ); ADCL; // måste läsa ADCL först - det låser sedan ADCH uint8_t high = ADCH;<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts }

Användande

Kontrollera Vcc eller batterispänning

Du kan anropa denna funktion readVcc() om du vill övervaka Vcc. Ett exempel skulle vara att kontrollera batteriladdningsnivån. Du kan också använda den för att avgöra om du är ansluten till en strömkälla eller körs på batteri.

Vcc-mätning för referensspänning

Du kan också använda den för att få rätt Vcc-värde för användning med analogRead() när du använder referensspänningen (Vcc). Om du inte använder en reglerad strömkälla kan du inte vara säker på att Vcc = 5,0 volt. Denna funktion låter dig få rätt värde. Det finns dock en varning...

I en av artiklarna gjorde jag ett uttalande att denna funktion kunde användas för att förbättra noggrannheten i analoga mätningar i de fall där Vcc inte var riktigt 5,0 volt. Tyvärr kommer denna procedur inte att ge ett korrekt resultat. Varför? Detta beror på noggrannheten hos den interna spänningsreferensen. Specifikationen ger en nominell spänning på 1,1 volt, men säger att den kan variera med upp till 10 %. Sådana mätningar kan vara mindre exakta än vår Arduino-strömförsörjning!

Ökar noggrannheten

Medan de stora toleranserna för den interna 1,1V-strömförsörjningen avsevärt begränsar mätnoggrannheten när den används i massproduktion, kan vi uppnå större noggrannhet för anpassade projekt. Detta är lätt att göra genom att helt enkelt mäta Vcc med en voltmeter och vår readVcc() funktion. Byt sedan ut konstanten 1125300L med en ny variabel:

skala_konstant = intern1.1Ref * 1023 * 1000

intern1.1Ref = 1,1 * Vcc1 (voltmetersavläsning) / Vcc2 (läsVcc() funktionsavläsning)

Detta kalibrerade värde kommer att vara en bra indikator för AVR-chipmätningar, men kan påverkas av temperaturförändringar. Experimentera gärna med dina egna mått.

Slutsats

Det finns mycket du kan göra med denna lilla funktion. Du kan använda en stabil referensspänning nära 5.0V utan att egentligen ha 5.0V på Vcc. Du kan mäta din batterispänning eller till och med se om du använder batteri eller stationär ström.

Slutligen kommer koden att stödja alla Arduinos, inklusive den nya Leonardo, såväl som ATtinyX4- och ATtinyX5-serierna.