Simple library for reading distance from SRF02 Ultrasonic Sensor in I2C mode.

Dependents:   Project_A el13jarDistanceSensorProject UltrasonicDistanceSensor-el13jb Distance_Sensor_SRF02 ... more

SRF02.cpp

Committer:
eencae
Date:
2016-06-22
Revision:
2:cb489f486ece
Parent:
0:b729d2ce03bd

File content as of revision 2:cb489f486ece:

/**
@file SRF02.cpp

@brief Member functions implementations

*/
#include "mbed.h"
#include "SRF02.h"

SRF02::SRF02(PinName sdaPin, PinName sclPin, char addr)
{
    i2c = new I2C(sdaPin,sclPin); // create new I2C instance and initialise
    i2c->frequency(400000);       // I2C Fast Mode - 400kHz
    leds = new BusOut(LED4,LED3,LED2,LED1);

    w_addr_ = addr; // set write address of sensor
    r_addr_ = w_addr_ + 1;  // read address has the lowest bit set (i.e. + 1)

}

int SRF02::getDistanceCm()
{
    char data[2];
    
    // need to send CM command to command register
    data[0] = CMD_REG;
    data[1] = CM_CMD;
    int ack = i2c->write(w_addr_,data,2);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
        
    // this will start the sensor ranging, the datasheet suggests a delay of at least 65 ms before reading the result
    wait_ms(70);
    
    // we can now read the result - tell the sensor we want the high byte
    char reg = RANGE_H_REG;   
    ack = i2c->write(w_addr_,&reg,1);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
    
    // if we read two bytes, the register is automatically incremented (H and L)
    ack = i2c->read(r_addr_,data,2); 
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message

    // high byte is first, then low byte, so combine into 16-bit value
    return (data[0] << 8) | data[1];
}

void SRF02::changeAddress(char addr) {
    
    char data[2];
    
    // sequence to change I2C (https://www.robot-electronics.co.uk/htm/srf02techI2C.htm)
    // need to write this sequence to the command register, followed by the new address
    
    data[0] = CMD_REG;
    data[1] = 0xA0;  // 1st byte in sequence
    int ack = i2c->write(w_addr_,data,2);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
        
    wait_ms(50);  // small delay in between 
    
    data[0] = CMD_REG;
    data[1] = 0xAA;   // 2nd byte in sequence
    ack = i2c->write(w_addr_,data,2);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
        
    wait_ms(50); // small delay in between 
    
    data[0] = CMD_REG;
    data[1] = 0xA5;  // 3rd byte in sequence
    ack = i2c->write(w_addr_,data,2);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
        
    wait_ms(50);  // small delay in between 
    
    data[0] = CMD_REG;  
    data[1] = addr;  // new address
    ack = i2c->write(w_addr_,data,2);  
    if (ack)
        error();  // if we don't receive acknowledgement, flash error message
    
    wait_ms(50);
    
}

void SRF02::error()
{
    while(1) {
        leds->write(15);
        wait(0.1);
        leds->write(0);
        wait(0.1);    
    }    
}