nano timers

I've made this code for a 38kHz signal on pin PB1 on a NANO. It's modelled after code I used for an Attiny85 provided by user dc42 here(reply #3)

setup(
   // TIMER 1 for interrupt frequency 38004.750593824225 Hz:
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B


  // turn on CTC mode
TCCR1B |= (1 << WGM12);
  // Set CS12, CS11 and CS10 bits for 8 prescaler
TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
  // enable timer compare interrupt
//TIMSK1 |= (1 << OCIE1A);
  // set compare match register for 38004.750593824225 Hz increments

  
GTCCR = 0;
OCR1A = 409; // = 16000000 / (1 * 38004.750593824225) - 1 (must be <65536)
)

This code is then used with

void on(){
TCNT1  = 0; // initialize counter value to 0
TCCR1A |= (1 << COM1A0);
}


void off(){
TCCR1A &= ~(1 << COM1A0);
}

This switches the pin on and off as needed.

The Attiny85 version works a charm but I can't get the NANO version going. What am I missing? thanks

There is a formula in the datasheet, try 209 for your OCR1A value.
Also, I'd suggest you don't leave the timer on all the time and just enabling the outputs. Set your TCCR1A value at initialization and in your on function, set the CS10 bit and in the off function clear it.

Did you set PB1 as an OUTPUT?

This, incidentally, controls OC1A and not OC1B :
TCCR1A |= (1 << COM1A0 ) ;

Alternatively, look at the example here:

and search for the title: "Modulating 38 kHz signal"

If you want a 50% duty cycle, just modify the example to fix OCR1B to half of OCR1A

Yet another alternative could be to use the tone library,

Thank you all kindly. I read more and cobbled together something different but working. My understand of the timing registers is a little better - my love of data sheets is just as low as ever.

Nick Gammons 'Modulating a 38 kHz carrier with a 500 Hz signal', on his blog Gammon Forum : Electronics : Microprocessors : Timers and counters is what I used, modified to remove the input variable. It's not the first time Nick Gammon has save the day for me, so an extra thanks to him.

const byte LED = 10;  // Timer 1 "B" output: OC1B

void setup() 
{
  pinMode (PB5, OUTPUT);
  pinMode (LED, OUTPUT);
  
  PORTB |= (1 << PB5);
  delay(300);
  PORTB &= ~(1 << PB5);
  delay(300);

  // set up Timer 1 - gives us 38.500 kHz 
  // Fast PWM top at OCR1A
  TCCR1A = bit (WGM10) | bit (WGM11) | bit (COM1B1); // fast PWM, clear OC1B on compare
  TCCR1B = bit (WGM12) | bit (WGM13) | bit (CS10);   // fast PWM, no prescaler
 
  OCR1A =  419;                 // zero relative 
  OCR1B = 209;             // 50% duty cycle
  
  delay(1000);
  }  // end of setup

void loop()
  {

  delay(5000);
  TCCR1A &= ~(1<<COM1B1);
  delay(3000);
  TCCR1A |= (1<< COM1B1);
  }

I've done as 6v6gt suggests and will use the TCCR1A register as the switch and put that in my on()/off() functions.

Interestingly, the numbers that the original code generated for the OCR1A count didn't produce a 38000Hz signal for me. It was close but needed modified. I'm putting this down to slight variances in IR receiver circuit that's running on a an Attiny85.