Link here

DA 24/7 C Demo 3

C demonstration code for the DA 24/7 Data Acquisition Wildcard: faster conversion times

The 24/7 Data Acquisition Wildcard™ is a complete analog front end, offering exceptional 24-bit resolution, excellent stability, and remarkable noise rejection for instrumentation applications. Ideal for high resolution, low frequency measurements and data logging, this analog-to-digital converter (ADC) accepts low level signals directly from transducers, amplifies and conditions them, and converts them with 24 bits of resolution with no missing codes performance.

This C language demonstration program shows how to read 4 different channels at a fixed sample rate without performing a calibration before each sample and without using interrupts. A self-calibration is performed only once at the outset, resulting in faster conversion times.


DA 24/7 C Demo 3

// ****************************************************************************************
// FILE NAME: wda247demo3.c
// copyright 2009 Mosaic Industries, Inc. All rights reserved.
// ---------------------------------------------------------------------
// DATE: 4/20/2009
// VERSION: 1.0, for QED/Q-Line (HC-11) and PDQ line (HCS-12) controllers
// ---------------------------------------------------------------------
// This is the demonstration code for the 24/7 Data Acquisition Wildcard.
// Please see its User Guide for more details.
//
// The final example shows how to read 4 different channels at a
// fixed sample rate without performing a calibration before each
// sample and without using interrupts.  This example performs a
// Self Calibration on each channel, reads the calibration
// coefficients using Read_FS_Cal() and Read_Zero_Cal(), stores the
// calibration coefficients into a structure, loads the 24-Bit A/D
// with the stored calibration coefficients using
// Start_Conv_With_Values(), periodically samples each channel using
// AD24_Sample_NP(), and finally stores the samples into an array.
//
// MAKE SURE THAT THE DA247_MODULE_NUM CONSTANT MATCHES YOUR HARDWARE JUMPER SETTINGS!!
//
// ---------------------------------------------------------------------
// Disclaimer: THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
// ANY WARRANTIES OR REPRESENTATIONS EXPRESS OR IMPLIED,
// INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES
// OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//
// *********************************************************************
 
 
#include <mosaic/allqed.h>
//__GNUC__ is true for Mosaic PDQ IDE
 
#ifdef __GNUC__
#include <wda247.h>
#else
#include "library.h"
#include "library.c"
#endif
 
// NOTE: YOU MUST MAKE SURE THAT DA247_MODULE_NUM CONSTANT MATCHES YOUR HARDWARE JUMPERS!!
#define DA247_MODULE_NUM 0 // double check your hardware jumper settings!!!
 
 
#define CH0       0               //  Constants for channels 0 - 3
#define CH1       1
#define CH2       2
#define CH3       3
#define SAMPLE_FREQ 320           // Constant corresponding to 60 hz
                         // 19200 / 60 = 320 [See Table 5]
#define NUM_SAMPLES 40            // Total number of samples:
                                  // 10 samples for 4 channels
#define NUM_CHANNELS 4            // Num channels we are sampling
// Declare an array for samples & allocate memory for the samples
// from 4 sensors; each sample is 4 bytes.
 
ulong ad24_data[NUM_SAMPLES/NUM_CHANNELS][NUM_CHANNELS];
typedef struct                    // Config options for each channel
{
  ulong ad_zero_cal;              // 24-bit zero sacle cal val
  ulong ad_fs_cal;                // 24-bit full scale cal val
  int  ad_freq_int;               // Frequency Integer 19 - 4000.
  char ad_gain;                   // Gain 1 to 128.
  char ad_polarity;               // Bipolar or Unipolar mode.
  char ad_res;                    // Resolution: 16-bit or 24-bit.
  char ad_bo;                     // Burn out current on/off
  char ad_fsync;                  // Sync on/off.
  char ad_ch;                     // Channel.
} AD_CHANNEL;
 
typedef struct                    // Global structure.
{
  AD_CHANNEL ch0;
  AD_CHANNEL ch1;
  AD_CHANNEL ch2;
  AD_CHANNEL ch3;
  char   current_channel;         // Current channel being used.
  int    index;                   // Index into data array
} AD_INFO;
 
AD_INFO ad24_struct;              // Declare a global instance of the
                                  // structure.
// Perform a Full Self Calibration on channel 0-1 for bipolar, unity
// gain, 60 Hz operation and get calibration coefficients.
// Initialize channel 0 of my_struct with calibration coefficients
// and settings.
 
int Init_CH0 ( void )
{
  int flag;
  flag = Start_Conversion( SELF_CAL, SAMPLE_FREQ, GAIN_1, BIPOLAR,
                           WORD_24BIT, BO_OFF, CH_0_1 );
  if( flag == -1 )
  {
    ad24_struct.ch0.ad_freq_int = SAMPLE_FREQ;
    ad24_struct.ch0.ad_gain     = GAIN_1;
    ad24_struct.ch0.ad_polarity = BIPOLAR;
    ad24_struct.ch0.ad_res      = WORD_24BIT;
    ad24_struct.ch0.ad_bo       = BO_OFF;
    ad24_struct.ch0.ad_fsync    = FSYNC_OFF;
    ad24_struct.ch0.ad_ch       = CH_0_1;
    ad24_struct.ch0.ad_zero_cal = Read_Zero_Cal();
    ad24_struct.ch0.ad_fs_cal   = Read_FS_Cal();
  }
  return(flag);
}
 
