Interface class for the Max Botix ultrasonic range finder model 1210. It includes input methods for PWM, Analog, and Serial. A PwmIn class was created to allow the PWM input to be read. Now includes automatic range update via interrupts.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MB1210.cpp Source File

MB1210.cpp

00001 //mbed Microcontroller Library
00002 //Max Botix Ultrasonic Range Finder MB1210 Interface
00003 //Copyright 2010
00004 //Thomas Hamilton
00005 
00006 #include "MB1210.h"
00007 
00008 MB1210::MB1210(PinName pw, PinName an, PinName tx, PinName rx) : OperatingMode(0x00),
00009     UnitFactor(1), PwmScalingFactor(17014.5), AnalogScalingFactor(1024), Range(0)
00010 {
00011     if (rx != NC)
00012     {
00013         SerialInput = new Serial(NC, rx);
00014         SerialInput->baud(9600);
00015         SerialInput->format(8, Serial::None, 1);
00016         SerialInput->attach(NULL, Serial::RxIrq);
00017         OperatingMode = 0x02;
00018     }
00019     if (an != NC)
00020     {
00021         AnalogInput = new AnalogIn(an);
00022         OperatingMode = 0x01;
00023     }
00024     if (pw != NC)
00025     {
00026         PwmInput = new PwmIn(pw);
00027         OperatingMode = 0x00;
00028     }
00029     if (tx != NC)
00030     {
00031         SerialOutput = new DigitalOut(tx);
00032         SerialOutput->write(0);
00033     }
00034 }
00035     //constructor dynamically allocates memory and cpu time (interrupts)
00036     //to input objects depending on how the device is connected
00037 
00038 MB1210::~MB1210()
00039 {
00040     delete PwmInput;
00041     delete AnalogInput;
00042     delete SerialOutput;
00043     delete SerialInput;
00044     delete this;
00045 }
00046     //input objects must be deallocated
00047 
00048 void MB1210::SoundVelocity(float MetersPerSecond)
00049 {
00050     PwmScalingFactor = (UnitFactor * MetersPerSecond * 50);
00051 }
00052     //set the velocity of sound for pwm readings
00053 
00054 void MB1210::Voltage(float Volts)
00055 {
00056     AnalogScalingFactor = (UnitFactor * 3379.2 / Volts);
00057 }
00058     //set the voltage correction factor for analog readings
00059 
00060 void MB1210::Unit(float UnitsPerMeter)
00061 {
00062     PwmScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
00063     AnalogScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
00064     UnitFactor = UnitsPerMeter / 100;
00065 }
00066     //set the unit factor to return the range in units other than cm
00067 
00068 void MB1210::Mode(char Selection)
00069 {
00070     if (SerialInput)
00071     {
00072         if (Selection & 0x08)
00073         {
00074             SerialInput->attach(this, &MB1210::Interrupt, Serial::RxIrq);
00075         }
00076         else
00077         {
00078             SerialInput->attach(NULL, Serial::RxIrq);
00079         }
00080             //attach or detach the interrupt function
00081     }
00082         //interrupts can only be generated if rx pin is connected
00083     if (SerialOutput)
00084     {
00085         SerialOutput->write(Selection & 0x04);
00086     }
00087         //synchronous modes can only be set if tx pin is connected
00088     OperatingMode = Selection & 0x03;
00089 }
00090     //change the operating mode; SerialOutput controls synchronicity
00091 
00092 void MB1210::AttachInterruptBuffer(float* Buffer)
00093 {
00094     InterruptBuffer = Buffer;
00095 }
00096     //the user changes the pointer to their own storage area so they can use the interrupt
00097 
00098 void MB1210::RequestSyncRead()
00099 {
00100     if (SerialOutput)
00101     {
00102         SerialOutput->write(1);
00103         wait_us(20);
00104         SerialOutput->write(0);
00105     }
00106 }
00107     //hold pin high for at least 20 us to request a synchronous range reading
00108 
00109 void MB1210::DiscardSerialBuffer()
00110 {
00111     while (SerialInput->readable())
00112     {
00113         SerialInput->getc();
00114     }
00115 }
00116     //read characters from the buffer until it is empty
00117 
00118 float MB1210::Read()
00119 {
00120     switch (OperatingMode)
00121     {
00122         case 0:
00123             if (PwmInput)
00124             {
00125                 return PwmInput->pulsewidth() * PwmScalingFactor;
00126             }
00127             else
00128             {
00129                 return 0;
00130             }
00131         case 1:
00132             if (AnalogInput)
00133             {
00134                 return AnalogInput->read() * AnalogScalingFactor;
00135             }
00136             else
00137             {
00138                 return 0;
00139             }
00140         case 2:
00141             if (SerialInput)
00142             {
00143                 unsigned char i = 0;
00144                 while (SerialInput->readable() && !SerialInput->scanf("R%3f", &Range) && (i < 32))
00145                 {
00146                     SerialInput->getc();
00147                     i++;
00148                 }
00149                     //find R and parse the range out
00150                 return Range * UnitFactor;
00151             }
00152             else
00153             {
00154                 return 0;
00155             }
00156         default:
00157             return 0;
00158     }
00159 }
00160     //OperatingMode switches to desired output method;
00161     //the result is scaled according to voltage, the speed of sound, and desired unit
00162 
00163 void MB1210::Interrupt()
00164 {
00165     *InterruptBuffer = Read();
00166     DiscardSerialBuffer();
00167 }
00168     //this is called whenever an interrupt mode is
00169     //set and a serial rx interrupt is generated;
00170     //it writes to the user's data storage area
00171 
00172 MB1210::operator float()
00173 {
00174     return Read();
00175 }
00176     //conversion function acts as shorthand for Read()