This was originally developed by Miss Rosy Cordova as partial fulfillment of her Capstone Design Project in the Dept of EE at Morgan State University. Miss Cordova now works for the Hughes Corporation.
This is not an endorsement of the product. We have used it and it works. The intent in placing this on the WWW is to save someone else the time in developing a C routine to control the Model 30 DAS.
Prairie Digital, Inc., 846 Seventeenth St, Industrial Park, Prairie du Sac, WI 53578, Tel (608) 643-8599, FAX (608) 643-6754.
Prairie Digital advertises various low cost data acquisition systems in Circuit Cellar Inc. The Model 30 is a half size ISA card which may be used in even the oldest of PCS. Connections to the external world may be made using a via 60 conductor ribbon connector. As most applications require only a few leads, one can wire-wrap to this connector and save the inconvenience of a 60-conductor ribbon cable and an external break out box.
It features a TI TLC549 8-bit serial A/D and a 4051 CMOS 8-channel analog multiplexer. All of this is controlled with an 8255. The address decoding may be set to either 0x0304-0x0307 (factory settings) or to 0x0284-0x0287. Determined by J1 and J2.
The card may optionally be used for 24 I/O lines by removing straps J3, J4, J5 and J6 which removes the A/D and J7, J8 and J9 which removes the address leads associated with the 4051 multiplexer.
The positive and negative A/D references are fixed at +5VDC and ground. The +5V reference is derived from an LM317 voltage regulator (as opposed to using the PCS +5V supply as a reference).
The following routine was written in TurboC (DOS).
It illustrates how to use the card to make eight temperature measurements where each temperature sensor consists of +5 VDC (terminal B7) through a series resistor R1 and an NTC thermistor to ground (terminal A32). The center node of each is connected to one of the analog input channels; terminals A21, A20, A19, A22, B19, B22, B20 and B21, corresponding the channels 0-7, respectively.
The INH and Vee leads on the 4051 (terminals A17 and B17) are both tied to ground (terminal A32).
The routine assumes the address straps J1 and J2 are set for addresses 0x0304-0x0307, J3-J6 are in (A/D in circuit) and J7-J9 are in (4051 addressing in).
/*
** File A_D.C Uses Prairie Digital Board to make temperature measurements at
** 8 points.
**
** Intended to illustrate how to perform A/D measurements and use the 4051
** analog multiplexer.
**
** Rosy Cordova & P. H. Anderson, Morgan State University, May, 95.
*/
#include <stdio.h>
#include <dos.h>
#include <math.h>
#include <conio.h>
#define CONTROL 0x0307
#define PORTA 0x0304
#define PORTB 0x0305
#define PORTC 0x0306
#define R1 10.0e3 /* 10.0 K resistor */
typedef unsigned char byte;
void config_8255(void);
void select_channel (byte channel);
byte make_meas (byte channel);
float calc_temperature(byte level);
main()
{
byte level;
int i, n;
float T_f;
clrscr();
for (n=0; n<100; n++) /* make 100 measurements */
{
for (i=0; i<8; i++)
{
level = make_meas(i);
T_f = calc_temperature(level);
printf("%.3f ", T_f);
}
printf("\n");
sleep(60); /* 1 minute pause between measurements */
}
}
void config_8255(void)
{
outportb(CONTROL, 0x81);
/*
8255 configured;
PORTA = output, PORTB = output,
PORTC_hi_nib = output, PORTC_lo_nib = input
*/
}
void select_channel (byte channel)
{
if (channel >=8)
{
printf("%d is an invalid channel.\n", channel);
exit(1);
}
else
{
outportb(PORTB, channel);
/* lower three bits control CMOS multiplexer */
}
}
byte make_meas (byte channel)
{
int n;
byte level=0x00;
config_8255();
select_channel(channel);
delay(5);
outportb(PORTC, 0xc1); /* hi nibble of PORTC controls A_D */
/* 1100 0000 = CS and CLK high */
outportb(PORTC, 0x40); /* CS now low */
for (n=7; n>=0; n--)
{
outportb(PORTC, 0x40); /* clk high */
delay(5);
level = level | (((inportb(PORTC) >>3) & 0x01) << n);
outportb(PORTC, 0x00); /* clk lo */
}
outportb(PORTC, 0x80); /*CS high */
return(level);
}
float calc_temperature(byte level)
{
float R_thermistor, T_kelvin, T_f, Beta=3383, T_o=297.2, R_o=1.09e4;
float level_f;
level_f = (float) level;
R_thermistor = -0.391e7*level_f/(391.0*level_f-1.0e5);
T_kelvin = Beta*T_o/((log(R_thermistor/R_o)*T_o)+Beta);
T_f = (T_kelvin - 273.0)*1.8+32.0;
return(T_f);
}