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.
Revision 4:a615b75d4126, committed 2010-08-28
- Comitter:
- Blaze513
- Date:
- Sat Aug 28 07:59:29 2010 +0000
- Parent:
- 3:05183e50a923
- Commit message:
Changed in this revision
--- a/MB1210.cpp Thu Aug 26 18:25:19 2010 +0000 +++ b/MB1210.cpp Sat Aug 28 07:59:29 2010 +0000 @@ -13,6 +13,7 @@ SerialInput = new Serial(NC, rx); SerialInput->baud(9600); SerialInput->format(8, Serial::None, 1); + SerialInput->attach(NULL, Serial::RxIrq); OperatingMode = 0x02; } if (an != NC) @@ -66,14 +67,34 @@ 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) @@ -120,12 +141,13 @@ if (SerialInput) { unsigned char i = 0; - while (SerialInput->readable() && !SerialInput->scanf("R%3d", &Range) && (i < 32)) + while (SerialInput->readable() && !SerialInput->scanf("R%3f", &Range) && (i < 32)) { SerialInput->getc(); i++; } - return (float)Range * UnitFactor; + //find R and parse the range out + return Range * UnitFactor; } else { @@ -137,20 +159,15 @@ } //OperatingMode switches to desired output method; //the result is scaled according to voltage, the speed of sound, and desired unit -void MB1210::Read(char* Buffer) + +void MB1210::Interrupt() { - if (SerialInput) - { - unsigned char i = 0; - while (SerialInput->readable() && !SerialInput->scanf("R%3s", Buffer) && (i < 32)) - { - SerialInput->getc(); - i++; - } - } + *InterruptBuffer = Read(); + DiscardSerialBuffer(); } - //this overload is for serial only, regardless of selected mode; - //reads 3 ASCII character result into the given buffer + //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() {
--- a/MB1210.h Thu Aug 26 18:25:19 2010 +0000 +++ b/MB1210.h Sat Aug 28 07:59:29 2010 +0000 @@ -21,12 +21,17 @@ float UnitFactor; float PwmScalingFactor; float AnalogScalingFactor; - unsigned short Range; + 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 + //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); @@ -43,9 +48,19 @@ //default is cm void Mode(char Selection); //argument sets operating mode; - //0 to 2 for synchronous modes, 4 to 6 for asynchronous modes; - //0 and 4 for pwm, 1 and 5 for analog, 2 and 6 for serial; + //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; @@ -59,11 +74,6 @@ //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; - void Read(char* Buffer); - //overloaded to take advantage of Serial ASCII string output; - //Buffer must be 3 bytes; 3 digit ASCII number - //measures range in cm regardless of selected unit; - //uses serial input method regardless of selected mode. operator float(); //shorthand for taking a range reading; //ex: "float reading = MB1210Object;"
--- a/main.cpp Thu Aug 26 18:25:19 2010 +0000 +++ b/main.cpp Sat Aug 28 07:59:29 2010 +0000 @@ -1,27 +1,29 @@ -#include "mbed.h" -#include "MB1210.h" - -DigitalOut debugled(LED1); -Serial Computer(USBTX, USBRX); - -MB1210 RangeFinder(p12, p15, p13, p14); - -int main() -{ - Computer.baud(9600); - debugled = 0; - RangeFinder.Unit(39.370);//change units to inches - 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 | ", RangeFinder.Read()); - RangeFinder.Mode(1);//switch to Analog mode - Computer.printf("Analog reading: %f in | ", RangeFinder.Read()); - RangeFinder.Mode(2);//switch to serial mode - Computer.printf("Serial reading: %f in | ", RangeFinder.Read()); - wait(0.9); - } +#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); + } } \ No newline at end of file