4 Decimal Places (.0000)

Hello Forum,

I was wondering if anyone can give some quick advise and sample code solutions? Don’t lauph to hard for me saying that. I am very new to this and am running a simple sketch. I’m just reading an analog input (A5) from a spectrophotometer’s output.

I have researched this topic in the Forum and some of the applications I read are far more complex than this setup. The values are pretty much spot on comparing them to a oscope but only display 2 integers (Ex. .080) All I want is to read 3 data values (Ex. .0823). Included is the sample code. Is there an easy way to do this without bit shifting, adding bytes…an so forth.

Thanks for any help,
Chad
Tempe, AZ

Chad_Analog_Input_Voltage_1.20.ino (1.44 KB)

Serial.println(Voltage_mV);     //Input Voltage Value

With floats you can specify the precision

Change to:

Serial.println(Voltage_mV , 4);     //Input Voltage Value

Thank you very much Delta! Works like a charm and great to know for future sketches.

Chad

Just be careful and don't fool yourself into thinking that you're really measuring voltage to 4 decimal places. The analogRead only gives you 1023 steps. No matter what type of variable or what type of calculation you do on it, you only have 1023 steps.

Think about your calculations. Stick in a number and run it through on paper to get the mV. Now stick in one number higher or lower and see how far away it is. That's your resolution. I doubt you have 4 decimal places to work with.

So if sensorValue is 512 that means (512 * (5.0 / 1023)) == 2.5024 V

If sensorValue is 513 then (513 * (5.0 / 1023)) == 2.5073 V

So the best resolution you can hope for is about 5mV.

I spoke to soon. I understand the calculations above and thanks. The problem is I noticed the value (maybe in a pattern changes 2-3 times) sometimes displaying the correct reading. Checked with DMM and it appears to be a steady voltage when adjusting the system pot and taking a new reading? Look at the serial monitor pic I enclosed to see it better. I went though all the lines adjusting and nothing seemed to correct it but removing ,4 for decimal places. I’ll have to look at the architecture better but you would think this wouldn’t be very difficult and designed for these types of applications? Just a simple data recorder. Again, pretty green and haven’t touched one of these sense college in a galaxy far far away.

Any ideas Delta?

Chad

So if sensorValue is 512 that means (512 * (5.0 / 1023)) == 2.5024 V

If sensorValue is 513 then (513 * (5.0 / 1023)) == 2.5073 V

Nope. (512 * (5.0 / 1024)) == 2.5 V and (513 * (5.0 / 1024)) == 2.5049 V

AWOL: Nope. (512 * (5.0 / 1024)) == 2.5 V and (513 * (5.0 / 1024)) == 2.5049 V

Nope, the OP used 1023 in his code.

I wasn't trying to get the right answer, I was trying to get the answer the OP would with his code.

11B73: The problem is I noticed the value (maybe in a pattern changes 2-3 times) sometimes displaying the correct reading. Checked with DMM and it appears to be a steady voltage when adjusting the system pot and taking a new reading? Look at the serial monitor pic I enclosed to see it better. I went though all the lines adjusting and nothing seemed to correct it but removing ,4 for decimal places.

Perhaps the spectrophotometer output is not as stable as you think it is. The DMM may be too slow to register the changes, and the scope may not have the precision to show you the fluctuations unless the vertical gain is greatly magnified.

Or, you may have interference and/or a ground loop in the connection between the Arduino and the spectrophotometer.

The OP may use 1023 but it really should be 1024 ;) And yes, you can only measure up to 1023 * (5/1024) = 4,995V, not 5V.

OP, you print mV but you just print the value in V. The change in value for a steady voltage is just because of the ADC error in de Arduino. The LSB is just flipping.

But, like I said many times around here, don't use floats. They are slow, inaccurate and not necessary.

I changed the code to not use floats. Also, 4 digits is "to much" for the 10-bit ADC in the Arduino. The reading isn't that accurate, every bit is almost 5mV. So I limited to 3 digits (but you can change it to 4 if you really really want).

