Legacy Forum: Preserving Nearly 20 Years of Community History - A Time Capsule of Discussions, Memories, and Shared Experiences.

I2C sample code for Devantech SRF08/SRF10 UltraSonic Ranger

Based on DMP's Vortex processor / SoC this board is a full computer capable of running a standard Windows and Linux installation on the backpack of your robot.
7 postsPage 1 of 1
7 postsPage 1 of 1

I2C sample code for Devantech SRF08/SRF10 UltraSonic Ranger

Post by roboard » Fri Jul 10, 2009 6:14 am

Post by roboard
Fri Jul 10, 2009 6:14 am

Some people asked us how to interfacing with SRF08/SRF10 UltraSonic Ranger by RoBoard. This is easy using RoBoIO library; the following is a brief sample code.

Code: Select all
#include <stdio.h>
#include <conio.h>

#include <roboard.h>

//you need to change this function for Linux and DOS
void wait_ms(unsigned long ms) {
    unsigned long nowtime = GetTickCount();
    while ((GetTickCount() - nowtime) <= ms);
}

int main(void) {
    unsigned b1, b2;

    if (i2c_Initialize(I2CIRQ_DISABLE) == false)
    {
        printf("fail to initialize I2C (%s)!\n", roboio_GetErrMsg());
        return -1;
    }

    printf("set I2C speed to 400Kbps\n\n");
    i2c0_SetSpeed(I2CMODE_STANDARD, 400000L);

    do
    {
        printf("send SRF ranging command\n");

        //START with address 0xe0>>1 to write 2 bytes
        i2c0master_StartN(0xe0>>1, I2C_WRITE, 2);

        //Note: the SRF device address 0xe0 actually contains the I2C r/w bit,
        //      so we divide it by 2 to get the correct I2C slave address;
        //      see the I2C lib section of RoBoard SW intro. slide for more details.

        i2c0master_WriteN(0);       //set SRF command register
        i2c0master_WriteN(81);      //set ranging Mode - result in cm

        wait_ms(100); //wait 100ms

        printf("read SRF ranging data......\n");

        //START with address 0xe0>>1 to write 1 bytes
        i2c0master_StartN(0xe0>>1, I2C_WRITE, 1);

        //set RESTART to read 2 bytes after I2C writing
        i2c0master_SetRestartN(I2C_READ, 2);

        i2c0master_WriteN(2);       //set 1st SRF range register
        b1 = i2c0master_ReadN();    //read echo high byte
        b2 = i2c0master_ReadN();    //read echo low byte

        printf("result = %u\n\n", b1*256 + b2);

    } while (getch() != 27); //press ESC to quit

    i2c_Close();
    return 0;
}


The above sample code is for WinXP and WinCE; if you want to compile it at Linux or DOS, just change the wait_ms() function.

Note: in our test, SRF08/SRF10 can connect to RoBoard's I2C0_SCL, I2C0_SDA pins without pull-up resistors and run on 400Kbps. But for other I2C sensors, pull-up resistors may be necessary for fast I2C transmission (>100Kbps).
Some people asked us how to interfacing with SRF08/SRF10 UltraSonic Ranger by RoBoard. This is easy using RoBoIO library; the following is a brief sample code.

Code: Select all
#include <stdio.h>
#include <conio.h>

#include <roboard.h>

//you need to change this function for Linux and DOS
void wait_ms(unsigned long ms) {
    unsigned long nowtime = GetTickCount();
    while ((GetTickCount() - nowtime) <= ms);
}

int main(void) {
    unsigned b1, b2;

    if (i2c_Initialize(I2CIRQ_DISABLE) == false)
    {
        printf("fail to initialize I2C (%s)!\n", roboio_GetErrMsg());
        return -1;
    }

    printf("set I2C speed to 400Kbps\n\n");
    i2c0_SetSpeed(I2CMODE_STANDARD, 400000L);

    do
    {
        printf("send SRF ranging command\n");

        //START with address 0xe0>>1 to write 2 bytes
        i2c0master_StartN(0xe0>>1, I2C_WRITE, 2);

        //Note: the SRF device address 0xe0 actually contains the I2C r/w bit,
        //      so we divide it by 2 to get the correct I2C slave address;
        //      see the I2C lib section of RoBoard SW intro. slide for more details.

        i2c0master_WriteN(0);       //set SRF command register
        i2c0master_WriteN(81);      //set ranging Mode - result in cm

        wait_ms(100); //wait 100ms

        printf("read SRF ranging data......\n");

        //START with address 0xe0>>1 to write 1 bytes
        i2c0master_StartN(0xe0>>1, I2C_WRITE, 1);

        //set RESTART to read 2 bytes after I2C writing
        i2c0master_SetRestartN(I2C_READ, 2);

        i2c0master_WriteN(2);       //set 1st SRF range register
        b1 = i2c0master_ReadN();    //read echo high byte
        b2 = i2c0master_ReadN();    //read echo low byte

        printf("result = %u\n\n", b1*256 + b2);

    } while (getch() != 27); //press ESC to quit

    i2c_Close();
    return 0;
}


