help with significant figures on percentages

I made a salt content probe for a project at school and for the percent salt content I need to get at least two significant digits, but I only get whole number percents. if it is not possible to get more than 1 it’s okay but I want as many as possible.

// include the library code:
#include <SoftwareSerial.h>

// initialize the library with the numbers of the interface pins
SoftwareSerial mySerial(3,2);

// variables for input pin and control LED and known resistance value
  int analogInput = 1;
  int analogInput1=0;
  float vout = 0.0;
  float vout1 = 0.0;
  float vin1 = 0.0;
  float vin = 0.0;
  float R1 = 50000.0;    // !! resistance of R1 !!
  float R2 = 4400.0;     // !! resistance of R2 !!
  float R3 = 1186.0;

// variable to store the value of voltage resistance and conductance
  int value = 0.00;
  int value1 = 0.00;
  int final_output = 0.00;
  int ohm_value = 0.00;
  int mseimval = 0.00;
  int tds = 0.00;

void setup(){
  // declaration of pin modes
  pinMode(analogInput, INPUT);
  pinMode(analogInput1, INPUT);

  // set up the LCD's number of columns and rows:
  mySerial.begin(9600);
  delay(500);
}

void loop(){
  value = analogRead(1);
  value1 = analogRead(0);
  vout1 = (value1 * 5.0) / 1024.0;
  vout = (value * 5.0) / 1024.0;
  vin1 = vout1 / (R2/(R1+R2));
  vin = vout / (R2/(R1+R2));
  ohm_value = (vin * R3)/(vin1 - vin); //takes the two voltages and converts into an ohm value
  mseimval = (ohm_value ^ -1);  //takes the ohm value and converts it into conductance
  tds = (mseimval * 0.497);   //takes to conductance value times to tds constant of NaCl to get PPM
  final_output = (tds / 10000.0); //divides the PPM by ten thousand to get a percent
  mySerial.write(254);
  mySerial.write(128);
  mySerial.print(final_output); //displays percentage
  mySerial.print("% salinity");
  mySerial.write(254);
  mySerial.write(128);
  delay(500);
  mySerial.print("                ");
}

Your list of statements:

  int value = 0.00;
  int value1 = 0.00;
  int final_output = 0.00;
  int ohm_value = 0.00;
  int mseimval = 0.00;
  int tds = 0.00;

make no sense, because an int data type cannot have a fractional component. Also, since R2 and R1 are known at compile time, figure out a constant that equals R2 / (R1 + R2). (The divide operation is pretty slow.) Also, you have expressions like:

ohm_value = (vin * R3)/(vin1 - vin);

where you are using 4-byte floats in the right-hand expression, but assigning it into a 2-byte int in the left expression. This is like taking a four gallon bucket of information and trying to pour it into a 2 gallon pail…you’re going to lose information. It would be best to make ohm_value a float, too. At the very least, cast the righthand expression to a float first:

ohm_value = (float)(vin * R3)/(vin1 - vin);

ok i changed the code but I still get a 1 significant figure answer any other changes you can think of to change this? thanks forthe help!

mySerial.print(final_output,2); //displays percentage

Pete

I think you don't understand significant figures.

A percent with two digits as an integer like 15% or 43% has exactly 2 significant figures.

Your statement that you want all the sig figs that you can get tells me you really don't know anything about sig figs. The number of sig figs available to you is a consequence of the inputs and not the calculation. You don't get to pick and choose. If you want more sig figs coming out then you have to give more sig figs going in.

If you want more sig figs coming out then you have to give more sig figs going in.

Why? To two significant figures 1/3 is .33 To four sig figs it is .3333 etc. Same input.

Pete

mseimval = (ohm_value ^ -1); //takes the ohm value and converts it into conductance

what is that line supposed to be doing?


just a style comment,

  • some empty lines can improve readability
  • some small comments added
// include the library code:
#include <SoftwareSerial.h>

// initialize the library with the numbers of the interface pins
SoftwareSerial mySerial(3,2);

// variables for input pin and control LED and known resistance value
// CONST VALUES
  const int analogInput = 1;
  const int analogInput1 = 0;
  const float R1 = 50000.0;    // !! resistance of R1 !!
  const float R2 = 4400.0;     // !! resistance of R2 !!
  const float R3 = 1186.0;

// VARIABLE VALUES
  float vout = 0.0;
  float vout1 = 0.0;
  float vin1 = 0.0;
  float vin = 0.0;


// variable to store the value of voltage resistance and conductance
  int value = 0.00;
  int value1 = 0.00;
  int final_output = 0.00;
  int ohm_value = 0.00;
  int mseimval = 0.00;
  int tds = 0.00;

void setup()
{
  // declaration of pin modes
  pinMode(analogInput, INPUT);
  pinMode(analogInput1, INPUT);

  // set up the LCD's number of columns and rows:
  mySerial.begin(9600);
  delay(500);
}

void loop()
{
  // MEASUREMENTS
  value = analogRead(1);  // why not use analogInput   here ?
  value1 = analogRead(0);

  // PROCESSING
  // convert adc to volts
  vout1 = (value1 * 5.0) / 1024.0;
  vout = (value * 5.0) / 1024.0;
  vin1 = vout1 / (R2/(R1+R2));
  vin = vout / (R2/(R1+R2));
  ohm_value = (vin * R3)/(vin1 - vin); //takes the two voltages and converts into an ohm value
  mseimval = (ohm_value ^ -1);  //takes the ohm value and converts it into conductance
  tds = (mseimval * 0.497);   //takes to conductance value times to tds constant of NaCl to get PPM
  final_output = (tds / 10000.0); //divides the PPM by ten thousand to get a percent

  // OUTPUT
  mySerial.write(254);
  mySerial.write(128);
  mySerial.print(final_output); //displays percentage
  mySerial.print("% salinity");
  mySerial.write(254);
  mySerial.write(128);

  delay(500);
  mySerial.print("                ");
}