Author Topic: A simple UNO voltage relay  (Read 3111 times)

0 Members and 1 Guest are viewing this topic.

OperaHouse

  • Hero Member
  • *****
  • Posts: 1031
  • Country: us
A simple UNO voltage relay
« on: March 07, 2015, 09:08:19 AM »
This MINI328 project monitors battery voltage and turns on a relay when the battery reaches a set voltage and
turns it off when it reaches a low voltage.  Shutdown occurs after that low voltage is maintained for a number
of program loops (about one minute) to prevent a false turn off due to momemtary slump from an inverter turning
on.   Two relay output pins are available.  Pin #9 is either on or off.  Pin #3 is a PWM output to limit the power
consumption of the relay.  Initially the duty cycle is 100% applying full power.  With each program loop the duty
cycle continues to drop till it reaches about 50%.  This can also be used to operate a 12V relay on 24V.

Code is shown in a very simple form.  Each line of code follows another in sequence.  There is no looping of code
till the program reaches the end.  Each line of code stands on its own.  This makes the code easier to understand.
The // at the beginning of a line indicates a comment to explain the code.  The compiler ignores these lines when
the machine code is generated.  You should always add comments to code.  what code you write now will not be obvious
a year later when the code needs to be changed.  If you copy all the sections into the Arduino editor, this program
will compile.  Voltages can be changed to meet your situation.

In this first section of code the variables used are defined and set to an initial value.   Next the output pins
and serial data rate are defined.   

Each analog input can accept 0-5V and create a digital count from 0-1024.  A resistive voltage divider turns battery
voltage into a value between 2-3 volts.  This provides enough safety margin to prevent overloading the input.
The first line of code reads the analog pin voltage and creates a count of about 500 for normal conditions.  The
calculated battery voltage in millivolts is created by the continuous adding of the raw data to the battery count.
Each loop of the program subtracts a fraction of the battery value.  Initially the subtracted value is very small
and that allows battery to build up.  Over time the subtracted value becomes the same as raw data added. In that way
the divider value actually becomes the multiplier.  This value can be changed to match the voltage divider.  A small
variable resistor can then be used for a fine adjustment.

Now that a battery voltage has been created, decisions can be made.  The battery is compared with the high voltage
setpoint.  If it is above that value, the relay is turned on.  The lower voltage setpoint is more complicated.  Each
loop of the program the timeout count is increased when the battery is below the low setpoint.  Short term high
current draws will not turn off the relay during this time delay period.  If the voltage recovers slightly, the timeout
value is reset to zero.  The last line of code is just a little housekeeping to prevent the timeout value from getting
too large and overrunning the counter.

// This is a simple voltage monitor with upper and lower
// voltage set points and a time delay to prevent false
// shut down.  A blinking light gives battery status.
// Outputs s atandard on off signal and a PWM output
// to drive a relay at lower power to save battery.

int battery   = 0;           // calculated battery voltage in mv
int timeout   = 0;           // shutdown timer
int rawdata   = 0;           // raw A/D value
int blinktime = 0;           // blink counter
int rly       = 0;           // relay state
int PWM3      = 0;           // PWM3 relay state
void setup() 
{
  Serial.begin(9600);        // setup serial
  pinMode(13, OUTPUT);       // sets the digital LED pin 13 as output
  pinMode(9, OUTPUT);        // sets the digital pin 9 as relay output
  pinMode(3, OUTPUT);        // sets the digital pin 3 as PWM relay output
}


void loop()  {
   
    // A resistive voltage divider produces about 2V-3V at pin A0
    // when 13V is applied to the resistive divider
    // that will give a count of about 500
   
    //  READ ANALOG VALUE AT PIN A0
    rawdata  = analogRead(0);                 
    // A/D values go from 0 to 1023
   
    // MULTIPLY A/D VALUE TO OBTAIN BATTERY VOLTAGE IN MILLIVOLTS
    battery  = battery - battery / 26;         
    // Sum the readings by subtracting one average reading first   
    // It isn't obvious but this routine effectivly multiplies the A/D reading
    // by 26 then a fraction of the total is subtracted
    // change this value to match voltage divider
    battery  = battery + rawdata;             
    // Add latest A/D reading to battery total. This makes a running average

    // HIGH VOLTAGE TURN ON
    if (battery > 13500) rly = 1;             
    // voltage is over 13.5V relay should be turned on

    // LOW VOLTAGE CUTOFF
    if (battery < 12400) timeout = timeout + 1;
    // voltage is under 12.4V start and add to timeout value
   
    // CHECK FOR A MOMENTARY RECOVERY OF VOLTAGE AFTER A SLUMP
    if (battery > 12550) timeout = 0;         
    // if voltage recovers enough, reset timeout
    // this won't turn on the relay, only reset the timeout
   
    // HAS VOLTAGE BEEN TOO LOW FOR TOO LONG?
    if (timeout >= 300) rly = 0;               
    // turn off relay when count is greater than 300. About a minute

    // MAKE SURE TIMEOUT DOESN'T CLIMB TOO HIGH
    if (timeout > 800) timeout = 800;         
    // makes sure timeout count doesn't become greater than 800
    // arbitrary value just to make sure counter doesn't over run


OperaHouse

  • Hero Member
  • *****
  • Posts: 1031
  • Country: us
Re: A simple UNO voltage relay
« Reply #1 on: March 07, 2015, 09:09:58 AM »
This section of code contains the outputs.  digitalWrite is a simple ON/OFF output. The first number designates the pin,
the following variable conveys the state.  A 1 or 0 can be used in place of the variable when driving a LED. This second
output is PWM which will lower the power consumed bu a relay.  Relay must have a diode placed across the coil for this to
work. If the relay is off, the duty cycle is 0% or a PWM count of zero.  When a relay is first turned on, the duty cycle
is set to 100% (a value of 255).  Any time the PWM count is greater than 125 (50% duty cycle), the PWM count is decremented
by one each program loop.  analogWrite is used for PWM outputs.  There are six designated pins which can be used.

    // STANDARD RELAY DRIVER OUTPUT PIN #9
    digitalWrite(9, rly);                     
    // sets status of simple ON/OFF RELAY output pin
    // the pwm driver can operate at the same time
                         
    // PWM RELAY DRIVER SECTION PIN #3                         
    // PWM relay output will reduce power condumption of relay
    if (rly == 0) PWM3 = 0;                   
    // set PWM value to zero if relay should be off
   
    // DECREMENT PWM VALUE EACH LOOP IF RELAY ON
    if (PWM3 >125) PWM3 = PWM3 - 1;           
    // decrement PWM3 till it reaches minimum value
    // reliable operation can often be 40%
   
    // TURN PWM RELAY ON BY SETTING INITIAL VALUE
    if (PWM3 == 0 && rly == 1) PWM3 = 255;     
    // when relay forst turns on set PWM3 to maximum value
    // prior state of relay has to be off in order to set this value
    // this could also be used to power a 12V relay from a 24V source
   
    // THIS OUTPUTS THE PWM SIGNAL TO PIN #3
    analogWrite(3,PWM3);                       
    // sets status of PWM3 RELAY output pin #3
    // PWM values are between 0 and 255



OperaHouse

  • Hero Member
  • *****
  • Posts: 1031
  • Country: us
Re: A simple UNO voltage relay
« Reply #2 on: March 07, 2015, 09:11:42 AM »
There is nothing worse than looking at a chip and wondering what it is doing.  Every program needs to have an indicator that
gives the status of the program.  The UNO and MINI have an on board LED for this purpose and it is designated as pin #13.
The easiest way to do this is a ditalWrite and a delay.  All these delays can really slow down a program.  Remember it takes
26 program loops for the battery voltage to stabilize.  For this reason blinktime counter is used to initiate the blink sequence
every twenty loops.  The first blink is always there just to indicate the program is running.  One blink the voltage is fine.

If the voltage is just a little low, a second blink happens.  Even lower voltage gives a third blink and a fourth blink indicates
that the relay is just about to turn off or has already.  It is kinda clunky to do the code this way but it is understandable. 
The fridge does this a slightly different way using program loop counts instead of delays.

    //  BLINKING LED STATUS DISPLAY
    // The following is not necessary but provides useful information on how the program is running
    // blinktime counts the number of program loops
    blinktime = blinktime + 1;                 
    // add one to the blink counter
    if (blinktime > 20) blinktime = 0;
    // reset counter when a certain count is reached
    // blink display happens only when the count is 2
                                               
    // FIRST BLINK - JUST TO SHOW THAT THE PROGRAM RUNNING
    if (blinktime == 2 && blinktime == 2)digitalWrite(13, 1);
    // pin #13 is the on board LED, 1 is ON   
    delay(20);                               
    // delay 20 milliseconds, the time the LED is on
    digitalWrite(13, 0);   
    // turns the LED off if it happens to be on so it blinks
    // this inserts a delay between the next blink in blink mode
    if (blinktime == 2)delay(300);             
    // delay 300 milliseconds, LONG DELAYS only in blink mode
   
    // SECOND BLINK - IF SLIGHTLY UNDER VOLTAGE
    if (blinktime == 2 && battery < 13400) digitalWrite(13, 1);   
    delay(20);                                 
    // delay 20 milliseconds
    digitalWrite(13, 0);   
    // sets the LED off so it blinks
    if (blinktime == 2)delay(300);             
    // delay 300 milliseconds
   
    // THIRD BLINK - IF EVEN LOWER VOLTAGE
    if (blinktime == 2 && battery < 12900) digitalWrite(13, 1);   
    delay(20);                                 
    // delay 20 milliseconds
    digitalWrite(13, 0);   
    // sets the LED off so it blinks
    if (blinktime == 2)delay(300);             
    // delay 300 milliseconds
   
    // FOURTH BLINK - IF IT IS JUST ABOUT TO TURN OFF RELAY
    if (blinktime == 2 && battery < 12500) digitalWrite(13, 1);   
    delay(20);                                 
    // delay 20 milliseconds
    digitalWrite(13, 0);   
    // sets the LED off so it blinks
    if (blinktime == 2)delay(300);             
    // delay 300 milliseconds

    // A single blink indicates everything is normal
   
   

OperaHouse

  • Hero Member
  • *****
  • Posts: 1031
  • Country: us
Re: A simple UNO voltage relay
« Reply #3 on: March 07, 2015, 09:14:51 AM »
This last section shows the use of Serial.print to output data to the laptop via the USB port and TOOLS in Arduino.  This is a
handy way to get variable data each program loop.  Sometimes your logic isn't that logical.  Notice the a print will keep going
on the same line. println perform a carage return (if you are old enough to remember a typewriter) or new line after printing
the data.  The picture shows a typical screen when you select SERIAL MONITOR in TOOLS.


    // PROGRAM DATA SENT TO ARDUINO SERIAL SCREEN IN TOOLS
    // send calculated voltage to TOOLS debug screen. This will give a real
    // time read of voltage so a pot can be adjusted so the computer value
    // matches what is read on the digital voltmeter.

    Serial.print("voltage is ");              // identify variable
    Serial.print(battery);                    // print voltage variable
    Serial.print("  raw A/D is ");            // identify variable
    Serial.print(rawdata);                    // print raw voltage A/D variable
    Serial.print("  timeout is ");            // identify variable
    Serial.print(timeout);                    // print timeout value
    Serial.print("  relay is ");              // identify variable
    Serial.print(rly);                           // print relay value
    Serial.print("  PWM3 is ");               // identify variable
    Serial.println(PWM3);                     // print relay value
   
 }                                            // end of program

oztules

  • Hero Member
  • *****
  • Posts: 1477
  • Country: aq
  • Village idiot
Re: A simple UNO voltage relay
« Reply #4 on: March 07, 2015, 01:57:21 PM »
I like it.

Your explanations are very useful to me as well.

Thanks Opera




................oztules
Flinders Island Australia