[Home]Rpi Iic Srf08.C

HomePage | RecentChanges | Preferences | My Website home page

Here is some C code to do serial with a timeout.

/*
 * rpi_iic.c - rs232 code to drive robot electronics IIC module. 
 *  modified from MD49.c
 *
 * 
 * robot electronics rpi_iic  example code for raspberry pi.
 * 
 * By James Henderson, 2012,
 * Modified Doug Rice 2014
 *
 * Useful documentation:-
 * http://en.wikibooks.org/wiki/Serial_Programming/termios
 *
 * Useful documentation about the IIC and ultrasound modules.
 * http://www.robot-electronics.co.uk/htm/raspberry_pi_examples.htm
 *
 * http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm
 * 
 * http://www.robot-electronics.co.uk/acatalog/Ultrasonic_Rangers.html
 * http://www.robot-electronics.co.uk/htm/srf02tech.htm
 * http://www.robot-electronics.co.uk/htm/srf02techI2C.htm
 
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>

void writeBytes(int descriptor, int count);
void readBytes(int descriptor, int count);

void setModeIIC(int fd, char mode); 
void setModeIICatod(int fd, char mode); 
void setModeIICultraSound(int fd, char mode);
int  aatoint(char hi,char lo);

char serialBuffer[100];					// Serial buffer sto store data for I/O


int main(int argc, char **argv)
{
	int fd;						// File descriptor of port we will talk to 
	//char *portName = "/dev/ttyAMA0";		// Name of the UART port on the Raspberry pi
	//char *portName = "/dev/ttyACM0";		// Name of the UART port on the Raspberry pi
	
	char   *portName = "/dev/ttyUSB0";		// Name of the IIC module
	struct termios options;				// Port options
	
        printf(" sizeof: %d aatoInt: %d", sizeof( fd ), aatoint( '1','2' ) );
       

	fd = open(portName, O_RDWR | O_NOCTTY);		// Open port for read and write not making it a controlling terminal
	if (fd == -1)
	{
   		perror("openPort: Unable to open port ");		// If open() returns an error
	} else {
	  printf("\n usb iic usb open \n");
	} 

	// setModeIIC(fd, 1);						// Set the mode of the MD49 to 1
	tcgetattr(fd, &options);
	cfsetispeed(&options, B19200);						// Set baud rate
	cfsetospeed(&options, B19200);					
	cfmakeraw(&options);
	tcflush(fd, TCIFLUSH);

	// http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html

	// printf("c_cc[VMIN]  %04X\n",options.c_cc[VMIN]);
	// printf("c_cc[VTIME] %04X\n",options.c_cc[VTIME]);
	options.c_cc[VMIN]  = 6; // wait for atleast these CHARs
	options.c_cc[VTIME] = 3; // wait deci seconds.

	tcsetattr(fd, TCSANOW, &options);
	usleep(1000);							// Sleep for UART to power up and set options
	tcflush(fd, TCIFLUSH);
	cfsetospeed(&options, B19200);					
	cfmakeraw(&options);
	tcflush(fd, TCIFLUSH);


	// http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
	
	usleep(1000);							// Sleep for UART to power up and set options
	
	// displaySoftwareValue(fd);					// Display the software version of the MD49
	
	printf("\n ==================== \n");
	
	setModeIICultraSound( fd, 1 );
	usleep(100000);						// Sleep for UART to power up and set options

	setModeIICultraSound( fd, 1 );

	while(1){
	  setModeIICultraSound( fd, 1 );
	}
	usleep(100000);						// Sleep for UART to power up and set options
	
	close(fd);							// Close port
	
	return 0;
}

void writeBytes(int descriptor, int count) {
   int cnt;
	if (( cnt = write(descriptor, serialBuffer, count)) == -1) {	// Send data out	
		perror("Error writing");
		close(descriptor);					// Close port if there is an error
		exit(1);
	}
}

void readBytes(int descriptor, int count) {

	int count_rd;
	if (count_rd = read(descriptor, serialBuffer, count) == -1) {		// Read back data into buf[]
		perror("Error reading ");
		close(descriptor);					// Close port if there is an error
		exit(1);
	}
	// printf(" count: %d %d ", count_rd ,  count );
}

void setModeIIC(int fd, char mode) {
	int count,cp3;
	//
	serialBuffer[0] = 0x5A;		
	serialBuffer[1] = 0x10;						// Mode we wish to set
	serialBuffer[2] = mode ;					// Mode we wish to set
	serialBuffer[3] = 0x00;						// Mode we wish to set
	writeBytes(fd, 4);

	readBytes( fd,1);
	printf("%02X \n", serialBuffer[0] );
        
}

void setModeIICatod(int fd, char mode) {

	setModeIIC( fd, 0x0C );

	
	usleep(100000);						// Sleep for UART to power up and set options
	serialBuffer[0] = 0x5A;		
	serialBuffer[1] = 0x12;						// Mode we wish to set
	serialBuffer[2] = 0x00;						// Mode we wish to set
	serialBuffer[3] = 0x00;						// Mode we wish to set

	writeBytes(fd, 4);
        usleep(  600000  );

	readBytes( fd,8);
	printf(  "%02X %02X   %02X %02X \n", serialBuffer[0] , serialBuffer[1],        serialBuffer[2], serialBuffer[3] );
}

void setModeIICultraSound(int fd, char mode) {

/* 82	0x52	 Real Ranging Mode - Result in micro-seconds */
	
