• 0

# AnalogShield

## Question

I am very new to this hardware and C programming.  I just purchased the Uno32 with an AnalogShield.  I am running the Passthrough program which works.  I would like to also display the input voltage but I am not able to calculate from the digital number that I am getting.  At 0V, I get -32693 counts.  At 1.587V (AA battery), I get -22377.  At -1.587V, I get 22533.  At -3.127, 12159.  AT 3.167, -11989 counts.  So at lower voltage, I get higher counts.  I think this is lack of knowledge on my part; hopefully someone can help me out.

Thanks!

int count = 0;
float val = 0;
void loop()
{
//count = count;
float voltage=count*(5.0/65535.0);
val = map(count, -32768.0, 32768.0, 0.0, 5.0);
analog.write(0, count);  //write out the value on port labeled 'OUT0'
Serial.println("count ");
Serial.println(count);
Serial.println("map -32768, 32768, 0, 5");
Serial.println(val);
Serial.println("Voltage as 65535 over 5V");
Serial.println(voltage);
Serial.println(" ");
//Serial.println("count");
//Serial.println("voltage");
//Serial.println(v);
delay(10000);
}

## Recommended Posts

• 0
Hi cmeuchel,

I believe I have found the source of your original problem.

The issue that you are running into is with the fact that the analog.read() function returns an unsigned 16 bit value. However, you have count declared as an "int" meaning it is a signed (+/-) value.  Therefore, because you are assigning an unsigned value to a signed value, the most significant bit (the largest value which accounts for all of your higher voltages) is no longer interpreted as a number, so-to-speak, but as a minus sign, messing up any attempts to correctly interpret the value.

So, when you are reading the 0V, the analog.read() function will return a value slightly larger than 32767, such as 32842 (greater by 75).  However, because the highest bit is interpreted as a negative sign instead of a '1' for the binary number, the C language sees the first number of the extra 75 as the negative sign (to make it -32767) and the remaining 74 out of the 75 extra as additional values making the final value which you printed -32693. (-32767 + 74 = -32693). With the even higher voltages, this negative value will continue to get closer and closer to a value of '0'.

The easiest way to fix this is to simply declare your variable count as an unsigned integer:
unsigned int count = 0;
This will fix your count value at higher voltages.

I also spotted one other issue with your map() function.

The second and third parameters for your map function are the min and max values, respectively, that you are expecting to be getting from the value you want to "scale" (count in this case).  However, as the analog.read function only returns unsigned int values between 0 and 65535 (with the zero value corresponding to -5V and the 65535 value corresponding to +5V) so you will never be giving the map function that lower bound of -32767.

So, there are a couple of ways to fix this, which you have already done to an extent, but I'll list them anyway for the sake of explanation.

voltage = count * (10.0 / 65535.0) - 5;
equation in order to account for the fact that the 0 to 65535 range that analog.read gives is associated with -5V to +5V (a 10 V range). The -5V will then get the voltage back to the correct polarity.  You would then also want to change the map function to say
val = map(count, 0.0, 65535.0, -5.0, 5.0);

Alternatively, if you really wanted to keep the -32767 and the 32767 as the 2nd and 3rd values in your map() function, you could subtract 32767 from your "count" variable before giving it to the map() function.
val = map(count, -32767.0, 32767.0, -5, 5);
This will then "map" your count to the -5V to 5V scale that the analog.read() function is working off of.

Let me know if you have any questions.

Thanks,

James

##### Share on other sites
• 0

Here is what solved the problem (there may be a more elegant way):

if(count<0)
{val=count+32767;
}
else
{val=count-32767;
};
float voltage=val*(10.0/65535.0);