// Perform a Full Self Calibration on channel 2-3 for bipolar, unity
// gain, 60 Hz operation and get calibration coefficients.
// Initialize channel 1 of my_struct with calibration coefficients
// and settings.
 
int Init_CH1 ( void )
{
  int flag;
  flag = Start_Conversion( SELF_CAL, SAMPLE_FREQ, GAIN_1, BIPOLAR,
                           WORD_24BIT, BO_OFF, CH_2_3 );
  if( flag == -1 )
  {
    ad24_struct.ch1.ad_freq_int = SAMPLE_FREQ;
    ad24_struct.ch1.ad_gain     = GAIN_1;
    ad24_struct.ch1.ad_polarity = BIPOLAR;
    ad24_struct.ch1.ad_res      = WORD_24BIT;
    ad24_struct.ch1.ad_bo       = BO_OFF;
    ad24_struct.ch1.ad_fsync    = FSYNC_OFF;
    ad24_struct.ch1.ad_ch       = CH_2_3;
    ad24_struct.ch1.ad_zero_cal = Read_Zero_Cal();
    ad24_struct.ch1.ad_fs_cal   = Read_FS_Cal();
  }
  return(flag);
}
 
// Perform a Full Self Calibration on channel 4-5 for bipolar, unity
// gain, 60 Hz operation and get calibration coefficients.
// Initialize channel 2 of my_struct with calibration coefficients
// and settings.
 
int Init_CH2 ( void )
{
  int flag;
  flag = Start_Conversion( SELF_CAL, SAMPLE_FREQ, GAIN_1, BIPOLAR,
                           WORD_24BIT, BO_OFF, CH_4_5 );
  if( flag == -1 )
  {
    ad24_struct.ch2.ad_freq_int = SAMPLE_FREQ;
    ad24_struct.ch2.ad_gain     = GAIN_1;
    ad24_struct.ch2.ad_polarity = BIPOLAR;
    ad24_struct.ch2.ad_res      = WORD_24BIT;
    ad24_struct.ch2.ad_bo       = BO_OFF;
    ad24_struct.ch2.ad_fsync    = FSYNC_OFF;
    ad24_struct.ch2.ad_ch       = CH_4_5;
    ad24_struct.ch2.ad_zero_cal = Read_Zero_Cal();
    ad24_struct.ch2.ad_fs_cal   = Read_FS_Cal();
  }
  return(flag);
}
 
// Perform a Full Self Calibration on channel 6-7 for bipolar, unity
// gain, 60 Hz operation and get calibration coefficients.
// Initialize channel 3 of my_struct with calibration coefficients
// and settings.
 
int Init_CH3 ( void )
{
  int flag;
  flag = Start_Conversion( SELF_CAL, SAMPLE_FREQ, GAIN_1, BIPOLAR,
                           WORD_24BIT, BO_OFF, CH_6_7 );
  if( flag == -1 )
  {
    ad24_struct.ch3.ad_freq_int = SAMPLE_FREQ;
    ad24_struct.ch3.ad_gain     = GAIN_1;
    ad24_struct.ch3.ad_polarity = BIPOLAR;
    ad24_struct.ch3.ad_res      = WORD_24BIT;
    ad24_struct.ch3.ad_bo       = BO_OFF;
    ad24_struct.ch3.ad_fsync    = FSYNC_OFF;
    ad24_struct.ch3.ad_ch       = CH_6_7;
    ad24_struct.ch3.ad_zero_cal = Read_Zero_Cal();
    ad24_struct.ch3.ad_fs_cal   = Read_FS_Cal();
  }
    return(flag);
}
 
// This routine loads the 24-Bit A/D with the next set of
// calibration coefficients without performing a calibration.
 
