This is my first big arduino project so im sure the code could be cleaned up a bit. Basically you push the power button sending power to a relay to power up arduino then pin 2 holds the relay on. Pushing charge button slowly raises alternator output to avoid belt slippage, once up to full voltage I want a quicker response so the alternators don't under/overshoot if the load changes.
Pushing equalize button does the same thing but set point is raised to 15.5V, pushing equalize button again raises set point to 16.2V, pushing again turns output off.
Shut down button writes pin 2 low which releases power relay shutting the system off.
float setPoint = 14.80; //set battery charge voltage to 14.8V (15V)(15.8 - 16.2)Eq
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 103500.0; // resistance of R1 (100K)
float R2 = 10000.0; // resistance of R2 (10K)
int value = 0;
int voltageAdjust = 0; //declair variable
const int charge_button = 5; // the number of the pushbutton pin
const int equalize_button = 6; // the number of the pushbutton pin
const int shutDown_button = 7; //shutdown button pin
const int charge_led = 10; // the number of the LED pin
const int equalize_low_led = 11; // the number of the LED pin
const int equalize_high_led = 12; // equalize high led pin
int buttonState_charge = 0; // variable for reading the charge button status
int buttonState_equalize = 0; // variable for reading the equalize button status
const unsigned long interval = 500; // SETS DELAY TIME FOR BUTTONS
unsigned long previousTime = 0; // delay since last
void setup() {
pinMode(analogInput, INPUT); //battery sense input
pinMode(2, OUTPUT); digitalWrite (2, HIGH); //energize power relay latch
pinMode(3, OUTPUT); //PWM output to pin 3 for alternator field windings
pinMode(13, OUTPUT); digitalWrite(13, HIGH); //power led
pinMode(charge_led, OUTPUT);
pinMode(equalize_low_led, OUTPUT);
pinMode(equalize_high_led, OUTPUT);
pinMode(charge_button, INPUT_PULLUP);
pinMode(equalize_button, INPUT_PULLUP);
pinMode(shutDown_button, INPUT_PULLUP);
}
void loop() {
analogWrite(3, voltageAdjust); //provide PWM at PIN3
// Read voltage of the battery bank
value = analogRead(analogInput); // read the value at analog input
vout = (value * 5.0) / 1024.0; // converts analog signal to voltage
vin = vout / (R2 / (R1 + R2)); // converts voltage to 12V scale
//---- Determine button states ----
unsigned long currentTime = millis(); //millis to debounce buttons (delay)
if (currentTime - previousTime >= interval) {
// Charge Button
int chargebtn = digitalRead(charge_button); //read charge button
if (chargebtn == LOW) {
buttonState_charge ++; //if button pushed then increment up function
voltageAdjust = 0; //return pwm output to 0 at start up
buttonState_equalize = 0; // set equalize off
if (buttonState_charge >= 2) { // return to 0
buttonState_charge = 0;
}
}
//Equalize Button
int equalizebtn = digitalRead(equalize_button); //read equalize button
if (equalizebtn == LOW) {
buttonState_equalize ++; // if button pushed then increment up
voltageAdjust = 0; //return pwm output to 0 at start up
buttonState_charge = 0; // set charge off
if (buttonState_equalize >= 3) { //return to 0
buttonState_equalize = 0;
}
}
//Shut Down Button
if (digitalRead(shutDown_button) == LOW) { //cuts power to latch relay shutting system off
digitalWrite (2, LOW);
}
previousTime = currentTime; // resets millis timer
}
// ---- Functions ----
//Charge Function
if (buttonState_charge == 0) { // off
digitalWrite (charge_led, LOW);
}
if (buttonState_charge == 1) { // charge
digitalWrite (charge_led, HIGH); //charge led on
setPoint = 14.85;
if (vin < 14.50) {
if (voltageAdjust < 220) { // MAX POWER OUT FROM ALTERNATORS (1 - 255)
voltageAdjust ++; // increase alternator output slowly
delay(200);
}
}
else if (vin >= 14.50) { // once up to voltage adjust quickly
if (vin < (setPoint - 0.1)) {
if (voltageAdjust < 220) { // MAX output from alternators
voltageAdjust ++;
delay(30);
}
}
if (vin > (setPoint + 0.1)) { // lower voltage
voltageAdjust --;
delay(30);
}
}
} //end button state 1
//Equalize Function
if (buttonState_equalize == 0) { //off
digitalWrite (equalize_low_led, LOW);
digitalWrite (equalize_high_led, LOW);
}
if (buttonState_equalize == 1) { //Equalize LOW Function
digitalWrite (equalize_low_led, HIGH);
setPoint = 15.20;
if (vin < 15.20) {
if (voltageAdjust < 190) { // MAX POWER OUT FROM ALTERNATORS (1 - 255)
voltageAdjust ++; // increase alternator output slowly
delay(200);
}
}
else if (vin >= 15.20) { // once up to voltage adjust quickly
setPoint = 15.50;
if (vin < (setPoint - 0.05)) {
if (voltageAdjust < 220) { // MAX output from alternators
voltageAdjust ++; // raise voltage
delay(30);
}
}
if (vin > (setPoint + 0.5)) { // lower voltage
voltageAdjust --;
delay(30);
}
}
} // end button state equalize = 1
// Equalize High Function
if (buttonState_equalize == 2) { //Equalize HIGH Function
digitalWrite (equalize_low_led, LOW); //low led off
digitalWrite (equalize_high_led, HIGH); //high led on
if (vin < 16.00) {
if (voltageAdjust < 190) { // MAX POWER OUT FROM ALTERNATORS (1 - 255)
voltageAdjust ++; // increase alternator output slowly
delay(200);
}
}
else if (vin >= 16.00) { // once up to voltage adjust quickly
setPoint = 16.20;
if (vin < (setPoint - 0.05)) {
if (voltageAdjust < 220) { // MAX output from alternators
voltageAdjust ++; // raise voltage
delay(30);
}
}
if (vin > (setPoint + 0.05)) { // lower voltage
voltageAdjust --;
delay(30);
}
}
} // end button state equalize = 2
} //end loop
The problem with the original regulators in the alternators was:
-at start up both alternators would jump to full load and stall the engine
-one alternator would always run hotter as the load was never equally shared, shortening its lifespan as they aren't designed to run full load for very long
-they topped out at 13.6V, I need 14.8V for proper charging and 16.2V for equalization charge
By running 2 alternators off the same mosfet I can run both of them at 70% load instead of 100%/20%. Adjustable programming gives me lots of flexability to tailor the charger to my battery bank.
Setup:
12 Volt, 1200Ah battery bank running an off grid solar powered house.
Alternators are identical 130A, 12V. Regulators have been removed, constant 12V supplied to rotors from power relay, - supplied from NPN mosfet.
Switched power supply delivering 7V to Arduino from 12V battery bank (first Arduino didn't like 16V lol)
PWM output runs a single NPN mosfet feeding both rotor field windings from 12V battery bank.
Voltage sense is a voltage divider on the battery bank side to avoid issues with voltage drop between dc generator and batteries to get accurate readings.
System works good I just need to figure out a way of smoothing out the hunting and surging due to the arduino over compensating. At start up the controller smoothly increases power output up to my max set point. As the batteries charge the power output from alternators decreases but the surging slowly increases. Near end of charge is the worst with +/- 0.4V of fluctuation, it helps a little to idle the engine down causing the PWM to run at a higher output to compensate for slower shaft speed but the fluctuations are still there. Increasing delays helps smooth it out but causes overshoot voltage spikes when a load is removed from battery bank.