GHIElectronics.NETMF.Hardware.AnalogIn vs Microsoft.SPOT.Hardware.AnalogInput

I’ve been working with one of the Sharp analog IR distance sensors (2Y0A21), using NETMF 4.2 on my Cerb40. I had a pretty rough go of it to begin with, trying to figure out what was coming back from the .Read() and .ReadRaw() methods of the AnalogInput class. I finally figured it out, so I thought I’d post it here to help anyone else that might be struggling.

The GHI library from 4.1 uses 10-bit resolution (by default, anyway), and the values that come back are 0-1023. This makes sense, because 10 bits, all 1s, comes out to be 1023. Therefore, by default (no SetLinearScale() called), the output is the raw reading from the ADC register. This is the same way that the ReadRaw() method works in NETMF 4.2, with the only difference being that in the STM32 firmware found on Cerberus & friends, anyway, the only resolution supported is 12 bits, and 12 bits (all 1s) is 4095. That means that the value that comes back is in the range 0-4095 instead of 0-1024.

Now, I needed to convert this value into volts to be able to tell what distance was being read on the sensor. This is the math I used:

using( var ain = new AnalogInput(Cpu.AnalogChannel.ANALOG_0) )
	// read the raw value from the sensor... with 12-bit precision, this will return an integer
	// between 0 and 4095
	var rawValue = ain.ReadRaw();

	// calculate the number of millivolts by taking the raw value, multiplying by
	// 3300 (3.3V in millivolts) and dividing by 4095 (which would be 3.3V)
	var milliVolts = ((double)rawValue * (double)3300) / (double)0xFFF;

	// now, if we want, we can calculate the number of volts by multiplying
	// the number of millivolts by 1000
	var volts  = milliVolts / 1000;

One could do this by using ain.Read(), without needing to know the resolution, because Read() returns a percentage. You only need to know that the maximum input is a full 3.3V:

using( var ain = new AnalogInput(Cpu.AnalogChannel.ANALOG_0) )
	// read the converted value from the sensor... this returns a double
	// between 0 (0V) and 1 (3.3V)
	var value = ain.Read();

	// now, if we want, we can calculate the number of volts by multiplying
	// the converted value by 3.3
	var volts  = value * (double)3.3;

	// finally, if we want millivolts, then take the number of volts and multiply by 1000
	var milliVolts = volts * (double)1000;

This seems to be correct to me, the math works out mostly. It’s a tiny bit tough because the Sharp sensor is very noisy, so a call to Read() and a subsequent call to ReadRaw() can return very different values. I’ll post a driver for that sensor here in a bit. Hopefully this helps someone be less confused than I was.

1 Like

For those that are interested, I posted a driver for the sensor on codeshare:


Thank you very much. This is what I am looking for.

You’re certainly welcome.