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 to Digital A/D First Order Filtering

A channel configured to CHANNEL_MODE_AD_1ST_ORDER performs first order digital filtering on values input from an A/D capable channel and provides the filtered value in its public data buffer. The filter constant and sample rate are provided in the initialization command. The filter constant is expressed as a number of 65536ths. For example, to use a filter constant of .5, a value of 36768 would be sent in the initialization command. The sample period is expressed in frames, from 0 to 255. A value of 0 represents one sample per frame. A value of 1 represents a sample every other frame. A value of 255 represents one sample every 256 frames. The public data buffer is initialized with the latest A/D conversion at initialization. After each sample period has elapsed the latest A/D sample is filtered into the public data buffer according to the following formula:

Public_Data_Buffer = Public_Data_Buffer * filter_constant + new_sample * ( 1 - filter_constant)

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

Byte # Byte Value Description
0 200 Configure pin
1 pin# Physical Pin number
2 7 Channel mode = CHANNEL_MODE_AD_1ST_ORDER
3 Filter constant high byte (k * 65536) / 256
4 Filter constant low byte (k * 65536) modulo 256
5 Sample Time Number of frames between samples
6 unused  
7 unused  


For example, to configure pin 2 to filter with constant .736 and a sample time of every four frames send:
200 2 7 0xBC 0x6A 3 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. #include "types.h"
#include "utilities.h"
#include "global_data.h"
#pragma code APPLICATION
#pragma romdata APPLICATION_DATA


void init_ad_filter_1st_order(void)
{
     // Get the constant
     tp.ad_filter_1st_order.k = RXBUFFER16(3);
     if (tp.ad_filter_1st_order.k > 0)
     {
         tp.ad_filter_1st_order.kinv = 0xFFFF - tp.ad_filter_1st_order.k;
         ++ tp.ad_filter_1st_order.kinv;
     }

     // How often do we sample?
     tp.ad_filter_1st_order.sampletime = rxbuffer[5];

     // Set the countdown to that period
     tp.ad_filter_1st_order.counter = rxbuffer[5];
     // And initialize to the first sample
     tp.generic.buffer = vread_ad();
}

void update_ad_filter_1st_order(void)
{
     // Is it time to sample?
     if (tp.ad_filter_1st_order.counter)
     {
             // No.  Update countdown
             -- tp.ad_filter_1st_order.counter;
     }
     else
     {
             // Yes!  Reset the timer for next time
             tp.ad_filter_1st_order.counter = tp.ad_filter_1st_order.sampletime;

             // If k is zero, just set the buffer to the latest sample
             if (tp.ad_filter_1st_order.k == 0)
             {
                     tp.generic.buffer = vread_ad();
             }
             else
             {
                     // Otherwise, mix the old and new data in proper
                     // proportions
                     //
                     // Using the TP2 space as temporary storage...

                     tp2.ad_filter_1st_order.temp32_1 = tp.generic.buffer;
                     tp2.ad_filter_1st_order.temp32_2.temp2 = vread_ad();
                     tp2.ad_filter_1st_order.temp32_1 *= tp.ad_filter_1st_order.k;
                     tp2.ad_filter_1st_order.temp32_2.temp2 *= tp.ad_filter_1st_order.kinv;
                     tp2.ad_filter_1st_order.temp32_2.temp2 += tp2.ad_filter_1st_order.temp32_1;
                     #ifdef LITTLE_ENDIAN_WOMBAT  // This code assumes little endian
                            if (tp2.ad_filter_1st_order.temp32_2.bytes[1] & 0x80 && tp2.ad_filter_1st_order.temp32_2.words[1] != 0xFFFF)
                            {
                                    ++tp2.ad_filter_1st_order.temp32_2.words[1];
                            }
                            tp.generic.buffer = tp2.ad_filter_1st_order.temp32_2.words[1];
                     #else
                          #error  
                     #endif
               }
        }
}
 

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