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
沒有留言:
張貼留言