A to D conversion is a lot easier than you may think.

 

Contents:


Simple A to D

I have a number of ideas involving the use of A to D converters, including a simple thermometer, and a Data Logger.

Below is a sample circuit to show how easy it is to use a Serial AD chip.

The circuit simply reads the voltage at the chip's input (Provided by the 47k variable resistor), and displays the digital value (in Decimal and Hexadecimal) on my 5 digit LED display. A little bit of maths and you could easily display the actual voltage (eg: 255 = 5V, 127 = 2.5V, 000 = 0V), but this gives you the idea.

The code is a simple modification of one of the sample codes in the data sheet for my 5 digit LED display. The actual ADC part of the code is very simple. The pdf for the AD chip is available from Texas Instrument's web site. Folks in NZ or Australia, Dick Smith has this chip in stock.

 


 

Circuit Diagram:

 


 

Code: 

Step 1: Test program - simply displays the actual byte sent from the ADC

Step 2: Modify code to display the actual voltage.

Step 3: Let's log some data!

 '{$STAMP BS2}

 

'*****DECLARE VARIABLES*****
'DATA for the Display's Character Lookup Table

data 63,6,91,79,102,109,125,7,127,111
'0-9
data %01110111,%01111100,%00111001,%01011110,%01111001,%01110001
'A-F (EEPROM address 10 to 15)

'CONSTANTS
dispclock CON 6
'P6 = clock to 4094's pin 3
dispdata CON 5
'P5 = Data to 4094's pin 2
ADclock CON 13
'P13 = Clock to TLC548
ADdata CON 14
'P14 = Data from TLC548
ADenable CON 15
'P15 = CS on TLC548 Low = enabled
'VARIABLES

strobedigit var nib
'a four bit variable used to determine which digit to update
character var byte
'the data to send to the display
datafromAD var byte
'the data from the PC
a var byte
'just a FOR loop variable
nibble var nib
'used to store the lower or upper 4 bits of "datafromAD"
divider var byte

'*****MAIN PROGRAM*****
HIGH ADenable
'Set up the display
Gosub blankdisplay

ReadAD:
LOW ADenable
SHIFTIN ADdata, ADclock, MSBPRE, [datafromAD]
HIGH ADenable
GOSUB DisplayASCIIHEXcode
goto ReadAD

DisplayASCIIHEXcode:
nibble = datafromAD
'transfer lower 4 bits of byte to nibble
read nibble, character
'lookup data in table to send to the display
strobedigit=0
gosub loadregisters

nibble = datafromAD >> 4 'transfer upper 4 bits of byte to nibble
read nibble, character
'lookup data in table to send to the display
strobedigit = 1
gosub loadregisters

DisplayASCIIDECIMALcode:
'Figure out hundreds unit
nibble = datafromAD/100
strobedigit = 4
read nibble, character
gosub loadregisters

'Figure out tens unit
divider = nibble*100
divider = datafromAD-divider
nibble = divider/10
strobedigit = 3
read nibble, character
gosub loadregisters

'Figure out ones unit
divider = datafromAD/10
divider = divider*10
nibble = datafromAD - divider
strobedigit = 2
read nibble, character
'(turn on decimal point to seperate Dec from Hex on the display)
character = character+%10000000
gosub loadregisters
return

blankdisplay:
SHIFTOUT Dispdata, Dispclock, msbfirst, [0]
'blank display
for a = 0 to 4
pulsout a,1
'Strobe each digit
next
return

loadregisters:
SHIFTOUT Dispdata, Dispclock, msbfirst, [character]
'Send data to the display
PULSOUT strobedigit,1
'Strobe required digit to display the data
return

 


 

Simple Volt Meter...

 '{$STAMP BS2}

'This version displays the actual voltage, rather than the digital value from the ADC

'*****DECLARE VARIABLES*****
'DATA for the Display's Character Lookup Table

data 63,6,91,79,102,109,125,7,127,111
'0-9

