Skip to content

Instantly share code, notes, and snippets.

@awoimbee
Created November 6, 2022 20:49
Show Gist options
  • Save awoimbee/0cd300523df7722a190498df3b49a033 to your computer and use it in GitHub Desktop.
Save awoimbee/0cd300523df7722a190498df3b49a033 to your computer and use it in GitHub Desktop.
Arduino leonardo (atmega32u4) pwm fan control
// CPU freq
#define F_CLK ((long)16000000)
// Standard fan PWM frequency is 25kHz
#define PWM_FREQ ((long)25000)
// e.g. PWM range is reversed on my TFC1212DE
#define REVERSE_PWM 0
/* Takes a percentage and returns the corresponding OCR1 register value */
word percent_to_ocr1(word percentage) {
if (REVERSE_PWM) {
percentage = 100 - percentage;
}
return (ICR1 * percentage) / 100;
}
void setup() {
// Set digital pin 9, 10, 11 to an OUTPUT
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
// Enable the PWM outputs OC1A, OC1B and OC1C on digital pins 9, 10 and 11
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);
// Set phase and frequency correct PWM and prescaler of 1 on timer 1
TCCR1B = _BV(WGM13) | _BV(CS10);
// Set TOP value for phase and phase correct PWM on timer 1 (phase correct counts up & down -> acts like 2x prescale)
ICR1 = (F_CLK - PWM_FREQ) / (2 * PWM_FREQ);
OCR1A = percent_to_ocr1(25); // pin 9
OCR1B = percent_to_ocr1(50); // pin 10
OCR1C = percent_to_ocr1(75); // pin 11
}
void loop() {
for (word i = 20; i <= 100; i += 1) {
OCR1A = percent_to_ocr1(i);
delay(2000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment