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

Committer:
Blaze513
Date:
Sat Aug 28 07:59:29 2010 +0000
Revision:
4:a615b75d4126
Parent:
3:05183e50a923

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Blaze513 2:997b4057c879 1 //mbed Microcontroller Library
Blaze513 2:997b4057c879 2 //Max Botix Ultrasonic Range Finder MB1210 Interface
Blaze513 2:997b4057c879 3 //Copyright 2010
Blaze513 2:997b4057c879 4 //Thomas Hamilton
Blaze513 2:997b4057c879 5
Blaze513 0:3d969e0b4ca0 6 #include "MB1210.h"
Blaze513 0:3d969e0b4ca0 7
Blaze513 1:b533b95e807a 8 MB1210::MB1210(PinName pw, PinName an, PinName tx, PinName rx) : OperatingMode(0x00),
Blaze513 1:b533b95e807a 9 UnitFactor(1), PwmScalingFactor(17014.5), AnalogScalingFactor(1024), Range(0)
Blaze513 0:3d969e0b4ca0 10 {
Blaze513 0:3d969e0b4ca0 11 if (rx != NC)
Blaze513 0:3d969e0b4ca0 12 {
Blaze513 0:3d969e0b4ca0 13 SerialInput = new Serial(NC, rx);
Blaze513 0:3d969e0b4ca0 14 SerialInput->baud(9600);
Blaze513 0:3d969e0b4ca0 15 SerialInput->format(8, Serial::None, 1);
Blaze513 4:a615b75d4126 16 SerialInput->attach(NULL, Serial::RxIrq);
Blaze513 0:3d969e0b4ca0 17 OperatingMode = 0x02;
Blaze513 0:3d969e0b4ca0 18 }
Blaze513 0:3d969e0b4ca0 19 if (an != NC)
Blaze513 0:3d969e0b4ca0 20 {
Blaze513 0:3d969e0b4ca0 21 AnalogInput = new AnalogIn(an);
Blaze513 0:3d969e0b4ca0 22 OperatingMode = 0x01;
Blaze513 0:3d969e0b4ca0 23 }
Blaze513 0:3d969e0b4ca0 24 if (pw != NC)
Blaze513 0:3d969e0b4ca0 25 {
Blaze513 0:3d969e0b4ca0 26 PwmInput = new PwmIn(pw);
Blaze513 0:3d969e0b4ca0 27 OperatingMode = 0x00;
Blaze513 0:3d969e0b4ca0 28 }
Blaze513 0:3d969e0b4ca0 29 if (tx != NC)
Blaze513 0:3d969e0b4ca0 30 {
Blaze513 0:3d969e0b4ca0 31 SerialOutput = new DigitalOut(tx);
Blaze513 0:3d969e0b4ca0 32 SerialOutput->write(0);
Blaze513 0:3d969e0b4ca0 33 }
Blaze513 0:3d969e0b4ca0 34 }
Blaze513 0:3d969e0b4ca0 35 //constructor dynamically allocates memory and cpu time (interrupts)
Blaze513 0:3d969e0b4ca0 36 //to input objects depending on how the device is connected
Blaze513 0:3d969e0b4ca0 37
Blaze513 0:3d969e0b4ca0 38 MB1210::~MB1210()
Blaze513 0:3d969e0b4ca0 39 {
Blaze513 0:3d969e0b4ca0 40 delete PwmInput;
Blaze513 0:3d969e0b4ca0 41 delete AnalogInput;
Blaze513 0:3d969e0b4ca0 42 delete SerialOutput;
Blaze513 0:3d969e0b4ca0 43 delete SerialInput;
Blaze513 0:3d969e0b4ca0 44 delete this;
Blaze513 0:3d969e0b4ca0 45 }
Blaze513 0:3d969e0b4ca0 46 //input objects must be deallocated
Blaze513 0:3d969e0b4ca0 47
Blaze513 0:3d969e0b4ca0 48 void MB1210::SoundVelocity(float MetersPerSecond)
Blaze513 0:3d969e0b4ca0 49 {
Blaze513 0:3d969e0b4ca0 50 PwmScalingFactor = (UnitFactor * MetersPerSecond * 50);
Blaze513 0:3d969e0b4ca0 51 }
Blaze513 0:3d969e0b4ca0 52 //set the velocity of sound for pwm readings
Blaze513 0:3d969e0b4ca0 53
Blaze513 0:3d969e0b4ca0 54 void MB1210::Voltage(float Volts)
Blaze513 0:3d969e0b4ca0 55 {
Blaze513 0:3d969e0b4ca0 56 AnalogScalingFactor = (UnitFactor * 3379.2 / Volts);
Blaze513 0:3d969e0b4ca0 57 }
Blaze513 0:3d969e0b4ca0 58 //set the voltage correction factor for analog readings
Blaze513 0:3d969e0b4ca0 59
Blaze513 0:3d969e0b4ca0 60 void MB1210::Unit(float UnitsPerMeter)
Blaze513 0:3d969e0b4ca0 61 {
Blaze513 0:3d969e0b4ca0 62 PwmScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
Blaze513 0:3d969e0b4ca0 63 AnalogScalingFactor *= (UnitsPerMeter / UnitFactor / 100);
Blaze513 0:3d969e0b4ca0 64 UnitFactor = UnitsPerMeter / 100;
Blaze513 0:3d969e0b4ca0 65 }
Blaze513 0:3d969e0b4ca0 66 //set the unit factor to return the range in units other than cm
Blaze513 0:3d969e0b4ca0 67
Blaze513 0:3d969e0b4ca0 68 void MB1210::Mode(char Selection)
Blaze513 0:3d969e0b4ca0 69 {
Blaze513 4:a615b75d4126 70 if (SerialInput)
Blaze513 4:a615b75d4126 71 {
Blaze513 4:a615b75d4126 72 if (Selection & 0x08)
Blaze513 4:a615b75d4126 73 {
Blaze513 4:a615b75d4126 74 SerialInput->attach(this, &MB1210::Interrupt, Serial::RxIrq);
Blaze513 4:a615b75d4126 75 }
Blaze513 4:a615b75d4126 76 else
Blaze513 4:a615b75d4126 77 {
Blaze513 4:a615b75d4126 78 SerialInput->attach(NULL, Serial::RxIrq);
Blaze513 4:a615b75d4126 79 }
Blaze513 4:a615b75d4126 80 //attach or detach the interrupt function
Blaze513 4:a615b75d4126 81 }
Blaze513 4:a615b75d4126 82 //interrupts can only be generated if rx pin is connected
Blaze513 0:3d969e0b4ca0 83 if (SerialOutput)
Blaze513 0:3d969e0b4ca0 84 {
Blaze513 0:3d969e0b4ca0 85 SerialOutput->write(Selection & 0x04);
Blaze513 0:3d969e0b4ca0 86 }
Blaze513 4:a615b75d4126 87 //synchronous modes can only be set if tx pin is connected
Blaze513 0:3d969e0b4ca0 88 OperatingMode = Selection & 0x03;
Blaze513 0:3d969e0b4ca0 89 }
Blaze513 0:3d969e0b4ca0 90 //change the operating mode; SerialOutput controls synchronicity
Blaze513 0:3d969e0b4ca0 91
Blaze513 4:a615b75d4126 92 void MB1210::AttachInterruptBuffer(float* Buffer)
Blaze513 4:a615b75d4126 93 {
Blaze513 4:a615b75d4126 94 InterruptBuffer = Buffer;
Blaze513 4:a615b75d4126 95 }
Blaze513 4:a615b75d4126 96 //the user changes the pointer to their own storage area so they can use the interrupt
Blaze513 4:a615b75d4126 97
Blaze513 0:3d969e0b4ca0 98 void MB1210::RequestSyncRead()
Blaze513 0:3d969e0b4ca0 99 {
Blaze513 0:3d969e0b4ca0 100 if (SerialOutput)
Blaze513 0:3d969e0b4ca0 101 {
Blaze513 0:3d969e0b4ca0 102 SerialOutput->write(1);
Blaze513 0:3d969e0b4ca0 103 wait_us(20);
Blaze513 0:3d969e0b4ca0 104 SerialOutput->write(0);
Blaze513 0:3d969e0b4ca0 105 }
Blaze513 0:3d969e0b4ca0 106 }
Blaze513 0:3d969e0b4ca0 107 //hold pin high for at least 20 us to request a synchronous range reading
Blaze513 0:3d969e0b4ca0 108
Blaze513 3:05183e50a923 109 void MB1210::DiscardSerialBuffer()
Blaze513 3:05183e50a923 110 {
Blaze513 3:05183e50a923 111 while (SerialInput->readable())
Blaze513 3:05183e50a923 112 {
Blaze513 3:05183e50a923 113 SerialInput->getc();
Blaze513 3:05183e50a923 114 }
Blaze513 3:05183e50a923 115 }
Blaze513 3:05183e50a923 116 //read characters from the buffer until it is empty
Blaze513 3:05183e50a923 117
Blaze513 0:3d969e0b4ca0 118 float MB1210::Read()
Blaze513 0:3d969e0b4ca0 119 {
Blaze513 0:3d969e0b4ca0 120 switch (OperatingMode)
Blaze513 0:3d969e0b4ca0 121 {
Blaze513 0:3d969e0b4ca0 122 case 0:
Blaze513 0:3d969e0b4ca0 123 if (PwmInput)
Blaze513 0:3d969e0b4ca0 124 {
Blaze513 0:3d969e0b4ca0 125 return PwmInput->pulsewidth() * PwmScalingFactor;
Blaze513 0:3d969e0b4ca0 126 }
Blaze513 0:3d969e0b4ca0 127 else
Blaze513 0:3d969e0b4ca0 128 {
Blaze513 0:3d969e0b4ca0 129 return 0;
Blaze513 0:3d969e0b4ca0 130 }
Blaze513 0:3d969e0b4ca0 131 case 1:
Blaze513 0:3d969e0b4ca0 132 if (AnalogInput)
Blaze513 0:3d969e0b4ca0 133 {
Blaze513 0:3d969e0b4ca0 134 return AnalogInput->read() * AnalogScalingFactor;
Blaze513 0:3d969e0b4ca0 135 }
Blaze513 0:3d969e0b4ca0 136 else
Blaze513 0:3d969e0b4ca0 137 {
Blaze513 0:3d969e0b4ca0 138 return 0;
Blaze513 0:3d969e0b4ca0 139 }
Blaze513 0:3d969e0b4ca0 140 case 2:
Blaze513 0:3d969e0b4ca0 141 if (SerialInput)
Blaze513 0:3d969e0b4ca0 142 {
Blaze513 1:b533b95e807a 143 unsigned char i = 0;
Blaze513 4:a615b75d4126 144 while (SerialInput->readable() && !SerialInput->scanf("R%3f", &Range) && (i < 32))
Blaze513 0:3d969e0b4ca0 145 {
Blaze513 1:b533b95e807a 146 SerialInput->getc();
Blaze513 1:b533b95e807a 147 i++;
Blaze513 0:3d969e0b4ca0 148 }
Blaze513 4:a615b75d4126 149 //find R and parse the range out
Blaze513 4:a615b75d4126 150 return Range * UnitFactor;
Blaze513 0:3d969e0b4ca0 151 }
Blaze513 0:3d969e0b4ca0 152 else
Blaze513 0:3d969e0b4ca0 153 {
Blaze513 0:3d969e0b4ca0 154 return 0;
Blaze513 0:3d969e0b4ca0 155 }
Blaze513 0:3d969e0b4ca0 156 default:
Blaze513 0:3d969e0b4ca0 157 return 0;
Blaze513 0:3d969e0b4ca0 158 }
Blaze513 0:3d969e0b4ca0 159 }
Blaze513 0:3d969e0b4ca0 160 //OperatingMode switches to desired output method;
Blaze513 3:05183e50a923 161 //the result is scaled according to voltage, the speed of sound, and desired unit
Blaze513 4:a615b75d4126 162
Blaze513 4:a615b75d4126 163 void MB1210::Interrupt()
Blaze513 0:3d969e0b4ca0 164 {
Blaze513 4:a615b75d4126 165 *InterruptBuffer = Read();
Blaze513 4:a615b75d4126 166 DiscardSerialBuffer();
Blaze513 0:3d969e0b4ca0 167 }
Blaze513 4:a615b75d4126 168 //this is called whenever an interrupt mode is
Blaze513 4:a615b75d4126 169 //set and a serial rx interrupt is generated;
Blaze513 4:a615b75d4126 170 //it writes to the user's data storage area
Blaze513 0:3d969e0b4ca0 171
Blaze513 0:3d969e0b4ca0 172 MB1210::operator float()
Blaze513 0:3d969e0b4ca0 173 {
Blaze513 0:3d969e0b4ca0 174 return Read();
Blaze513 0:3d969e0b4ca0 175 }
Blaze513 0:3d969e0b4ca0 176 //conversion function acts as shorthand for Read()