void Load_Coefficients( int current_ch )
{
  switch( current_ch )
  {
    case CH0: Start_Conv_With_Values( ad24_struct.ch0.ad_fs_cal,
                ad24_struct.ch0.ad_zero_cal,
                ad24_struct.ch0.ad_freq_int,
                ad24_struct.ch0.ad_gain,
                ad24_struct.ch0.ad_polarity,
                ad24_struct.ch0.ad_res,
                ad24_struct.ch0.ad_bo,
                ad24_struct.ch0.ad_fsync,
                ad24_struct.ch0.ad_ch );
                break;
    case CH1: Start_Conv_With_Values( ad24_struct.ch1.ad_fs_cal,
                ad24_struct.ch1.ad_zero_cal,
                ad24_struct.ch1.ad_freq_int,
                ad24_struct.ch1.ad_gain,
                ad24_struct.ch1.ad_polarity,
                ad24_struct.ch1.ad_res,
                ad24_struct.ch1.ad_bo,
                ad24_struct.ch1.ad_fsync,
                ad24_struct.ch1.ad_ch );
                break;
    case CH2: Start_Conv_With_Values( ad24_struct.ch2.ad_fs_cal,
                ad24_struct.ch2.ad_zero_cal,
                ad24_struct.ch2.ad_freq_int,
                ad24_struct.ch2.ad_gain,
                ad24_struct.ch2.ad_polarity,
                ad24_struct.ch2.ad_res,
                ad24_struct.ch2.ad_bo,
                ad24_struct.ch2.ad_fsync,
                ad24_struct.ch2.ad_ch );
                break;
    case CH3: Start_Conv_With_Values( ad24_struct.ch3.ad_fs_cal,
                ad24_struct.ch3.ad_zero_cal,
                ad24_struct.ch3.ad_freq_int,
                ad24_struct.ch3.ad_gain,
                ad24_struct.ch3.ad_polarity,
                ad24_struct.ch3.ad_res,
                ad24_struct.ch3.ad_bo,
                ad24_struct.ch3.ad_fsync,
                ad24_struct.ch3.ad_ch );
                break;
  }
}
 
// This routine takes one sample, stores it to an array, then starts
// a conversion for the next channel.
 
void Get_Sample ( void )
{
  // Get sample from the 24-Bit A/D, store to array
  ad24_data[ad24_struct.index][ad24_struct.current_channel]=AD24_Sample_NP();
  // Increment channel number, did we sample all the channels yet?
  if( ad24_struct.current_channel++ >= NUM_CHANNELS - 1 )
  {
    // Init channel number to 0, we finished sampling all channels.
    ad24_struct.current_channel = 0;
    // Set varible to store next group of data
    ad24_struct.index++;
  }
  // Load coefficients for the next channel
  Load_Coefficients ( ad24_struct.current_channel );
}
 
// This routine repeatedly calls Get_Sample() every timeslice_ticks
// * 5ms.  Be sure other tasks do not take longer than
// timeslice_ticks * 5ms.
 
void Execute_So_Often ( uint num_times, ulong timeslice_ticks )
{
  ulong sample_time;
  int i;
  for( i = 0; i < num_times; i++ )
  {
    sample_time = FetchTSCount();
    Get_Sample();
    do
    {
      Pause();
    }
    while ( FetchTSCount() - sample_time < timeslice_ticks );
  }
}
 
// This routine takes 10 samples from 4 sensors at 60 Hz.  All of
// the settings for each channel are stored in a global structure.
// All channels must have the same sampling rate!
 
int Sample_Routine3 ( void )
{
  int flag;
  flag = Init_AD24( DA247_MODULE_NUM );// 24/7 Data Acquisition Wildcard is
                              // the first Wildcard on the stack
  Use_Onboard_Ref();          // Use on-board reference
  ad24_struct.current_channel = CH0;// Set ch0 as current channel
  ad24_struct.index = 0;      // Init array index number
  // Init structure;  Be sure to call Init_CH0 last since it is the
  // first channel sampled.
  Init_CH3(); Init_CH2(); Init_CH1(); Init_CH0();
  // Get 1 sample every 60 ms.  60 ms is the fastest we can call
  // Get_Sample() because the sample rate is 60Hz and the 24-Bit A/D
  // takes 3 clock cycles to obtain a sample when using
  // Start_Conv_With_Values().  This alone is 3/60 or 50 ms.  If a
  // full Self-Calibration was performed before each conversion, the
  // fastest rate you could sample one channel would be 10/60 or 167
  // ms.  This would amount to 666 ms for 4 channels or 1.5 Hz per
  // channel.
  Execute_So_Often( NUM_SAMPLES, (ulong)12 ); // 12*5ms = 60ms
  return(flag);
}
 
_Q void print_routine( void )
{
    int i,j;
    long val;
    printf("\n\n channel      value\n----------------------\n");
    for( i = 0; i < NUM_CHANNELS; i++ )
    {
      for( j = 0; j < NUM_SAMPLES/NUM_CHANNELS; j++ )
      {
        printf("    %d        %lx\n", i, ad24_data[j][i]);
      }
    }
}
 
int main( void )
{ Sample_Routine3();
  print_routine();
  return 0;
}



See also →
24/7 Data Acquisition Wildcard Users Guide
24/7 Data Acquisition Wildcard Glossary
DA 24/7 C Demo 1
DA 24/7 C Demo 2
DA 24/7 Forth Demo 1
DA 24/7 Forth Demo 2
DA 24/7 Forth Demo 3

 
This page is about: C Language Example Program, 24-bit A/D Conversion, Self-calibration – This C language demonstration program shows how to read 4 different channels at a fixed sample rate without performing a calibration before each sample and without using interrupts.
 
 
Navigation