According to http://www.robot-electronics.co.uk/htm/srf08tech.shtml
i2c_srf08.h
/*
 * i2c_srf08.h : SRF08 ultra sonic range finder
 *
 *  (C) 2011 by Steve Chang
 *  stevegigijoe@yahoo.com.tw
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#ifndef _I2C_SRF08_H
#define _I2C_SRF08_H
#include "bool.h"
typedef struct I2cSrf08 I2cSrf08;
I2cSrf08 *I2cSrf08_DefaultInstance(char *device);
int I2cSrf08_Open(I2cSrf08 *is);
void I2cSrf08_Close(I2cSrf08 *is);
void I2cSrf08_SetMaxRange(I2cSrf08 *is, unsigned char range);
void I2cSrf08_SetMaxGain(I2cSrf08 *is, unsigned char gain);
int I2cSrf08_BlockRangeInCentimeters(I2cSrf08 *is);
int I2cSrf08_RangingInCentimeters(I2cSrf08 *is);
int I2cSrf08_GetRange(I2cSrf08 *is);
#endif
i2c_srf08.c
/*
 * i2c_srf08.c : SRF08 ultra sonic range finder
 *
 *  (C) 2011 by Steve Chang
 *  stevegigijoe@yahoo.com.tw
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "i2c_srf08.h"
struct I2cSrf08  {
  int fd;
  char *device;
  unsigned char range;
  unsigned char gain;
  bool ranging;
};
I2cSrf08 *I2cSrf08_DefaultInstance(char *device)
{
  static I2cSrf08 i2csrf08;
  
  if(!device)
    return 0;
  memset(&i2csrf08, 0, sizeof(I2cSrf08));
  
  i2csrf08.device = strdup(device);
#if 0  
  i2csrf08.range = 0xff; /*  11 m : default */
  i2csrf08.range = 0x8c; /*  6 m */
  i2csrf08.range = 0x18; /*  1 m */
  i2csrf08.range = 0x1;  /*  86 mm */
  i2csrf08.range = 0x0;  /*  43 mm */
#endif
  i2csrf08.range = 0xff; /*  11 m : default */
#if 0
  i2csrf08.gain = 0x0; /*  min 94 */
  i2csrf08.gain = 0x1f; /* default & max 1025 */
