ARDUINO based four relay dump load controller with individual software set points and delays. Easy way to
build a dump load to control up to four heater relays. Relay drivers turn on at full power and then
slowly reduce drive to 65% duty cycle by PWM to save coil heating. Relays must have a diode. Just add a
cheap ebay FET board to drive your big relay. Set points are set in software as well as hystresis and time
delays. Data goes out to the Arduino compiler serial screen for easy setup every two seconds. Time delays
are in 1/8 second increments. A/D multiplier can be changed to other values. Get it close and a little pot
adjustment will read out the data directly in volts. On board LED blinks to indicate the number of relays on.
Software written so a beginner can understand and modify to their situation.
A/D input = A0
Relay #1 = D3
Relay #2 = D11
Relay #3 = D9
Relay #4 = D10
/*
RELAY_4_DELAY Program for 4 voltage relays with time delay.
Relay drivers have a stepped PWM that reduces current and coil heating.
Diodes must be used across relay coil, PWM rate 240Hz.
Time interval for each loop is every 1/8 second.
Condition must be present X loops otherwise timer counter is reset.
On board LED #13 will blink periodically to show micro is working.
Extra blink for each additional relay.
Serial print of data periodically.
Adjusting input voltage and multiplier gives direct volt reading
Ver 1.1 04/09/18 semi working baseline program
revised 04/00/18
The following two characters * and / end a multi line comment
*/
// Declare program variables as integers and set initial values
int ADavg = 0; // multiplied average A/D value
int SETpoint_1 = 2000; // relay #1 set point
int HYST_1 = 70; // HYST
int count_1 = 0; // counts at voltage
int Tcount_1 = 40; // 8 counts per second
int SETpoint_2 = 2100; // relay #2 set point
int HYST_2 = 70; // HYST
int count_2 = 0; // counts at voltage
int Tcount_2 = 50; // 8 counts per second
int SETpoint_3 = 2200; // relay #3 set point
int HYST_3 = 70; // HYST
int count_3 = 0; // counts at voltage
int Tcount_3 = 60; // 8 counts per second
int SETpoint_4 = 2300; // relay #4 set point
int HYST_4 = 70; //HYST
int count_4 = 0; // counts at voltage
int Tcount_4 = 70; // 8 counts per second
int RELAY_1 = 0; // #1 relay ON/OFF state pin#3 TCCR2B
int RELAY_2 = 0; // #2 relay ON/OFF state pin#11 TCCR2B
int RELAY_3 = 0; // #3 relay ON/OFF state pin#9 TCCR1B
int RELAY_4 = 0; // #4 relay ON/OFF state pin#10 TCCR1B
int blinktime = 0; // Used to blink LED & relays on
void setup() {
// initialize the digital pins as outputs.
// Pin 13 is on board LED and is a visual
// indicator the micro is working
pinMode(13, OUTPUT); // Onboard Monitor LED
pinMode(11, OUTPUT); // 244Hz PWM #2 (reference only)
pinMode(10, OUTPUT); // 244Hz PWM #4 (reference only)
pinMode(9, OUTPUT); // 244Hz PWM #3 (reference only)
pinMode(3, OUTPUT); // 244Hz PWM #1 (reference only)
Serial.begin (9600); // serial routine, 9600 baud
} // End setup
void loop() { // start of the program loop
// ****************************************************
// LOWER THE PWM FREQUENCY FOR RELAY DRIVER
// This changes the frequency of PWM pins 11 & 3 ONLY
// Fewer transitions = less heat created
// Pins 11 and 3 for 16MHz clock
// Settinng Divisor Hz
// 0x01 1 31250
// 0x02 8 3906
// 0x03 32 976
// 0x04 64 488
// 0x05 128 244
// 0x06 256 122
// 0x07 1024 30
// TCCR2B = TCCR2B & 0b11111000 | <setting>;
TCCR2B = TCCR2B & 0b11111000 | 0x06; // PWM rate 11 & 3
// PWM pins 9 & 10 These you can change as above
// TCCR1B = TCCR1B & 0b11111000 | <setting>;
TCCR1B = TCCR1B & 0b11111000 | 0x06 ; // PWM rate 9 & 10
//Pins 5 and 6: Standard
// changing this changes program delay times AVOID
//Setting Divisor Frequency
// 0x03 64 976
//TCCR0B = TCCR0B & 0b11111000 | 0x03 ;
// ******************************************************
// This section reads the analog signals. Range is 0 to 5V
// or 0 to 1023 and totals up four readings to remove noise
// which can be several counts. Average should closely match
// raw A/D value X 4. Change this value for different multipliers.
// Values over 8 can lead to over run and errors.
ADavg = ADavg - ADavg/4; // Subtract average reading
ADavg = ADavg + analogRead (0); // add new reading reading
// #########################################################
// RELAY CONTROL
// This section controls the up/down count for the 4 relays
// shown. PWM goes from ON 255 at start down to 165 (65%).
// Change for fully on or less ending drive.
// OFF PWM drive goes to zero. This reduces relay heating.
// RELAY #1
if (ADavg < SETpoint_1 - HYST_1) count_1 = count_1 - 1; // voltage less, reset count
if (ADavg > SETpoint_1) count_1 = count_1 + 1; // voltage higher, increase count
if (count_1 <= 0) count_1 = 0; // limit lower range of count
if (count_1 >= Tcount_1) count_1 = Tcount_1; // limit upper range of count
if (count_1 == 0 ) RELAY_1 = 0; // turn relay OFF when count zero
if (count_1 == Tcount_1 && RELAY_1 == 0) RELAY_1 = 255; // turn relay ON if prior off state
// and count reached timer limit
if (RELAY_1 > 0 && RELAY_1 > 165 ) RELAY_1 = RELAY_1 - 5; // if on reduce relay drive to minimum
analogWrite(3, RELAY_1); // send relay value
// RELAY #2
if (ADavg < SETpoint_2 - HYST_2) count_2 = count_2 - 1; // voltage less, reset count
if (ADavg > SETpoint_2) count_2 = count_2 + 1; // voltage higher, increase count
if (count_2 <= 0) count_2 = 0; // limit lower range of count
if (count_2 >= Tcount_2) count_2 = Tcount_2; // limit upper range of count
if (count_2 == 0 ) RELAY_2 = 0; // turn relay OFF
if (count_2 == Tcount_2 && RELAY_2 == 0) RELAY_2 = 255; // turn relay ON if prior off state
if (RELAY_2 > 0 && RELAY_2 > 165 ) RELAY_2 = RELAY_2 - 5; // if on reduce relay drive to minimum
analogWrite(11, RELAY_2); // send relay value
// RELAY #3
if (ADavg < SETpoint_3 - HYST_3) count_3 = count_3 - 1; // voltage less, reset count
if (ADavg > SETpoint_3) count_3 = count_3 + 1; // voltage higher, increase count
if (count_3 <= 0) count_3 = 0; // limit lower range of count
if (count_3 >= Tcount_3) count_3 = Tcount_3; // limit upper range of count
if (count_3 == 0 ) RELAY_3 = 0; // turn relay OFF
if (count_3 == Tcount_3 && RELAY_3 == 0) RELAY_3 = 255; // turn relay ON if prior off state
if (RELAY_3 > 0 && RELAY_3 > 165 ) RELAY_3 = RELAY_3 - 5; // if on reduce relay drive to minimum
analogWrite(9, RELAY_3); // send relay value
// RELAY #4
if (ADavg < SETpoint_4 - HYST_4) count_4 = count_4 - 1; // voltage less, reset count
if (ADavg > SETpoint_4) count_4 = count_4 + 1; // voltage higher, increase count
if (count_4 <= 0) count_4 = 0; // limit lower range of count
if (count_4 >= Tcount_4) count_4 = Tcount_4; // limit upper range of count
if (count_4 == 0 ) RELAY_4 = 0; // turn relay OFF
if (count_4 == Tcount_4 && RELAY_4 == 0) RELAY_4 = 255; // turn relay ON if prior off state
if (RELAY_4 > 0 && RELAY_4 > 165 ) RELAY_4 = RELAY_4 - 5; // if on reduce relay drive to minimum
analogWrite(10, RELAY_4); // send relay value
// #################################################################################
// This section blinks the on board LED #13
blinktime = blinktime + 1; // increment blink timer each loop
if (blinktime >= 16) blinktime = 0; // 16 loops each blink cycle, reset count
// This section blinks LED ONCE to show program is operating
if (blinktime == 1) digitalWrite (13, LOW); // LED OFF, INSURE INITIAl OFF
if (blinktime == 2) digitalWrite (13, HIGH); // LED ON, ONE BLINK, CPU RUNNING
if (blinktime == 3) digitalWrite (13, LOW); // turn LED OFF
// This section blinks LED to show relays on, STATUS LED #13
// Relay is on any time value is greater than zero
if (blinktime == 5 && RELAY_1 > 0) digitalWrite( 13, HIGH); // LED ON Second BLINK RELAY_1
if (blinktime == 6) digitalWrite (13, LOW); // turn LED OFF
if (blinktime == 7 && RELAY_2 > 0) digitalWrite (13, HIGH); // LED ON Third BLINK RELAY_2
if (blinktime ==
digitalWrite (13, LOW); // turn LED OFF
if (blinktime == 9 && RELAY_3 > 0) digitalWrite (13, HIGH); // LED ON Fourth BLINK RELAY_3
if (blinktime == 10) digitalWrite (13, LOW); // turn LED OFF
if (blinktime == 11 && RELAY_4 > 0) digitalWrite (13, HIGH); // LED ON Fifth BLINK RELAY_4
if (blinktime == 12) digitalWrite (13, LOW); // turn LED OFF
// ###############################################################################
// This section prints the values to the programmers serial screen. Printing takes
// time. Done after a number of program loops. This speeds up the loop and reading
// data easier
if (blinktime == 14) // if count reached, do following between brackets
{ // start of stuff to do
Serial.print(ADavg); // multiplied A/D value of readings
Serial.print(" avg ");
Serial.print(SETpoint_1); // relay set point
Serial.print(" ");
Serial.print(SETpoint_2);
Serial.print(" ");
Serial.print(SETpoint_3);
Serial.print(" ");
Serial.print(SETpoint_4);
Serial.print(" SET ");
Serial.print(count_1); // timer of each RELAY
Serial.print(" "); // 8 counts = 1 second
Serial.print(RELAY_1); // PWM value 0-255
Serial.print(" ");
Serial.print(count_2);
Serial.print(" ");
Serial.print(RELAY_2);
Serial.print(" ");
Serial.print(count_3);
Serial.print(" ");
Serial.print(RELAY_3);
Serial.print(" ");
Serial.print(count_4);
Serial.print(" ");
Serial.print(RELAY_4);
Serial.println(" cnt/drv");
// This println is like the carrage return
// if you know what a typwriter is
} // end bracket end of printing stuff
// ###########################################
delay (120); // 120ms loop delay, 8 loops = 1 second
} // END of the program loop