Stap 2: Instellen van DAC en Test
PORTD = 125; //send gegevens DAC
Dit heet de poort direct aanpakken. Op de Arduino zijn digitale pinnen 0-7 allemaal op poort d van de Atmel328-chip. Het PORTD opdracht laat ons vertelt pins 0-7 te hoog of laag gaan in één regel (in plaats van op digitalWrite() acht keer). Niet alleen is dit gemakkelijker code, het is veel sneller voor de Arduino te verwerken en hierdoor de pinnen aan alle veranderingen tegelijk in plaats van één voor één (u kunt alleen praten met één pin tegelijk met digitalWrite()). Aangezien poort d acht pinnen op het (digitale pinnen 0-7 heeft) wij annuleerteken zenden op een van de 2 ^ 8 = 256 mogelijke waarden (0-255) waarmee de pinnen. Bijvoorbeeld, als we de volgende regel schreef:
PORTD = 0;
het zou het opzetten van pinnen 0-7 laag. Dit zal de 0V uitgang met de DAC ingesteld op pinnen 0-7. Als we de volgende verzonden:
PORTD = 255;
het zou het opzetten van pinnen 0-7 hoog. Hierdoor wordt de DAC aan output van 5V. We kunnen combinaties van lage en hoge ook een uitgangsspanning tussen 0 en 5 v van de DAC-Staten sturen. Bijvoorbeeld:
PORTD = 125;
125 = 01111101 in binaire. Dit stelt pin 7 lage (de msb is ingesteld op 0), pinnen 6-2 hoog (de volgende vijf bits zijn 1), pin 1 laag (de volgende bit 0), en pin 0 hoog (de lsb is 1). U kunt meer lezen over hoe dit werkt hier. Voor het berekenen van de spanning die dit zal de uitgang van de DAC, gebruiken we de volgende vergelijking:
spanning uitgang van DAC = [(waarde verzonden naar PORTD) / 255] * 5V
dus voor PORTD = 125:
spanning uitvoer van DAC = (125 / 255) * 5V = 2.45V
De code hieronder verschillende spanningen tussen 0 en 5 v afgeeft en houdt elk voor een korte tijd om aan te tonen van de concepten die ik hierboven heb beschreven. In de loop van de belangrijkste functie die ik heb geschreven:
PORTD = 0; //send (0/255) * 5 = 0V uit DAC
vertraging (1); //wait 1ms
PORTD = 127; //send (127/255) * 5 = 2.5V uit DAC
vertraging (2); //wait 2ms
PORTD = 51; //send (51/255) * 5 = 1V uit DAC
vertraging (1); //wait 1ms
PORTD = 255; //send (255/255) * 5 = 5V uit DAC
delay (3), //wait 3ms
De uitvoer wordt weergegeven op een oscilloscoop in fig 4. De horizontale middenlijn over de oscilloscoop vertegenwoordigt 0V en elke horizontale lijn vertegenwoordigt een stijging/daling van spanning van 2V. De afbeelding c HTING fig 4 tonen de output van elk van de lijnen van code hierboven, klik op de afbeelding om de afbeelding te bekijken.
//Analog out //by Amanda Ghassaei
De onderstaande code uitgangen een helling van 0 tot 5V. In de loop-functie, de variabele "a" wordt verhoogd van 0 tot 255. Telkens wanneer die het wordt verhoogd, wordt de waarde van "a" verzonden naar PORTD. Deze waarde wordt gehouden voor 50us, voordat een nieuwe waarde 'a' wordt verzonden. Zodra "a" 255 heeft bereikt, wordt het teruggezet op 0. De tijd voor elke cyclus van deze klep (ook wel de periode genoemd) nodig:
periode = (duur van elke stap) * (aantal stappen)
periode = 50us * 256 = 12800us = 0.0128s
de frequentie is dus:
frequentie van helling 1/0.0128s = 78 = Hz
De uitvoer van de DAC op een oscilloscoop kan worden gezien in fig 5.
//Ramp out //by Amanda Ghassaei
De onderstaande code uitgangen een sinusgolf gecentreerd rond 2.5V, tot een max van 5V en een min van 0V oscillerende. In de loop-functie, wordt de variabele "t" verhoogd van 0 tot 100. Telkens wanneer het wordt verhoogd, de expressie:
127+127*Sin(2*3.14*t/100)
wordt verzonden naar PORTD. Deze waarde is voor 50us aangehouden voordat "t" weer wordt verhoogd en een nieuwe waarde wordt verzonden naar PORTD. Zodra "t" 100 bereikt, wordt het teruggezet op 0. De periode van deze sinusgolf moet worden:
periode = (duur van elke stap) * (aantal stappen)
periode = 50us * 100 = 5000us = 0.005s
dus de frequentie moet:
frequentie van helling = 1/0.005s = 200 Hz
//Sine out //by Amanda Ghassaei
Maar dit is niet het geval, de uitvoer van de DAC is getoond in fig 6. Zoals aangegeven in de toelichting van de afbeelding, het hoeft niet een frequentie van 200hz, de frequentie ervan is meer als 45hz. Dit is omdat de regel:
PORTD = 127+127*sin(2*3.14*t/100);
neemt een zeer lange tijd te berekenen. In het algemeen nemen vermenigvuldiging/divisie met decimale getallen en de functie sin() de Arduino een heleboel tijd om uit te voeren.
Een oplossing is het berekenen van de waarden van sinus tevoren en deze opslaan in het geheugen van de Arduino. Dan wanneer de Arduino schets alles de Arduino hoeft draait zal te doen is herinneren deze waarden uit het geheugen (een zeer gemakkelijke en snelle taak voor de Arduino). Ik liep een eenvoudige Python script (zie hieronder) voor het genereren van 100 waarden van 127+127*sin(2*3.14*t/100):
importeren van math
voor x in bereik (0, 100):
afdrukken van str(int(127+127*math.sin(2*math.pi*x*0.01)),)+str(","),
Ik deze waarden opgeslagen in een matrix genaamd "sinus" in de Arduino schets hieronder. Vervolgens in mijn lus stuurde voor elke waarde van de "t" ik een element van sinus [] naar PORTD:
PORTD = sinus [t];
De uitvoer van deze DAC voor deze schets wordt weergegeven in Fig. 7. U kunt zien dat het een sinusgolf van 200hz, output zoals verwacht.
//Sine out with stored array //by Amanda Ghassaei