Ultraschallsensor (SRF02)

Der Ultraschallsensor SRF02 dient zur Längenmessung über die Laufzeit des Ultraschalls. Dafür gibt es generell zwei verschiedene Modi:

  • Messung der Distanz/Laufzeit über Reflexion an einem Gegenstand (hierfür wird nur ein SRF02 benötigt)
  • Messung der Distanz/Laufzeit über eine Sender-Empfängerstrecke (hierfür werden selbstverständlich zwei (oder mehr) SRF02 benötigt

Es können jeweils entweder Laufzeiten (in µs) oder Distanzen (in cm oder inch) ausgelesen werden.
Die verschiedenen Modi können auch entsprechend der folgenden Tabelle entnommen werden.

Command (Hex) Action
0x50 Real Ranging Mode - Result in inches
0x51 Real Ranging Mode - Result in centimeters
0x52 Real Ranging Mode - Result in micro-seconds
0x53 Real Ranging Mode - Result in inches, automatically Tx range back to controller as soon as ranging is complete
0x54 Real Ranging Mode - Result in centimeters, automatically Tx range back to controller as soon as ranging is complete.
0x55 Real Ranging Mode - Result in micro-seconds, automatically Tx range back to controller as soon as ranging is complete
   
0x56 Fake Ranging Mode - Result in inches
0x57 Fake Ranging Mode - Result in centimeters
0x58 Fake Ranging Mode - Result in micro-seconds
0x59 Fake Ranging Mode - Result in inches, automatically Tx range back to controller as soon as ranging is complete
0x5A Fake Ranging Mode - Result in centimeters, automatically Tx range back to controller as soon as ranging is complete
0x5B Fake Ranging Mode - Result in micro-seconds, automatically Tx range back to controller as soon as ranging is complete
   
0x5C Transmit an 8 cycle 40khz burst - no ranging takes place
0x5D Get software version - sends a single byte back to the controller
0x5E Get Range, returns two bytes (high byte first) from the most recent ranging
0x5F Get Minimum, returns two bytes (high byte first) of the closest range measurable - see Autotune section
0x60 Force Autotune Restart - same as power-up. You can ignore this command
   
0xA0 1st in sequence to change I2C address
0xA5 3rd in sequence to change I2C address
0xAA 2nd in sequence to change I2C address


Quelle: www.robot-electronics.co.uk/htm/srf02tech.htm

Die Kommunikation mit dem SRF02 erfolt über Serielle Schnittstelle oder I²C. Die folgenden Beispielprogramme werden ausschließlich im I²C Modus vorgestellt.

Das Befehlsregister, mit dem die verschiedenen Befehle ausgeführt werden können, ist das Register 0. Um einen Befehl auszuführen muss lediglich der enstsprechende Befehlscode in das Register geschrieben werden.

//ground
#include <SoftwareSerial.h>
#include <Wire.h>

//----------config starts here-----------
const boolean useI2c = true; //srf02 mit i2c oder uart
const byte temperature =  21;      //temperature in Celsius
//const byte receiverAddress = 2; //uart = i2c - 112;
const byte receiverAddress = 114; //i2c = uart + 112
//----------config ends here-------------

const float speedOfSound =  0.0200457 * sqrt(temperature + 273.15);      //speed of sound mm/µs
unsigned int receiverReading = 0;
SoftwareSerial srf02(10, 11); // RX, TX

void setup()
{
  Wire.begin();
  srf02.begin(9600);
  Serial.begin(9600);          // start serial communication at 9600bps
  Serial.println("Start");
  /* Set address to E0
  int newAddress = 224;
  for (int i=0;i<16;i++) {
    oldAddress = 112 +i;
    changeAddress(byte(oldAddress), byte(newAddress));
  }
  */
}


void loop()
{
  int reading = 0;
  if (useI2c) {
    i2cStartMeasurement(byte(receiverAddress));
  } else {
    uartStartMeasurement(byte(receiverAddress));
    srf02.listen();
  }
  delay(70);    // datasheet suggests at least 65 milliseconds
  if (useI2c) {
    receiverReading = i2cGetMeasurement(byte(receiverAddress));
  } else {
    receiverReading = uartGetMeasurement(byte(receiverAddress));
  }
  Serial.print(receiverReading);
  Serial.print("\t|\t");
  receiverReading = receiverReading * speedOfSound;
  Serial.println(receiverReading);
  delay(200);
}

int uartGetMeasurement (byte address) {
  int reading = -1;
  srf02.write(address);
  srf02.write(0x5E);      // Get Range, returns two bytes (high byte first) from the most recent ranging.
  while (srf02.available() < 2);
  if (srf02.available() > 0) {
    reading = srf02.read();
  }
  reading = reading << 8;
  //while (srf02.available() == 0);
  if (srf02.available() > 0) {
    reading |= srf02.read();
  }
  return reading;
}

void uartStartMeasurement (byte address) {
  //address = (address >> 1) & 0x0F;
  srf02.write(address);
  srf02.write(0x52);
}



int i2cGetMeasurement (byte address) {
  int reading = -1;
  Wire.beginTransmission(address);     // transmit to device #112
  Wire.write(byte(0x02));              // sets register pointer to echo #1 register (0x02)
  Wire.endTransmission();              // stop transmitting
  Wire.requestFrom(address, byte(2));  // request 2 bytes from slave device #112
  if(2 <= Wire.available())            // if two bytes were received
  {
    reading = Wire.read();             // receive high byte (overwrites previous reading)
    reading = reading << 8;            // shift high byte to be high 8 bits
    reading |= Wire.read();            // receive low byte as lower 8 bits
  }
  return reading;
}

void i2cStartMeasurement (byte address) {
    Wire.beginTransmission(address);
    Wire.write(byte(0x00));
    Wire.write(byte(0x52));
    Wire.endTransmission();
}

void i2cFakeRange (byte address) {
    Wire.beginTransmission(address);
    Wire.write(byte(0x00));
    Wire.write(byte(0x5C));  //0x50  Real Ranging Mode - Result in inches
                             //0x51  Real Ranging Mode - Result in centimeters
                             //0x52  Real Ranging Mode - Result in micro-seconds
                             //0x56  Fake Ranging Mode - Result in inches
                             //0x57  Fake Ranging Mode - Result in centimeters
                             //0x58  Fake Ranging Mode - Result in micro-seconds
                             //0x5C  Transmit an 8 cycle 40khz burst
    Wire.endTransmission();
}
void i2cChangeAddress(byte oldAddress, byte newAddress)
{
// !! newAddress =  {224-239}
  Wire.beginTransmission(oldAddress);
  Wire.write(byte(0x00));
  Wire.write(byte(0xA0));
  Wire.endTransmission();

  Wire.beginTransmission(oldAddress);
  Wire.write(byte(0x00));
  Wire.write(byte(0xAA));
  Wire.endTransmission();

  Wire.beginTransmission(oldAddress);
  Wire.write(byte(0x00));
  Wire.write(byte(0xA5));
  Wire.endTransmission();

  Wire.beginTransmission(oldAddress);
  Wire.write(byte(0x00));
  Wire.write(newAddress);
  Wire.endTransmission();
}

 

Anhänge:
Diese Datei herunterladen (Ultrasonic Sensor Operation on a Quadcopter.pdf)Ultrasonic Sensor Operation on a Quadcopter.pdf[ ]%2013-%05-%21 %1:%Mai%+02:00