Interesting observation on the ADC of Teensy 3.0

Status
Not open for further replies.

darkness

Active member
Hi,

I'm trying to design a smart discharger for my batteries in order to determine their capacity and automatically shut off the discharge when the batteries go below a certain voltage. In my course of preparing the software and hardware, I realised a very interesting phenomenon across the various analog channels available in the Teensy 3.0. As I need to be able to accurately compare the voltages at different points in my circuit, I needed all of the ADC channels to be matched. I built a simple circuit such that I connect a single battery across every analog channel (A0-A9), measured their ADC values and plotted a frequency histogram of the data. The numbers are quite interesting:

Code:
	A0	A1	A2	A3	A4	A5	A6	A7	A8	A9
1685	0	1	0	0	0	0	0	0	0	0
1686	0	0	0	0	0	0	0	0	0	0
1687	0	0	1	0	0	0	0	0	0	0
1688	0	0	0	0	0	0	0	0	0	0
1689	0	0	0	0	0	0	0	0	0	0
1690	1	0	0	1	0	0	1	0	0	0
1691	0	1	0	0	3	1	2	0	0	0
1692	6	0	1	1	1	1	1	3	1	2
1693	4	0	4	0	1	2	4	2	2	6
1694	5	0	10	0	4	6	5	3	3	4
1695	8	7	5	7	3	2	7	3	6	8
1696	6	8	13	13	4	8	9	11	4	3
1697	22	19	19	7	10	8	14	8	9	9
1698	37	23	20	24	15	12	17	23	20	15
1699	78	36	33	33	27	26	18	34	23	28
1700	199	57	52	58	67	42	39	53	54	42
1701	412	166	118	166	106	85	104	112	97	82
1702	1050	336	253	360	267	196	223	242	189	165
1703	2330	805	573	813	622	455	478	542	433	360
1704	4909	1840	1381	1854	1523	1057	1149	1261	1040	897
1705	8853	3879	2931	3893	3168	2396	2425	2768	2298	2071
1706	13871	7329	5824	7504	6168	4941	4820	5470	4775	4238
1707	18777	12130	10182	12323	10463	8846	8848	9669	8458	7650
1708	21312	17360	15143	16868	15723	13737	13682	14547	13378	12508
1709	20422	20620	19592	20535	19600	18495	18379	19102	18384	17418
1710	16712	21209	20843	20729	21094	21162	20840	21024	20879	20580
1711	11106	18254	19394	17892	19285	20120	20054	19664	20070	20551
1712	6432	12895	14980	12986	14558	16339	16534	15597	16498	17228
1713	3212	7824	9831	8145	9540	11308	11383	10540	11729	12726
1714	1572	4093	5719	4339	5325	6848	6858	6073	7104	7818
1715	681	1969	3007	2223	2664	3470	3600	3145	3762	4310
1716	255	875	1419	917	1274	1640	1648	1498	1849	2133
1717	113	399	639	449	517	750	728	591	778	922
1718	46	168	258	176	228	274	323	264	349	369
1719	19	87	119	73	84	111	137	116	153	178
1720	14	32	53	37	52	50	69	59	49	76
1721	7	18	22	20	29	29	35	22	36	32
1722	8	22	15	16	13	16	16	12	17	30
1723	12	12	15	7	18	15	11	11	12	9
1724	4	4	11	9	10	12	11	8	10	7
1725	0	6	3	5	10	11	7	5	11	7
1726	0	4	5	3	5	11	3	7	6	3

The frequency histogram may be more telling:
freqhist_zps7d936acb.png


From top view:
freqhist2_zps080613a7.png


Notice that moving from channel A0 to A9, there is an offset in the "earlier" channels compared to the rest. The channels start to be more matched in terms of their output starting from A1. However, channel A0 is offset by at least 2 ADC values compared to A1-A9. Therefore, if you need matched ADC outputs, seems like channels A1 to A9 are better suited and A0 should not be used. For more critical applications, seems like channels A5 to A9 are very well matched and A1 to A4 are also well matched.

