Continuously varying PWM frequency

I apologize but trying to interpret how the registers work is a recurring nightmare for my brain, let alone how it interacts with native Arduino functions:

I have an ATTiny85 and I would like to use one of the Timer1 pins (PB4 in this case) to use PWM as a means of communicating to another Arduino on a digital (also an interrupt) pin. I thought about doing this 2 ways: Either vary the duty cycle or vary the frequency. I believe varying the frequency is better because it's easier to measure on the receiving end by simply timing the pulses, which are all the same. Now I realize I can use the prescalar to do this or the compare register but I am not confident in the precise implementation. My goal also is to have the PWM running 100% of the time, never to turn it off but only to alter the frequency when I want to send a different "digit" if you will.

According to the data sheet, I can alter the frequency by adjusting the values of CS10-CS13 and OCR1C in the TCCR1 register. However what I am more interested in knowing is how to change these values while the pwm is running so that nothing breaks and only the frequency changes. Do I have to stop the pwm or maybe restart it after changing these? Can I call analogWrite instead of using register commands to start the pwm? A simple code snippet would be really helpful to show starting the pwm using the analogWrite command and then changing the frequency to something else without breaking the PWM.

Thank you.

I should also note that I've overclocked the unit to 20MHz so I dunno if that is going to throw off any of the timer settings I would normally use.

Can anyone assist with this?

I'm thinking I can simply start by calling analogWrite(4, 127), which should put 50% duty on PB4 at the default frequency. However I don't know how the native arduino function sets up the timer.

I will need to turn off PB1, change the timer's prescalar to 4096, make sure the mode is set to PWM and then I believe I need to vary the value of OCR1C, according to what frequency I want. I am also assuming that after I set these values I no longer need to call the analogWrite function, as it should already be running anyway. After that I would simply need to change OCR1C to change the frequency.

I'm not too sure how the timer handles duties that are not 50/50, since the timer would need to continue to count up to TOP for the LOW side of the pulse, wouldn't it? Thankfully I don't need anything but 50/50 but I'm hoping by setting analogWrite(4, 127), it correctly sets up the registers so that it resets at OCR1C and goes LOW, then HIGH, etc etc.

Is this the correct strategy? The register setup is rather complex to me and I'm having trouble following the various descriptions in the datasheet. An example would be more helpful but what I've found on google so far doesn't really resemble what I am trying to do, which is to arbitrarily change frequency on the fly on PB4.

Since no one seems to be replying, I will, but not to help, but to point out a logic failure. You cannot vary either frequency or pulse width without proper clocking by the current pwm signal. Do either and you will have a "glitch" on the current PWM stream. You can only change, with no glitch. at the beginning of a pulse, either the + or the - time.

Paul

If by glitch you are referring to the timing adjustment that occurs at the moment you switch pulse width or frequency, I came across that in the documentation and while I read about a "glitch free" mode of operation, I would say it's largely irrelevant anyway. I'm using this Tiny as a co-processor of sorts and its only job is to put out PWM constantly with its frequency proportional to an analog input on a different pin. I'm basically using as a crude form of communication to the main CPU. However it's not synchronous communication. In fact it doens't even need to happen continuously. Basically the main processor will "listen" to the PWM when it feels like it and only for the duration of a couple of pulses, and even then there's some averaging that will take place, so any glitch that might make it to the main cpu, if that happens at all, will be of little consequence in the larger scheme of things. For me it's far more important that I'm able to change frequency on the fly, irrespective of any glitches that may occur because I have cpu cycles to waste, measuring the frequency on the other end.

oK

Here's how I have guessed that the implementation should work. Is this correct?

  PLLCSR &= ~_BV(PCKE);                   // Set Synchronous mode (disable PLL)
  
  DDRB = _BV(PB4);                        // Make the Right pin (PB4) an output
  
  OCR1C = 255;                            // Governs the frequency of PWM  
  OCR1B = 127;                            // Governs Duty Cycle
    
  GTCCR = _BV(PWM1B);                     // Enable PWM 1B
  GTCCR |= _BV(COM1B1) | _BV(COM1B0);     // Only generate output on the standard not the inverted pin
  
  TCCR1 = _BV(CS10);                      // 4096 Prescaler.
  TCCR1 = _BV(CS12);
  TCCR1 = _BV(CS13);
  
  TCCR1 |= _BV(COM1A1) | _BV(COM1A0);     // Copy COM1A1 and COM1A0 because of hardware glitch

...and later in the main loop, to update the frequency:

      OCR1C = finalrpm;                   // Update the frequency
      OCR1B = finalrpm / 2;               // Update the duty cycle