PWM: Forskelle mellem versioner

Fra HTX Arduino
Spring til navigation Spring til søgning
Linje 47: Linje 47:


==Anvendelse af PWM signalet==
==Anvendelse af PWM signalet==
Man kan anvende sit PWM signal til mange formål; alt fra at dæmpe lyset i en lysdiode til at justere rotationshastigheden for en DC motors aksel. Da PWM signalet reelt er et digital signal der skifter mellem 0 V og 5 V skal man overveje om dette firkantsignal uden videre kan anvendes til det ønskede formål; Er det en lysdiode der skal dæmpes ned, er det måske OK at den står og flimrer lidt, hvor imod det kan give problemer hvis PWM signalet skal anvendes som en konstant, præcis spænding i et målekredsløb. Gælder sidstnævnte, kan man tilføje en analog filtrering mellem PWM signalet og målekredsløbet (se afsnittet [[#Analog filtrering]]).
Man kan anvende sit PWM signal til mange formål; alt fra at dæmpe lyset i en lysdiode til at justere rotationshastigheden for en DC motors aksel. Da PWM signalet reelt er et digital signal der skifter mellem 0 V og 5 V skal man overveje om dette firkantsignal uden videre kan anvendes til det ønskede formål; Er det en lysdiode der skal dæmpes ned, er det måske OK at den står og flimrer lidt, hvor imod det kan give problemer hvis PWM signalet skal anvendes som en konstant, præcis spænding i et målekredsløb. Gælder sidstnævnte, kan man tilføje en analog filtrering mellem PWM signalet og målekredsløbet (se afsnittet [[#Analog filtrering|Analog filtrering]]).


Anvender man PWM signalet til en elmotor, så vil motorens inertimoment ved rotation fungere som filter, der glatter firkantsignalet ud. Inertimomentet kan beskrives som <i>trægheden</i> eller <i>modviljen</i> til at ændre på rotationsbevægelsen og afhænger bl.a. af massen af det der roterer (jo større masse, desto større inertimoment, og dermed større modvilje til at ændre rotationsbevægelsen).
Anvender man PWM signalet til en elmotor, så vil motorens inertimoment ved rotation fungere som filter, der glatter firkantsignalet ud. Inertimomentet kan beskrives som <i>trægheden</i> eller <i>modviljen</i> til at ændre på rotationsbevægelsen og afhænger bl.a. af massen af det der roterer (jo større masse, desto større inertimoment, og dermed større modvilje til at ændre rotationsbevægelsen).

Versionen fra 25. nov. 2022, 14:08

Puls Bredde Modulation (eller Puls Width Modulation - deraf PWM) er en måde at lave et signal der kan give en analog værdi ved hjælp af et digitalt output.

Motivation

Hvis man tilslutter en 12 V DC motor til en strømforsyning, og langsomt skruer op for spændingen, kan man se, at DC motorens rotationshastighed afhænger af hvor høj spændingen er. Når spændingen er 0 V roterer motorens aksel ikke, og når spændingen når 12 V, roterer DC motorens aksel med maksimal hastighed. Det ses dermed, at man kan regulere DC motorens rotationshastighed ud fra den analoge spænding den forsynes med.

Hvis man ønsker at regulere DC motoren fra mikroprocessoren, har man behov for at lave en variabel spænding. Da mikroprocessorens output arbejder digitalt, og vi har behov for en analog spænding vi kan variere, vil vi gøre brug af metoden der hedder pulse width modulation (dvs. puls bredde modulation eller bare PWM). PWM laver en variabel spænding ud fra digitale pulser.

Hvis man sætter et outputben på mikroprocessoren høj, vil man på benet kunne måle en spænding på 5 V. Figuren herunder viser hvordan dette ser ud målt over tid.


Outputben på mikroprocessor er høj hele tiden, så der måles konstant 5 V.
Outputben på mikroprocessor er høj hele tiden, så der måles konstant 5 V.


Hvis man i stedet sætter outputbenet lavt, vil man kunne måle en spænding på 0 V. Dette er vist herunder målt over tid.


Outputben på mikroprocessor er lav hele tiden, så der måles konstant 0 V.
Outputben på mikroprocessor er lav hele tiden, så der måles konstant 0 V.


Hvis man skifter mellem høj og lav, og gør det f.eks. med en frekvens på 500 Hz (dvs. 500 perioder pr. sekund), og lader benet være højt 1 msek, og derefter lavt i 1 msek, så vil man kunne måle en spænding på 2,5 V på benet. Dette ses på figuren nedenfor.


Outputben på mikroprocessor skifter konstant mellem høj og lav; samme tid høj som lav, så der måles den halve forsyningsspænding, altså 2,5 V.
Outputben på mikroprocessor skifter konstant mellem høj og lav; samme tid høj som lav, så der måles den halve forsyningsspænding, altså 2,5 V.


Er det i stedet for 0,5 msek benet er højt, og 1,5 msek benet er lavt (dvs. højt af tiden, og lavt af tiden), så bliver middelspændingen af de 5 V = 1,25 V. Dette ses på figuren herunder.


Outputben på mikroprocessor skifter mellem høj og lav; '"`UNIQ--postMath-00000004-QINU`"' af tiden er høj og '"`UNIQ--postMath-00000005-QINU`"' af tiden lav. Dermed måles '"`UNIQ--postMath-00000006-QINU`"' af forsyningsspænding, altså 1,25 V.
Outputben på mikroprocessor skifter mellem høj og lav; af tiden er høj og af tiden lav. Dermed måles af forsyningsspænding, altså 1,25 V.


Man kan altså bestemme middelspændingen på outputputtet ved at justere hvor lang tid benet henholdsvis er højt og lavt. For at man ikke oplever at spændingen ”hopper” op og ned, skal skiftene ske hurtigt. Hvis det for eksempel sker med en frekvens på 500 Hz (dvs. at en periode varer 2 msek), så opleves spændingen som værende konstant.

Princippet - Er det OK dækket i ovenstående afsnit?

Måden man gør det på er ved at sende et signal ud med en fast frekvens, hvor man så lader signalet være højt i en vis procentdel af tiden og lav i resten af tiden.

Herunder er der illustreret 4 forskellige signaler på et PWM-output. Signalet kan helt i yderområderne være lavet hele tiden (0%) og højt hele tiden (100%).

4 PWM signaler med forskellig værdi, fra 5% til 90%
4 PWM signaler med forskellig værdi, fra 5% til 90%

På den måde kan man bestemme hvilken gennemsnits-spænding der kommer ud.

Anvendelse af PWM signalet

Man kan anvende sit PWM signal til mange formål; alt fra at dæmpe lyset i en lysdiode til at justere rotationshastigheden for en DC motors aksel. Da PWM signalet reelt er et digital signal der skifter mellem 0 V og 5 V skal man overveje om dette firkantsignal uden videre kan anvendes til det ønskede formål; Er det en lysdiode der skal dæmpes ned, er det måske OK at den står og flimrer lidt, hvor imod det kan give problemer hvis PWM signalet skal anvendes som en konstant, præcis spænding i et målekredsløb. Gælder sidstnævnte, kan man tilføje en analog filtrering mellem PWM signalet og målekredsløbet (se afsnittet Analog filtrering).

Anvender man PWM signalet til en elmotor, så vil motorens inertimoment ved rotation fungere som filter, der glatter firkantsignalet ud. Inertimomentet kan beskrives som trægheden eller modviljen til at ændre på rotationsbevægelsen og afhænger bl.a. af massen af det der roterer (jo større masse, desto større inertimoment, og dermed større modvilje til at ændre rotationsbevægelsen).


Analog filtrering

For at signalet skal blive en fornuftig DC-spænding, så laves en analog filtrering af signalet med er RC-led som vist her:

PWM-diagram.PNG

PWM på Arduino

Et Arduino Uno board har seks porte der kan sættes op til at lave PWM; Det er portben 3, 5, 6, 9, 10 og 11, der er angivet med ~ på boardet.


Arduino UNO Rev. 3 Analoge udgange i de Digitale I/O
Arduino UNO rev. 3 Analoge PWM udgange

Programkoden der skal til for at anvende PWM på et af de ~-mærkede outputben er at skrive:

  analogWrite(analogOutPin, outputValue);

analogOutPin skal sættes til portbensnummeret. Benet skal være sat op til output.

outputValue skal være af typen byte, så værdien ligger fra 0 til 255.


Programeksempel med konstant 2,5 V

Ønsker man en konstant spænding på 2,5 V fra en af PWM portbenene, kan man skrive som følger. I eksemplet anvendes portben 3.

  const int pwmPin = 3;

  void setup()
  {
     pinMode(pwmPin, OUTPUT); 
     analogWrite(pwmPin, 127);   
  }

  void loop()
  {

  }

Da 2,5 V er den halve spænding af Arduinoboardets 5 V spænding, sættes outputValue værdien til den halve værdi af maksimum, hvilket er 127.


Programeksempel med variabel spænding

Hvis man ønsker at justere outputspændingen ud fra positionen på et potentiometer, kan man koble potentiometrets midterste ben til et analog input på Arduinoboardet, og de to andre ben til henholdsvis +5 V og GND; Dermed kan inputspændingen læses, og bruges til at justere outputspændingen på det ønskede portben.

Bemærk, at Arduino Uno har en 10 bit ADC (link til ADC), og dermed arbejder med heltalsværdier mellem 0 og 1023, mens PWM på Arduino Uno er i 8 bit, og dermed heltalsværdier mellem 0 og 255. Det betyder, at når man læser et heltal der kan ligge mellem 0 og 1023, skal det konverteres ned i talrummet af heltal mellem 0 og 255. Til dette anvendes funktionen

  map(value, fromLow, fromHigh, toLow, toHigh)

hvor value er værdien der skal konverteres (her værdien læst fra potentiometret) fromLow er den mindste værdi value kan antage (her 0) fromHigh er den højeste værdi value kan antage (her 1023) toLow er den laveste værdi der skal konverteres til (her 0) toHigh er den højeste værdi der skal konverteres til (her 255)

I eksemplet her anvendes portben 3 til PWM output, mens det analoge signal fra potentiometret læses fra analog port A0.

  const int pwmPin = 3;
  const int aInput = A0;

  int analogInputValue;
  int pwmValue;

  void setup()
 {
    pinMode(pwmPin, OUTPUT); 
    pinMode(aInput, INPUT);   
 }

 void loop()
 {
    analogInputValue = analogRead(aInput);
    pwmValue = map(analogInputValue, 0, 1023, 0, 255);
    analogWrite(pwmPin, pwmValue);
 }

Strømtræk fra en PWM port på Arduinoboardet

Da et Arduinoboard i følge specifikationerne[1] maksimalt kan levere 20 mA fra en output port, kan man være nød til at anvende en transistor mellem portbenet på Arduinoboardet og den komponent der skal drives. Det kan f.eks. være en MOSFET transistor

PWM på PIC

Eksempel på output

Hvis man stiller CCPR1L / outputValue til 64, så kan man måle det viste:

Osc-pwm-25.png

Den nederste kurveform er et 5V output målt på P1A, hvor det er højt i ca. 0.26 ms ud af de i alt 1.02 ms som periodetiden er. Det er ca. 25 % af tiden, og som det kan ses på den blå kurve øverst, så ligger den udglattede udgangsspænding på ca. 25 % af de 5V (1.25V), men i praksis er spændingen lidt lavere, som her måles til 1.16V. Det skyldes at Forsyningspændingen ligger lidt under 5V.

Koden til PWM på PIC

Alle PIC-typer kan i princippet lave PWM, men det gøres lettest i en PIC der kan det som indbygget standard.

Til PIC16F684 er der lavet et eksempel på PWM-kode, der skitseres her.

Der vælges at lave output på P1A, der er pin_C5, så denne skal indstilles til output.

Herefter initialiseres CCP1CON registeret til kun lave output på P1A og at det er PWN der skal anvendes. Derefter sættes timer 2 op, så den fungerer - her er valgt 4 gange prescaler. Koden skrives som:

-- Initialisering af PWM
CCP1CON = 0b_0000_1100   -- P1A aktiv høj, resten inaktive
T2CON = 0b_0000_0101

Registeret PR2 sættes til sin maksimale værdi, så der kommer maksimal opløsning på PWM-signalet

PR2 = 255

Tilsammen giver disse to ting at frekvensen på PWM-signalet bliver ca. 1 kHz ved et oscillatorfrekvens på 4 MHz.

Værdien der giver PWM outputtet

Når det ovenstående er indstillet, så kan man blot skrive en værdi til CCPR1L på mellem 0 og 255, hvilket så giver værdien i forhold til de 255.

Der ligger faktisk 2 bit ekstra i opløsning, som skal angives i de 2 lave bit af CCP1CON, så man kan angive totalt set en 10 bit værdi.

PWM til at danne forskellige frekvenser

I stedet for at anvende PWM til at lave en tilnærmet DC-værdi med, så kan man også få PWM-udgangen til at danne en fast frekvens, hvor man så kan indstille duty-cycle til 50%.

Ved at rette på periode-tiden kan man få udgangen til at lave forskellige frekvenser.

En simpel måde at gøre det på er at sætte post- og pre-scaler til faste værdier, og så kun rette på PR2 og CCPR1L, som det er illustreret her ved hjælp af proceduren lyd, der tager periodetiden som parameter. Med denne initialisering kan der dannes frekvenser fra 1 kHz og opad.

-- Initialisering af PWM
CCP1CON = 0b_0000_1100   -- P1A aktiv høj, resten inaktive
PR2 = 255
T2CON = 0b_0000_0101

-- Procedure der sætter en frekvens på PWM
-- 255 giver ca. 1 kHz
-- 128 giver ca. 2 kHz
procedure lyd (byte in periode) is
   PR2 = periode
   CCPR1L = periode / 2
end procedure

Hvis man ønsker at dække et bredere frekvensområde, så skal man indstille både PR2, CCPR1L og T2CON, for at kunne danne frekvenserne præcist nok. Dette er illustreret i følgende kode (ikke testet):

-- Initialisering af PWM
CCP1CON = 0b_0000_1100   -- P1A aktiv høj, resten inaktive

-- Procedure der kan lave frekvenser fra 244 Hz til 20000 Hz ved en oscillatorfrekvens på 4MHz
-- Koden er tilpasser minimum frekvensen efter oscillatorfrekvensen
--   Oscillator    Minimum
--    4_000_000      244
--    8_000_000      488
--   20_000_000     1219
procedure tone(word in frekvens) is
   -- Perioden beregnes som PR2 = F_OSC / (4 * Frekvens * Prescaler) - 1
   -- Det skal bemærkes at post-scaleren ikke regnes med i dannelsen af frekvensen
   var dword periode = target_clock / 2 -- Gem den sidste halvering til afrunding
   if frekvens <= (target_clock / 16416) then     -- Så lave frekvenser understøttes ikke
      return
   elsif frekvens <= (target_clock / 4104) then  -- Frekvenser der håndteres med prescaler 16
      T2Con = 0b0110
      periode = periode / 16
   elsif frekvens <= (target_clock / 1026) then -- Frekvenser der håndteres med prescaler 4
      T2Con = 0b0101
      periode = periode / 4
   else                       -- Ved Prescaler = 1 rettes periodetiden ikke
      T2CON = 0b0100
   end if

   periode = periode / frekvens -- Midlertidig beregning af perioden
   periode = (periode + 1) / 2  -- Division med afrunding i stedet for trunkering
   CCPR1L = byte(periode/2)     -- Lav ca. 50% dutycycle
   periode = periode - 1        -- Den sidste tilpasning efter formlen
   PR2 = byte(periode)
end procedure

Test-koden og et regneark der illustrerer hvordan tonerne beregnes ligger i en ZIP-fil.

Koden tester først om indstillingen kan laves ved den givne oscillatorfrekvens, og hvis den kan det, så indstilles prescaleren, så PR2 får størst mulig værdi, uden at der kommer overflow. Der forberedes også beregningen af periodetiden.

Periodetiden beregnes ud fra frekvensen, og der tilpasses formlen for periodetiden. Endelig laves en afrunding af resultatet, i stedet for en normal truckering som man ellers gør i JAL divisioner. Dutycycle sættes til ca. 50% ved at sætte CCPR1L til halvdelen af PR2.

Ved disse beregninger skulle frekvensen gerne ramme inden for +/- 1% på frekvenser fra 244 Hz til 20000 Hz ved oscillatorfrekvensen på 4 MHz.

Andre PIC-typers PWM

Der er ikke angivet hvordan koden skrives til andre PIC-typer, men princippet er nogenlunde det samme. Først skal man lave indstillingerne der angiver hvilke output der skal lave PWM, og så skal man sætte PIC'en op så der er noget der angiver periodetiden, og noget der angiver hvor stor en del af periodetiden der skal være højt signal.

Analog
Analog Begreber Grundlæggende El-fysik - AC-Spænding - AC-Strøm - DC-Spænding - DC-Strøm - Effekt - Nøjagtighed - Præcision - Spænding - Strøm - Frekvens - Komponent - Relæ
Analog Komponenter Spole - Spole ved AC - Spole ved DC - Spolen - Beregning af induktiv-reaktansen - Spolen - Seriekobling og parallelkobling - Spolen - Tidskonstant for RL-led - Kondensator - Kapacitet - Kondensator ved DC - Modstand - Operationsforstærker - Diode - Zenerdiode - Transistor - MOSFET transistor - Transformator - Adapter - DC-motor - Mikrofon - LED - Photo Interrupter - 7-segment-display
Analog Kredsløb Belastet spændingsdeler - Filter - H-bro - Regulator - RFID - Spændingsdeler - Subtraktionsforstærker - Wheatstones målebro
Operationsforstærker Opamp Kredsløb - Differensforstærker - Inverterende forstærker - Ikke inverterende forstærker - Instrumentationsforstærker - Modkobling - Spændingsfølger - Summationsforstærker - Subtraktionsforstærker
Filtre Aktive filtre - Komplekse tal - Maple - Sammenkobling af filtre - Butterworth - Chebyshev - Band-pass - RC-Led - Spole ved AC
Diverse Aktuator - Analog-bogen - Diagram - Komplekse tal - Konverter - PWM - Radiobølger - Regulerings teknik - Simulering - Strain gauge - Transducer - Mikrofonforstærker


Logik Begreber
Gates AND-gate - OR-gate - NOT-gate - NAND-gate - NOR-gate - XOR-gate - XNOR-gate - Inverter-gate - Schmitt-trigger
Flip-flop RS-flip-flop - D-flip-flop - JK-flip-flop - Latch - Toggle-flip-flop
Sekventiel logik Flip-flop - Multivibrator - Astabil Multivibrator - Monostabil Multivibrator - Digital tæller - Binær counter - BCD-counter - Skifteregister - Bistabil Multivibrator
Logiske grundbegreber Kombinatorisk logik - Binære tal - Hexadecimal - BCD - Talsystemer - Sandhedstabel - Pull-down - Pull-up - 7-segment-display - Binær Adder - Binær comperator - Logisk Dekoder - HEX-fil
Logisk Reduktion Boolesk Algebra - De Morgan - Karnaughkort - Karnaughkort udlæsning - Automatisk reduktion
Hukommelse RAM - ROM - PROM - EPROM - EEPROM
Logik-familier CMOS-logik - TTL-logik
Seriel Kommunikation Arduino Bluetooth - Baud - Handshake - I2C - I2C Adresser - I2C Bus - I2C Generelt - RS-232 - Serial hardware - Serial hw int cts - Serial software - Seriel port - UART
Generelt Digital-bogen - Digitale Input - Konverter - PWM - Schmitt-trigger - Simulering - Pulsplaner