Further more, when I connect the ground of the battery to AGND, I'm getting a lot of noise on the circuit (the ADC values generated above are based on connection to AGND). From the values above, the variance is in the region of around 7 ADC units (using a resolution of 12 bits). However, when I connect to GND instead of AGND, the variance is around only 1.5 ADC units. So which ground reference pin should I be using in this case? Also, I have also tried to connect a 1uF capacitor across the ADC channels to ground for the analog pins that I'm reading. Is that a good practice and recommended?
 
That is an interesting finding. Could you post more details of your circuit and code?

In particular, I wonder if you always measured the channels in order (say, A0 then A1 ... A9) and if so, whether the same results are obtained if you measure in the opposite order (A9, A8 ... A0)?

Also, you mentioned a battery - can this be considered to have a uniform voltage over the time taken to run your tests?
 
Last edited:
Nantonos, I couldn't believe it but when I swapped the reading sequence around, indeed now A9 has a higher reading than A0. I'm still generating data as I'm typing this (around 30k data points). I probably would be able to post some results in an hour's time or so (intending to generate at least 200k readings per channel).

I did not insert any delays between consecutive reads from channel to channel. There is only a delay at the end of reading all of the channels. I suspect by inserting a delay between reads may stabilise the results. I will try that after generating this set of results.

As for whether the battery voltage remains stable throughout the test should be immaterial to the outcome of this test. A decreasing voltage should theoretically only increase the spread of data points, but should not result in the
"sweeping effect" of the voltage reading across the channels.

The picture of the circuit is as below. It's basically just a direct connection of the positive terminal of the battery to all of the analog channels being tested. The negative terminal is connected to AGND. There are capacitors across some of the analog channels to ground to reduce the ADC noise. The two crocodile clips (right at the bottom of the picture) goes to the battery.

2013-01-12-2323_zps6f0a42ac.jpg


The code that I used is as follows:

Code:
#define NUM_SAMPLES           1     // number of samples to take between intervals
#define SAMPLING_INTERVAL     1      // sampling intervals in seconds
#define SAMPLING_RESOLUTION   12     // resolution in bits


elapsedMillis sinceLastInput;
double powerDissipated = 0;
int elapsedSeconds = 0;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
  analogReadRes(SAMPLING_RESOLUTION);
  analogReference(DEFAULT);
}

// the loop routine runs over and over again forever:
void loop() {

  int sensorValue1, sensorValue2, sensorValue3, sensorValue4, x;
  int sensorValue5, sensorValue6, sensorValue7, sensorValue8, sensorValue9, sensorValue10;
  
  sinceLastInput = 0;
  sensorValue1 = 0;
  sensorValue2 = 0;
  sensorValue3 = 0;
  sensorValue4 = 0;
  sensorValue5 = 0;
  sensorValue6 = 0;
  sensorValue7 = 0;
  sensorValue8 = 0;
  sensorValue9 = 0;
  sensorValue10 = 0;

  for (x=0; x<NUM_SAMPLES; x++)
  {
    // // read the input on analog pin 0:
    // sensorValue1 += analogRead(A0);
    // sensorValue2 += analogRead(A1);
    // sensorValue3 += analogRead(A2);
    // sensorValue4 += analogRead(A3);
    // sensorValue5 += analogRead(A4);
    // sensorValue6 += analogRead(A5);
    // sensorValue7 += analogRead(A6);
    // sensorValue8 += analogRead(A7);
    // sensorValue9 += analogRead(A8);
    // sensorValue10 += analogRead(A9);


    // read the input on analog pin 0:
    sensorValue10 += analogRead(A9);
    sensorValue9 += analogRead(A8);
    sensorValue8 += analogRead(A7);
    sensorValue7 += analogRead(A6);
    sensorValue6 += analogRead(A5);
    sensorValue5 += analogRead(A4);
    sensorValue4 += analogRead(A3);
    sensorValue3 += analogRead(A2);
    sensorValue2 += analogRead(A1);
    sensorValue1 += analogRead(A0);

    // delay((SAMPLING_INTERVAL*1000 - 200)/NUM_SAMPLES);
  }

  elapsedSeconds += SAMPLING_INTERVAL;

  Serial.print(elapsedSeconds);
  Serial.print(",    ");
  Serial.print(sensorValue1/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue2/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue3/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue4/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue5/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue6/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue7/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue8/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue9/NUM_SAMPLES);
  Serial.print(", ");
  Serial.print(sensorValue10/NUM_SAMPLES);
  Serial.print(", ");

  Serial.println();


  while (sinceLastInput < SAMPLING_INTERVAL * 10) {};
  
  
}
 
