Link here

How to measure an Analog Distance Sensor


This video shows how to use the PDQ Board to measure an analog voltage, and output the data on multiple digital displays. Topics covered include: ADC (analog to digital converter), controlling LED's, digital inputs, digital outputs, analog inputs.

Call anytime
If you have any questions please give us a call. We will be glad to discuss your application with you! See this link: Contact Us
 

Video


Click here to view the video in a new window.

 

Introduction

This video is a demonstration of reading an analog voltage, computing data, and controlling LEDs. I am using a Sharp GP2D12 Infrared (IR) sensor. More information about sharp distance sensors. The PDQ board connects to your host PC via a serial cable, running at a baud rate of 115200.

 

Software

The following software is involved in this demonstration:

  1. Mosaic IDE Plus - Compiles the C source code below, resulting in a .DLF, or "download file."
  2. Mosaic Terminal - Communicates with the PDQ Board over a serial comm port.
  3. QED-Forth Real Time Operating System (RTOS) - Operating system controlling the PDQ Board

The Mosiac IDE Plus compiles your C source code into a binary file. The Mosaic Terminal sends this file to the PDQ Board Users Guide. The QED-Forth RTOS on the PDQ Board Users Guide receives this file into ram, and then saves to flash memory after the download is complete. If you type "main" into the terminal followed by the 'enter' key, the RTOS will execute main() from the loaded source code. You also have the option to "Autostart" your program; this instructs the PDQ Board to execute main() at device power-on.

 

Hardware

This project is constructed from boards manufactured by Mosaic Industries as well as materials sold by other vendors.

 

Mosaic Hardware

Other

  1. Switches, 10 LED Bar Graph, 7-Segment LED Display - Generic products, check http://www.digikey.com/.
 

Schematic

The following schematic describes how all the components in this circuit are connected. Please download the pdf for a high resolution view of this document. http://www.mosaic-industries.com/embedded-systems/_media/microcontroller-projects/how-to-measure-an-analog-distance-sensor.pdf

how-to-measure-an-analog-distance-sensor.pdf (right-click save as)

 

Source Code

#include  <MOSAIC\ALLQED.h>    // include the standard library functions
 
// This sample program accompanies the youtube video located here:
//
//      - http://www.youtube.com/watch?v=8ABlonlmBwk
//
// This program reads an IR distance sensor and visually outputs the distance on
// a seven segment LED display.  A 10 LED bar graph also fills up as the distance
// decreases.  4 switches are connected to digital inputs which allow the user
// to change the display.  This program is meant to be a simple demonstration of
// the onboard I/O available on the PDQ board.  This program is a modified
// version of the demo project entitled "Analog I/O Demo" which is provided with the
// Mosaic IDE Plus.
 
 
//  Copyright 2010 Mosaic Industries, Inc.  All Rights Reserved.
//  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.
 
 
// ************* Switch Definitions *****************
 
// This #define masks one bit from Port M
// if SWITCH1 is non-zero, then it is ON
 
#define SWITCH1 ( PORTM & 0x04 )      // ON = enable bar graph
#define SWITCH2 ( PORTM & 0x08 )      // ON = enable seven-segment display
#define SWITCH3 ( PORTM & 0x10 )      // ON = freeze output on all displays
#define SWITCH4 ( PORTM & 0x20 )      // ON = exit to forth prompt
 
 
// ************* Forward Declaration ****************
 
_Q void DoBarGraph( int val );
_Q void LEDOutput( float cm );
_Q void BlankDigit( void );
_Q void DisplayBarGraph( int bar );
 
// ******* Multiple 10 Bit A/D Conversions with Results in a C Array *********
 
#define DEFAULT_NUMSAMPLES  16
 
_qv uint c_results_10[DEFAULT_NUMSAMPLES];   // declare c buffer for 10 bit A/D results
 
 
_Q void SampleToArray(int channel)
// converts using 10bit A/D on specified channel (0-7), puts results in
// the 1-dimensional C array c_results_10[]
// We use the EXTENDED_ADDR union defined in TYPES.H to convert
// the simple 16bit array address into the 32bit xaddr required by ATDMultiple()
{                xaddr xcbuffer = TO_XADDR(c_results_10,0);
 
  //USAGE:    ATDMultiple ( xaddr buffer, uint utime, int one_byte,
  //          int numsequences, int starting_channel_id, int numchannels );
        ATDMultiple(xcbuffer, 0xfff, 0, DEFAULT_NUMSAMPLES, channel, 1);
}
 
 
 
//  ********************* Initializations ****************
 
 
_Q void InitAnalogPins(void)
// zeros the standard C array to hold 10bit results;
// turns on the analog converters
{       int i;
        ATDOn(0);   // turn on converter for AN0-AN7
 
        for(i=0;i<DEFAULT_NUMSAMPLES;i++)
                c_results_10[i]=0;             // zero the C array
}
 
 
// DigitArray holds 8 bit patterns which are used to light up the seven segment
// display.  The pattern is written to each segment (denoted with letters)
// in the following order, with an X for the decimal place:
//    XGFEDCBA
// In this configuration, A is the least significant bit, and the decimal place
// is the most significant bit.  Remember that these LEDs are active low, so
// 0 means lit, 1 means dark.
//
//                            0     1     2     3     4     5     6     7     8     9     A     Blank
const char DigitArray[12] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0xff };
 
 
// This function sets up the digital I/O pins
// Each pin is connected to an LED in the active low configuration
_Q void InitDigitalPins(void)
{
    // we set the value of the port before we change the port to output
    PORTT = 0xff; // turn off the LED's
    PORTP = 0xff; // turn off LED's
    PORTM = 0xff; // turn off LED's
    DDRT = 0xff; // make Port T all outputs
    DDRP = 0xff; // make Port P all outputs
    DDRM = 0x03; // make just the lower 2 pins outputs
}
 
