Hello,
I'm in trouble with a SRF08 sonar. I'm not able to make it working.
The sonar is connected to the PB7-PB6 lines.
I wrote the code below, when the program runs the led on the SRF08
blinks and it is possible to hear a soft "tick" but the only value I
get is always 255. I put on PB7 and PB6 lines to pull up resistors
(1.8 K) connected to 5V line.
Any suggestion ?
Any help would be greatly appreciated !!!
Thanks
Paolo
==================
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <time.h>
#include <sys/ioctl.h>
#include <asm/etraxgpio.h>
#include <syslog.h>
#include <stdarg.h>
#include <net/if.h>
#define RX_BUFFER_LEN 1024
#define I2C_DATA_LINE 1<<6
#define I2C_CLOCK_LINE 1<<7
int i2c_fd;
int serial_fd;
// Software delay in us
void udelay(int us) {
int a;
int b;
int delayvar=1111;
for (b=0;b<33;b++) {
for (a=0;a<us;a++) {
delayvar*=3;
delayvar/=3;
}
}
}
// Get the SDA line state
int i2c_getbit(void) {
unsigned int value;
value=ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_READBITS));
if ((value&(I2C_DATA_LINE))==0) return 0;
else return 1;
}
// Set the SDA line state
void i2c_data(int state) {
if (state==1) ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE,
IO_SETBITS), I2C_DATA_LINE);
else ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),
I2C_DATA_LINE);
}
// Set the SCL line state
void i2c_clk(int state) {
if (state==1) ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE,
IO_SETBITS), I2C_CLOCK_LINE);
else ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS),
I2C_CLOCK_LINE);
}
// Set the SDA line as output
void i2c_dir_out(void) {
int iomask;
iomask = I2C_DATA_LINE;
ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_OUTPUT),
&iomask);
}
// Set the SDA line as input
void i2c_dir_in(void) {
int iomask;
iomask = I2C_DATA_LINE;
ioctl(i2c_fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETGET_INPUT),
&iomask);
}
// Open the GPIOB dev
int i2c_open(void) {
i2c_fd = open("/dev/gpiob", O_RDWR);
i2c_data(1);
i2c_dir_out();
i2c_clk(1);
i2c_data(1);
udelay(100);
return i2c_fd;
}
// Close the GPIOB dev
void i2c_close(void) {
close(i2c_fd);
}
// Send a start sequence to I2C bus
void i2c_start(void){
i2c_data(0);
i2c_clk(0);
}
// Send a stop sequence to I2C bus
void i2c_stop(void) {
i2c_clk(1);
i2c_data(1);
}
// Read a byte from I2C bus and send the ack sequence
unsigned char i2c_inbyte(void) {
unsigned char value = 0;
int bitvalue;
int i;
// Read data byte
i2c_dir_in();
for (i=0;i<8;i++) {
i2c_clk(1);
bitvalue = i2c_getbit();
value |= bitvalue;
if (i<7) value <<= 1;
i2c_clk(0);
}
// Send Ack
i2c_data(0);
i2c_dir_out();
i2c_data(0);
i2c_clk(1);
i2c_clk(0);
udelay(100);
return value;
}
// Send a byte to the I2C bus and return the ack sequence from slave
0 = Nack, 1=Ack
int i2c_outbyte(unsigned char x) {
int i;
int ack;
i2c_clk(0);
for (i=0;i<8;i++) {
if (x & 0x80) i2c_data(1);
else i2c_data(0);
i2c_clk(1);
i2c_clk(0);
x <<= 1;
}
i2c_dir_in();
i2c_clk(1);
ack=i2c_getbit();
i2c_clk(0);
i2c_dir_out();
if (ack==0) return 1;
else return 0;
}
// Send a start sequence
// Send 0xE0 (I2C address of the SRF08 with the R/W bit low (even
address)
// Send 0x00 (Internal address of the command register)
// Send 0x51 (The command to start the SRF08 ranging)
// Send the stop sequence.
void SRF08Init(){
i2c_start();
i2c_outbyte(0xE0);
udelay(100);
i2c_outbyte(0x00);
udelay(100);
i2c_outbyte(0x51);
udelay(100);
i2c_stop();
}
// send start sequence
// 0xE0: SRF08 I2C address with R/W bit clear
// 0x02: SRF08 range sensor register address
// send a restart sequence
// 0xE1: SRF08 I2C address with R/W bit set
// get the high byte of the range and send acknowledge.
// get low byte of the range - note we don't acknowledge the last
byte.
// send stop sequence
unsigned char SRF08Read(){
unsigned char value = 0;
i2c_start();
i2c_outbyte(0xE0);
udelay(100);
i2c_outbyte(0x02);
i2c_start();
i2c_outbyte(0xE1);
udelay(5000);
value=i2c_inbyte();
i2c_stop();
return value;
}
int main(void) {
if (i2c_open()<0) {
printf("i2c open error\n");
return 1;
}
while(1) {
SRF08Init();
sleep(1);
printf("Distance :%d\n", SRF08Read());
}
i2c_close();
return 0;
}
============