Advertisement
NittyGritty

Arduino_PWM_Fan

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