Interface library for the Devantech SRF02/SRF08 ultrasonic i2c rangers. Depends on I2cRtosDriver lib!

Srf0208IF.h

Committer:
humlet
Date:
2013-05-26
Revision:
2:dfc8b09b4e3b
Parent:
SRF02_IF.h@ 1:32c4dd194228
Child:
3:70c946ba29cc

File content as of revision 2:dfc8b09b4e3b:

#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