'CONSTANTS
dispclock CON 6
'P6 = clock to 4094's pin 3
dispdata CON 5
'P5 = Data to 4094's pin 2
ADclock CON 13
'P13 = Clock to TLC548
ADdata CON 14
'P14 = Data from TLC548
ADenable CON 15
'P15 = CS on TLC548 Low = enabled

'VARIABLES
strobedigit var nib
'a four bit variable used to determine which digit to update
character var byte
'the data to send to the display
datafromAD var byte
'the data from the AD
Voltage var byte
a var byte
'just a FOR loop variable
nibble var nib
'used to store the lower or upper 4 bits of "datafromAD"
divider var byte

'*****MAIN PROGRAM*****
HIGH ADenable
'Set up the display
Gosub blankdisplay

ReadAD:
LOW ADenable
SHIFTIN ADdata, ADclock, MSBPRE, [datafromAD]
HIGH ADenable
ConverttoVolts:
Voltage = (datafromAD * 100)/510
'debug dec Voltage
GOSUB DisplayVoltage
goto ReadAD

DisplayVoltage:
'Figure out hundreds unit
nibble = Voltage/100
strobedigit = 2
read nibble, character
gosub loadregisters

'Figure out tens unit
divider = nibble*100
divider = Voltage-divider
nibble = divider/10
strobedigit = 1
read nibble, character
'(turn on decimal point)
character = character+%10000000
gosub loadregisters

'Figure out ones unit
divider = Voltage/10
divider = divider*10
nibble = Voltage - divider
strobedigit = 0
read nibble, character
gosub loadregisters
return

blankdisplay:
SHIFTOUT Dispdata, Dispclock, msbfirst, [0]
'blank display
for a = 0 to 4
pulsout a,1
'Strobe each digit
next
return

loadregisters:
SHIFTOUT Dispdata, Dispclock, msbfirst, [character]
'Send data to the display
PULSOUT strobedigit,1
'Strobe required digit to display the data
return

 


 

Data Logging:

In order to log data, you can do it two ways.

1. Store data in memory on your microcontroller board and download later, or

2. Send data, as it is collected, to a PC.

Then - display the results.

Here is how I set up my test circuit, for option 2, to log the voltage every second as I adjusted the Variable resistor, and display the data in Excel on my Mac and Windows PC.

a). Firstly, in order to present the data in a format that Excel can understand, you need to create a "Comma separated values" file. This is a text file where commas separate the field values.

b). Use Hyperterminal to receive data from the Stamp, and turn on Text Capture.

So, to display something like the following table in Excel:

 Time Voltage
 1  0.02
 2  0.50
 3  3.70
 4  4.70

Your text file will need to look like this:

Time,Voltage
1,0.02
2,0.50
3,3.70
4,4.70
 
The code below will do this. This version displays the voltage on my 5 digit LED module, and the data is sent out the serial port, formatted as per the requirements above.

 '{$STAMP BS2}

'This version displays the actual voltage, rather than the digital value from the ADC, and sends the data to a PC for logging.

'*****DECLARE VARIABLES*****
'DATA for the Display's Character Lookup Table

data 63,6,91,79,102,109,125,7,127,111
'0-9

'CONSTANTS
dispclock CON 6
'P6 = clock to 4094's pin 3
dispdata CON 5
'P5 = Data to 4094's pin 2
ADclock CON 13
'P13 = Clock to TLC548
ADdata CON 14
'P14 = Data from TLC548
ADenable CON 15
'P15 = CS on TLC548 Low = enabled

'VARIABLES
strobedigit var nib
'a four bit variable used to determine which digit to update
character var byte
'the data to send to the display
datafromAD var word
'the data from the AD
Voltage var word
time var byte
a var byte
'just a FOR loop variable
nibble var nib
'used to store the lower or upper 4 bits of "datafromAD"
divider var byte

'*****MAIN PROGRAM*****
HIGH ADenable
'Set up the display
Gosub blankdisplay
time=0
pause 2000
serout 16,396, ["Time,Voltage",13]

