DAC

Met PWM is een "tweede keus" Digital to Analogue Converter (= digitaal naar analoog omzetter) kortweg DAC genaamd, te maken.
Het is een heel simpele DAC.
Wanneer een uitgang hoog is, is deze ongeveer 5V en als hij laag is dan 0V.
Stel dat je een PWM met 50% duty op de uitgang zet dan is de poort voor de helft van de tijd hoog en voor de helft laag en is de gemiddelde spanning 2,5V (50% van 5V).


Passieve DAC.
 

Om een mooiere analoge spanning van de PWM pulsjes te maken moeten we de pulsjes er uit filteren en de gemiddelde spanning opslaan in een condensator.
De condensator bevat de ingestelde spanning direct nadat de PWM instructie is uitgevoerd.
Hoe lang de spanning op het ingestelde niveau blijft, hangt onder andere af van de stroom dat het circuit opneemt dat er op wordt aangesloten.
Om de spanning constant te houden moet het programma daarom regelmatig de PWM instructie op die poort uitvoeren om de condensatorlading weer op niveau te brengen.
PWM laadt de condensator op, de belasting, zoals een transistor of multimeter, ontlaadt deze weer.

Zoals het tijd kost om een condensator te ontladen, zo kost het ook tijd om de condensator op te laden.
Door het opgeven van een aantal cycles in de PWM instructie kun je de condensator geheel opladen.
Een kleine condensator is snel (met een paar cycles) naar de gewenste spanning te brengen, maar moet dan wel regelmatig worden ververst.
Een wat grotere condensator heeft meer cycles nodig om te worden opgeladen tot het gewenste niveau, maar hoeft dan minder vaak te worden bijgeladen.
Een kleine condensator heeft aan 5 cycles genoeg, meer pulsjes geven heeft dan ook geen nut, voller dan vol wordt de condensator toch niet.
Door een voltmeter te plaatsen op de uitgang van de DAC kun je door experimenteren bepalen wanneer de condensator niet meer bij laadt en zo het aantal cycles voor de PWM instructie bepalen.

Meteen nadat de PWM instructie klaar is met pulsjes genereren, wordt de opgegeven poort omgeschakeld als ingang (= hoogohmig).
Dit wordt niet voor niets gedaan.
Als namelijk de poort een uitgang met constant hoog of laag niveau zou blijven, dan zou de ingestelde gemiddelde spanning in de condensator hierdoor meteen weer teniet worden gedaan.


Regelbare spanning 0 ... 5V


Regelbare spanning met een passieve DAC.
 

Sluit een voltmeter (= spanningsmeter) aan op de analoge uitgang van bovenstaand schema en voer onderstaand programma uit:

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

WHILE 1 = 1                   ;Oneindige lus
  PWM PORTA.6, 127, 20        ;20 PWM pulsjes met 127/255 duty naar PORTA.6 
  DELAYMS 5000                ;5 seconden wachten, de spanning zal zakken
WEND

De instructie PWM stuurt hier 20 cycles (= pulsjes) met een duty van 127 (= 50%) naar PORTA.6.
Door die 20 pulsjes wordt de condensator opgeladen.
Omdat de duty 50% is zal ook de gemiddelde spanning op 50% van 5V zijn, dus ongeveer 2,5V.
Nadat de PWM instructie de 20 pulsjes heeft gegeven, is de volgende opdracht 5 seconden wachten.
In die tijd is PORTA.6 een ingang (hoogohmig) en komen er dus geen pulsjes uit deze poort.
De voltmeter geeft de spanning van 2,5V aan en zal dan langzaam verminderen, omdat de condensator zich via de voltmeter ontlaadt.
Nadat de DELAYMS tijd voorbij is wordt de condensator door PWM weer opgeladen, het programma loopt immers in een lus.
Meteen zie je de spanning weer op niveau komen.
Het is dus van belang dat je de condensator regelmatig met PWM pulsjes ververst om de spanning op niveau te houden.
Hoe meer stroom er van de condensator wordt onttrokken en hoe stabieler je de spanning wilt hebben, hoe vaker dit moet gebeuren.
De 5 seconden in dit voorbeeld zijn dus duidelijk te lang voor een stabiele spanning.

Met de formule (Duty ÷ 255) × Voedingsspanning kan de uitgangsspanning worden berekend.
Duty is hier op 127 gezet en de voedingsspanning is 5V, in de formule is dat (127 ÷ 255) × 5, de uitgangsspanning zal dus ongeveer 2,5V zijn.


Met onderstaand programma is de spanning te regelen met de 25k potmeter die op PORTA.1 is aangesloten.
Vergeet niet in serie met de potmeter de 100n condensator te plaatsen.
Het PWM signaal komt weer op uitgang PORTA.6.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Poortnamen
SYMBOL Potmeter     = PORTA.1 ;Hierop zit de potmeter om de spanning in te stellen
SYMBOL PWM_Signaal  = PORTA.6 ;Het PWM signaal wordt op deze poort gezet

;Variabele declareren
DIM Spanning        AS BYTE   ;Deze variabele bevat de instelling van de potmeter

CLEAR                         ;Wis alle RAM geheugen


