I spent considerable time last night trying to get the differential ADC inputs working on my Arduino Leonardo board, and finally gave up. Here is what I found:
- It was easy to set up the MUX to get differential inputs to do something—I wasn’t having trouble selecting the appropriate pairs of pins.
- The signal was much smaller than expected. I expected a 2-fold reduction in signal, as the range for the 10-bit conversion goes from [0,+5V) to [–5V, +5V], but what I saw was an 8-fold reduction in the signal.
- Despite clear descriptions in the manual of how the differential inputs are supposed to work, the 8-bit output of the differential ADC is not aligned with the the MSB in the same place as the 10-bit single-ended DAC. This further means that setting the ADLAR bit to get left-alignment of the outputs does not left align the signal, but leaves it a factor of 4 short of that goal. With the gain set to 10, there seemed to be one bit less, and so the signal seemed to have not a gain of 10, but of 10/16, rather defeating the point of having an amplifier.
- The signal was far noisier than just reading the two channels separately and subtracting in software. Setting the gain to 10 seemed to amplify the noise more than the signal.
- When using the paired inputs with a gain of 10, I saw random negations of the signal, flipping its sign a few times per second, not correlated with the input signal.
- I tried looking at the signal both with ADLAR set and without, and ADLAR seemed to be just doing a left-shift of 6 bits, as the documentation claims—the problems are in the alignment of the ADC output before shifting.
I read the documentation for the 32U4 differential ADC several times, and finally concluded that the chip I had was not behaving at all according to the specs (which themselves had several typos—Atmel writes some of the worst-checked documentation I’ve seen from a major manufacturer).
It is possible that the chip I have has been subtly fried (though the single-ended ADC seems to work fine), but I can’t find much evidence on the web that anyone uses the 32U4 with the differential inputs, particularly not with the output left-aligned. If anyone has a Leonardo Arduino board (or other ATMega32U4-based board), I’d be interested in hearing whether you can get the differential ADC inputs on the board to work properly. If you do get differential inputs to work properly, please send me some information about how you did it, because I’m frustrated. Perhaps I’m missing some crucial tidbit of information that would make everything make sense.
In the meantime, I’m regarding the differential ADC channels of the 32U4 as an unimplemented marketing lie, and not going to try to use them in PteroDAQ (which wastes a couple of days work on refactoring the code to make it easier to handle boards with different gain on different differential channels). At least the code still works with the KL25Z differential channels, which seem more limited than the 32U4 ones (only 2 pairs and both have gain of 0.5), but which actually work as documented.