Strange PWM Behavior on ATTiny85

So I am working on a pretty simple little project. Basically I am generating two PWM signals on an ATTiny85 using the excellent tinyCore. What I want to do is write the same duty cycle to both outputs (OC1A and OC1B). I am testing this by hooking up LED’s to the two outputs with 100 uF smoothing capacitors to get rid of high frequency hash. When I do this, I notice that OC1A LED is much less bright and is out of phase with OC1B, which behaves as I would expect in terms of brightness. I have tried new LED’s, changing the smoothing caps, changing chips, ground references, locations on the breadboard, etc., all to no avail. I used virtually identical code on a previous project with no issue, though OC1A and OC1B had independent duty cycles on that one. Configuration of the timers and everything was the same. Here is the code (code from unrelated pins/functions is omitted for the sake of clarity, full file attached). Any insight here would be greatly appreciated, as it has me really scratching my head.

//DigitalPin Assignments
const unsigned int pwm2 = 4; //PWM out on OC1B/PCINT4/Pin3
const unsigned int pwm1 = 1; //PWM out on OC1A/PCINT1/Pin6

void setup() {

  //Define pin modes
  pinMode(pwm1, OUTPUT);
  pinMode(pwm2, OUTPUT);

  // Initialize pin states
  digitalWrite(pwm2, LOW);
  analogWrite(pwm2, 128);

  // Set up timer/PWM items
  PLLCSR |= (1 << PLLE) | (1 << PCKE);

  // Set prescaler to PCK
  TCCR1 |= (1 << CS10) | (1 << CS11) | (0 << CS12) | (0 << CS13) | (1<<PWM1A);
  // Set OCR1B compare value and OCR1C for fastest PWM clock rate
  OCR1B = 128;
  //OCR1A = 128; //See if this makes a difference. It doesn't
  OCR1C = 127;
  // Enable OCR1B output on PB4, configure compare mode and enable PWM B
  DDRB |= (1 << PB4) | (1 << PB1);
  GTCCR |= (1 << COM1B0) | (1 << COM1B1);
  GTCCR |= (1 << PWM1B);

  TCCR0A |= 0b11; // Set to fast PWM
  //TCCR1 |= (1 << COM1A0); // Set this bit to make sure that OCR1A starts up correctly. Not sure why, but it works.
  TCCR1 |= (1 << COM1A1); // Set this bit to make sure that OCR1A starts up correctly. Not sure why, but it works.

  //Set up Interrupt items
  GIMSK = 0b00100000; //Enable pin change interrupts
  PCMSK = 0b00000001; //Enable PCINT0 for tap switch to be pin change interruptible

  sei(); // Start interrupt service

void loop() {

  //Check a couple other pins



//Update PWM outputs based on above settings
void updatePWM() {
    //Complicated code for determining duty cycle value

    // Set both PWM's
    OCR1B = dutyCycle;
    //analogWrite(pwm2,dutyCycle); //Just trying out different things
    analogWrite(pwm1,dutyCycle); //Just trying out different things
// Update some unrelated parameters
}// end of updatePWM()

tinyLFO.ino (17.7 KB)

So I looked at my PWM outputs using my Espotek Labrador (traces attached). I used 100 uF caps to smooth them. I am seeing some weird stuff here, besides being out of phase, they also have differing amplitudes and even shape on the trough of the waveform. I'm not sure what's going on here. I did notice that I didn't have COM1A0 and COM1A1 settings equal to COM1B0 and COM1B1, but I'm not sure if that is a big deal, as setting them identical didn't seem to change anything. Thoughts?

Didn’t look at the code, don’t care (yet).

You cannot shove a 100uf cap on a PWM output pin and expect some magical transformation into dc. Do you have a resistor in front of the cap? I sure hope so.

That scope display is... well, annoying. What is the frequency of the waveforms or at least the horizontal time base? It looks like mains noise but I think the timebase is strange, maybe 30ms per division which makes no sense for PWM or mains. It looks more like measurement errors because one channel has negative voltage. Not likely in a 5 volt system.

I’d remove the caps and measure the outputs as straight PWM and get that working. Then work on the low pass filter.

Briefly reading the code. Why this?
TCCR0A |= 0b11; // Set to fast PWM
Is it related to Timer1 you are using?

I am not attempting to get DC, I am using the PWM out as LFO generation. The scope trace above is 250 ms per division on the time axis, showing the resulting LFO (smoothed PWM) signal. I agree that the negative voltage is weird. I'll check calibration and re-measure.

I have TCCR0A |= 0b11 to set the two LSB's of TCCR0A to 1's to enable fast PWM, per the datasheet (Table 11-5, page 79). My PWM outputs are using timer1, specifically OC1A and OC1B on pins PB1 and PB4, respectively.

TCCR0A controls Timer0, you are using Timer1. I don't think it explains your problem but it is still a "weirdness" that should be fixed.

Oh, that would explain why it didn't seem to do what I thought it should! Stupid mistake on my part. Thanks!

Also, it turns out I had a couple of bad LED's, so the brightness issue was due to that. Now I just have the LED's flashing out of phase with each other. If I can fix that, I think I'll be good.

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