Last edited:
This is the result of swapping the read sequence from A9 backwards to A0.

Code:
	A0	A1	A2	A3	A4	A5	A6	A7	A8	A9
1702	0	0	0	0	0	0	0	3	0	1
1703	1	0	0	0	0	2	0	4	0	5
1704	4	0	0	4	0	1	4	42	3	81
1705	5	3	6	18	4	4	57	327	32	573
1706	67	11	47	79	22	57	487	1609	324	2611
1707	421	123	261	474	307	567	2345	5302	1963	8177
1708	2027	667	1151	2045	1516	2623	8069	19741	6432	31396
1709	6130	2568	3762	6154	5092	8363	35093	59078	29561	71582
1710	21744	7276	10530	18975	16819	34835	77105	68478	77650	53787
1711	62018	26209	36421	53154	54061	75315	51671	28751	57906	18531
1712	65255	65857	70775	64705	69209	51741	14209	7436	14670	5245
1713	26299	59909	48767	32987	33271	14661	3356	2033	3791	1085
1714	6950	22403	15496	10595	9534	4047	740	390	813	143
1715	1909	6144	4531	3207	2740	895	94	33	80	17
1716	346	1748	1182	709	575	115	6	10	8	3
1717	50	267	257	109	76	11	1	0	4	0
1718	9	48	42	21	8	0	0	0	0	0
1719	2	3	8	1	3	0	0	0	0	0
1720	0	1	1	0	0	0	0	0	0	0

freqreverse_zps36da6833.png


I'm going to add a 3ms delay between reads and see if it improves the situation (not sure if this simulates a sample and hold?). Be posting again soon.
 
You are using the internal ADC reference which doesn't have the same accuracy/stability as 12-bit readings would need. It is possible that during your run the MCU temperature is changing and that changes the reference which in turn changes the apparent reading.

You could test this by also converting the internal temperature sensor -- it is on analog channel 0x26 (38 decimal). Its output isn't in deg. C (and needs manual calibration). You can get an approximate value in deg. C by doing:
tempeatureC = 432 - analogRead(0x26)*0.02936

(note -- these were appropriate cal. constants for my board; others may vary).
 
Results with 3ms delay between all reads.

Code:
1701	0	0	0	1	0	0	0	1	0	0
1702	2	0	1	0	0	2	0	6	1	2
1703	19	2	3	5	5	6	18	37	2	1
1704	119	25	52	88	32	39	178	263	12	55
1705	641	163	212	480	249	285	864	1339	106	407
1706	2649	818	1005	1711	1217	1513	3938	5184	764	1957
1707	9547	2999	3348	6038	4533	6626	18478	20251	3048	7184
1708	31961	10573	11784	19963	16774	26099	46712	44856	14273	26465
1709	47921	34349	35714	42274	42484	49804	39439	36339	46953	48419
1710	24213	47412	45818	35738	39895	30244	12301	12815	44106	29091
1711	6184	21536	20146	13719	14747	8017	2464	3052	12531	8756
1712	1340	5462	5227	3772	3878	1921	457	669	2507	2159
1713	293	1313	1284	935	930	327	71	102	561	371
1714	30	239	278	176	153	42	5	11	58	53
1715	8	31	48	23	26	0	1	1	4	5
1716	0	4	4	2	2	1	0	0	0	1
1717	0	0	2	1	1	0	0	0	0	0

freq-ran_zpscec1c21f.png


Jp3141, I do have a TL1431 that I could probably setup to test it out with. The only problem is that it is a SMD component and it would not fit my breadboard. I would need some kind of breakout board to hook it up to the Teensy.

I'm not sure if temperature would be a contributory factor but I can test it out. However, temperature should not affect individual channels right? If they have an effect on the reading it should be across all channels and showing a greater variance in the readings (i.e., more noise).
 
Are you using the 1.2 volt internal reference, or the 3.3 volt VCC as reference?

