Hi,
I'm working on a computer fan control project that contains three parts with one wire setting using an Arduino Mega2560 :
- to set 10 fans at the same speed with 10 PWM outputs on the board.
- use PWM control to be able to set 10 different fans at different speed (with different % duty cycle) and each pin outputs to each fan.
- set 10 fans at the same speed but the speed can change over time as settled (for example, ramp down first and stay at low speed for 10 seconds and then speed up again).
I'm totally new to Arduino and wasn't great at coding either so I really need some guidance on the project and this is what I have done so far.
I chose PWM outputs 2..11 on the Mega2560 board as the 10 outputs (because I want to avoid rewiring every time I change different modes I described above, I chose to use one PWM output for each fan). The code I wrote before for part 1) looks like this: (you can type the % duty cycle in the setup section and upload it to the board)
unsigned int dc=20 ; // % duty cycle that you can set yourself
float t; // timevoid setup(){
pinMode(2, OUTPUT); //fan1
pinMode(3, OUTPUT); //fan2
pinMode(4, OUTPUT); //fan3
pinMode(5, OUTPUT); //fan4
pinMode(6, OUTPUT); //fan5
pinMode(7, OUTPUT); //fan6
pinMode(8, OUTPUT); //fan7
pinMode(9, OUTPUT); //fan8
pinMode(10, OUTPUT); //fan9
pinMode(11, OUTPUT); //fan10
}void loop(){
t=40.00*(float)dc/100.00; //unit is "us", gives 25kHz PWM output
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
delayMicroseconds(t);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
delayMicroseconds(40.00-t);
}
The fans requires a PWM frequency at 25kHz and that's why I chose 40 us as one period. However, I heard that digitalWrite takes a few us to run (maybe even longer?) and therefore the PWM frequency to the fans are no longer 25kHz, but lower than that. Also, part 2) & 3) are time sensitive (especially 3) because 10 fans should be the same speed at any given time) so I thought I should probably look for some other ways to do this.
I read through some other posts and people suggested use port manipulation (Arduino Reference - Arduino Reference) because that runs much faster and you can turn on/off a few pins at exactly the same time. The reference and playground doesn't give information on Mega2560 because I think it uses ATmega2560 rather than ATmega168 or ATmega8 so the pins/ports are different.
I saw this link from another post shows the ports map for 2560(?)Arduino Pins - Google Drive and therefore wrote this following code with ports correspond to the spreadsheet and first tried to blink the LED on PWM channel 13 but nothing happened (still trying for part 1)):
void setup(){
DDRE = B00111000;//PWM pins 5,3,2 set as output according to the map because pin 5,3,2 are listed as PE5,PE4,PE3. similar with the rest
DDRH = B01111000;//PWM pins 10,8,7,6 set as output
DDRB = B11110000;//PWM pins 4,12,11,9 set as output
DDRG = B00100000;//PWM pin 13 set as output
PORTE &= B11000111;//Turn off pins 5,3,2
PORTH &= B10000111;//Turn off pins 10,8,7,6
PORTB &= B00001111;//Turn off pins 4,12,11,9
PORTG &= B11011111;//Turn off pin 13
}void loop(){
//trying to blink
PORTG = B00100000;//pin 13 on
delay(1000);//for 1 second
PORTG = B00000000;//pin 13 off
delay(1000);//for 1 second
}
So, I'm wondering if you guys would like to help me out on where I did wrong for the code and any suggestions on how to achieve part 2) & 3). [For part 2), I was thinking of having 10 different % duty cycle input that I can set different numbers in and upload to the board so each fan would run at that assigned % duty cycle until I interrupt or upload new code. And for part 3), I want the fans to run a set-up duty cycle profile over time then either loop back to repeat or just stay at low until I interrupt or upload new code.]
Any help would be really appreciated!
Thanks!
Ash