Making custom frequency PWM

Excuse me, I need to make a pin pulse with a custom frequency to control an LED. This LED must flash at a specific frequency in a square wave like fashion, I want to be able to control the duty cycle of the pulse too. I understand tat an atmega328p as contained in an uno has 3 timers built in, and if you mess with two of them you interfere with clock timings for delay() and such, but the third can be freely edited, though I'm not sure if you can do custom frequencies or just pick from a list of frequencies separated by multiples of two. I cannot bit bang as I need to do something else at the same time as the flashing is in progress, and this is pretty fast flashing (in the several KHz range) so trying to bit bang and have interrupts would not go well as the flashing signal would cease to accurately work while the other things were happening*. I also need to be able to use I2C, analog input pins 0,1,2 and 3 and a few digital inputs and outputs too while this goes on, I don't actually mind if my pulses get messed up while I2C communication occurs as it is quite rare, but I do need to keep being able to use analog inputs and other digital inputs and outputs while my flashing s going on. I don't think that custom PWM should interfere with any of those things but thought I should mention that I cannot use solutions which do prevent use of analog inputs, I2C and other digital in and out puts.

Is there any good example code for how to do custom PWM?

Thank you

*other things: I'm flashing the LED at a modulation frequency and then while it is flashing reading a sensor to look for it's reflection. Modulation is important as it is in a fairly bright environment, so this way I can filter away background noise. The LED needs to keep flashing at the chosen frequency and duty cycle while the sensor reading goes on.

Check out the TimerOne library GitHub - PaulStoffregen/TimerOne: TimerOne Library with optimization and expanded hardware support
or TimerThree library GitHub - PaulStoffregen/TimerThree: TimerThree Library with optimization and expanded hardware support

The are identical, except for which timer they use. There are several examples which will get you started

Your understanding of the 328P is partially correct. but it's the Arduino code you're mucking up, not the MCU. While all three timers are initialized for PWM, it's only timer0 that has anything to do with the other functions you mention. So long as you don't change the prescaler for timer0, and understand that it must not enter CTC mode with an adjusted OCR0A, and that the overflow interrupt is in use elsewhere, you can use all the rest of it's functionality.

What that means is that you can continually adjust OCR0A and OCR0B and use their interrupts.

timer1 and timer2, you can do anything you want with them.

Read about Timer1 in the datasheet for the ATmega328P processor. You set the PWM frequency by controlling the clock frequency (16 MHz system clock divided by the prescale value you pick from a table) and the TOP value (the count at which the counter reverses direction). The duty cycle can be adjusted between 0 and TOP by setting the value in the Output Compare Register for the output pin.

By minimizing the prescale you maximize TOP for a given frequency. By maximizing TOP you maximize the number of steps available in your Duty Cycle choice. TOP, however, can't go over 65535 for a 16-bit timer (255 for an 8-bit timer).

Infraviolet:
I understand tat an atmega328p as contained in an uno has 3 timers built in, and if you mess with two of them you interfere with clock timings for delay() and such, but the third can be freely edited, though I'm not sure if you can do custom frequencies or just pick from a list of frequencies separated by multiples of two.

Out of the box:
Only timer0 is used for millis/micros/delay
timer0 (8 bit) also controls PWM output pins 5, 6, using fast PWM mode and a period of 1.024ms
timer1 (16 bit) controls PWM output pins 9, 10, using phase-correct PWM mode and a period of 2.04ms
timer2 (8 bit) controls PWM output pins 11, 3, using phase-correct PWM mode and a period of 2.04ms

The chip datasheet explains in full detail how each timer functions, they are each different in detail alas, although
very similar.

Thanks for this info, but I swear that somewhere I read something suggesting that there are two timers which if altered will interfere with normal functions. Rather than just timer0 (pins 5 and 6) being the one you mustn't edit if you want the arduino to work normally.

There are libraries that use timers. Most common are Servo, SoftwareSerial, and the third-party IRremote.