He has analogReference(DEFAULT); which uses the 3.3 V supply as a reference -- it's probably noisy, and of course is not guaranteed very tightly. I guess he's using NiCd cells (count of 1710 = 3.3*1710/4096 ~ 1.4 V (overcharged ?)

'darkness' -- is it possible that the 3.3 V noise is correlated with your measurements ? Perhaps the CPU current consumption is a function of the portion of code that is running ?
 
Using VCC as a reference makes sense for ratiometric measurements (like reading the position of a pot). The A/D readings will scale as VCC changes, but since a ratiometric signal also scales with VCC, the effect is canceled out.

For absolute measurements, either the internal reference or a shunt-type external reference connect to the AREF pin should be used. VCC can change, causing the A/D readings to change, even if the input voltage is perfectly constant.

Here's my guess.... maybe as code measures the 10 pins, VCC stays fairly constant. Then perhaps as it transmits the 10 numbers, the USB port consumes more power while its transmitter is active, causing the VCC to lower slightly. Or perhaps it lowers and then raises before setting back to nominal, as the LDO regulator's feedback loop responds? Either way, when the loop repeats, the effect of the previously altered VCC tends to be seen on the first measurement?

Or perhaps using the A/D changes VCC slightly, where the first measurement depends on VCC before the A/D activity, and then the other 9 have a slightly altered VCC because the A/D's circuitry (probably the high speed comparator doing the successive approximation) consumes more current while active?

Just to keep things in perspective, we're talking about a change slightly under 2 steps near the middle of 4096 scale. Assuming the input voltage really is constant, and the ADC works, that corresponds to approximately a 0.1% change in VCC during the time 10 measurements are made.

You *MUST* use the internal reference or a stable external shunt reference to achieve high performance for absolute voltage measurements. I'm actually amazed it's working so well using VCC. If you connect VCC to power other circuitry with fluctuating current requirements, or even if you write more sophisticated code that exercises the on-chip perhipherals, the performance using VCC as a reference will likely become worse.
 
Last edited:
Here's my guess.... maybe as code measures the 10 pins, VCC stays fairly constant. Then perhaps as it transmits the 10 numbers, the USB port consumes more power while its transmitter is active, causing the VCC to lower slightly. Or perhaps it lowers and then raises before setting back to nominal, as the LDO regulator's feedback loop responds? Either way, when the loop repeats, the effect of the previously altered VCC tends to be seen on the first measurement?

Or perhaps using the A/D changes VCC slightly, where the first measurement depends on VCC before the A/D activity, and then the other 9 have a slightly altered VCC because the A/D's circuitry (probably the high speed comparator doing the successive approximation) consumes more current while active?

Just to keep things in perspective, we're talking about a change slightly under 2 steps near the middle of 4096 scale. Assuming the input voltage really is constant, and the ADC works, that corresponds to approximately a 0.1% change in VCC during the time 10 measurements are made.

Paul is correct -- here is a scope shot of the 3.3V line (w.r.t. GND) with markers (blue trace) at start and stop of USB writing. Before this is the ADC activity ((you can see 10 conversions).
TEK0001.png

Here is the relevant portion of the code:
// read the input on analog pin 0:
sensorValue10 += analogRead(A9);
sensorValue9 += analogRead(A8);
sensorValue8 += analogRead(A7);
digitalWrite(1, HIGH);
sensorValue7 += analogRead(A6);
digitalWrite(1, LOW);
sensorValue6 += analogRead(A5);
sensorValue5 += analogRead(A4);
sensorValue4 += analogRead(A3);
sensorValue3 += analogRead(A2);
sensorValue2 += analogRead(A1);
sensorValue1 += analogRead(A0);

// delay((SAMPLING_INTERVAL*1000 - 200)/NUM_SAMPLES);
}

elapsedSeconds += SAMPLING_INTERVAL;
digitalWrite(0, HIGH);

Serial.print(elapsedSeconds);
Serial.print(", ");
Serial.print(sensorValue1/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue2/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue3/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue4/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue5/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue6/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue7/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue8/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensåorValue9/NUM_SAMPLES);
Serial.print(", ");
Serial.print(sensorValue10/NUM_SAMPLES);
Serial.print(", ");

Serial.println();
digitalWrite(0, LOW);


while (sinceLastInput < SAMPLING_INTERVAL * 10) {};


At conversion #3, I bring pin 1 high, at conversion 4 I bring it low. Pin 0 goes high when USB starts and low when it ends.

Ignore the very large (full screen) spike at the 3rd conversion -- this comes from capacitive coupling to the scope.

However, you can see definite 3.3V ripple of over 1 mV corresponding to each ADC conversion. Also see that before the ADC conversion sequence, 3.3V is slightly higher than during.

AGND is even noisier (roughly 40 mV spikes) during ADC conversion.

Edit -- I just looked at AREF (which is 3.3 V in this mode) -- it has a 10 mV droop during the ADC conversions:
TEK0002.png

Paul -- what's the recommended cap on AREF ? You have 0.1 uF & 470 ohm.
 
Thanks guys for the input. I have tried to wired up a shunt regulator and ended up with more problems than I started. Hope to get some advice.

I took out my Teensy and soldered a single core wire to the AREF pin. I also fashioned up a DIP board to hook up a TL1431. Using a voltmeter to measure the output voltage from the cathode end of the regulator, the output was a nice 2.50V. However, immediately upon connecting the AREF wire to the cathode end, the voltage drops to 2.43V. It seems like somehow the AREF pin is sinking current resulting in the voltage drop. Also, the ADC reading was completely haywire (the spread was more than 200 ADC units).

The circuit that I used for the shunt is Figure 1 from the datasheet (page 6). The input end is connected to the 5V Vcc from Teensy, R is chosen to be 330 ohm (datasheet says to keep I_KA between 1 to 100 mA). V_KA is connected directly into AREF. The circuit is as shown below:

2013-01-13-1900_zpse5f50529.jpg


I suspect that the problem may be due to my circuit (poor electronics knowledge? ;)). Is that a need to buffer the reference voltage from the shunt prior to connecting it into AREF?

