Will a lookuptable be a solution for this problem?

Hello, i am having a problem. I will try to describe the best i can.

My project is measuring the voltage of a buttoncellbattery, under no load and under load. It then calculates the internal resistance of the battery.

At the end of the measurement i want to display on an LCD screen if the battery is OK, or the battery is not OK. But the terms of a bad battery and good battery can difference.

For instance,

Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance < 20Ohm = GOOD BATTERY
Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance > 20Ohm = BAD BATTERY
Open voltage from battery < 3.18V, voltage from loaded battery <3V, Internal resistance < 20Ohm = GOOD BATTERY
Open voltage from battery < 3.18V, voltage from loaded battery >3V, Internal resistance < 20Ohm = BAD BATTERY
Open voltage from battery > 3.18V, voltage from loaded battery >3V, Internal resistance < 20Ohm = BAD BATTERY.

But after the measurement is done i do not want to design my software like this:

if(
Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance < 20O){
LCDPrint("GOOD");
}
else if(Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance > 20Ohm){
LCDPrint("BAD");
}
else if(Open voltage from battery < 3.18V, voltage from loaded battery <3V, Internal resistance < 20Ohm_{
LCDPrint("GOOD");

How can i handle this? Is it possible to use a lookup table where i store al the values and write all the possible outcomes?

Perhaps a switch/case?

I have no idea how to do this. Thats the reason i came to you fokes.

Is that data the actual stuff you will use to determine battery quality or is it just an example?

What is the source of your values and pass/fail criteria? Before we get into more complicated stuff here, are you asking about storing multiple battery data? Or just handling the single case you have shown above (3, 3.18V)? I am worried that you may just be asking how to construct the calculations and output control, instead of how to test different battery types.

Killerpirate:
For instance,

Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance < 20Ohm = GOOD BATTERY
Open voltage from battery > 3.18V, voltage from loaded battery <3V, Internal resistance > 20Ohm = BAD BATTERY
Open voltage from battery < 3.18V, voltage from loaded battery <3V, Internal resistance < 20Ohm = GOOD BATTERY
Open voltage from battery < 3.18V, voltage from loaded battery >3V, Internal resistance < 20Ohm = BAD BATTERY
Open voltage from battery > 3.18V, voltage from loaded battery >3V, Internal resistance < 20Ohm = BAD BATTERY.

That does not seem a very logical presentation of the info. It is hard to see what is the dominant factor in determining good from bad. But maybe there isn't one.

How do you propose to measure the internal resistance?

Why is the last item on the list identifying a bad battery - surely if the voltage holds up under load it is a good battery?

I can't see the value of a lookup table when there are only 5 options. The usual purpose of a lookup table is to match an IF test with an irregular set of results - for example to match a linear input to a very non-linear output without a complex and slow calculation - for example matching an angle to the sine of the angle.

If this was my project I would first test for the dominant factor, then for the second most important and then for the third. It would just be a straightforward set of IF statements. If there is no dominant factor then, of course, the order of testing does not simplify things.

...R

You are putting the cart before the horse. Forget that computers exist. Take a pencil and paper and design a written procedure that someone could use to decide whether the battery is bad or good. Make it explicit and reliable. Now take that and code it. Show us the code if it doesn't work, and we can help...

i like using tables. but in this case you would also need to encode whether value is >/<

the script below is more or less a decision tree. But you only identified 5 out of 8 case. you could specify the conditions that are good and assume bad otherwise

results

 test: batV 3.1, ldV 2.90, res 190, Battery good
 test: batV 3.1, ldV 2.90, res 210, Battery ?
 test: batV 3.1, ldV 3.10, res 190, Battery bad
 test: batV 3.1, ldV 3.10, res 210, Battery ?
 test: batV 3.3, ldV 2.90, res 190, Battery good
 test: batV 3.3, ldV 2.90, res 210, Battery bad
 test: batV 3.3, ldV 3.10, res 190, Battery bad
 test: batV 3.3, ldV 3.10, res 210, Battery ?
# test

# Open voltage > 3.18V, voltage loaded <3V, resistance < 20Ohm = GOOD
# Open voltage > 3.18V, voltage loaded <3V, resistance > 20Ohm = BAD

# Open voltage > 3.18V, voltage loaded >3V, resistance < 20Ohm = BAD

# Open voltage < 3.18V, voltage loaded <3V, resistance < 20Ohm = GOOD
# Open voltage < 3.18V, voltage loaded >3V, resistance < 20Ohm = BAD

awk '
function batTest (batV, ldV, res) {
    s = "?"
    if (batV > 3.18)  {
        if (ldV < 3)  {
            if (res < 200)
                s = "good"
            else
                s = "bad"
        }
        else  {
            if (res < 200)
                s = "bad"
        }
    }
    else {
        if (res < 200)  {
            if (ldV < 3)
                s = "good"
            else
                s = "bad"
        }
    }

    printf " test: batV %3.1f, ldV %3.2f, res %3d, Battery %s\n", \
        batV, ldV, res, s
}

BEGIN {
    for (batV = 3.1; batV < 3.4; batV += 0.2)
        for (ldV = 2.9; ldV < 3.2; ldV += 0.2)
            for (res = 190; res < 220; res += 20)
                batTest(batV, ldV, res)
}'

Something that may also cause you a problem is what happens if open voltage is exactly 3.18v, loaded voltage is exactly 3v, and/or internal resistance is exactly 200 ohms? Testing for only greater or less than a specific number, without allowing for the exact number itself, will give you an occasional unpredictable result.

Thanks for your replies!

Well, my device will do the following: It measures a battery in the beginning of the program. At this time the battery is not connected (ie, the mosfets on the PCB are off), so it will measure its open circuit voltage (around 3.18, 3.2V for a good new battery.) Then it takes 3 individual measurements. There are 3 mosfets on the device with 3 different resistors between the battery and the drain of the FET.

R1 = 68 Ohm
R2 = 120 Ohm
R3 = 680 Ohm

The software will calculate the internal resistance(IR1, IR2, IR3) of the battery according to the different voltage drops when the resistors are connected via the FETS.

So i will not have 8 cases, but 16 cases. (4 parameters, OCV, IR1, IR2 and IR3)
In overall, when the OCV is > 3.17V, IR1 < 10 ohm and IR2 < 11 Ohm the battery should be okay. But i wanted to describe every 16 cases and determine after the measurement which case is relevant. So i will just compare the measured data to all 16 cases.

don't understand how you have 16 cases if there are just 3 parameters

gcjr:
i like using tables. but in this case you would also need to encode whether value is >/<

the script below is more or less a decision tree. But you only identified 5 out of 8 case. you could specify the conditions that are good and assume bad otherwise

results

 test: batV 3.1, ldV 2.90, res 190, Battery good

test: batV 3.1, ldV 2.90, res 210, Battery ?
test: batV 3.1, ldV 3.10, res 190, Battery bad
test: batV 3.1, ldV 3.10, res 210, Battery ?
test: batV 3.3, ldV 2.90, res 190, Battery good
test: batV 3.3, ldV 2.90, res 210, Battery bad
test: batV 3.3, ldV 3.10, res 190, Battery bad
test: batV 3.3, ldV 3.10, res 210, Battery ?








test

Open voltage > 3.18V, voltage loaded <3V, resistance < 20Ohm = GOOD

Open voltage > 3.18V, voltage loaded <3V, resistance > 20Ohm = BAD

Open voltage > 3.18V, voltage loaded >3V, resistance < 20Ohm = BAD

Open voltage < 3.18V, voltage loaded <3V, resistance < 20Ohm = GOOD

Open voltage < 3.18V, voltage loaded >3V, resistance < 20Ohm = BAD

awk '
function batTest (batV, ldV, res) {
    s = "?"
    if (batV > 3.18)  {
        if (ldV < 3)  {
            if (res < 200)
                s = "good"
            else
                s = "bad"
        }
        else  {
            if (res < 200)
                s = "bad"
        }
    }
    else {
        if (res < 200)  {
            if (ldV < 3)
                s = "good"
            else
                s = "bad"
        }
    }

printf " test: batV %3.1f, ldV %3.2f, res %3d, Battery %s\n",
        batV, ldV, res, s
}

BEGIN {
    for (batV = 3.1; batV < 3.4; batV += 0.2)
        for (ldV = 2.9; ldV < 3.2; ldV += 0.2)
            for (res = 190; res < 220; res += 20)
                batTest(batV, ldV, res)
}'

Thanks, but the nested IF statements is the reason i wanted something like an LUT. I dont like nestes IFs

Thanks, but the nested IF statements is the reason i wanted something like an LUT. I dont like nestes IFs

i love tables. i have code where the tables are larger than the logic

look forward to seeing your implementation using tables

gcjr:
i love tables. i have code where the tables are larger than the logic

look forward to seeing your implementation using tables

Sorry, but what exactly do you mean by tables? Is what you wrote on a couple posts before called a table?

Killerpirate:
So i will not have 8 cases, but 16 cases. (4 parameters, OCV, IR1, IR2 and IR3)
In overall, when the OCV is > 3.17V, IR1 < 10 ohm and IR2 < 11 Ohm the battery should be okay. But i wanted to describe every 16 cases and determine after the measurement which case is relevant. So i will just compare the measured data to all 16 cases.

I still can't see how you think a lookup table would be useful.

IMHO you are going to have to evaluate all the IFs before you can figure out which element of the table is relevant. And since the answer is binary - GOOD or BAD - it is hard to see any saving from putting those two options in a table.

I suggest you write some real code using IF statements so we can get a better understanding of what you are trying to do and what you are hoping to simplify.

Is it always necessary to test all three values - open circuit voltage, on-load voltage and internal resistance - in order to make a decision? If there are cases where a single item will determine a pass or a fail then you can greatly simplify the coding.

...R

Killerpirate:
So i will not have 8 cases, but 16 cases. (4 parameters, OCV, IR1, IR2 and IR3)
In overall, when the OCV is > 3.17V, IR1 < 10 ohm and IR2 < 11 Ohm the battery should be okay. But i wanted to describe every 16 cases and determine after the measurement which case is relevant. So i will just compare the measured data to all 16 cases.

You could check each of your parameters and encode the results into a single byte by setting a specific bit if each condition is true. That would give you a number from 0 through 15, representing the 16 possible combinations of results, which can them be used in a switch/case statement or as an index into an array.

float OCV = random(6);  //these lines included so sketch will compile
float IR1 = random(200);
float IR2 = random(200);
float IR3 = random(200);

const byte OCVbit = 3;
const byte IR1bit = 2;
const byte IR2bit = 1;
const byte IR3bit = 0;

void setup() {
  byte batteryCondition = 0;
  if (OCV > 3.18) {
    bitSet(batteryCondition,OCVbit);
  }
  if (IR1 < 10) {
    bitSet(batteryCondition,IR1bit);
  }
  if (IR2 < 11) {
    bitSet(batteryCondition,IR2bit);
  }
  if (IR3 < 12) {
    bitSet(batteryCondition,IR3bit);
  }
}

//batteryCondition now contains the combined results of all four if statements
//batteryCondition = 0b00001111 would indicate all tests are true

void loop() {
}

Killerpirate:
Sorry, but what exactly do you mean by tables?

see thread title -- "Will a lookuptable be a solution for this problem?"