PWM, Register and mystery

Hi there,

I’m a newbie to electronics, programing and of course, arduino so don’t hesitate to tell me everything you feel.

This is my first post and my first question not fully answered on this forum or internet.

The project is about to control a 12v PC fan with Arduino Mega 2560.

The schematic is simple, 12v to the 4 wire pwm fan, ground tied with arduino’s ground, analog 10 pin to the tachometer fan’s pin, digital 12 to the PWM Control Fan’s pin. Furter improvements will include a potentiometer and a relay to power on/of and for speed control.

I have the sensation I’m going to burn up my arduino if don’t use some protection but don’t know what or where , so if you have any advice please just let me know.

I’m using a code provided for dc42 to another newbie like me, it was simplified a bit, also added some readings an writings to see better what is going on, I have to say that the led on digital 13 is visible changing power, but on FAN the changes is more than a feeling than an obvious change.

This is the code:

// Definition of Arduino type
// Analog output (i.e PWM) pins. These must be chosen so that we can change the PWM frequency without affecting the millis()
// function or the MsTimer2 library. So don't use timer/counter 1 or 2. See comment in setup() function.
// THESE PIN NUMBERS MUST NOT BE CHANGED UNLESS THE CODE IN setup(), setTransistorFanSpeed() AND setDiodeFanSpeed() IS CHANGED TO MATCH!

// On the Mega we use OC1B and OC1C
const int transistorFanPin = 12;     // OC1B
const int diodeFanPin = 13;          // OC1C

// Definitions for PWM fan control
const unsigned char maxFanSpeed = 80;   // this is calculated as 16MHz divided by 8 (prescaler), divided by 25KHz (target PWM frequency from Intel specification) 

void setup()
{
   Serial.begin(9600);
   
  // Set up the PWM pins for a PWM frequency close to the recommended 25KHz for the Intel fan spec.
  // We can't get this frequency using the default TOP count of 255, so we have to use a custom TOP value.
  
  // On the Mega we use TC1 and OCR1B, OCR1C
  TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << COM1C1) | (1 << COM1C1) | (1 << WGM11) | (1 << WGM10);  // OC1A disconnected, OC1B = OC1C inverted fast PWM  
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);  // TOP = OCR1A, prescaler = 8
  TCCR1C = 0;
  OCR1AH = 0;
  OCR1AL = 79;  // TOP = 79

  OCR1BH = 0;
  OCR1BL = maxFanSpeed;
  OCR1CH = 0;
  OCR1CL = maxFanSpeed;
  
  TCNT1H = 0;
  TCNT1L = 0;

  // We have to enable the ports as outputs before PWM will work.
  pinMode(transistorFanPin, OUTPUT);
  pinMode(diodeFanPin, OUTPUT);
}

// Set the transistor fan speed, where 0 <= fanSpeed <= maxFanSpeed
void setTransistorFanSpeed(unsigned char fanSpeed)
{
  OCR1BH = 0;
  OCR1BL = fanSpeed;
}

// Set the diode fan speed, where 0 <= fanSpeed <= maxFanSpeed
void setDiodeFanSpeed(unsigned char fanSpeed)
{
  OCR1CH = 0;
  OCR1CL = fanSpeed;
  Serial.print("Fan Speed: ");
  Serial.println(fanSpeed);
}

void loop()
{
   int Speed;
 
   setTransistorFanSpeed(80);
   setDiodeFanSpeed(80);

   Speed=analogRead(10);
   Serial.print("RPM: ");
   Serial.println(Speed);
 
   delay(30000);

   Speed=analogRead(10);
   Serial.print("RPM: ");
   Serial.println(Speed);
 
   setTransistorFanSpeed(28);
   setDiodeFanSpeed(28);

   delay(30000);
}

but, I really Don’t understand the fisrt part of the code, can anyone explain it in a dummy way?

more than the obvious register name change, what change on this part of code, and what thats mean?

  TCCR2A = 0x23;
  TCCR2B = 0x09;  // select clock
  OCR2A = 79;  // aiming for 25kHz
  pinMode(controlPin, OUTPUT);  // enable the PWM output (you now have a PWM signal on digital pin 3)
  OCR2B = 62;  // set the PWM duty cycle[/i]

I hope not waiting too much, maybe you must point me to some man or help.

Thanks in advantage.
Kind regards.

Hi, welcome to the forum.

Please put your sketch between [code][/code] tags.
You can modify your first post and add that.

Do you have an Arduino Mega 2560 board ?
Are you sure that code will also work on the Arduino Mega 2560 board ?

If you want to know about the registers, this is the manufacturers page:
http://www.atmel.com/devices/atmega2560.aspx
If you open the complete datasheet (the second one is the complete datasheet), you can read all about the registers… it is 435 pages, and you might have to read it 5 times :astonished:

This : TCCR2A = 0x23;
sets the TCCR2A register to 0010 0011 (0x23). That is an internal register inside the microcontroller. The register is for a timer. Every bit has a special meaning in that register.

Is the tach out of a fan a 12V digital signal ? You may never connect that to an Arduino.
Or is it open collector ?

The PWM control for the fan is a 5V signal, that is okay. You could add a protection resistor in the signal line of 100 ohm to 1k.

This seems to be a similar question (from 2008, that is long ago in Arduino years) : http://forum.arduino.cc/index.php?topic=18742.0

Peter_n:
Hi, welcome to the forum.

Thanks!
Sorry I was out for a while.

Peter_n:
Please put your sketch between [code][/code] tags.
You can modify your first post and add that.

Done!

Peter_n:
Do you have an Arduino Mega 2560 board ?
Are you sure that code will also work on the Arduino Mega 2560 board ?

Not really sure, sorry :frowning:

Peter_n:
If you want to know about the registers, this is the manufacturers page:
http://www.atmel.com/devices/atmega2560.aspx
If you open the complete datasheet (the second one is the complete datasheet), you can read all about the registers… it is 435 pages, and you might have to read it 5 times :astonished:

I Did, but understood nothing :stuck_out_tongue:

Peter_n:
Is the tach out of a fan a 12V digital signal ? You may never connect that to an Arduino.
Or is it open collector ?

The PWM control for the fan is a 5V signal, that is okay. You could add a protection resistor in the signal line of 100 ohm to 1k.

The thach is inside the cooler, the reading for the tach are erratics, maybe was not doing fine contac. this is the Fan 4-Wire fans

Peter_n:
This seems to be a similar question (from 2008, that is long ago in Arduino years) : http://forum.arduino.cc/index.php?topic=18742.0

Thanks for the tip, I should continue with the project so i´ll been sticking arround.

The analog input for the tachometer looks a bit weird. I think this can only work if you have some analog filtering before the Arduino input. It may also depend on the exact model of the fan.

The linked web page says there are two pulses on the tach wire for each revolution. If those pulses are made by a simple switch inside the fan then the ratio of on-time to off-time will be the same for all speeds. If it's some digital pulse of a standardised length then the ratio changes as the speed changes. In the first case, an analog filter won't work and in the second case it probably will.

I would prefer to see that tach wire hooked up to a digital input and an interrupt used to count pulses. Depending on the desired RPM, this may not be feasible.