For the software side, the only change I did was to change the DEFAULT reference to EXTERNAL.

Minor update:
I just used a voltmeter to test if I had accidentally shorted anything (esp. between AREF and A9 since they are side by side). I was surprised to find that the 3.3V pin is "continuous" with the AREF pin! (i.e, the beeper on the voltmeter sounded when I connected them). I measured the resistance between them and it was 470 ohm. Is this normal?
 
Last edited:
So did you tie REF to Cathode and just put this from AREF to GND ?

The 470 is correct -- see http://www.pjrc.com/teensy/schematic.html

The TL1431 needs about 1 mA (0.45 mA typ.). So i think you should be able to connect just this (REF&Cathode) to AREF -- no other components needed.

I don't know what changing the reference from DEFAULT to EXTERNAL should do.
 
I tried to do a search on the teensy codes and found that choosing DEFAULT and EXTERNAL actually makes no difference to the code (they have the same #define codes).

For the TL1431, all I did was to tie REF, cathode and AREF all to the same pin. Anode is connected directly to ground. Vcc (5.12V as measured from voltmeter) is connected to the AREF pin via a 330 ohm resistor (measured out to be 325 ohm from a voltmeter).

I looked at the schematic as the link above but I don't understand how it is supposed to work. Assuming that the 3.3V is connected via a 470 ohm resistor to VREFh, when I connect the 2.5V reference directly to VREFh, it would generate a current to flow through the 470 ohm resistor (right?). However, that current does not seem to have a place to go (assuming that VREFh has an infinite input resistance). I'm confused... :confused:
 
THe K20 refrence manual (http://cache.freescale.com/files/32bit/doc/ref_manual/K20P64M50SF0RM.pdf?fpsp=1&WT_TYPE=Reference Manuals&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation) helps a little -- see p608 and p626++.

In the schematic, VDDA is also 3.3 V from VOUT33. It is decoupled (filtered) with the ferrite. VREFH is connectedto this with the 470 ohm, and with no other connections, will also be 3.3 V. When you connect your 2.5 VREF to the AREF pin, a current of (5.12 - 2.5)/330 = 7.9 mA will flow from the 5.12 supply. In addition, a current of (3.3 - 2.5) /470 = 1.7 mA will flow from the 3.3 V supply (VDDA) and both will flow through your TL1431 to GND -- total = 9.6 mA.

The TL1431 doesn't actually need that much current (although it is not a problem) -- you can probably get by with removing the 5 V connection and just depending on the existing 470ohm.

I think this should have maintained 2.5 V on VREFH. When you just had 5.12 V and 330 ohm, do you still have 2.500 V on REF&Cathode ? If so, and you touch this connection to the VREFH pin (not VDDA) via a DVM measuring current, you should see a current of about 1.7 mA -- do you ?

For optimal performance, you should connect the GND (Anode) to AGND.
 
Jp3141, thank you for staying with me on this thread. Your explanation on the shunt is very clear, now I understand how the currents are flowing in my circuit.

On my specific implementation, with the 5V Vcc connected to the TL1431 through the 330 ohm, the output was 2.50V (as expected). The problem is that when I plug the blue wire (the AREF wire) into cathode, the voltage drops to 2.43V, it no longer is able to maintain 2.50V. As for the current measurement, I would have to give it a try when I'm home tonight when I have access to my circuit. I would also give the AGND connection a try as well as removing Vcc and relying solely on the 1.7mA path from Vout33.
 
You must be doing something wrong (!) -- before connecting, you have one circuit with 2.5 V (the TL1431), and another circuit (Teensy VREFH) with 3.3V. When you connect, how can you end up with a lower voltage (2.43) ?

Perhaps the TL1431 is oscillating -- do you have a decoupling cap across it & physically close (anything will work, try 0.1 uF or larger).
Does the 2.43 change when you touch the pin with 1 finger ? -- that's a sure sign of an oscillation.
 
Lol, I'm sure something is wrong that's why I'm asking for help. :eek: You are right in that logically, the voltage cannot be lower than what I started with (be it 3.3V or 2.5V). However, I'm completely baffled as to the results that I'm seeing.

Sorry for probing more info but where should I be connecting the decoupling cap? Between the cathode and anode? Or should it be between AREF and AGND? I do have a few caps available that I can try (0.01uF, 0.1uF, 1uF and 100uF).

I think you are right in that there is some kind of oscillation. In the earlier post I mentioned that the ADC output has a spread of over 200 ADC units. What I didn't mention is that the output seems to exhibit some kind of oscillating behaviour in that there are multiple peaks at various ADC values, instead of a standard Gaussian spread indicative of noise.
 
Last edited:
Connect the cap directly between Cathode & Anode. Try your 100 uF. If you can keep all the wires short - << 10 cm.

The datasheet (p.11, fig. 15) says that 0.1 uF isn't good -- that's what is on AREF on the Teensy board.

In a tidier layout with shorter wires, you shouldn't need this.
 
Thanks Jp3141. I missed out that chart in the datasheet completely! :p

In the datasheet, the x-axis is in mF and not uF. I hope it's a printing error on the datasheet as 0.1 uF is way way to the left of the charts. In fact, it seems that 100 uF will be smacked right in the centre of the unstable region(?). In any case, I will give it a try tonight and report back. Really appreciate your kindness and patience in the guidance given.
 
No, I think it's uF -- notice the resistors are 'W' -- this happens when the document uses a Symbol font for µ amd the ohm symbol, but then it gets converted to a normal font.
 
I got both good and bad news.

The good news is, using a 33uF or 100uF works! It solves the oscillating problem and provided a stable reference.

Now the bad news, it seems like there is still some inherent characteristics across each of the channels. I have tried reading from A0 to A9, then A9 to A0, and also inserting delays between reads. In all three cases, the inherent "offsets" were there. But at least now, they are consistent regardless of the read sequence or whether delays are used between reads. This is unlike previously when Vout3.3 was used.

This is a typical set of output. The "shape" of the histogram is the same in all 3 cases, so I'm just going to attached one set for reference.

Code:
	A0	A1	A2	A3	A4	A5	A6	A7	A8	A9
2208	0	0	1	0	0	0	1	1	0	0
2209	1	0	0	0	0	1	1	0	0	1
2210	2	1	0	0	0	1	0	2	0	0
2211	7	0	0	2	2	2	6	7	1	1
2212	11	2	0	7	2	14	18	16	2	3
2213	23	6	10	12	15	22	49	39	10	22
2214	67	34	29	50	26	43	89	96	29	48
2215	120	57	48	68	79	106	171	166	42	93
2216	253	126	127	180	176	224	362	367	123	209
2217	459	217	224	327	316	402	691	707	247	401
2218	962	419	501	626	639	821	1197	1280	424	728
2219	1687	797	948	1144	1208	1395	2138	2326	865	1369
2220	2847	1416	1486	1982	2136	2402	3532	3924	1485	2527
2221	4544	2466	2558	3449	3610	4053	6046	7221	2605	4011
2222	8154	3971	4112	5952	6087	6988	11130	13313	4526	6916
2223	14799	6741	6867	10911	11495	12677	17420	18813	7979	13263
2224	20277	12652	12597	17141	17781	18432	19207	18537	14785	19489
2225	18335	19582	19127	19197	19095	18414	15150	13132	20054	19390
2226	11425	19885	19786	15049	14249	13126	9049	7549	18150	12677
2227	5776	13264	13120	9389	8664	7807	4660	3824	11754	6920
2228	2867	6871	6781	4838	4727	4116	2230	1937	6114	3679
2229	1337	3364	3397	2477	2481	2026	1051	992	2960	1739
2230	663	1697	1794	1241	1218	1104	555	485	1629	903
2231	301	830	864	603	647	562	240	235	747	441
2232	144	446	406	308	304	259	121	141	351	213
2233	91	184	240	135	136	105	53	56	179	88
2234	36	94	90	56	67	67	23	30	97	42
2235	16	52	61	39	24	27	23	14	32	27
2236	12	29	28	23	17	10	10	7	21	9
2237	4	9	11	12	14	11	0	6	6	8
2238	0	5	4	4	6	3	0	0	3	3
2239	2	5	3	1	2	2	0	0	3	2
2240	1	1	2	0	0	0	0	0	0	1
2241	0	0	1	0	0	1	0	0	0	0


freq_shunt_zps5a6b3400.png



Since the characteristics is consistent, I can correct for the various "offset" in code for this particular piece of hardware. The only disadvantage is that if I switch to another Teensy, I will probably need to "recalibrate" it again.

I will also try out the code on my Arduino Leonardo to see if there are differences in behaviour. The only thing is that I need to get down to connecting up all the breadboard again and to rewrite the code for Arduino... ;)
 
This is the output from Leonardo. The ADC values was only 555 and 556 with zeros in all other ADC values, very clean!

Code:
	A0	A1	A2	A3	A4	A5	A6	A7	A8	A9
555	5232	5275	5258	5314	5332	5323	5120	5165	5173	5185
556	301	258	275	219	201	210	413	368	360	348

To be fair, this is 10 bits compared to the 12 bits on the Teensy. I will try to do a 10 bit comparison on the Teensy.
 
This is the results from Teensy 10 bits:

Code:
	A0	A1	A2	A3	A4	A5	A6	A7	A8	A9
552	0	0	0	0	0	0	4	0	0	0
553	34	7	12	24	10	14	58	31	5	3
554	6466	881	1204	2946	2013	1913	8591	4393	1073	1640
555	211560	68158	72838	121360	99432	88197	230714	163874	67512	107588
556	426702	442136	435664	441671	443433	436505	406384	441517	437690	463432
557	67493	193456	193115	140892	160828	176649	66432	100618	196822	136572
558	1360	8903	10662	6671	7835	10208	1435	3161	10396	4344
559	9	80	125	58	69	135	8	28	124	40
560	2	3	5	4	6	4	0	4	3	6
561	0	2	1	0	0	1	0	0	1	1

freq_10bits_zpscd32c57d.png


As can be seen, it maintains the same characteristic "offset" as the 12-bit results.

Thanks for all the help provided. Now I can get down to coding the actual project that I'm working on. Cheers!!
 
Good luck.

There is some info on the Freescale web site about the ADC and how to get optimal performance (I can't find it right now) -- it mentions dips in the supply etc.

Note that the TL1431 accuracy (0.4 %) would correspond to about the variations you are seeing -- i.e. without a better reference, you won't have a more precise system.
 
Status
Not open for further replies.
Back
Top