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

MB1210.cpp

Committer:
Blaze513
Date:
2010-08-28
Revision:
4:a615b75d4126
Parent:
3:05183e50a923

File content as of revision 4:a615b75d4126:

//mbed Microcontroller Library
//Max Botix Ultrasonic Range Finder MB1210 Interface
//Copyright 2010
//Thomas Hamilton

#include "MB1210.h"

MB1210::MB1210(PinName pw, PinName an, PinName tx, PinName rx) : OperatingMode(0x00),
    UnitFactor(1), PwmScalingFactor(17014.5), AnalogScalingFactor(1024), Range(0)
{
    if (rx != NC)
    {
        SerialInput = new Serial(NC, rx);
        SerialInput->baud(9600);
        SerialInput->format(8, Serial::None, 1);
        SerialInput->attach(NULL, Serial::RxIrq);
        OperatingMode = 0x02;
    }
    if (an != NC)
    {
        AnalogInput = new AnalogIn(an);
        OperatingMode = 0x01;
    }
    if (pw != NC)
    {
        PwmInput = new PwmIn(pw);
        OperatingMode = 0x00;
    }
    if (tx != NC)
    {
        SerialOutput = new DigitalOut(tx);
        SerialOutput->write(0);
    }
}
    //constructor dynamically allocates memory and cpu time (interrupts)
    //to input objects depending on how the device is connected

MB1210::~MB1210()
{
    delete PwmInput;
    delete AnalogInput;
    delete SerialOutput;
    delete SerialInput;
    delete this;
}
    //input objects must be deallocated

void MB1210::SoundVelocity(float MetersPerSecond)
{
    PwmScalingFactor = (UnitFactor * MetersPerSecond * 50);
}
    //set the velocity of sound for pwm readings

void MB1210::Voltage(float Volts)
{
    AnalogScalingFactor = (UnitFactor * 3379.2 / Volts);
}
    //set the voltage correction factor for analog readings

void MB1210::Unit(float UnitsPerMeter)
{
    PwmScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
    AnalogScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
    UnitFactor = UnitsPerMeter / 100;
}
    //set the unit factor to return the range in units other than cm

void MB1210::Mode(char Selection)
{
    if (SerialInput)
    {
        if (Selection & 0x08)
        {
            SerialInput->attach(this, &MB1210::Interrupt, Serial::RxIrq);
        }
        else
        {
            SerialInput->attach(NULL, Serial::RxIrq);
        }
            //attach or detach the interrupt function
    }
        //interrupts can only be generated if rx pin is connected
    if (SerialOutput)
    {
        SerialOutput->write(Selection & 0x04);
    }
        //synchronous modes can only be set if tx pin is connected
    OperatingMode = Selection & 0x03;
}
    //change the operating mode; SerialOutput controls synchronicity

void MB1210::AttachInterruptBuffer(float* Buffer)
{
    InterruptBuffer = Buffer;
}
    //the user changes the pointer to their own storage area so they can use the interrupt

void MB1210::RequestSyncRead()
{
    if (SerialOutput)
    {
        SerialOutput->write(1);
        wait_us(20);
        SerialOutput->write(0);
    }
}
    //hold pin high for at least 20 us to request a synchronous range reading

void MB1210::DiscardSerialBuffer()
{
    while (SerialInput->readable())
    {
        SerialInput->getc();
    }
}
    //read characters from the buffer until it is empty

float MB1210::Read()
{
    switch (OperatingMode)
    {
        case 0:
            if (PwmInput)
            {
                return PwmInput->pulsewidth() * PwmScalingFactor;
            }
            else
            {
                return 0;
            }
        case 1:
            if (AnalogInput)
            {
                return AnalogInput->read() * AnalogScalingFactor;
            }
            else
            {
                return 0;
            }
        case 2:
            if (SerialInput)
            {
                unsigned char i = 0;
                while (SerialInput->readable() && !SerialInput->scanf("R%3f", &Range) && (i < 32))
                {
                    SerialInput->getc();
                    i++;
                }
                    //find R and parse the range out
                return Range * UnitFactor;
            }
            else
            {
                return 0;
            }
        default:
            return 0;
    }
}
    //OperatingMode switches to desired output method;
    //the result is scaled according to voltage, the speed of sound, and desired unit

void MB1210::Interrupt()
{
    *InterruptBuffer = Read();
    DiscardSerialBuffer();
}
    //this is called whenever an interrupt mode is
    //set and a serial rx interrupt is generated;
    //it writes to the user's data storage area

MB1210::operator float()
{
    return Read();
}
    //conversion function acts as shorthand for Read()