This project is designed to test the stability of analog to digital converters (ADC). I have heard several times an opinion, also expressed in some literature, that in most cases two lower-order bits of ADC should be disregarded due to digital noise as they are flickering all the time and are not stable. It was absolutely NOT the case in my experiments.
The circuit is intended to measure temperature in °C by using LM60 temperature sensor. The output of this sensor is a voltage proportional to temperature:
V(mV) = 424 + 6.25·TC
The temperature range measured by this application is 0 - 49°C. Hence, the sensor output is between 424mV and 730mV. In order to increase the accuracy of converting this range into the digital form, the ADC built into the PIC is equipped to work with an external reference provided by LM285 (1.235V). The ADC is configured for a 10-bit resolution, thus the minimum distinguishable voltage is 1235/1024 = 1.2mV. The output of ADC is very stable and does not fluctuate with time, provided that the temperature does not change. Definitely, there is no any digital noise cause by the two lower-order bits of ADC.
Schematic | Layout | |
The temperature is measured every 180 msec and displayed as an integer number. For the desired temp range the ADC's value varies between 352 and 607. Hence, we can measure temperature with 0.2°C accuracy only. To increase the accuracy up to 0.1°C one should use adjust voltage reference or use a higher resolution ADC (12 bits or more).
Since no averaging of temperature samples is needed, the program is also pretty simple. A table is used to convert ADC value into the temperature setting. PIC's output RA5 is used to turn on an alarm if the temperature exceeds some threshold defined within the code (25°C for now).
ADC of PIC16F819 is more advanced in the sense that it allows as Vref+ as well as Vref- coming from external pins. In our test Vref- is just grounded. The ADC is as stable as in the PIC above, which was expected.
Schematic | Layout | |
However, since ADC is still only 10-bit, measuring the temperature with 0.1°C resolution in this schematic is impossible.
In order to achieve a 0.1°C resolution I used external sigma-delta ADC MCP3425. It is manufactured in a tiny SOT23-6 package, has differential inputs, an I2C digital interface, and a 2.048 V voltage reference. Since only PIC provides SCK signals for communication, no pull-up resistor is needed at this line. To use it on proto-board I assembled it on a small PCB, which also contains a 4K7 pull-up resistor and two capacitors, according to the data-shit recommendations. The board has a placeholder for the second pull-up resistor, if needed.
The MCP3425 is a perfect device providing up to 16-bit resolution and a programmable gain amplifier (PGM). It performs calibration of internal offset by every conversion. I tried it in a 16-bit mode with PGM=1 and PGM=2. In both cases all 16 bits are steady and stable in this experiment and do not flicker! This is quite impressive, since the ADC can distinguish voltages which are about 32 μV apart.
For the circuit below I configured MCP3425 for a 14-bits resolution with PGM=1 and in a single shot mode. Since its "-" input is grounded, only 13 bits are used. I further divide the ADC value by 2 to downgrade the resolution to 12 bits, as is needed for my application. Uneven brightness of digits on the photos is due to my camera - in the reality all digits are equally bright.
Schematic | Layout | ADC board | ||
The circuit can measure temperatures in the range from -40°C to 107°C. The values between -9.9°C and 99.9°C are displayed with one decimal digit, the others as an integer number. The lowest measured temperature is limited by the sensor specs, the upper one depends on the amount of memory in the PIC. The display is updated every 360 msec, and the circuit is very sensitive to the temperature. It can be used to measure temperature of humans body, for example. However, since LM60 is not intended for precise temperature measurement, for highest accuracy the sensor needs to be calibrated.
To make the program simple I used a nice feature of PIC16F819 to store and read 13-bit data from its flash program memory. I created a huge table of conversion values in the flash program memory (see the code provided). Since every memory address can hold a 13-bit constant, there is a place to store BCD codes for 3 digits and one bit (bit 12) remains for the decimal point.
By combining the above mentioned formula from LM60 data-sheet
TC = (V(mV) - 424) / 6.25
and the relation between the sensor output V(mV) and the ADC code N for a 12-bit resolution
V(mV) = 2048·(N / 4095)
we get the value of TC as a function of N:
TC = (2048·(N / 4095) - 424) / 6.25
These values were precomputed by a special Java program and are stored in the conversion table. Since for TC = -40°C we have N = 348, there is no need to store the conversion data for N < 348. So, first N is decremented by 348 and the resulting value is used as a key for the conversion table. The table is placed in PIC's memory right after the code (address 0x00D6) and takes all the remaining PIC's memory. This way every flash memory address is occupied either by the code or data! If you wish to extend the code, the table size should be reduced accordingly.
Keeping experimenting with ADCs under various conditions, I believe I understand why do some people recommend to disregard two lower-order bits of ADCs. Simple PICs are very sensitive to the board layout and can easily catch noise from power lines, thus affecting the ADC operation. To resolve the problem some microcontrollers have separate pins for analog and digital power and ground.
To demonstrate this I added a LED controller board based on MAX6950. One of the advantages of using it is in reducing the number of PIC connections down to three due to the SPI interface. Furthermore, the driver takes care on updating the display in multiplex mode. It has a default setup (Rset resistor of 56K) and can deliver up to 40mA per segment. The display scanning frequency is about 1250Hz so that each of four digits on the display becomes enabled for 200μs. The driver has a programming control of digits intensity provided by PWM. I use it in the minimum brightness mode with PWM duty cycle 1/16. The board will be described later.
Schematic | Layout | LED driver board | ||
Although the average current drawn by the entire circuit is about 35mA, there is a lot of noise on power/ground lines and I was unable to get stable 10-bit ADC reading by powering PIC and the driver board from the same power supply. So I ended up by separating them: the board is powered now from its own 7805 voltage regulator (5V) and the rest of the circuit is powered from 78L033 (3.3V). It took me a while to come up to the layout shown above while I finally could achieve stable 10-bit ADC output. The number on display is a 10-bit ADC reading.
This is one of smallest and simplest TI microcontrollers, but it is equipped with a powerful 16-bit ADC. I used it with an internal 1.2V reference. Unfortunately, the LM60 output is about 0.57V, which exceeds nominal ADC range (0.5V with 1.2V voltage reference), so the ADC readings were unstable. To make them stable I used an averaging over 256 samplings and downgraded the result down to 13 bits, shown on the picture below. I am going to experiment more with that microcontroller by adding an external 2.5V voltage reference.
Schematic | Layout | |
coming soon |
---|
Well, what about our old friend MCP3425 in a noisy environment? I added it to the circuit and it surprised me again. The readings are stable in a 16-bit mode! Stable means that occasional fluctuations are ± 1 LSB. This ADC is equipped with internal noise reduction circuit, which turns out to be very efficient. Note that that the PIC, ADC, and LED board are powered from the same voltage regulator (see the image in the middle). I forgot to add the 0.1μF bypassing cap at the output of LM60, which one should add for sure. The number of display is just the ADC reading.
Schematic | Layout 1 | Layout 2 | TPS5410 | |||
![]() |
---|
To make ADC's job even harder I powered the circuit from a switching DC-DC step-down converter on TPS5410 with 500 KHz switching frequency (see the image on the right). With a 35mA load the peak-to-peak output ripple is 10mV. The converter deserves a separate report to be done later. Anyway, under these conditions the stability of MCP3425 did not change at all. Note that the above mentioned circuit with PIC16F684 did not pass this test. Once both linear voltage regulators are replaced with the switching one the ADC reading fluctuations jump up to ±5 LSB.
Last modified:Mon, Jan 23, 2023.