;Hoofdprogramma
WHILE 1 = 1                     ;Oneindige lus
  Spanning = POT Potmeter, 140  ;Geef potmeterwaarde aan variabele 'Spanning'
  PWM PWM_Signaal, Spanning, 20 ;20 PWM pulsen van grootte 'Spanning' naar PORTA.6 
WEND

Schaal van de functie POT is hier gezet op 140, eventueel aanpassen.

Met dit programma is de analoge spanning in te stellen van 0 ... 5V met de potmeter.
Om iets nuttigs met deze analoge spanning te kunnen doen moet deze nog wel worden versterkt.
Wil je het met een transistor doen, neem dan een darlington, zoals de BC517, deze nemen weinig stroom op.
Een voorbeeld project met de BC517 en PWM is de draadloze lichtdimmer van deze site, daar staat ook een schema.

In het volgende schema is hiervoor gebruik gemaakt van een opamp met transistor.


Spanning 0 ... 10V
Met onderstaand schema en programma is een simpele, regelbare voeding gemaakt met behulp van de opamp LM358.
De spanning stel je in met de Up/Down toetsen en is af te lezen op het aangesloten HD44780 display.
Met de ene toets verhoog je dus de spanning, met de andere toets verlaag je de spanning.
De spanning is in het programma begrensd op 10,0V.
Deze spanning wordt vaak gebruikt voor aansturing van bijvoorbeeld een frequentieregelaar, waarmee grote motoren kunnen worden aangestuurd.
Het bubbelbad bij mij thuis maakt gebruik van zo'n (kleine) frequentieregelaar, waardoor ik de motor traploos in snelheid kan regelen en daarmee de kracht van de hydrojets.


Maximale belasting is afhankelijk van de transistor, de BC337 kan maximaal 500mA hebben.
 

Voor de voeding van de LM358 en de transistor is minstens 12V nodig.
Met de potmeter wordt deze teruggeregeld naar 10,0V.
*) Hoe groter het vermogen dat wordt opgenomen, hoe groter de waarde van de elco moet zijn.
Hoewel niet getekend op het schema, wordt een 100n condensator voor de ontkoppeling over pin 4 en 8 van de LM358 aangeraden.
 

LM358
De LM358 is een low power dual opamp (= laag vermogen, dubbele operationele versterker).
Hoewel de LM358 een dubbele opamp is, dus twee stuks in één 8-pins behuizing, gebruiken we hier maar één van de twee.
In het schema staan de pinnummers van de ene opamp genoteerd.
De pinnummers van de andere opamp in de behuizing staan er tussen haakjes bij, die kun je eventueel gebruiken voor een tweede DAC.

Het voordeel van de LM358 is dat deze geen +15V en -15V nodig heeft zoals gebruikelijk bij de meeste opamps.
Alleen +5V is al voldoende.
Wij willen echter naar +10V kunnen regelen dus moet de opamp op +12V worden aangesloten.
Een negatieve spanning is gelukkig niet nodig.

Download datasheet LM358
 

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Logische constanten
SYMBOL LAAG         = 0       ;Laag signaal

;Algemene constanten
SYMBOL WijzigSpeed  = 10      ;Snelheid van wijzigen van PWM bij hoger en lager toetsen 

;Poortnamen
SYMBOL PWM_Signaal  = PORTA.6 ;Op deze poort komt het PWM signaal
SYMBOL ToetsHoger   = PORTB.0 ;Toets om spanning te verhogen
SYMBOL ToetsLager   = PORTB.1 ;Toets om spanning te verlagen

;Variabele declareren
DIM Spanning        AS BYTE   ;Deze variabele bevat de spanning (als PWM duty waarde)

;        76543210
PORTA = %00000000             ;Maak alle poorten van PORTA laag
TRISA = %10111111             ;PORTA.6 is uitgang voor het PWM signaal

PORTB_PULLUPS ON              ;Pull-up activeren voor de toetsen
CLEAR                         ;Wis alle RAM geheugen
DELAYMS 500                   ;LCD stabilisering 


;Hoofdprogramma
CLS                           ;Wis display

WHILE 1 = 1                   ;Oneindige lus
  ;Als op 'ToetsHoger' wordt gedrukt en spanning is nog niet maximaal, dan deze verhogen 
  IF ToetsHoger = LAAG AND Spanning < 250 THEN INC Spanning
  ;Als op 'ToetsLager' wordt gedrukt en spanning is nog niet nul, dan deze verlagen 
  IF ToetsLager = LAAG AND Spanning > 0   THEN DEC Spanning 

  ;Reken PWM waarde om naar spanning en plaats dit op het display 
  PRINT AT 1, 1, DEC2 Spanning / 25, ",", DEC2 Spanning * 4, " volt"

  ;Stuur naar poort 'PWM_Signaal', de grootte 'Spanning' als een PWM signaal
  PWM PWM_Signaal, Spanning, WijzigSpeed
WEND

TRISA is hier opgegeven maar is eigenlijk overbodig omdat de instructie PWM de opgegeven poort in de instructie zelf in- en uitgang maakt.
 