/*
  Read Analog Voltage
  
  Reads an analog input voltage on pin A5 & common ground, converts it to voltage, 
  and prints the result to the Serial Monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground. 
  Includes a Loop Command for future use
  // Indicates Notes & Compiler Does Not Include
  ;  Semi Colon After Each Command
  
  Chad J. Stoltzmann 04-08-2015
*/

    // The setup routine Runs once when you press Reset:

    int Counter =0; //Simple Counter Loop (See Below to Close Loop)
  
  
void setup() {  //Needed in all Code!

    // Initialize serial communication at 9600 bits per second

    Serial.begin(9600); //BAUD Rate
    Serial.println("*****Upload to Micro-Controller Complete*****"); //Text
    Serial.println("*****Reading Device Analog Voltage Input*****"); //Text
}

  // The loop routine runs over and over again forever:
    
void loop() {  //Needed in all Code
    int sensorValue = analogRead(A5);  // Read Input V on Analog Pin (A5) and Ground on UNO R.3

    // Convert the Analog Reading (which goes from 0.00 - 1023) to a voltage (0.01 - 1V):

    //Do multiplication first to keep accurate. Long because 1023 * 5000 is to big for an int.
    unsigned long voltageInMv = sensorValue * 5000UL;
    //check for rounding errors, if remainder is larger then halve the resolution, add 1 mV
    if(voltageInMv % 1024 >= 512){
        voltageInMv = voltageInMv / 1024 + 1;
    }
    else{
        voltageInMv = voltageInMv / 1024 + 1;
    }


    Serial.println(Counter = Counter + 1);  //Simple Counter Loop Adjust (1) with Integers
    Serial.print(voltageInMv / 1000);       //Print the whole volts
    Serial.print(".");                      //Print decimal point on same line
    Serial.println(voltageInMv % 1000);     //Print decimal places (up to mV) and end line
    Serial.println("Volts(mV)");          //Text
    Serial.println("_________");          //Text

    delay(1500);                          //Delay(ms)
}

Hello,

I’m still learning this forum and was looking to find how you reply to each post individually but with no luck. I was wondering about the 1023 myself? This goes back to Digital 101 and should be 1024 and was confusing to me. 1, 8, 16, 32, 64, 128, 256 ,512, 1024…

I was wondering about the ground as well and constant signal values outputted by the spectrophotometer. This is reading off of a high end photocell and converting the photons into electrons producing the voltage (mV) output.
Is it the board ground connection? I had it on both the power side ground input and the opposite sides near the AREF pin? Both are giving me the same readings.

I agree that a scope of DMM might not pick up the slight variations from the photocell but based on both units again the signal appears stable?

Let me get to the septillion code (thank you!) and report back my findings.

Thanks again everyone,
Green Thumb (Fingers) Chad

Here is the second ground by AREF pin Test screen shot.

That's about as good as you're going to get with an Arduino. If you'll notice you get readings at .0929 , .0978, and .1026. These translate (in your code anyway) to reading from the ADC of 19, 20, and 21. You are right on the bottom end of the smallest voltages that the ADC can read. And the LSB of the analog reading is going to vary a little. That's the nature of taking measurements. If you're right on the line somewhere then it's going to read one direction one time and the other direction the next.

I'm afraid that's about the best you're going to do with just an Arduino.

If you know the range of expected voltages and it's pretty low then you might be well served to buffer that through an OpAmp or an Instrumentation Amplifier to bring the signal level up a little and give yourself a bit more precision at the cost of some of the range you're not using.

Here is my results from Septellion’s code. I hope this isn’t a simple grounding loop issue?

Thanks very much though.
Chad

Chad_Analog_Input_Voltage_1.2.ino (1.95 KB)

And screen shot of serial monitor.

That's the exact same thing I just pointed out. Those are three consecutive increments of what the ADC can give you. That is your best resolution. Unless you're going to buffer that signal up into a range where it can be read better, that's the best you're going to get. It's not a ground loop. It's not your connections. That's just the limit of the ADC on an Arduino.