Driver for HC-SR04 connected to a Microbit
Embed:
(wiki syntax)
Show/hide line numbers
MicrobitUltrasound.cpp
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 /** 00027 * Class definition for MicroBitPin. 00028 * 00029 * Commonly represents an I/O pin on the edge connector. 00030 */ 00031 #include "MicrobitUltrasound.h" 00032 #include "MicroBitSystemTimer.h" 00033 #include "MicroBitFiber.h" 00034 00035 /** 00036 * Constructor. 00037 * Create new MicrobitUltrasound that reports distance to closest object 00038 * 00039 * @param triggerPinName Name of the MicroBitPin to be used as trigger. 00040 * 00041 * @param echoPinName Name of the MicroBitPin to be used as response from sensor. 00042 * 00043 * @code 00044 * MicrobitUltrasound uSoundSensor(MICROBIT_PIN_P1, 100, true, MICROBIT_PIN_P2, PullUp); 00045 * @endcode 00046 */ 00047 MicrobitUltrasound::MicrobitUltrasound(PinName triggerPinName, int _triggerPeriod_ms, bool _triggerActiveValue, 00048 PinName echoPinName, PinMode echoPinMode, uint16_t id): 00049 trigger(triggerPinName), echo(echoPinName) 00050 { 00051 this->id = id; 00052 this->status = 0; 00053 this->sampleTime = 0; 00054 this->triggerDuration_us = MICROBIT_ULTRASOUND_TRIGGER_DURATION_DEFAULT_US; 00055 this->triggerPeriod_ms = (uint16_t)_triggerPeriod_ms; 00056 this->triggerActiveValue = _triggerActiveValue; 00057 00058 echo.mode(echoPinMode); 00059 echo.rise(this, &MicrobitUltrasound::onEchoRise); 00060 echo.fall(this, &MicrobitUltrasound::onEchoFall); 00061 } 00062 00063 /** 00064 * Constructor. 00065 * Create new MicrobitUltrasound that reports distance to closest object 00066 * 00067 * @param triggerPinName Name of the MicroBitPin to be used as trigger. 00068 * 00069 * @param echoPinName Name of the MicroBitPin to be used as response from sensor. 00070 * 00071 * @code 00072 * MicrobitUltrasound uSoundSensor(MICROBIT_PIN_P1, MICROBIT_PIN_P2); 00073 * @endcode 00074 */ 00075 MicrobitUltrasound::MicrobitUltrasound(PinName triggerPinName, PinName echoPinName, uint16_t id): 00076 trigger(triggerPinName), echo(echoPinName) 00077 { 00078 this->id = id; 00079 this->status = 0; 00080 this->sampleTime = 0; 00081 this->triggerPeriod_ms = MICROBIT_ULTRASOUND_PERIOD_DEFAULT_MS; 00082 this->triggerDuration_us = MICROBIT_ULTRASOUND_TRIGGER_DURATION_DEFAULT_US; 00083 this->triggerActiveValue = TRIGGER_ACTIVE_VALUE; 00084 00085 //echo.mode((PinMode)MICROBIT_ULTRASOUND_PULLMODE_DEFAULT); 00086 echo.rise(this, &MicrobitUltrasound::onEchoRise); 00087 echo.fall(this, &MicrobitUltrasound::onEchoFall); 00088 } 00089 00090 /** 00091 * Destructor for MicrobitUltrasound, where we deregister from the array of fiber components. 00092 */ 00093 MicrobitUltrasound::~MicrobitUltrasound() 00094 { 00095 fiber_remove_idle_component(this); 00096 } 00097 00098 /** 00099 * Set Echo PinMode 00100 */ 00101 void MicrobitUltrasound::setEchoPinMode(PinMode echoPinMode) 00102 { 00103 echo.mode(echoPinMode); 00104 } 00105 00106 /** 00107 * This member function manages the calculation of the timestamp of a pulse detected 00108 * on the echo pin. 00109 * 00110 * @param eventValue the event value to distribute onto the message bus. 00111 */ 00112 void MicrobitUltrasound::pulseWidthEvent(int eventValue) 00113 { 00114 MicroBitEvent evt(id, eventValue, CREATE_ONLY); 00115 uint64_t now = evt.timestamp; 00116 uint64_t previous = echo.getTimestamp(); 00117 00118 if (previous != 0) 00119 { 00120 evt.timestamp -= previous; 00121 evt.fire(); 00122 } 00123 00124 echo.setTimestamp(now); 00125 } 00126 00127 00128 /** 00129 * Interrupt handler for when an rise interrupt is triggered. 00130 */ 00131 void MicrobitUltrasound::onEchoRise() 00132 { 00133 if(status & ULTRASOUND_STATUS_EVENTON_PULSE) 00134 pulseWidthEvent(MICROBIT_ULTRASOUND_EVT_ECHO_PULSE_LO); 00135 00136 if(status & ULTRASOUND_STATUS_EVENTON_RISE) 00137 MicroBitEvent(id, MICROBIT_ULTRASOUND_EVT_ECHO_RISE); 00138 00139 if(status & ULTRASOUND_STATUS_EVENTON_EDGE) 00140 MicroBitEvent(id, MICROBIT_ULTRASOUND_EVT_ECHO_EDGE); 00141 } 00142 00143 /** 00144 * Interrupt handler for when an fall interrupt is triggered. 00145 */ 00146 void MicrobitUltrasound::onEchoFall() 00147 { 00148 if(status & ULTRASOUND_STATUS_EVENTON_PULSE) 00149 pulseWidthEvent(MICROBIT_ULTRASOUND_EVT_ECHO_PULSE_HI); 00150 00151 if(status & ULTRASOUND_STATUS_EVENTON_FALL) 00152 MicroBitEvent(id, MICROBIT_ULTRASOUND_EVT_ECHO_FALL); 00153 00154 if(status & ULTRASOUND_STATUS_EVENTON_EDGE) 00155 MicroBitEvent(id, MICROBIT_ULTRASOUND_EVT_ECHO_EDGE); 00156 } 00157 00158 /** 00159 * Set the sample rate at which the micro:bit triggers sensor (in ms). 00160 * 00161 * The default sample period is 1 second. 00162 * 00163 * @param period the requested time between triggers, in milliseconds. 00164 * 00165 * @note the micro:bit sends triggers in the background. 00166 */ 00167 void MicrobitUltrasound::setPeriod(int period_ms) 00168 { 00169 this->triggerPeriod_ms = period_ms; 00170 } 00171 00172 /** 00173 * Get the sample rate at which the micro:bit triggers sensor (in ms). 00174 * 00175 * @return period the requested time between triggers, in milliseconds. 00176 */ 00177 int MicrobitUltrasound::getPeriod() 00178 { 00179 return (int)triggerPeriod_ms; 00180 } 00181 00182 /** 00183 * Send trigger to start measurement in sensor 00184 * 00185 * This call also will add the class to fiber components to receive 00186 * one callback only. 00187 * 00188 * @return MICROBIT_OK on success. 00189 */ 00190 void MicrobitUltrasound::fireTrigger(void) 00191 { 00192 int actVal, pasVal; 00193 actVal = triggerActiveValue? 1 : 0; 00194 pasVal = triggerActiveValue? 0 : 1; 00195 trigger.write(pasVal); 00196 wait_us(MICROBIT_ULTRASOUND_IDLE_DURATION_DEFAULT_US); 00197 trigger.write(actVal); 00198 wait_us(triggerDuration_us); 00199 trigger.write(pasVal); 00200 } 00201 00202 /** 00203 * Start periodic trigger to sensor. This call also will add the class 00204 * to fiber components for periodic callbacks. 00205 * 00206 * @return MICROBIT_OK on success. 00207 */ 00208 int MicrobitUltrasound::start(void) 00209 { 00210 int result; 00211 status |= MICROBIT_COMPONENT_RUNNING; 00212 result = updateSample(); 00213 return result; 00214 } 00215 00216 /** 00217 * Stop periodic trigger to sensor. 00218 * 00219 * @return MICROBIT_OK on success. 00220 */ 00221 int MicrobitUltrasound::stop(void) 00222 { 00223 int result; 00224 status &= !MICROBIT_COMPONENT_RUNNING; 00225 result = fiber_remove_idle_component(this); 00226 return result; 00227 } 00228 00229 00230 00231 /** 00232 * Update Sensor measurement 00233 * 00234 * @return MICROBIT_OK on success. 00235 */ 00236 int MicrobitUltrasound::updateSample(void) 00237 { 00238 int result; 00239 if(!(status & ULTRASOUND_STATUS_ADDED_TO_IDLE)) 00240 { 00241 // If we're running under a fiber scheduer, register ourselves for a periodic callback to keep our data up to date. 00242 // Otherwise, we do just do this on demand with the trigger function. 00243 result = fiber_add_idle_component(this); 00244 if (result != MICROBIT_OK) 00245 return result; 00246 status |= ULTRASOUND_STATUS_ADDED_TO_IDLE; 00247 } 00248 00249 // check if we need to update our trigger... 00250 if (isTriggerNeeded()) 00251 { 00252 fireTrigger(); 00253 // Send an event to indicate that we just sent a new trigger. 00254 if (status & ULTRASOUND_STATUS_EVENTON_TRIGGER) 00255 MicroBitEvent e(id, MICROBIT_ULTRASOUND_EVT_TRIGGER); 00256 00257 // Schedule our next trigger. 00258 sampleTime = system_timer_current_time() + triggerPeriod_ms; 00259 } 00260 00261 return MICROBIT_OK; 00262 } 00263 00264 /** 00265 * Periodic callback from MicroBit idle thread. 00266 */ 00267 void MicrobitUltrasound::idleTick() 00268 { 00269 updateSample(); 00270 } 00271 00272 /** 00273 * Determines if we're due to take another trigger 00274 * 00275 * @return 1 if we're due to take a new trigger, 0 otherwise. 00276 */ 00277 int MicrobitUltrasound::isTriggerNeeded() 00278 { 00279 return system_timer_current_time() >= sampleTime; 00280 } 00281 00282 00283 /** 00284 * Enables a particular event for the current module 00285 * 00286 * @return 1 if we're due to take a new trigger, 0 otherwise. 00287 */ 00288 int MicrobitUltrasound::eventOn(int eventType) 00289 { 00290 switch(eventType) 00291 { 00292 case MICROBIT_ULTRASOUND_EVT_ECHO_PULSE_HI : status |= ULTRASOUND_STATUS_EVENTON_PULSE; 00293 break; 00294 case MICROBIT_ULTRASOUND_EVT_ECHO_PULSE_LO : status |= ULTRASOUND_STATUS_EVENTON_PULSE; 00295 break; 00296 case MICROBIT_ULTRASOUND_EVT_TRIGGER : status |= ULTRASOUND_STATUS_EVENTON_TRIGGER; 00297 break; 00298 case MICROBIT_ULTRASOUND_EVT_ECHO_RISE : status |= ULTRASOUND_STATUS_EVENTON_RISE; 00299 break; 00300 case MICROBIT_ULTRASOUND_EVT_ECHO_FALL : status |= ULTRASOUND_STATUS_EVENTON_FALL; 00301 break; 00302 case MICROBIT_ULTRASOUND_EVT_ECHO_EDGE : status |= ULTRASOUND_STATUS_EVENTON_EDGE; 00303 break; 00304 default : return MICROBIT_INVALID_PARAMETER; 00305 break; 00306 } 00307 return MICROBIT_OK; 00308 }
Generated on Tue Jul 12 2022 18:37:37 by 1.7.2