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?
2 Answers
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
- 4,907
- 1
- 14
- 21
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);
}
- 113
- 4