Stap 8: Software: Timers en Interrupts
Ik weet niet wat foto's te plaatsen voor het verklaren van de software, dus, natuurlijk, waarschijnlijk beter gewoon post een foto met een kat. Ook is de volledige arduino code beschikbaar aan download hierboven. (lbdOrganPWM.ino)
Timers en Interrupts
Om te kunnen gebruiken de hardware PWM in volgorde met de lijn van de ac triggering, alles wat we moeten doen is ervoor te zorgen de teller die wordt gebruikt voor de uitvoer van de PWM-waarde wordt teruggezet op de nul-kruising van de wisselstroom van de lijn. Met de activerende circuit uitgelegd in stap 7, hechten wij een hardware-interrupt aan deze pin te resetten van de tellers als er wordt gegenereerd.
Elke timer wordt geïnitialiseerd aan het begin van het programma naar de golfvorm generatie modus voor snel PWM mode met ICRn als de hoogste waarde. Deze timer-modus is wat maakt gebruik van de hardware PWM mogelijk.
Aangezien we 7-bits resolutie in de snelheid van de MIDI-notitie hebben, willen we om vrij dicht bij deze resolutie voor de intensiteit van de gloeilamp. Eerlijk gezegd, iets meer dan 16 stappen is vrij te verwaarlozen, maar aangezien we kunnen we net zo goed. Dus als we de prescaler van de timers ingesteld op 1024 (pag. 161 van Atmega2560 gegevensblad), dan we 16 Mhz hebben / 1024 voor onze klok timer = 15625 Hz. De frequentie van ons doel van onze totale PWM golfvorm is 120Hz, overeenkomen met de halve cyclus van de spanning van de lijn 60Hz. We verdelen dus, 15626/120 om ~ 130. Dat betekent dat als wij onze ICRn register to130 ingesteld, zullen we een frequentie die overeenkomen met de frequentie van de lijn met ~ 130 stappen. Dat is perfect aangezien we hebben 128 stappen in de MIDI-snelheid!
Er is enige variatie in de frequentie van lijn na het proberen van dit uit, en dus uiteindelijk heb ik met behulp van een hoogste waarde (ICRn) van 122. Dit leek me een veilig genoeg waarde waar ik zou ervoor dat mij zou zwenking vandoor naar de triac op de nul-cross. Als je te ver voorbij de drempel van de nul-cross, je missen en het licht nooit worden uitgeschakeld of worden gedimd.
Laatste ding, over de Timer-config is de polariteit van de PWM. Omdat zodra de timer wordt tot aan het eindpunt wij willen zorg ervoor dat de triac wordt uitgeschakeld (dit betekent dat we dicht bij de nul-cross zijn), we moeten gebruiken de omgekeerde-modus van de PWM-pin, zo dat wanneer de Timer = 0, de pin is laag. Dat gewoon betekent dat wanneer we de waarde van een snelheid van 100, we willen het PWM-register ingesteld op 127-100 = 27.
Voor de behandeling van de nul-cross, heeft de arduino bibliotheek een ingebouwde functie voor dit met behulp van de hardware-interrupts:
attachInterrupt(5,zeroCrossDetect,FALLING);
Waarbij 5 is de interrupt-nummer (pin 18 op de Mega), vallende aangeeft het is alleen geactiveerd op de dalende rand (1 -> 0, niet 0 -> 1) van de interrupt-pin, en zeroCrossDetect is de functie hieronder.
Het werkt door het instellen van alle tellers die door de specifieke PWM pinnen die ik besloten heb te nul aan het nul Kruis wordt gebruikt. Het stelt ook de prescaler en wave-form generatie modus voor elke timer, de reden hiervoor is dat de timer begint op de AC-cyclus aan het begin van het programma, om ervoor te zorgen er geen offset vanaf het begin.
void zeroCrossDetect() { TCNT1 = 0; TCNT3 = 0; TCNT4 = 0; TCNT5 = 0; TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10) | (1<<CS12); TCCR3B = (1<<WGM32) | (1<<WGM33) | (1<<CS30) | (1<<CS32); TCCR4B = (1<<WGM42) | (1<<WGM43) | (1<<CS40) | (1<<CS42); TCCR5B = (1<<WGM52) | (1<<WGM53) | (1<<CS50) | (1<<CS52); }