Serial Wombat
a general-purpose digital interface device for hobbyists, engineers and students

 


Home
Overview
Protocol
Documentation
Channel Modes
Direct Control
Controlled Pin
Raw A/D
A/D Averaging
A/D 1st Order Filtering
Matrix Keypad
Servo Control
Analog Direct
Analog Follow
Rotary Encoder
Debouncing
Counter
Hysteresis
Morse Code
Pulse
Unipolar Stepper
LCD Driver 1
LCD Driver 2
HW Pulse Meas.
2D Lookup
SPI Master
HD44780 Generic
Remote Control
DataLogger
Min-Max
Public Data
Timed IO
Getting Started
Connectivity
Pin Mode SDK Beta
Sample Projects
Downloads
Contact Us
Purchase
Forum

Did you know...

 

Analog Input Averaging

A channel configured to CHANNEL_MODE_AD_AVERAGE averages some number of consecutive A/D samples and provides that average in its public data buffer to be used by the host PC or by another channel. When initializing the channel the host can command the number of samples to be averaged. This number must be a power of two between 0 and 15. Therefore, valid numbers of samples are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 and 32768. Each sample contributing to the average is taken when the channel is serviced. Therefore, an average of 32 samples will be updated every 32ms if the frame time is 1ms. Note that after the desired number of samples are collected and the public data is updated, all past data is discarded for the start of the next average. When a channel is initialized to CHANNEL_MODE_AD_AVERAGE, its public data is initialized to the current value of that channel's A/D conversion.

To configure a channel to CHANNEL_MODE_AD_AVERAGE, send the following set of 8 bytes:

Byte # Byte Value Description
0 200 Configure pin
1 pin# Physical Pin number
2 15 Channel mode = Average
3 Number of samples Expressed as a power of two between 0 and 15, inclusive.
4 unused  
5 unused  
6 unused  
7 unused  

For example, to configure pin 2 to average 32 samples, the following command would be send:
200 2 15 5 0x55 0x55 0x55 0x55

Return packet is an echo of the sent packet.

 

Pin Mode Source Code

The following code is what creates the pin mode for this function inside of the Wombat. You don't need to know this to use the pin mode, but some people find it interesting. See the SDK for some insight into how pin modes work. Hold your mouse over various words and variables for definitions. #ifndef COMPILING_FIRMWARE
        #include <stdio.h>
#endif

#include "types.h"
#include "utilities.h"
#include "global_data.h"
#ifdef COMPILING_FIRMWARE

#pragma code APPLICATION
#pragma romdata APPLICATION_DATA

#endif 




void init_ad_average(void)
{
        if (rxbuffer[0] == CONFIGURE_CHANNEL_MODE_0)
        {
             // Initialize the buffer with latest reading
             tp.generic.buffer = vread_ad();
             tp.ad_average.sum = 0;
             tp.ad_average.count = 0;
             if (rxbuffer[3] > 15)
             {
                     tp.ad_average.samples = 15;
             }
             else 
             {
                     tp.ad_average.samples = rxbuffer[3];
             }
        }
}

void update_ad_average(void)
{
        // Add to the sum, and the number of samples
        tp.ad_average.sum += vread_ad();
        ++tp.ad_average.count;

        // Get an integer which corresponds to 2^x
        tp2.ad_average.temp16 = uint16_bitfield[tp.ad_average.samples];

        if ( tp.ad_average.count >= tp2.ad_average.temp16)
        {
             // If we got enough samples, figure the average
             tp2.ad_average.temp32 = tp.ad_average.sum;

             // Since samples must be a power of 2, we can
             // do a shift rather than a divide
             tp.ad_average.sum >>= (tp.ad_average.samples );
             tp.generic.buffer = tp.ad_average.sum;

             // Round the result...
             tp2.ad_average.temp16 >>= 1;
             if ( tp.generic.buffer != 0xFFFF && (tp2.ad_average.temp32 & tp2.ad_average.temp16))
             {
                     ++tp.generic.buffer;
             }

             // And reset for next time
             tp.ad_average.count = 0;
             tp.ad_average.sum = 0;
             tp.ad_average.source = virtual_pin;
        }

            
}

/////////////////////////////////////////////////////////////////////////
//  CODE FROM HERE DOWN IS TESTING CODE FOR USE ON PC, not FIRMWARE
#ifdef TEST_AD_AVERAGE

#define NUM_OF_TESTS 7
   int test;
uint16 const test_vector[][7] = {
                          {0x8000,0x4000,0xC000,0x0000,20,4, 0x6000},
                          {0x8000,0x8000,0x8000,0x8000,20,4, 0x8000},
                          {0xFFFF,0xFFFF,0xFFFF,0xFFFF,40000,15, 0xFFFF},
                          {0x8000,0x8000,0x7FFF,0x7FFF,40000,15, 0x8000},
                          {0x8000,0x7FFF,0x7FFF,0x7FFF,40000,15, 0x7FFF},
                          {0x1234,0x7FFF,0x7FFF,0x7FFF,1,15, 0x1234},
                          {0x0008,0x0002,0x9,17,3,1, 0x0005},
};
int test_iteration;
  
int main(void)
{
#define NUM_OF_SAMPLES 60 
#define NUM_OF_SAMPLES_LOG_2 4
#define PIN 2

        system_init();

    for  (test = 0; test < NUM_OF_TESTS; ++test)
    {

        printf ("Running test %d: values %d %d %d %d, iterations: %d samples: 2^ %d\n",
                 test,
                test_vector[test][0],
                test_vector[test][1],
                test_vector[test][2],
                test_vector[test][3],
                test_vector[test][4],
                test_vector[test][5]) ;

        ADbuffer[map_physical_pin_ad(PIN)].u = test_vector[test][0];
        rxbuffer[0] = CONFIGURE_CHANNEL_MODE_0;
        rxbuffer[1] = PIN;
        rxbuffer[2] = PIN_MODE_AD_AVERAGE;
        rxbuffer[3] = test_vector[test][5];

        process_rxbuffer();

        for (test_iteration = 0; test_iteration < test_vector[test][4]; ++test_iteration)
       {
           ADbuffer[map_physical_pin_ad(PIN)].u = test_vector[test][test_iteration % 4];
           process_pins();
       }

       if (get_buffer(map_pin(PIN)) != test_vector[test][6])
       {
          printf ("Test %d returned %d, expected %d\n",test, tp.generic.buffer, test_vector[test][6]);
          return (1);
       }
    }
       printf ("All tests passed.\n");
       return (0);

}    

#endif
 

Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.