// display a digit on the 7 segment LED
_Q void DisplayDigit( int digit )
{
    // bind the range of 'digit' between 10 and 0
    if( digit > 10 )
    {
      digit = 10;
    }
    if( digit < 0 )
    {
      digit = 0;
    }
 
    // Note: if 'digit' is 10, an A is displayed on the seven segment display
 
    //PortP bits 2-7
    ChangeBits( (DigitArray[digit] << 2), 0xfc, (int) &PORTP );
 
    //PortM bits 0-1
    ChangeBits( (DigitArray[digit] >> 6), 0x03, (int) &PORTM );
 
}
 
// Completely turns off the 7-segment display
_Q void BlankDigit( void )
{
    //PortP bits 2-7
    ChangeBits( (DigitArray[11] << 2), 0xfc, (int) &PORTP );
 
    //PortM bits 0-1
    ChangeBits( (DigitArray[11] >> 6), 0x03, (int) &PORTM );
}
 
// Allows the 7 segment display to be lit in any configuration
// NOTE: This and other functions defined with _Q are interactively
// callable from the forth prompt.  This function is not called from within main
_Q int test( int bits )
{
    //Make sure digital pins are setup correctly
    InitDigitalPins();
 
    //PortP bits 2-7
    ChangeBits( (bits << 2), 0xfc, (int) &PORTP );
 
    //PortM bits 0-1
    ChangeBits( (bits >> 6), 0x03, (int) &PORTM );
 
    return 0;
}
 
// This function takes a 10 bit input (named 'bar') and displays it on the bar graph
// The 10 bits are split across PortT and PortP.
// The 8 least significant bits of 'bar' are output on PortT, while the remaining
// 2 bits are output on PortP
_Q void DisplayBarGraph( int bar )
{
  // output 8 bits to PortT
  ChangeBits( 0xff & bar, 0xff, (int) &PORTT );
 
  bar >>= 8;
 
  // output 2 bits to PortP
  ChangeBits( bar, 0x3, (int) &PORTP );
}
 
 
// converts A/D counts to centimeters
_Q float CountsToCm( int counts )
{
  float cm;
 
  // The following conversion equation was obtained by plugging 18 sample
  // points into Microsoft Excel. A second order polynomial equation fit
  // the data best.
  //
  //   x = 1000/counts
  //   y = .00003*x^2 + 0.0678*x + 4.2692
 
  cm = 0.0003*counts*counts + .0678*counts + 4.2692;
  cm = 1000/cm;
  cm += 1;
 
  return cm;
}
 
 
 
 
 
// This function processes the data we just read into the C array
// It also calls LEDOutput() which handles lighting up LED's
_Q void ProcessArray( void )
{     int i, shifted;
      float cm;
 
      for( i = 0; i < DEFAULT_NUMSAMPLES; i++ )
      {
        shifted = c_results_10[i] >> 6;  // shift the data so it is right justified
        shifted = shifted & 0x3ff;       // the shift may have carried in 1's,
                                         // so we need to zero out the upper bits
 
        // convert A/D counts to centimeters
        cm = CountsToCm( shifted );
 
        // output data to the bar graph and seven segment LEDs
        LEDOutput( cm );
 
      }
}
 
 
// The bar graph is empty at this distance (cm)
#define MAX_DIST (45)
 
// the bar graph is full at this distance (cm)
#define MIN_DIST (15)
 
 
 
// This function takes in centimeters and outputs to the bar graph and
// seven segment LED display.  The range for the bar graph is #defined above
_Q void LEDOutput( float cm )
{
  float conversion;
  int filled;
  int bits;
 
 
  // calculate how full the bar graph should be
  conversion = cm - MIN_DIST;           // subtract minimum
  conversion = conversion / MAX_DIST;   // divide by maximum
 
  conversion = conversion * 10;   // conversion has a range from 0.0 to 1.0
                                  // now multiply by how many LEDs we have
 
  // bind conversion at the top limit
  // we need this because it is easy for cm to go above MAX_DIST
  if( conversion > 10 )
    conversion = 10;
 
  // filled is the number of lights displayed on the bar graph
  // it is also the number visible on the seven segment display
  filled = 10 - (int) conversion;
 
 
  // 'bits' holds the bit pattern for the bar graph
  // we start bits with ten 1's
  bits = 0x3ff;
 
  // we then shift it to the right 'filled' bits.
  bits >>= filled;
 
 
  // if switch1 is on, display the bar graph.  if not display all 1's or not lit
  if( SWITCH1 )
    DisplayBarGraph( bits );
  else
    DisplayBarGraph( 0x3ff );
 
 
  // if switch2 is on, light up the seven segment display
  if( SWITCH2 )
    DisplayDigit( filled );
  else
    BlankDigit();
 
}
 
// ************************** main *****************************
 
 
 
int main (void)
{
  // init digital and analog i/o pins
  InitAnalogPins();
  InitDigitalPins();
 
  // loop forever
  while(1)
  {
 
    if( ! SWITCH4 ) // only loop if switch4 is OFF
    {
      SampleToArray(0);        // sample 8 bit A/D channel 0
      ProcessArray();          // converts input to centimeters, also calls display routines
    }
    if( SWITCH3 ) // exit loop if switch3 is ON
      break;
  }
  return 0;
}



See also → Microcontroller Projects

 
This page is about: How to Measure Analog Distance Sensor – This video shows how to use PDQ Board to measure an analog voltage, and output data on multiple digital displays. Topics covered include: ADC (analog to digital converter), controlling LEDs, digital inputs, digital outputs, analog inputs. Call anytime If …
 
 
Navigation