Yes, there will be noise, as there is on any ADC. Also note that the ADC is only 12 bit and so the last 4 bits of the sample are not actual valid data.
The ADC also takes significant charge from the pin when it samples, so depending on the sampling rate and output impedance of what you’re connecting to the pin, you’ll see variation from that too. If this is a problem, you should use a unity gain buffer amp on the input.
sjm - Thanks for posting those samples. Could I ask which impee board are you using? As you can see from my samples, I have some noise source that is giving brief samples that are almost rail-to-rail making this unusable. I’m beginning to think it may be the switcher on the April board but don’t have a good enough scope to see what is really going on.
Hugo - Thanks for the guidance. Many MCU/DSP data sheets will have a section on the ADC which provides some details on the equivalent input circuit and recommendation for the holdup sampling cap. Do you have anything from your supplier that you can pass along?
The first line in my code above gives you a clue as to the board
But as Hugo pointed out, these are 12 bit values left aligned (and according to the wiki, the bottom 4 bits are copies of the top 4*). With this in mind, doing a (val>>4) does improve it somewhat.
not sure why they did this, I would have kept it right aligned, and masked out the top 4 bits.
I suspect the ADC external input impedance will be around 50k, with a sampling switch resistance of 1k, shunted by a sample/hold cap of 8pF. External parasitic capacitance will be at least 7pF (these are typical values for a STM32F10xxx).
@cnstjohn The cpu is an stm32f205, datasheet is on the ST.com website. The imp card has a shared AGND/DGND (through a connector, no less) which doesn’t help with ground noise, but it’s not been too bad in our experience.
@Hugo - Thanks for info. I’ll do my home work on the MCU details there.
@sjm - missed the impee reference ( reading too fast ). Your data shows the kind of variation I would have expected. I’d be curious to see if you get the same kind of readings with the sampler class on your April board.
I’m beginning to suspect the reference voltage. I’m feeding the board with a very clean 5v supply but there may be some switching noise from the 3v3 buck. Just haven’t had enough time to dig in more.
@cnstjohn VREF noise is quite possible. The imp module has VREF broken out separately which allows you to clean it up - the imp card has no such luxury due to the small number of pins.
I see similar results when using the sampler class. It doesn’t appear to be as “clean” as the basic read() function. As before, this is just a pot wired from 3V3 to GND, wiper on pin 9.
`// Analog test using sampler class on Sparkfun April
function DataReady(buffer, length)
{
local i;
if (length > 0)
{
for (i=0;i<length;i+=2)
server.log(format("%d",buffer[i]*256+buffer[i+1]));
}
}
function StopSampler()
{
hardware.sampler.stop();
}
@sjm - Thanks so much for doing that. Does look very similar to what I have seen. Both those experiments produce great data. Looks like you were running the sample much slower and still getting similar data ( I did both 4k and 8k ). I also dropped in a 1uF cap as a ADC hold up cap on pin 9 without any significant difference in the data.
@Hugo - Is there Anybody up there in the Mothership that has time to confirm these findings on an April board and maybe make some recommendations? My product concept doesn’t need a super ADC but these noise samples will make me look at an external device which would be a cost adder.
Thanks Peter, I wasn’t too clear on that myself. It’s not the first time I’ve been bitten by endian issues, and I’m sure it won’t be the last. Data looks much better when the bytes are swapped:
@Peter - You may have also hit on my issue. I am processing values from the blob as follows:
value = swap2(buffer);
The results looked reasonable but I didn’t check closely. The assumption was that this would create and MSB left justified 16bit number that I could do some math on. Sounds like this is not the case.
When you update the wiki it would really be great to see some examples of how you process the blob buffer into properly ordered 12bit values that you can use with the math class.
There should be no need to call swap2(). Either read the values bytewise, like in SJM’s “DataReady” function (but corrected for endianness as per my post above), or read them as 16-bit integers directly using blob.readn(): function DataReady(buffer, length) { local i; if (length > 0) { buffer.seek(0); for (i=0; i<length; i+=2) { server.log(format("%d",buffer.readn("w"))); } } }
Either way, you end up with integers in the range 0-65535 (inclusive) that you can then do your further processing on.
I tried modifying my code per your “readn” suggestion as follow:
local val;
buffer.seek(0);
for (local i=0; i<length; i=i+2) {
//val = swap2(buffer[i]);
val = buffer.readn(“w”);
but when it runs produces:
Saturday, March 16, 2013 10:47:59: ERROR: invalid format
Saturday, March 16, 2013 10:47:59: ERROR: at samplesReady:28
@Peter - Sorry. The code snippet is really poor now that I look at it again. Was trying to just grab the important statements. Also didn’t check the squirrel manual close on the readn() error to see the single vs double quote issue. Parser could use some more verbose error messages in this case.
All in all now if seems the ADC noise was really all about not handling the Blob data right. I used @sjm approach with Peter’s corrections for little endianess and now the readings are stable.
Would be great to see some of this flow into the manual on the sampler class with some examples.
I am able to move forward to the next phase of my project