Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.

Saturday 7 January 2012

MBED Example: How to use MB1210 Max Botix ultrasonic range finder model 1210 libraries

.from: http://mbed.org/users/Blaze513/programs/MB1210/5zqck


XxXxXxXxXxXxXxXxXxXxXxXxXxXx MB1210.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//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()

XxXxXxXxXxXxXxXxXxXxXxXxXxXx MB1210.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx

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

#ifndef MB1210Library
#define MB1210Library

#include "mbed.h"
#include "PwmIn.h"

class MB1210
{
    private:
        PwmIn* PwmInput;
        AnalogIn* AnalogInput;
        DigitalOut* SerialOutput;
        Serial* SerialInput;

        char OperatingMode;
        float UnitFactor;
        float PwmScalingFactor;
        float AnalogScalingFactor;
        float Range;
        float* InterruptBuffer;

        void Interrupt();

    public:
        MB1210(PinName pw, PinName an, PinName tx, PinName rx);
            //pulse width modulation input, analog input, serial output, serial input;
            //specify NC if pin is not used;
            //if the pulse width pin is used, interrupts will perform a
            //few microseconds of calculations every time a reading is taken
        ~MB1210();
            //deallocates PwmInput, AnalogInput, SerialOutput, and SerailInput
        void SoundVelocity(float MetersPerSecond);
            //if, for some reason, you need to correct the speed of sound
            //for Pwm modes, enter the new value here in meters per second;
            //default is 340.29 m/s
            //Note: most accurate mode
        void Voltage(float Volts);
            //sets expected operating voltage for Analog modes;
            //user responsibility to ensure operating voltage between 3.3 V and 5 V;
            //default is 3.3 V
        void Unit(float UnitsPerMeter);
            //argument sets the putput units through multiplication;
            //default is cm
        void Mode(char Selection);
            //argument sets operating mode;
            //set flag 0x08 to 0 for polled modes, or 1 for interrupt modes;
            //set flag 0x04 to 0 for synchronous modes, or 1 for asynchronous modes;
            //set flags 0x03 to 0 for pwm, 1 for analog, or 2 for serial;
            //asynchronous modes generate pulse width interrupts, prepare an
            //analog reading, and send a 5 byte serial reading every 99 ms;
            //interrupt modes automatically read the range into the buffer provided
            //by AttachInterruptBuffer with the selected input method every 99 ms
            //if in an asynchronous mode, or 99 ms after RequestSyncRead is called;
            //the rx pin must be connected to use an interrupt mode;
            //the tx pin must be connected to use a synchronous mode;
            //default is 0
        void AttachInterruptBuffer(float* Buffer);
            //if interrupts are used, user must provide address to write result to
        void RequestSyncRead();
            //this tells the device to prepare a synchronous range reading;
            //must be called at least 99 ms before the reading is needed;
            //changes asynchronous mode to synchronous equivalent
        void DiscardSerialBuffer();
            //the serial port has a buffer and only the oldest data is read from it;
            //the buffer has limited space and, when full, the newest data is discarded;
            //this method allows the user to empty the buffer of old data so new data is used
        float Read();
            //get a reading from the device in the set mode;
            //RequestSyncRead() must be called at least 99 ms
            //before this method can be called in a synchronous mode;
            //may be called at any time during asynchronous mode;
        operator float();
            //shorthand for taking a range reading;
            //ex: "float reading = MB1210Object;"
};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx PwmIn.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Pulse Width Modulation Input Interface
//Copyright 2010
//Thomas Hamilton

#include "PwmIn.h"

PwmIn::PwmIn(PinName pwi) : InterruptIn(pwi), PeriodMeasurement(0), PulseWidthMeasurement(1)
{
    mode(PullDown);
    rise(this, &PwmIn::PulseStart);
    fall(this, &PwmIn::PulseStop);
    start();
}

float PwmIn::read()
{
    return (float)PulseWidthMeasurement / PeriodMeasurement;
}

float PwmIn::period()
{
    return (float)PeriodMeasurement / 1000000;
}

int PwmIn::period_ms()
{
    return PeriodMeasurement / 1000;
}

int PwmIn::period_us()
{
    return PeriodMeasurement;
}

float PwmIn::pulsewidth()
{
    return (float)PulseWidthMeasurement / 1000000;
}

int PwmIn::pulsewidth_ms()
{
    return PulseWidthMeasurement / 1000;
}

int PwmIn::pulsewidth_us()
{
    return PulseWidthMeasurement;
}

void PwmIn::PulseStart()
{
    PeriodMeasurement = read_us();
    reset();
}

void PwmIn::PulseStop()
{
    PulseWidthMeasurement = read_us();
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx PwmIn.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx

//mbed Microcontroller Library
//Pulse Width Modulation Input Interface
//Copyright 2010
//Thomas Hamilton

#ifndef PwmInLibrary
#define PwmInLibrary

#include "stdint.h"
#include "mbed.h"

class PwmIn : private InterruptIn, Timer
{
    private:
        unsigned int PeriodMeasurement;
        unsigned int PulseWidthMeasurement;

        void PulseStart();
        void PulseStop();

    public:
        PwmIn(PinName pwi);
        float read();
        float period();
        int period_ms();
        int period_us();
        float pulsewidth();
        int pulsewidth_ms();
        int pulsewidth_us();
};

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXx main.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include "mbed.h"
#include "MB1210.h"

DigitalOut debugled(LED1);
Serial Computer(USBTX, USBRX);

MB1210 RangeFinder(p12, p15, p13, p14);
float Range;
int main()
{
    Computer.baud(9600);
    debugled = 0;
    RangeFinder.Unit(39.370);//change units to inches
    RangeFinder.AttachInterruptBuffer(&Range);
    RangeFinder.Mode(0x0A);
    while(1)
    {
        debugled = !debugled;
        RangeFinder.RequestSyncRead();//request a range reading
        wait_ms(100);//wait for reading to be prepared
        //RangeFinder.Mode(0);//switch to PWM mode
        //Computer.printf("PWM reading: %f in | ", Range);
        //RangeFinder.Mode(1);//switch to Analog mode
        //Computer.printf("Analog reading: %f in | ", Range);
        //RangeFinder.Mode(2);//switch to serial mode
        Computer.printf("Serial reading: %f in | ", Range);
        wait(0.9);
    }
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXx

No comments:

Post a Comment