#endif
  i2csrf08.gain = 0x1f;
  
  return &i2csrf08;
}
#define SRF08_I2C_ADDR  0x70
int I2cSrf08_Open(I2cSrf08 *is)
{
  is->fd = open(is->device, O_RDWR);
  if(is->fd == -1)
    return -1;
  
  if(ioctl(is->fd, I2C_SLAVE, SRF08_I2C_ADDR) < 0)  {
    printf("[SRF08] None exist device address 0x%x\n", SRF08_I2C_ADDR);
    close(is->fd);
    is->fd = 0;
    return -1;
  }
  
  unsigned char buf[2];
  
  buf[0] = 0x1; /*  Register 1  */
  buf[1] = is->gain;  /*  Gain */
  if(write(is->fd, buf, 2) != 2)
    return -1;
  buf[0] = 0x2; /*  Register 2  */
  buf[1] = is->range;  /*  Range */
  if(write(is->fd, buf, 2) != 2)
    return -1;
  
  return is->fd;
}
void I2cSrf08_Close(I2cSrf08 *is)
{
  if(is->fd)
    close(is->fd);
  is->fd = 0;
}
void I2cSrf08_SetMaxRange(I2cSrf08 *is, unsigned char range)
{
  is->range = range;
  
  unsigned char buf[2];
  
  buf[0] = 0x2; /*  Register 2  */
  buf[1] = is->range;  /*  Range */
  if(write(is->fd, buf, 2) != 2)
    printf("[SRF08] Fail to write !!!\n");
  
  return;
}
void I2cSrf08_SetMaxGain(I2cSrf08 *is, unsigned char gain)
{
  if(gain > 0x1f)
    gain = 0x1f;
  
  is->gain = gain;
  
  unsigned char buf[2];
  
  buf[0] = 0x1; /*  Register 1  */
  buf[1] = is->gain;  /*  Gain */
  if(write(is->fd, buf, 2) != 2)
    printf("[SRF08] Fail to write !!!\n");
  
  return;
}
int I2cSrf08_BlockRangeInCentimeters(I2cSrf08 *is)
{
  unsigned char buf[2];
  
  buf[0] = 0x0; /*  Register 0  */
  buf[1] = 81;  /*  Range in centimeters */
  if(write(is->fd, buf, 2) != 2)
    return -1;
  
  while(1)  {
    usleep(65000);
    buf[0] = 0x0; /*  Register 0 : software reversion */
    if(write(is->fd, buf, 1) != 1)  {
      usleep(100);
      continue;
    }
    
    if(read(is->fd, buf, 1) != 1)  {
      usleep(100);
      continue;
    }
    
    if(buf[0] != 0xff)  /*  While ranging it returns 0xff */
      break;  /*  Range data ready now  */
  }
  
  int i;
  char hb, lb;
  unsigned short r = 0;
  for(i=0;i<17;i++) { /*  There are 17 echo buffers */
    buf[0] = 2 + (i << 1); /*  Register 2, 4, 6 ...  */
    if(write(is->fd, buf, 1) != 1)
      return -1;
    if(read(is->fd, buf, 1) != 1)
      return -1;
    hb = buf[0];
    
    buf[0] = 3 + (i << 1); /*  Register 3, 5, 7 ...  */
    if(write(is->fd, buf, 1) != 1)
      return -1;
    if(read(is->fd, buf, 1) != 1)
      return -1;
    lb = buf[0];
    if(hb == 0 && lb == 0)
      break;
/*    
    printf("High byte : %d\n", hb);
    printf("Low byte : %d\n", lb);
*/
    r = (hb << 8) + lb;
    printf("[SRF08] %dst echo range = %u\n", i, r);
  }
  
  return 0;
}
int I2cSrf08_RangingInCentimeters(I2cSrf08 *is)
{
  if(is->ranging == true)
    return 0;
  unsigned char buf[2];
  buf[0] = 0x0; /*  Register 0  */
  buf[1] = 81;  /*  Range in centimeters */
  if(write(is->fd, buf, 2) != 2)
    return -1;
  
  is->ranging = true;
  
  return 0;
}
int I2cSrf08_GetRange(I2cSrf08 *is)
{
  if(is->ranging == false)
    return 0;
  unsigned char buf[1];
  char hb, lb;
  buf[0] = 0x0; /*  Register 0 : software reversion */
  if(write(is->fd, buf, 1) != 1)
    return -1;
  if(read(is->fd, buf, 1) != 1) {
    printf("[SRF08] Fail to read !!!\n");
    return -1;
  }
  if(buf[0] == 0xff)  {
    printf("[SRF08] Range data not ready !!!\n");
    return -1;
  }
  buf[0] = 2; /*  Register 2, 4, 6 ...  */
  if(write(is->fd, buf, 1) != 1)
    return -1;
  if(read(is->fd, buf, 1) != 1)
    return -1;
  hb = buf[0];
  buf[0] = 3; /*  Register 3, 5, 7 ...  */
  if(write(is->fd, buf, 1) != 1)
    return -1;
  if(read(is->fd, buf, 1) != 1)
    return -1;
  lb = buf[0];
  is->ranging = false;
  
  if(hb == 0 && lb == 0)  {
    printf("[SRF08] Fail to get range !!!\n");
    return -1;
  }
  unsigned short r = (hb << 8) + lb;
  
  return (int)r;
}
ultra_sonic.c
/*
 * ultra_sonic.c : SRF08 ultra sonic range finder sample program
 *
 *  (C) 2011 by Steve Chang
 *  stevegigijoe@yahoo.com.tw
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include 
#include "i2c_srf08.h"
#define I2C_SRF08_DEVICE  "/dev/i2c-2"
int main(int argc, char **argv)
{
  I2cSrf08 *is = I2cSrf08_DefaultInstance(I2C_SRF08_DEVICE);
  
  int r = I2cSrf08_Open(is);
  if(r == -1) {
    printf("Fail to open %s\n", I2C_SRF08_DEVICE);
    goto leave;
  }
  while(1)
    I2cSrf08_BlockRangeInCentimeters(is);
leave:
  I2cSrf08_Close(is);
  return r;
}
The result as below
# ./ultra_sonic
[  851.740844] i2c_omap i2c_omap.2: Transmit error
[SRF08] 0st echo range = 32
[SRF08] 1st echo range = 86
[SRF08] 2st echo range = 150
[SRF08] 3st echo range = 216
[SRF08] 4st echo range = 280
[SRF08] 5st echo range = 344
[SRF08] 6st echo range = 410
[SRF08] 7st echo range = 474
[SRF08] 8st echo range = 560
[SRF08] 9st echo range = 795
[SRF08] 10st echo range = 926
[SRF08] 11st echo range = 1050
[SRF08] 0st echo range = 33
[SRF08] 1st echo range = 87
[SRF08] 2st echo range = 151
[SRF08] 3st echo range = 217
[SRF08] 4st echo range = 281
[SRF08] 5st echo range = 346
[SRF08] 6st echo range = 410
[SRF08] 7st echo range = 474
[SRF08] 8st echo range = 563
[SRF08] 9st echo range = 630
[SRF08] 10st echo range = 795
 
沒有留言:
張貼留言