The above sample code is for WinXP and WinCE; if you want to compile it at Linux or DOS, just change the wait_ms() function.

Note: in our test, SRF08/SRF10 can connect to RoBoard's I2C0_SCL, I2C0_SDA pins without pull-up resistors and run on 400Kbps. But for other I2C sensors, pull-up resistors may be necessary for fast I2C transmission (>100Kbps).
Last edited by roboard on Mon Aug 17, 2009 1:05 pm, edited 1 time in total.
roboard
Savvy Roboteer
Savvy Roboteer
Posts: 302
Joined: Fri Jul 03, 2009 4:44 am

Re: I2C sample code for Devantech SRF08/SRF10 UltraSonic Ran

Post by roboard » Fri Jul 10, 2009 6:23 am

Post by roboard
Fri Jul 10, 2009 6:23 am

An additional remark: The old RoBoIO library v1.5b has a bug in I2C lib. To run the above sample correctly, you need to download the fix version of RoBoIO library v1.5b from the RoBoard website.
An additional remark: The old RoBoIO library v1.5b has a bug in I2C lib. To run the above sample correctly, you need to download the fix version of RoBoIO library v1.5b from the RoBoard website.
roboard
Savvy Roboteer
Savvy Roboteer
Posts: 302
Joined: Fri Jul 03, 2009 4:44 am

Post by Tsai Sung Yang » Mon Dec 07, 2009 11:16 am

Post by Tsai Sung Yang
Mon Dec 07, 2009 11:16 am

Hi, I was trying to set up two SRF10, so I need to change one's address which default is 0xE0.

I tried above code and added this:

Code: Select all
i2c0master_StartN(0xe0>>1, I2C_WRITE, 5);
i2c0master_WriteN(0);     // Command
i2c0master_WriteN(0xA0);  // 1st in sequence to change I2C address
i2c0master_WriteN(0xAA);  // 2st in sequence to change I2C address
i2c0master_WriteN(0xA5);  // 3st in sequence to change I2C address
i2c0master_WriteN(0xE2);  // New address


but seems doesn't work, its address is still 0xE0 :?
Hi, I was trying to set up two SRF10, so I need to change one's address which default is 0xE0.

I tried above code and added this:

Code: Select all
i2c0master_StartN(0xe0>>1, I2C_WRITE, 5);
i2c0master_WriteN(0);     // Command
i2c0master_WriteN(0xA0);  // 1st in sequence to change I2C address
i2c0master_WriteN(0xAA);  // 2st in sequence to change I2C address
i2c0master_WriteN(0xA5);  // 3st in sequence to change I2C address
i2c0master_WriteN(0xE2);  // New address


but seems doesn't work, its address is still 0xE0 :?
Last edited by Tsai Sung Yang on Tue Dec 08, 2009 5:23 pm, edited 1 time in total.
Tsai Sung Yang
Robot Builder
Robot Builder
Posts: 17
Joined: Wed Nov 11, 2009 2:02 pm
Location: Taiwan

Post by roboard » Tue Dec 08, 2009 11:57 am

Post by roboard
Tue Dec 08, 2009 11:57 am

You can try to send each command to register at location 0 like following code:
Code: Select all
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xA0);// 1st in sequence to change I2C address
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xAA);// 2st in sequence to change I2C address

last to 0xE2

Reference:SRF10 Ultra sonic range finder
http://www.robot-electronics.co.uk/htm/srf10tech.htm
You can try to send each command to register at location 0 like following code:
Code: Select all
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xA0);// 1st in sequence to change I2C address
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xAA);// 2st in sequence to change I2C address

last to 0xE2

Reference:SRF10 Ultra sonic range finder
http://www.robot-electronics.co.uk/htm/srf10tech.htm
roboard
Savvy Roboteer
Savvy Roboteer
Posts: 302
Joined: Fri Jul 03, 2009 4:44 am

Post by Tsai Sung Yang » Tue Dec 08, 2009 5:22 pm

Post by Tsai Sung Yang
Tue Dec 08, 2009 5:22 pm

It works!! Thank you! :D
So the function can only write 2 byte at a time?

roboard wrote:You can try to send each command to register at location 0 like following code:
Code: Select all
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xA0);// 1st in sequence to change I2C address
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xAA);// 2st in sequence to change I2C address

last to 0xE2

Reference:SRF10 Ultra sonic range finder
http://www.robot-electronics.co.uk/htm/srf10tech.htm
It works!! Thank you! :D
So the function can only write 2 byte at a time?

roboard wrote:You can try to send each command to register at location 0 like following code:
Code: Select all
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xA0);// 1st in sequence to change I2C address
  i2c0master_StartN(0xE0>>1, I2C_WRITE, 2);
  i2c0master_WriteN(0);
  i2c0master_WriteN(0xAA);// 2st in sequence to change I2C address

