Arduino - PWM an zwei Ausgängen

OP #6160369
ich versuche nun seit zwei Tagen, jetzt hoffe ich hier Unterstützung zu 
bekommen:
ich benötige an zwei Ausgängen des Arduinos ein ~130Hz PWM-Signal, ich 
verwende in meinem Code D9 und D10. D10 gibt das Signal aus, wie 
gewünscht. D9 gibt nur ein HIGH aus, ohne PWM. hat jemand eine Idee was 
im Code fehlt oder falsch ist?

hier der Code:
1
int interruptNumber = 0;
2
int tasterPin = 2;
3
bool on = 1;
4

5
void setup() {
6
  Serial.begin(9600);
7
  DDRB = 0b00000110;
8
  TCCR1A = 0;
9
  TCCR1A = _BV(WGM10) | _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1);     //Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM, WGM10, WGM11(Fast-PWM)
10
  TCCR1B = 0;
11
  TCCR1B = _BV(CS12) | _BV(WGM12) | _BV(WGM13);   //CS12 - Prescaler 256; WMG12 & WGM13 für Fast-PWM
12
  OCR1A = 490;    //für benötigte Frequenz von 130Hz
13
  OCR1B = 100;   //duty-cycle
14
  pinMode(tasterPin, INPUT_PULLUP);
15
  attachInterrupt(interruptNumber, interruptfunction, FALLING);   //sollte PWM-Signal zwischen D9 und D10 hin und herschalten
16
}
17

18
void loop() {
19
 OCR1A = map(analogRead(A0), 0, 1023, 0, 490);   //Steuerung von duty-cycle
20
}
21

22
void interruptfunction() {
23
  if (on == 1) {
24
    TCCR1A = _BV(WGM10) | _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1);
25
    on = 0;
26
  }
27
  else {
28
    TCCR1A = _BV(~WGM10) | _BV(~WGM11) | _BV(~COM1A1) | _BV(~COM1B1);
29
    on = 1;
30
  }
31
}
#6160428
Mike C. schrieb:
> TCCR1A = _BV(WGM10) | _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1);
> //Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM, WGM10,
> WGM11(Fast-PWM)

Das ist aber //Set OC1A/OC1B on compare match, clear OC1A/OC1B at
BOTTOM (inverting mode)

Mike C. schrieb:
> OCR1A = 490;    //für benötigte Frequenz von 130Hz

Wenn du OCR1A im Mode 15 ( Fast PWM, TOP = OCR1A, Update of OCR1x at 
BOTTOM) einsetz, dann definiert OCR1A deine Frequenz. Richtig.

Mike C. schrieb:
> OCR1A = map(analogRead(A0), 0, 1023, 0, 490);   //Steuerung von
> duty-cycle

Dann kannst du aber vergessen den DutyCycle damit festlegen zu wollen.
Du änderst hier die PWM-Frequenz, nicht den DutyCylce.

Außerdem änderst du praktisch die ganze Zeit die PWM Frequenz (in der 
Loop) und deshalb bleibt OC1A = D9 immer high, weil immer ein Compare 
Match für OCR1A auftritt.

Wenn du Fast PWM nutzen willst und auf D9 und D10 unterschiedliche DC 
ausgeben willst, musst du WGM Mode 14 mit dem ICR1 als Register für die 
Definition der Frequenz verwenden.
Gast #6160435
> TCCR1A = _BV(~WGM10) | _BV(~WGM11) | _BV(~COM1A1) | _BV(~COM1B1);

Ich bezweifel, dass diese Zeile das tut, was du beabsichtigst - 
_BV(~xxx) ergibt keinen Sinn ...
OP #6160497
Timo N. schrieb:
> Wenn du Fast PWM nutzen willst und auf D9 und D10 unterschiedliche DC
> ausgeben willst, musst du WGM Mode 14 mit dem ICR1 als Register für die
> Definition der Frequenz verwenden.

Danke dir Timo, so funktioniert es natürlich, so ist es auch total 
logisch.

int interruptNumber = 0;
int tasterPin = 2;
bool on = 1;

void setup() {
  Serial.begin(9600);
  DDRB = 0b00000110;
  TCCR1A = 0;
  TCCR1A = _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1);
  TCCR1B = 0;
  TCCR1B = _BV(CS12) | _BV(WGM12) | _BV(WGM13);
  ICR1 = 490;
  pinMode(tasterPin, INPUT_PULLUP);
  attachInterrupt(interruptNumber, interruptfunction, FALLING); 
//sollte PWM-Signal zwischen D9 und D10 hin und herschalten
}

void loop() {
  OCR1A = map(analogRead(A0), 0, 1023, 0, 490);   //Steuerung von 
duty-cycle
  OCR1B = OCR1A;
}

void interruptfunction() {
  if (on == 1) {
    TCCR1A = _BV(WGM11) | _BV(COM1A1) | _BV(COM1B1);
    on = 0;
  }
  else {
    TCCR1A = 0;
    on = 1;
  }
  Serial.println(TCCR1A, BIN);
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.