S215   090920     

Lab II20-40 Battery Voltage Tracker
30 points
OEES 215

Back to Main Page

In this lab project, we'll be developing a voltmeter that will keep track of the lowest and highest voltages it has seen.

In the lab project after this one, we'll be adding to this program to enable the user to select which mode of operation is desired, by turning the pot to one of four positions. The program of the next project will be used to track minimum and maximum voltages of the deep cycle batteries used in solar and wind power systems we build. Such information will allow us to determine if the solar panels/wind turbine and deep cycle battery are adequate for the load the system is powering.


Example: Minimum Function

This example demonstrates the use of the Mn0 function. This function keeps a record of the smallest value (the minimum) that has been sent to it. If the main program sends a still smaller value to the function, the old minimum is replaced by this most recent value. When called, this function returns the current minimum.

The RstMinMax0 function resets the minimum and maximum for the Mn0 and Max0 functions. Notice that the RstMinMax0 function is called prior to entering the main loop and also whenever the pushbutton is pressed.

The InitRunAvg0 function initializes the eight values to be averaged to whatever number is sent it. In this case, we're initializing these values to the number obtained by the ADC.  Such initialization eliminates the garbage that would otherwise be returned by the Runavg0 function the first eight times it's called.

The example program below uses DispNmbr, a new function that has been added to the function library in library version 10. DispNmbr allows us to place a decimal point in the number being displayed. Like the Disp... functions we have used earlier, we only send it integers (numbers with no decimal point). The first argument used by DispNmbr is the number to be displayed. The second argument is desired position of the decimal point.

Here are examples of how DispNmbr works:
  • Function call: DispNmbr(12345, 2). Displayed: 123.45
  • Function call: DispNmbr(12345, 3). Displayed: 12.345
  • Function call: DispNmbr(12345, 0). Displayed: 12345

The DispNmbr function gives us no control over how many digits are to be displayed, nor does it allow us to display a number with an offset. (The DispNDP does give such control.) DispNmbr will display up to eight characters, with the decimal point being considered as a character. If there are leading zeroes, they will be blanked out. Leading zeroes are zeroes that appear to the left of a number's significant digits. As an example, the number 001.23 contains two leading zeroes, as does the number 005.07. (The zero beteen the 5 and the 7 is a significant digit.)  Zeroes to the right of the decimal point are not blanked, nor is a zero immediately to the left of the decimal point. For example, none of the zeroes in the number 0.00123 will be blanked. The left-most two zeroes in the number 000.0345 will be blanked, resulting in 0.0345 being displayed.

Here are more examples of  how leading zeroes are blanked out.
  • Function call: DispNmbr(12345678, 0). Displayed: 12345678
  • Function call: DispNmbr(1234, 2). Displayed: 12.34
  • Function call: DispNmbr(12, 7). Displayed: .0000012 (seven digits and a decimal point).
  • Function call: DispNmbr(123, 4). Displayed: 0.0123

By the way, if more than eight significant digits are sent to DispNmbr, the 9th digit and any to the left of it are truncated. For example, if 1234567890 is sent, the eight digits 34567890 are displayed.


#include "s215-header10.h"
#pragma code
void main (void)
{
    unsigned short min, adc;
    InitPorts();         //Initialize I/O ports and ADC (set it
                         //  to ADC channel 0).

    RstMinMax0();            //Reset minimum and maximum
    InitRunAvg0(ADC10bit()); //Initialize running average to the
                             //  value
 returned by the ADC.
    while (1==1)
    {
    //|||||||||||||||||||||||||| Main Loop ||||||||||||||||
    if (PB==1)               //Reset minimum and maximum when
                             //  button pressed.

    {
        LED0 = 1;            //Turn LED on to verify that button
                             //  was pressed.

        RstMinMax0( );
    }
    LED0 = 0;                //Turn LED back off.
   
    adc = Runavg0(ADC10bit());
    min = Mn0(adc);
    DispNmbr(min, 2);   
        //Display number. Decimal point between 2nd and 3rd
        // digits from the right.


    Delay10ms(1);
     //|||||||||||||||||||||||| End of Main Loop |||||||||||       
    }
}

To try out the above program, right-click here to download the source file.
  1. Turn the pot fully clockwise and press the pushbutton. You should see something like 10.23 in the display (or a number a little smaller than this). 
    • 10.23 is 1023 with a decimal point inserted. 1023 is the maximum number put out by the ADC.
  2. Turn the pot counterclockwise a little, and notice that the number displayed decreases.
  3. Now, turn the pot clockwise a little, and notice that the number doesn't change. 
    • This is because the Mn0 function remembers the smallest number it has seen since the button was last pressed.
  4. Next, press the button to reset the minimum. You should see a larger number in the display. 
    • This number represents the current pot position.
  5. Then, turn the pot counterclockwise. You should see the displayed number decrease.





Example: Maximum Function
The following program demonstrates use of the Mx0 function. This function keeps a record of the largest value (the maximum) that has been sent to it. If the main program sends a still larger value to the function, the old maximum is replaced by this most recent value. When called, this function returns the current maximum. Everything else about this program is similar to the previous example.


#include "s215-header10.h"
#pragma code
void main (void)
{
    unsigned short min, adc;
    InitPorts();         //Initialize I/O ports and ADC (set it
                         //  to ADC channel 0).

    RstMinMax0();            //Reset minimum and maximum
    InitRunAvg0(ADC10bit()); //Initialize running average to the
                             //  value
 returned by the ADC.
    while (1==1)
    {
    //|||||||||||||||||||||||||| Main Loop ||||||||||||||||
    if (PB==1)               //Reset minimum and maximum when
                             //  button pressed.

    {
        LED0 = 1;            //Turn LED on to verify that button
                             //  was pressed.

        RstMinMax0( );
    }
    LED0 = 0;                //Turn LED back off.
   
    adc = Runavg0(ADC10bit());
    max = Mx0(adc);
    DispNmbr(max, 2);   
        //Display number. Decimal point between 2nd and 3rd
        // digits from the right.


    Delay10ms(1);
     //|||||||||||||||||||||||| End of Main Loop |||||||||||       
    }
}

To try out the above program, right-click here to download the source file.
  1. Turn the pot fully counterclockwise and press the pushbutton. You should see something like 0.00 in the display (or a number a little larger than this). 
  2. Turn the pot clockwise a little, and notice that the number displayed increases.
  3. Now, turn the pot counterclockwise a little, and notice that the number doesn't change. 
    • This is because the Mx0 function remembers the largest number it has seen since the button was last pressed.
  4. Next, press the button to reset the maximum. You should see a smaller number in the display. 
    • This number represents the current pot position.
  5. Then, turn the pot clockwise. You should see the displayed number increase.

Modify the examples to create a program that will track minimums and maximum
Start with either of the above examples, and save it with a new file name of II20-40 Battery Voltage Tracker.c . (Spaces in file names are OK for files that won't be downloaded from the Internet.)

Modify the program so that it will do the following:
  1. Read voltages between 0 and 30 volts coming in on analog channel 5 (as was the case in the Voltmeter 2 program).
  2. Display 30.00 when 30 volts is applied.
  3. If switch 0 is on, display the minimum voltage that has occurred since the last button press.
  4. If switch 1 is on, display the maximum voltage that has occurred since the last button press.
  5. If neither switch is on, display the voltage present on analog channel 5.
  6. If the button is pressed, reset the minimum and maximum.
 
Back to Main Page