.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()
//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
//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();
}
//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
//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);
}
}
#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