Further in regard to this I've been trying to write some code based on a sample of Nick gammon's which I found ( How to create a 38 Khz pulse with arduino using timer or PWM? - Programming Questions - Arduino Forum ) on these forums from 2012 ish. He had it working for pin 11, but I also need to do a similar thing for pins 9 and 10. Each pin must be able to make a 38KHz output, with the others being off at the time. I wrote some functions to do this but am not sure if I've correctly modified the various pieces of low level code which control the timer registers, can anyone advise whether the code below should work? (I can't test it myself for a while, I'm having to write up some code for now but won't be able to truly test it for some weeks until I'm back in a place where I can get at an oscilloscope). I can confirm that it does compile.

Thanks

The code is below, it's just a few functions which I think should be fairly obvious from name what each does, I've got three different pins 11, 10 and 9 acting as PWM outputs. At any given time only one of them is needed. I hope to use these functions by using one function to start the pulsed output, and then the corresponding one to stop it after a delay of a specific number of microseconds. I cannot use interrupts for this (I've already got fat too many interrupts in use in other parts of my code) and have previously tried fast bit banging with port manipulation but think that using hardware PWM timers will be more accurate. The ideas of having a separate PWM pin for a bright, medium and dim LED might seem a little strange but given the circuitry in which this operates it is the best option.

void Start_LED_38KHz_Bright(){//gives hardware controleld 38.095KHz PWM output on pin 11
  TCCR2A = _BV (COM2A0) | _BV(WGM21);  // CTC, toggle OC2A on Compare Match
  TCCR2B = _BV (CS20);   // No prescaler
  OCR2A =  209;          // compare A register value (210 * clock speed)= 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095
  PORTD &= ~(1<<PORTD3); //ensures that the d3 pin doesn't pulse while pin 11 does
}

void Start_LED_38KHz_Medium(){//gives hardware controleld 38.095KHz PWM output on pin 10
  TCCR1A = _BV (COM1B0) | _BV(WGM21);  // CTC, toggle OC1B on Compare Match
  TCCR1B = _BV (CS20);   // No prescaler
  OCR1A =  209;          // compare A register value (210 * clock speed)= 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095
  PORTB &= ~(1<<PORTB1); //stops pin 9 pulsing when pin 10 is pulsed
}

void Start_LED_38KHz_Dim(){//gives hardware controleld 38.095KHz PWM output on pin 9
  TCCR1A = _BV (COM1A0) | _BV(WGM21);  // CTC, toggle OC1A on Compare Match
  TCCR1B = _BV (CS20);   // No prescaler
  OCR1A =  209;          // compare A register value (210 * clock speed)= 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095
  PORTB &= ~(1<<PORTB2); //stops pin 10 pulsing when pin 9 is pulsed
}

void Stop_LED_38KHz_Bright(){//stops pulses on pin 11
  PORTB &= ~(1<<PORTB3);
}

void Stop_LED_38KHz_Medium(){//stops pulses on pin 10
  PORTB &= ~(1<<PORTB2);
}

void Stop_LED_38KHz_Dim(){//stops pulses on pin 9
  PORTB &= ~(1<<PORTB1);
}

An example of my planned usage for these functions is:

Start_LED_38KHz_Bright();
delayMicroseconds(263);
Stop_LED_38KHz_Bright();

P.S. I'm assuming that none of these timer pieces of possible code that I've posted should have any problematic effect on other timers such as the one which controls delay()?

The functions I discussed in post #7 never seemed to work, I can't tell why though. They didn't cause the relevant pins to come on at all let alone flash at 38KHz (I was monitoring with an oscilloscope). I can't quite work out why. Thanks

Re your #7. That is true in the sense that all timers are initialized (in the background) to enable PWM. In that way analogWrite will work on the prescribed pins without the developer having to muck with the timers. Most of the Arduino pins have multiple functions. They can be left alone and it's up to you to configure them for use or, they can be pre-configured for one of the optional functions available. It was the decision of the develioers of the IDE to configure them for PWM thinking most users would play with servo motors. So yes, if you make changes you will affect PWM, but isn't that what you're doing anyhow? The comments regarding timer0 and millis et al, are still valid.