ReadAD:
LOW ADenable
SHIFTIN ADdata, ADclock, MSBPRE, [datafromAD]
HIGH ADenable
PAUSE 1000
ConverttoVolts:
Voltage = (ABS(datafromAD) * 100)/51
GOSUB DisplayVoltage
time= time +1
goto ReadAD

DisplayVoltage:
'Figure out ones unit
nibble = Voltage/100
strobedigit = 2
read nibble, character
'(turn on decimal point)
character = character+%10000000
gosub loadDisplay
serout 16,396, [dec time,",",dec nibble,"."]
'Figure out first decimal place
divider = nibble*100
divider = Voltage-divider
nibble = divider/10
strobedigit = 1
read nibble, character
serout 16,396, [dec nibble]
gosub loadDisplay
'Figure out second decimal place
divider = Voltage/10
divider = divider*10
nibble = Voltage - divider
strobedigit = 0
read nibble, character
serout 16,396, [dec nibble,13]
gosub loadDisplay
return

blankdisplay:
SHIFTOUT Dispdata, Dispclock, msbfirst, [0]
'blank display
for a = 0 to 4
pulsout a,1
'Strobe each digit
next
return

loadDisplay:
SHIFTOUT Dispdata, Dispclock, msbfirst, [character]
'Send data to the display
PULSOUT strobedigit,1
'Strobe required digit to display the data
return

 
Here is an example of the captured data.

 



How to display in Excel:
 
Within Excel, start recording a Macro. Open your text file, and follow the wizard to get your data displayed correctly.
You can create graphs of your data as in the screenshot below.
 
Now, everytime you run the Macro, you can easily collect data from your A to D circuit.
 
 

A complete working datalogger.


 

The code to make this all work is below.

Notes:

 

TABLE 1 - Memory Map of the 24C02 at Device address 002 on the I2C BUS

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 L e n n a r d E l e c t r o n
10 i c s w w w . l e n n a r d . n
20 e t . n z F i r m w a r e v 1
30 . 0 0 0 9 / 0 2 S a m p l e
40 M e m o r y A b o u t S a m
50 p l e R a t e i s A d j u s
60 t O K O n B
70 o a r d M e m o r y S t o r e
80 D o w n l o a d P
90 r e s s G o w h e n r e a
A0 d y D o w n l o a d i n g . . .
B0 o f s e c m i n h o u r 0E 11
C0 15 15 15 11 15 1F 0E 11 11 11 11 11 1F 1F 0E 1F
D0 1F 1F 1F 1F 1F 1F 0E 11 1F 1F 1F 1F 1F 1F 0E 11
E0 11 1F 1F 1F 1F 1F 0E 11 11 11 1F 1F 1F 1F 0E 11
F0 11 11 11 1F 1F 1F 18 14 14 14 1C 01 0A 04 00 00
Display messages
Custom LCD characters
User settings

The code is here.


 

<TO ADD LATER>

There are two ways to collect data from the Datalogger.

</TO ADD LATER>

 


 

Improvements:

 


 

Screen shots:

All the data for these examples was collected by downloading the data from my datalogger's memory to Hyperterminal (or a similar Mac terminal emulator) using text capture mode, then the captured text file was loaded in to Excel and the chart wizard used to create the graphs.


You can see that the temperature went up and down a bit during the day. It can get hot in the lounge, and opening a window, and the door to the balcony helped cool the room down (until the wind stopped...). The Time along the X axis was a simple calculation in Excel.


The next two examples use the modified code (just displaying the actual voltage).

 

You can see the light level going up and down as clouds passed by overhead. Around about 6.30pm, is when the sun started to disappear behind the hills of Crofton Downs, and from 7pm to 7.40pm more peaks and throughs as clouds cleared then gathered again, then from around 7.50pm, the sun started to set altogether.


This is a chart created in Excel. A .csv file is imported to Excel with the data as read from the Datalogger's memory, then in Excel, a simple calculation is performed to get the actual voltage that the data represents.