last to 0xE2

Reference:SRF10 Ultra sonic range finder
http://www.robot-electronics.co.uk/htm/srf10tech.htm
Tsai Sung Yang
Robot Builder
Robot Builder
Posts: 17
Joined: Wed Nov 11, 2009 2:02 pm
Location: Taiwan

Post by roboard » Wed Dec 09, 2009 11:00 am

Post by roboard
Wed Dec 09, 2009 11:00 am

According to the provisions of the SRF10,you can change address by only one method:
Send commands in the correct sequence to the command register at location 0, which means 4 separate write transactions on the I2C bus.
According to the provisions of the SRF10,you can change address by only one method:
Send commands in the correct sequence to the command register at location 0, which means 4 separate write transactions on the I2C bus.
roboard
Savvy Roboteer
Savvy Roboteer
Posts: 302
Joined: Fri Jul 03, 2009 4:44 am

Re: I2C sample code for Devantech SRF08/SRF10 UltraSonic Ran

Post by Chaosmann » Fri Jan 01, 2010 7:25 am

Post by Chaosmann
Fri Jan 01, 2010 7:25 am

Hi, have got a brand new SRF08 yesterday so I wanted to test it with the code above.
But after hours I found out that the first i2c0master_StartN call in the loop have to write to 0xE1 instead on 0xE0.

I've just written an example for Linux which reads the value from the light sensor:

Code: Select all
#include <iostream>
#include <stdio>                               // for in-/output
#include <unistd>                             // for usleep
#include "include/roboard.h"

#define SRF08Address 0xE0

using namespace std;

void GotoXY( int x, int y ) {
    printf("%c[%d;%df",0x1B,y,x);
}

void SRFStart( int add ) {
    i2c0master_StartN( add>>1, I2C_WRITE, 2 );
    i2c0master_WriteN( 0 );
    i2c0master_WriteN( 0x51 );
}

unsigned SRFReadLight( int add ) {
    //START with address 0xe0>>1 to write 1 bytes
    i2c0master_StartN( (add+1)>>1, I2C_WRITE, 1 );
    //set RESTART to read 2 bytes after I2C writing
    i2c0master_SetRestartN( I2C_READ, 1 );
    i2c0master_WriteN( 1 );
    return i2c0master_ReadN();
}

int main( void ) {
    unsigned b1, b2;

    printf( "\f" ); // clear the screen

    if (i2c_Initialize(I2CIRQ_DISABLE) == false) {
        printf("fail to initialize I2C (%s)!", roboio_GetErrMsg());
        return -1;
    }

    printf( "set I2C speed to 400Kbps" );
    i2c0_SetSpeed( I2CMODE_AUTO, 400000 );
    do {
        SRFStart( SRF08Address );
        usleep( 200000 );
        GotoXY( 1,2 ); cout << SRFReadLight( SRF08Address ) << "  " << endl;;
    } while ( true );

    i2c_Close();
    return 0;
}
Hi, have got a brand new SRF08 yesterday so I wanted to test it with the code above.
But after hours I found out that the first i2c0master_StartN call in the loop have to write to 0xE1 instead on 0xE0.

I've just written an example for Linux which reads the value from the light sensor:

Code: Select all
#include <iostream>
#include <stdio>                               // for in-/output
#include <unistd>                             // for usleep
#include "include/roboard.h"

#define SRF08Address 0xE0

using namespace std;

void GotoXY( int x, int y ) {
    printf("%c[%d;%df",0x1B,y,x);
}

void SRFStart( int add ) {
    i2c0master_StartN( add>>1, I2C_WRITE, 2 );
    i2c0master_WriteN( 0 );
    i2c0master_WriteN( 0x51 );
}

unsigned SRFReadLight( int add ) {
    //START with address 0xe0>>1 to write 1 bytes
    i2c0master_StartN( (add+1)>>1, I2C_WRITE, 1 );
    //set RESTART to read 2 bytes after I2C writing
    i2c0master_SetRestartN( I2C_READ, 1 );
    i2c0master_WriteN( 1 );
    return i2c0master_ReadN();
}

int main( void ) {
    unsigned b1, b2;

    printf( "\f" ); // clear the screen

    if (i2c_Initialize(I2CIRQ_DISABLE) == false) {
        printf("fail to initialize I2C (%s)!", roboio_GetErrMsg());
        return -1;
    }

    printf( "set I2C speed to 400Kbps" );
    i2c0_SetSpeed( I2CMODE_AUTO, 400000 );
    do {
        SRFStart( SRF08Address );
        usleep( 200000 );
        GotoXY( 1,2 ); cout << SRFReadLight( SRF08Address ) << "  " << endl;;
    } while ( true );

    i2c_Close();
    return 0;
}
Chaosmann
Robot Builder
Robot Builder
Posts: 16
Joined: Wed Dec 09, 2009 3:43 am


7 postsPage 1 of 1
7 postsPage 1 of 1