/*
 The SRF02 appears as a set of 6 registers.

Location	Read			Write	
0		Software Revision	Command Register
1		Unused (reads 0x80)	N/A 
2		Range High Byte		N/A
3		Range Low Byte		N/A
4	 Autotune Minimum - High Byte	 N/A
5	 Autotune Minimum - Low Byte	 N/A

*/

/*
Writing to I2C devices with a 1 byte internal address register
This includes almost all I2C devices. Following the I2C_AD1 command you send the device I2C address, 
then the devices internal register address you want to write to and the number of bytes you're writing. 
The maximum number of data bytes should not exceed 64 so as not to overflow the USB-I2C's internal buffer.

 	Primary USB-I2C command	Device Address + R/W bit	Device internal register	Number of data bytes	The data bytes
Byte Type	I2C_AD1	Addr+R/W	Reg	Byte Count	Data
Example	0x55	0xE0	0x00	0x01	0x51
Meaning	Primary USB-I2C command	SRF08 I2C address	SRF08 command Reg	One command byte follows	Start ranging in cm
This 5 byte sequence starts an SRF08 at address 0xE0 ranging. 

All 5 bytes should be sent to the USB-I2C in one sequence. 
A gap will result in the USB-I2C re-starting its internal command synchronization loop and ignoring the message. 
After all bytes have been received the USB-I2C performs the IC2 write operation out to the SRF08 
and sends a single byte back to the PC. 

This returned byte will be 0x00 (zero) if the write command failed and non-zero if the write succeeded. 
The PC should wait for this byte to be returned (timing out after 500mS) before proceeding with the next transaction.

*/
	
/*	I2C_AD1	0x55	 Read/Write single or multiple bytes for 1 byte addressed devices (the majority of devices will use this one) */
	
	int aai, aaat ;
	
	
	serialBuffer[0] = 0x55;	// iic command to do iic 	
	serialBuffer[1] = 0xE0;	// iic address
	serialBuffer[2] = 0x00;	// device internal reg
	serialBuffer[3] = 0x01;	// number of bytes to write
	serialBuffer[4] = 0x51;	// 0x52	 Real Ranging Mode - Result in micro-seconds

	writeBytes(fd, 5);
	readBytes( fd,1);
	/*
	if ( serialBuffer[0] == 0 ) {
	  printf(  "not ok: %02X ", serialBuffer[0] );
	}
        */
        usleep(  100000  );

	// Set up the iic for a read operation.
	serialBuffer[0] = 0x55;	// iic command to do iic 	
	serialBuffer[1] = 0xE1;	// iic address
	serialBuffer[2] = 0x00;	// device internal reg
	serialBuffer[3] = 0x06;	// number of bytes to read
	writeBytes(fd, 4);
	readBytes( fd,6);

 	// au.b1[0] = serialBuffer[3];
 	// au.b1[1] = serialBuffer[2];

        aai  = aatoint( serialBuffer[3], serialBuffer[2]);
        aaat = aatoint( serialBuffer[5], serialBuffer[4]);

//	printf(  "ver: %02X %02X range: %04X cm  %06d cm ", serialBuffer[0], serialBuffer[1], aai,aai  );   // serialBuffer[2], serialBuffer[3] 
//	printf(  "AT:  %04X cm  %06d cm \n", aaat, aaat );

//	printf(  "srf08:range  %06d cm, autoTune: %06d \n",  aai,aaat  ); 
//	printf(  "srf08: %06d cm,  %06d cm \n",  aaat,aai  ); 

	printf(  "srf08: %06d cm,  %06d cm %0*d+\n",  aaat,aai,(int)(aai/4),1  ); 

}


int aatoint(char hi,char lo){

  union ua{
    int i;
    char a[2];  // lo-hi
  } u;
  
  if ( sizeof( u.i ) == 4 ) {
    u.a[0]=hi;
    u.a[1]=lo;
    u.a[2]=0;
    u.a[3]=0;
  } else {
    printf( "sizeof( int ) != 4 - needs little enden numbers\n" );
    exit(1);
  }
  return u.i; 
}

/* END */

HomePage | RecentChanges | Preferences | My Website home page
This page is read-only | View other revisions
Last edited March 8, 2014 8:04 am by dougrice.plus.com
Search: