1

I need to drive a LED strip via MOSFET module. The module needs a high resolution PWM for very dim conditions. How can I set my pin to a 16 bit PWM resolution on an Arduino Nano Every?

awado
  • 113
  • 4

2 Answers2

4

It's possible for D5 (TCA0-WO2) + D9 (TCA0-WO0) + D10 (TCA0-WO1) all three of them will be 16bit if you change TCA0 top value, but you can't use analogWrite.

void setup() {
  // change period of TCA0 (already configured and started by arduino core)
  TCA0.SINGLE.PER = 0xFFFF; // change top value from 255 to 65535

// set PWM value of D9 (channel 0) TCA0.SINGLE.CMP0 = 0; // initial value // enable PWM output (needed only once in setup) pinMode(9, OUTPUT); // setup pin as an output TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP0EN_bm; // enable pwm->pin

// D5 TCA0.SINGLE.CMP2 = 1; // initial value pinMode(5, OUTPUT); TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP2EN_bm;

// D10 TCA0.SINGLE.CMP1 = 65530; // initial value pinMode(10, OUTPUT); TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm; }

and in the code you'll use only TCA0.SINGLE.CMPn = val; where n is 0..2

(untested, but should be working)

EDIT: I forgot the period will be 3.8Hz, so you'll need to change also TCA0 prescaller or use smaller precision like 10b or so. Changing prescaller will mess up the all the TCB counters periods along with the one used for millis counter so you'd need also change that

EDIT2: for classic UNO/nano it'll look like this:

TCCR1B = 0; // stop timer

ICR1 = 0xFFFF; // f = 16MHz / (2NICR1) = 16MHz / (2*65536) => ~122Hz OCR1A = 1; // PB2 -> D9 (PWM value) TCCR1A = _BV(COM1A1); // enable PWM output on PB2 TCCR1B = _BV(WGM13) | _BV(CS10); // mode=8 (phase and freq correct, ICR1 as top) and start timer with prescaller /1

KIIV
  • 4,907
  • 1
  • 14
  • 21
0

Thanks again for your help KIIV. I can confirm it works. This an example of a low light PWM for an LED on Pin 10. Maybe it helps others.

int brightness = 0;  // how bright the LED is
int fadeAmount = 1;  // how many points to fade the LED by

void setup() { TCA0.SINGLE.PER = 0x4000; TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV16_gc | 1 << TCA_SINGLE_ENABLE_bp TCA0.SINGLE.CMP1 = 65530; // initial value pinMode(10, OUTPUT); TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP1EN_bm; }

void loop() { // set the brightness of LED pin: TCA0.SINGLE.CMP1 = brightness;

// change the brightness for next time through the loop: brightness = brightness + fadeAmount;

// reverse the direction of the fading at the ends of the fade: if (brightness <= 0 || brightness >= 64) { fadeAmount = -fadeAmount; } // wait to see the dimming effect delay(50); }

awado
  • 113
  • 4