NittyGritty

PWM_Fan.ino

Feb 1st, 2018
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.17 KB | None | 0 0
  1. int pwmPin   = 10;   // fan PWM -> connected to digital pin 9
  2. int pwmVal   = 0;
  3. int DEBUG    = 1; // DEBUG counter; if set to 1, will write values back via serial
  4.  
  5. // Definition of Arduino type
  6. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  7. #define  IS_MEGA  (1)
  8. #define  IS_UNO   (0)
  9. #else
  10. #define  IS_MEGA  (0)
  11. #define  IS_UNO   (1)
  12. #endif
  13.  
  14. // Analog output (i.e PWM) pins. These must be chosen so that we can change the PWM frequency without affecting the millis()
  15. // function or the MsTimer2 library. So don't use timer/counter 1 or 2. See comment in setup() function.
  16. // THESE PIN NUMBERS MUST NOT BE CHANGED UNLESS THE CODE IN setup(), setTransistorFanSpeed() AND setDiodeFanSpeed() IS CHANGED TO MATCH!
  17. #if IS_UNO
  18. // On the Uno we can only use the OC1B pin, so these pin numbers are both 10
  19. const int transistorFanPin = 10;     // OC1B
  20. const int diodeFanPin = 10;          // OC1B
  21. #else
  22. // On the Mega we use OC1B and OC1C
  23. const int transistorFanPin = 12;     // OC1B
  24. const int diodeFanPin = 13;          // OC1C
  25. #endif
  26.  
  27. // Definitions for PWM fan control
  28. const unsigned char maxFanSpeed = 80;   // this is calculated as 16MHz divided by 8 (prescaler), divided by 25KHz (target PWM frequency from Intel specification)
  29.  
  30. void setup()
  31. {
  32.  
  33.   pinMode(pwmPin, OUTPUT);   // sets the pin as output
  34.  
  35.   if (DEBUG) {
  36.     Serial.begin(9600);
  37.     Serial.println('Serial Init');
  38.   }
  39.  
  40.   // Set up the PWM pins for a PWM frequency close to the recommended 25KHz for the Intel fan spec.
  41.   // We can't get this frequency using the default TOP count of 255, so we have to use a custom TOP value.
  42.  
  43. #if IS_UNO
  44.  
  45.   // Only timer/counter 1 is free because TC0 is used for system timekeeping (i.e. millis() function),
  46.   // and TC2 is used for our 1-millisecond tick. TC1 controls the PWM on Arduino pins 9 and 10.
  47.   // However, we can only get PWM on pin 10 (controlled by OCR1B) because we are using OCR1A to define the TOP value.
  48.   // Using a prescaler of 8 and a TOP value of 80 gives us a frequency of 16000/(8 * 80) = 25KHz exactly.
  49.   TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) | (1 << WGM10);  // OC1A (pin 9) disconnected, OC1B (pin 10) = inverted fast PWM  
  50.  #ifdef FAN_AUDIO_TEST
  51.   // test code to get 440Hz output (= concert A) to test the logic
  52.   OCR1AH = 0;
  53.   OCR1BL = 71;  // 50% duty cycle
  54.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12);  // TOP = OCRA, prescaler = 256
  55.  
  56.   OCR1AL = 141; // TOP = 141, 16000000 / (256 * 142) = 440.014
  57.   OCR1BH = 0;
  58.  #else
  59.   OCR1AH = 0;
  60.   OCR1AL = 79;  // TOP = 79
  61.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR0A, prescaler = 8
  62.  
  63.   OCR1BH = 0;
  64.   OCR1BL = maxFanSpeed;  // max fan speed (i.e. pin 5 initially low all the time)  
  65.  #endif
  66.  
  67.   TCNT1H = 0;
  68.   TCNT1L = 0;
  69. #else
  70.  
  71.   // On the Mega we use TC1 and OCR1B, OCR1C
  72.   TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1) | (1 << COM1C1) | (1 << WGM11) | (1 << WGM10);  // OC1A disconnected, OC1B = OC1C inverted fast PWM  
  73.   TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR1A, prescaler = 8
  74.   TCCR1C = 0;
  75.   OCR1AH = 0;
  76.   OCR1AL = 79;  // TOP = 79
  77.  
  78.   OCR1BH = 0;
  79.   OCR1BL = maxFanSpeed;
  80.   OCR1CH = 0;
  81.   OCR1CL = maxFanSpeed;
  82.  
  83.   TCNT1H = 0;
  84.   TCNT1L = 0;
  85. #endif
  86.  
  87.   // We have to enable the ports as outputs before PWM will work.
  88.   pinMode(transistorFanPin, OUTPUT);
  89.   pinMode(diodeFanPin, OUTPUT);
  90. }
  91.  
  92. // Set the transistor fan speed, where 0 <= fanSpeed <= maxFanSpeed
  93. void setTransistorFanSpeed(unsigned char fanSpeed)
  94. {
  95.   OCR1BH = 0;
  96.   OCR1BL = fanSpeed;
  97. }
  98.  
  99. // Set the diode fan speed, where 0 <= fanSpeed <= maxFanSpeed
  100. void setDiodeFanSpeed(unsigned char fanSpeed)
  101. {
  102. #if IS_UNO
  103.   OCR1BH = 0;
  104.   OCR1BL = fanSpeed;
  105. #else
  106.   OCR1CH = 0;
  107.   OCR1CL = fanSpeed;
  108. #endif
  109.  
  110. }
  111.  
  112. // Main program
  113. void loop()
  114. {
  115.      analogWrite(pwmPin, pwmVal);
  116.  
  117.      if (DEBUG) { // If we want to read the output
  118.       if (pwmVal < maxFanSpeed) {
  119.          pwmVal += 2;
  120.          Serial.println(pwmVal);  // Print red value
  121.       } else {
  122.         pwmVal = 0;
  123.          Serial.println('at max high');  // Print red value
  124.       }
  125.     }
  126.     delay(1000); // Pause for 'wait' milliseconds before resuming the loop
  127. }
Add Comment
Please, Sign In to add comment