PWM Sinus Arduino

Es kommt häufig vor, dass Messsonden oder andere Bauelemente eine Sinusspannung brauchen um funktionieren zu können. Befindet sich ein Mikrokontroller auf der entsprechenden Schaltung kann dieser als Sinusgenerator verwendet werden. Dazu wird der DutyCycle des PWM, sinusförmig moduliert.

In diesem Beispiel wurde als Hardware ein Arduino Uno verwendet also ein ATMega328P mit einem 16MHz Quarz. Um die PWM-Frequenz zu berechnen kann folgende Formal verwendet werden. Die Auflösung wurde bei 255 Bits gelassen.

Um die Sinusfrequenz ermitteln zu können muss die Sinusfrequenzschrittweite und die PWM-Frequenz bekannt sein. Sinusfrequenzschrittweite „summ“ kann Werte zwischen 5 und 63 annahmen. Um die Sinusfrequenz zu ermitteln kann folgende Formel verwendet werden.

Um am Ausgang des Mikrokontrollers ein sinusähnliches Signal zu bekommen muss noch ein Tiefpassfilter hinzugeschaltet werden. Ein kleines Detail noch, sollte der Ausgang belastet werden so ist es empfehlenswert eine Verstärkerstufe miteinzubauen.

Zur Berechnung des Filters können folgende Formeln verwendet werden.


Source Code

#include <avr/interrupt.h>   
#include <avr/io.h>

byte sin_inc;
byte sin_pwm[256];
const byte summ = 5; void setup() {      // fill sinus array   for (int i = 0; i < 256; i++)   {     sin_pwm[i] = int(abs((sin(i*0.0246399)+1)*127.5));     Serial.println(sin_pwm[i]);   }   // set fast mode set clear on inerrupt   TCCR1A = 1<<COM1A1 | 1<<WGM10;   // WGM12 set fast mode; CSnn set presaler pwm frequency ~64kHz   TCCR1B = 1<<WGM12  | 0<<CS12  | 0<<CS11  | 1<<CS10;   // set inerrupts   TIMSK1 = 1<<TOIE1  | 0<<ICIE1;   // set compare register   OCR1A = 0x0000;   // set global interrupt   sei(); } void loop() {   } //Timer1 overflow interrupt vector handler ISR(TIMER1_OVF_vect) {   // sets new DutyCycle   // sinus Frequency = (f_PWM * summand) / 255 ; Summand max = 63   OCR1A = sin_pwm[sin_inc += summ]; };