Afregelen
Druk op 'ToetsHoger' totdat het display 10,00 volt aangeeft.
Regel nu met de potmeter van de LM358 de uitgangsspanning van de BC337 af op 10,0V.

Verwacht geen hoge precisie, het is maar een simpele DAC.
Als het display 10,00 volt aangeeft zal de spanning op de BC337 inderdaad 10,0V zijn.
Maar als je terugregelt met de 'ToetsLager' toets naar bijvoorbeeld 5,00 volt, dan zal de spanning waarschijnlijk iets afwijken, bijv. 4,8V.
De afwijking zou je in het programma zelf natuurlijk weer op kunnen vangen.

De variabele 'Spanning' kan een waarde hebben van 0 ... 255.
Bij 'ToetsHoger' wordt deze echter begrensd tot aan 250.
INC Spanning wordt immers alleen uitgevoerd als de waarde van 'Spanning' kleiner is dan 250.
Omdat de toetsen met GND (massa) zijn verbonden en de inwendige pull-up weerstanden zijn ingeschakeld, krijgt de PIC een LAAG signaal als er op een toets wordt gedrukt, daarom IF Toets = LAAG THEN...

Nog even over het display.
Een waarde van 250 komt overeen met de zojuist met de potmeter afgeregelde 10,00 volt.
Het getal 250 wordt omgezet in 10,00 voor het display.
Vóór de komma staat DEC2 Spanning / 25 en 250 gedeeld door 25 is... aha, de 10 van 10,00 volt.
Dan komt de komma (gewoon tussen aanhalingstekens).
Ná de komma staat DEC2 Spanning * 4 en 250 × 4 is 1000.
Door direct achter DEC een 2 te zetten worden alleen de twee rechtse cijfers van 1000 achter de komma geplaatst (00 dus).
Tot slot wordt daarachter nog een spatie en "volt" gezet.
Het totaal plaatje op het display is bij 10V nu 10,00 volt.


Bovenstaande programma maakt stapjes van 0,04V bij het verhogen en verlagen.
Vindt je stapjes van 0,05V mooier, dan moet je onderstaand programma in de PIC programmeren.
Dit programma verdeelt 0 ... 10V echter in maar 200 stapjes, terwijl het vorige dit in 250 stapjes doet (= hogere resolutie).

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Logische constanten
SYMBOL LAAG         = 0       ;Laag signaal

;Algemene constanten
SYMBOL WijzigSpeed  = 10      ;Snelheid van wijzigen van PWM bij hoger en lager toetsen 

;Poortnamen
SYMBOL PWM_Signaal  = PORTA.6 ;Op deze poort komt het PWM signaal
SYMBOL ToetsHoger   = PORTB.0 ;Toets om spanning te verhogen
SYMBOL ToetsLager   = PORTB.1 ;Toets om spanning te verlagen

;Variabele declareren
DIM Spanning        AS BYTE   ;Deze variabele bevat de spanning (als PWM duty waarde)

;        76543210
PORTA = %00000000             ;Maak alle poorten van PORTA laag
TRISA = %10111111             ;PORTA.6 is uitgang voor het PWM signaal

PORTB_PULLUPS ON              ;Pull-up activeren voor de toetsen
CLEAR                         ;Wis alle RAM geheugen
DELAYMS 500                   ;LCD stabilisering 


;Hoofdprogramma
CLS                           ;Wis display

WHILE 1 = 1                   ;Oneindige lus
  IF ToetsHoger = LAAG AND Spanning < 200 THEN INC Spanning  ;Spanning verhogen
  IF ToetsLager = LAAG AND Spanning > 0   THEN DEC Spanning  ;Spanning verlagen 

  PRINT AT 1, 1, DEC2 Spanning / 20, ",", DEC2 Spanning * 5, " volt"

  PWM PWM_Signaal, Spanning, WijzigSpeed                     ;PWM naar poort PWM_Signaal 
WEND

Het programma is verder precies hetzelfde, alleen zijn er een paar waarden aangepast.
De potmeter van de LM358 moet weer opnieuw worden ingeregeld en de afwijking kan anders zijn.

Even weer over het display.
De met de potmeter opnieuw afgeregelde 10,0V komt nu overeen met de waarde 200.
Nu wordt het getal 200 omgezet in 10,00.
Vóór de komma staat DEC2 Spanning / 20 en 200 gedeeld door 20 is... daar is ie weer, de 10 van 10,00 volt.
Ná de komma staat DEC2 Spanning * 5 en 200 × 5 is 1000, waarvan dus alleen de 2 rechtse cijfers worden gebruikt.
Het totaal plaatje op het display is bij 10V weer 10,00 volt, instellen van de spanning gaat nu echter met stapjes van 0,05V i.p.v. 0,04V.

Een echte DAC komt later in de cursus wel eens aan de beurt (zonder de PWM instructie).
Tip: de single (= enkelvoudige) MCP4921 en de dual (= dubbele) MCP4922 DAC's zijn voor een paar Euro verkrijgbaar bij Voti.
Dit zijn SPI DAC's met een resolutie van 12-bits, die in PICBasic eenvoudig zijn aan te sturen met behulp van de PIC Basic instructie SHOUT.