Change OCR1B on the fly

I work on an Arduino Uno.
For setting up a PWM signal I use fast PWM.

#define MY_MEASURE1 20 
#define MY_MEASURE2 200

...
...

void pwmSignal() {
  // 16 bit Timer Counter 1
  TCCR1A = (0 << COM1A1) + (1 << WGM11);
  TCCR1B = (1 << WGM13) + (1 << WGM12) + (1 << CS12);
  ICR1 = MY_TOP; 
  OCR1A = MY_BOTTOM; 
  OCR1B = MY_MEASURE1;  // for analog measurement
  DDRB |= (1 << DDB1); 
  TIMSK1 |= (1 << OCIE1B); 
}

Generation of PWM on Port 9 is OK. It generates a signal with 1ms duty cycle, based on OCR1A and ICR1. -> ok
Additionally I want to do an analog measurement when counter reaches MY_MEASURE1 (see code). For this I use OCR1B: An interrupt service routine is triggered when there is the compare match for OCR1B. -> also ok.

But now I want to execute an additional analog measurement in the same cycle when counter reaches MY_MEASURE2. For this, I change OCR1B value directly within the ISR:

This ISR is just for examining the problem:

int iread = 0;

ISR(TIMER1_COMPB_vect) {

  switch (iread) {
  case 0:
    iread = 1;
    adc1 = adc;
    OCR1B = MY_MEASURE2;
    digitalWrite(check, 1);
    analogRead(stromAnalog);
    digitalWrite(check, 0);
    break;

  case 1:
    iread = 0;
    adc2 = adc;
    OCR1B = MY_MEASURE1;
    digitalWrite(check, 1);
    analogRead(stromAnalog);
    digitalWrite(check, 0);
    break;
  }
}

Note: The digitalWrite is to produce a test output to see whats happens. It is the second trace line in the following image.

The problem is: There is only one measurement during a PWM cycle. The change in OCR1B takes place only at the next cycle so I have alternate measurements at MY_MEASURE1, MY_MEASURE2, but only with one per cycle and not twice.

I would expect compare match interrupt twice within a cycle. Instead I get this:

You see, A and B will occur alternately, but not in the same cycle.

Where is the problem??

From what I remember the compare registers are double-buffered are loaded synchronously with the counter reseting normally (as this is required for proper behaviour in PWM).

The full gory details are in the datasheet for the ATmega328 chip.

hmmm. this would explain the observed behavior. I cannot find the corresponding place in the datasheet.

You are right:
image
Reading helps :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.