Interface library for the Devantech SRF02/SRF08 ultrasonic i2c rangers. Depends on I2cRtosDriver lib!
Diff: Srf0208IF.h
- Revision:
- 2:dfc8b09b4e3b
- Parent:
- 1:32c4dd194228
- Child:
- 3:70c946ba29cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Srf0208IF.h Sun May 26 20:52:27 2013 +0000 @@ -0,0 +1,162 @@ +#ifndef SRF0208IF_H +#define SRF0208IF_H +#include "stdint.h" + +namespace mbed +{ + +class I2CMasterRtos; + +/// common base interface class for SRF02 and SRF08 utrasonic rangers +class Srf0208IF +{ +protected: + int m_adr; + I2CMasterRtos& m_i2c; + +public: + + /// little helper that translates two raw bytes into a word + static int twoByte2int(const char* data){ + return ((static_cast<uint16_t>(*(data)))<<8) | static_cast<uint16_t>(*(data+1)); + } + /// little helper that translates the us transit time into a distance in mm + static int time2dist_us2mm(int us){ + return us!=-1 ? (us*sonicSpeed)>>1 : us; + } + + + /// sonic speed in m/s @ 21°C ... c=(331.5+0.6*T/°C)m/s + /// To calculate the distance in mm: Multiply the µs measurement with this constant and divide by 2 + static const int sonicSpeed = 344; + + /// The constructor + Srf0208IF(int adr, I2CMasterRtos& i2c): m_adr(adr), m_i2c(i2c){}; + + /// Trigger ranging. Result can be read back after 66ms via triggerEchoMeasurement() + /// @return true on success + bool triggerRanging(); + + /// Read back measured transit time in µs of the last triggerRanging() or triggerEchoMeasurement() request. + /// Depending on the distance the Measurement takes up to 66ms. + /// @return -1 on error + int readTransitTime_us(); + + /// Read back measured distance in mm of the triggerRanging() or triggerEchoMeasurement() request. + /// Depending on the distance the Measurement takes up to 66ms. + /// @return -1 on error + int readDistance_mm() { + return time2dist_us2mm(readTransitTime_us()); + }; + + /// Assign a new adress to the SRF ranger device. Available 8bit addresses: E0, E2, E4 ... FE + /// Ensure that only one SRF device is connected to the bus + void resetI2CAdress(int newAddress); + + /// Reads the SRF's SW revision + /// @return -1 on error + int readSWRevision(); + + /// Returns true if ranging is done + bool rangingCompleted(){ + return readSWRevision()!=-1; + } +}; + +/// Provides special features of the SRF02 +class Srf02IF : public Srf0208IF +{ +public: + + /// The constructor + Srf02IF(int adr, I2CMasterRtos& i2c):Srf0208IF(adr,i2c){}; + + /// Just send a ping + /// @return true on success + bool triggerPing(); + + /// Just wait for an echo and measure the time + /// Result can be read back after 66ms via triggerEchoMeasurement() + /// @return true on success + bool triggerEchoMeasurement(); + + /// Read current minimum range from srf02 + int readMinimalTransitTime_us(); + + /// Read current minimum range from srf02 + int readMinimalDistance_mm(){ + return time2dist_us2mm(readMinimalTransitTime_us()); + } + +}; + +/// Provides special features of the SRF08 +class Srf08IF : public Srf0208IF +{ + char m_rawBuffer[36]; + +public: + + /// The constructor + Srf08IF(int adr, I2CMasterRtos& i2c):Srf0208IF(adr,i2c){}; + + /// read light sensor measurement + /// @return -1 on error + int readBrightness(); + + /// trigger ANN mode ranging + /// @return true on success + bool triggerANNRanging(); + + /// Set maximum distance. Use to reduce measurement time. + /// @param maxDst maximum distance 0..0xff (1+maxDst)*43mm => 43mm..11m / 3ms..64ms + /// @return true on success + bool writeMaxDist(int maxDst); + + /// Set/Limit maximum gain. Use to suppress roving echos from previous measurements. + /// Necessary at mesurement rates higher than 1/66ms=15Hz. + /// During measurement the analog signal amplification is increased every 70µs until + /// the maximum gain is reached after 31 steps at ~390mm. + /// @param maxGain 0..31 / 0x0..0x1f =>magic non linear function=> 94..1025 (see SRF08 docu) + /// @return true on success + bool writeMaxGain(int maxGain); + + /// Get transit time (µs) of n'th echo from internal buffer. + /// Call burstRead() before! + /// @param echoIdx 0..16 + int getTransitTimeFromRawBuffer_us(int echoIdx) const { + return twoByte2int(&(m_rawBuffer[(++echoIdx)<<1])); // (1+idx)*2 + } + + /// Get distanc (mm) of n'th echo from internal buffer. + /// Call burstRead() before! + /// @param echoIdx 0..16 + int getDistanceFromRawBuffer_mm(int echoIdx) const { + return time2dist_us2mm(getTransitTimeFromRawBuffer_us(echoIdx)); + } + + /// Get light sensor data from internal buffer. + /// Call burstRead() before! + int getBrightnessFromRawBuffer() const { + return static_cast<int>(m_rawBuffer[1]); + } + /// Get ANN data from internal buffer + /// Call burstRead() before! + /// Each slot is 2048µs/353mm wide. + /// @param slotIdx slot 0..31 + int getANNSlotDataFromRawBuffer(int slotIdx) const { + return (static_cast<int>(m_rawBuffer[slotIdx+4])); + } + /// Reads all data from start to stop register in one go and store it in class internal buffer. + /// - reg 0x00: SW Revision + /// - reg 0x01: light sensor (SRF08 only) + /// - reg 0x02+0x03: range high+low byte + /// - reg 0x03+0x04: srf02: min range high+low byte srf08: 2nd echo + /// - reg 0x04+0x05 .. 34+35: 3rd..17th echo high+low byte + /// @return true on success + bool burstRead(int startReg=1, int stopReg=35); +}; + +} +#endif +