I mentioned that a dump load could be written with about six lines of code. It took ten to
perform the basic functions. There is one has an extra line of code that changes the PWM
to 30Hz. This might be slow enough to use those new FET blocks.
The program has a couple features. A switch input allows the set voltage to be set higher
to perform an equalize function. Numbers could be set to a float value when the system is
unattendd for a long period of time. The set voltage is where PWM just begins. A differential
is added to that value to determine when the PWM is fully on. That calculation is performed
by the MAP function. The actual start voltage will have to be determined by actual use. A once
per second blink of the onboard LED provides an indication that the module is functioning.
Additional blinks (4) provide an increasing indication of the PWM level. A diagnostic screen
that can be read in TOOLS provided real time data of program variables. Modifications could
include a pot to manually change the set voltage without connecting the board to a laptop.
An additional useful load, such as a circulating fan, could also be added to the program. Why
just waste energy. A second PWM output could be used for a water heater. When that has taken
the maximum energy, the additional energy can be sent to the dump load.
/*
PWM_DUMP_1 dump load controller
1. Read battery voltage on A0
2. Read switch input to determine set voltage
3. Determine output PWM value using MAP
4. Send out PWM at a slow freq of 30Hz
5. Provide diagnostic screen
Upon posting, this document is considered “uncontrolledâ€.
Please contact me for the most current version.
Created 12/17/2016
*/
// Declare variables as integers and set initial values
int AI0 = 0; // Battery raw A/D conversion
int blinktime = 0; // blink counter
int SETvolt = 0; // selected set voltage
int PWMdrv = 0; // PWM output drive
int Xbattery = 0; // multiplied raw battery
int battery = 0; // battery voltage to two decimal places
int differential = 25; // difference between start and end voltage .25V
int HIGHvolt1 = 1430; // charge voltage SWITCH OPEN
int HIGHvolt0 = 1510; // charge voltage SWITCH CLOSED
int seconds = 0;
int minutes = 0;
void setup()
{
// initialize the digital pins
// Pin 13 has LED on Arduino UNO board
pinMode(13, OUTPUT); // board LED output enabled
pinMode(2, INPUT); // switch on pin 2 input enabled
digitalWrite (2, HIGH); // add pullup to input
Serial.begin (9600); // Set up serial monitor routine
}
void loop() { // This is the start of the program
// LOWER THE PWM FREQUENCY FOR LOWER FET HEATING
// This changes the frequency of PWM pins 11 & 3 ONLY
// Fewer transitions = less FET heat created
// Pins 11 and 3 for 16MHz clock
// Setting Divisor Hz
// 0x01 1 31250
// 0x02 8 3906
// 0x03 32 976
// 0x04 64 488
// 0x05 128 244
// 0x06 256 122
// 0x07 1024 30
// PWM pins 9 & 10
// TCCR1B = TCCR1B & 0b11111000 | <setting>;
TCCR1B = TCCR1B & 0b11111000 | 0x07 ; // 30Hz PWM operation
// DETERMINE WHICH UPPER VOLTAGE TO USE
// this is optional, and allows equalize or float to be performed
if (digitalRead (2) == 1) SETvolt = HIGHvolt1; // read switch for enable, ON if left open
else SETvolt = HIGHvolt0; // read switch for enable, ON if left open
// This section reads the analog signals. Range is 0 to 5V DC or 0 to 1023 counts
AI0 = analogRead (0); // Read the battery voltage PIN #A0
// MULTIPLY RAW DATA VALUE BY 8 TO GET (12V) 4X BATTERY
// MULTIPLY RAW DATA VALUE BY 16 TO GET (24V) 4X BATTERY
// MULTIPLY RAW DATA VALUE BY 32 TO GET (48V) 4X BATTERY
// Limit is 48V (80V max input) use 16 / 4 for higher voltage
// A/D of 1023 will not overload or go to unsigned for higher V
// Multiple samples filters out noise by averaging
// Binary multiply/divide is fast with 2,4,8,16,32
Xbattery = Xbattery - Xbattery / 8; // subtract one average reading
Xbattery = Xbattery + AI0; // add in a new reading
battery = Xbattery / 4; // calc BATTERY to two decimal places, .01V
// divide by 4 to get battery
// DETERMINE CORRECT PWM VALUE
// input , lower volt, upper volt, lower output, upper output
PWMdrv = map (battery, SETvolt, SETvolt + differential, 0, 255);
// SETvolt + differential is 250mV (25) above set point
// SETT UPPER AND LOWER LIMIT OF PWM
if (PWMdrv < 10) PWMdrv = 0;
if (PWMdrv > 245) PWMdrv = 255;
// SEND OUT THE PWM
analogWrite (11, PWMdrv);
delay (15); // set loop timing for 1 second
// **********EVERYTHING BELOW THIS IS OPTIONAL**************
// Just ten lines of code above will make this functional
// BLINK and COUNT TIMERS
// This section has count routine
blinktime = blinktime + 1; // increment blink counter
if (blinktime == 100) // 100 ish is about 1 second
{
blinktime = 0; // Reset blink counter
seconds = seconds +1; // increment seconds
}
if (blinktime == 0 && seconds >= 60) // 60 is 1 minute
{
minutes = minutes +1; // add a minute
seconds = 0; // reset seconds
}
// RESET MINUTES EACH WEEK
if (minutes > 10080) minutes = 0; // Prevents overload
// BLINK LED TO SHOW RUNNING
if (blinktime == 0) digitalWrite (13,HIGH); // processor on blink #1
if (blinktime == 5) digitalWrite (13,LOW);
// BLINK LED TO SHOW POWER LEVEL
if (PWMdrv >= 10 && blinktime == 10) digitalWrite (13, HIGH); // low PWM
if (blinktime == 20) digitalWrite (13, LOW);
if (PWMdrv >= 50 && blinktime == 30) digitalWrite (13, HIGH); // some WM
if (blinktime == 40) digitalWrite (13, LOW);
if (PWMdrv >= 100 && blinktime == 50) digitalWrite (13, HIGH); // moderate PWM
if (blinktime == 60) digitalWrite (13, LOW);
if (PWMdrv >= 150 && blinktime == 60) digitalWrite (13, HIGH); // strong PWM
if (blinktime == 70) digitalWrite (13, LOW);
if (PWMdrv >= 200 && blinktime == 80) digitalWrite (13, HIGH); // high PWM
if (blinktime == 90) digitalWrite (13, LOW);
// SCREEN PRINT ROUTINE
if ( blinktime == 0)
{
Serial.print (AI0);
Serial.print (" ");
Serial.print ((float)SETvolt / 100);
Serial.print (" ");
Serial.print ((float)battery / 100);
Serial.print ("V ");
Serial.print ((float)(SETvolt + differential) / 100);
Serial.print (" .");
Serial.print (differential);
Serial.print (" DIFF ");
Serial.print (PWMdrv);
Serial.print (" DRIVE ");
if (digitalRead (2) == 1) Serial.print ("SW OPEN ");
else Serial.print ("SW CLOSED ");
Serial.print (minutes);
Serial.print (":");
Serial.print (seconds);
Serial.print(" ");
Serial.print (Xbattery);
Serial.println(" Xbat"); // start new line
}
} // END of the program loop