Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.
Showing posts with label robotic. Show all posts
Showing posts with label robotic. Show all posts

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