Error reading from SRF10 .Net Gadgeteer with extender (I2C)

Hi All,

I was hooking up devantech SRF10 through gedgeteer extender. The address I use was 0x70 according to 7bit and 8bit address difference. I managed to hook up the sensor and was able to write ranging command such as

buffer = new byte[] { 0x70, 0x00, 0x51};
int i = i2c.Write(buffer, 500);
Thread.Sleep(readDelay);

through I2CBus.

However I always get 1280 as distance when I read from buffer. Here is complete code I done in timer tick.

void timer_Tick(GT.Timer timer)
{
Debug.Print(“writing range”);

        //Ranging
        buffer = new byte[] { 0x70, 0x00, 0x51};
        int i = i2c.Write(buffer, 500);
        Thread.Sleep(readDelay);
                 
        i2c.Read(buffer, 100);
        i2cRead();
 
    }

    void i2cRead()
    {
        int distance = buffer[0] << 8;
        distance |= buffer[1];
        previousRange = currentRange;
        currentRange = distance;
                              
        Debug.Print("previous " + previousRange);
        Debug.Print("current  " + currentRange);
      
    }

There could be two problems, 1) my way of reading buffer is wrong or 2) getting data from buffer is wrong.

I really you all expert’s advice urgently…

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

void timer_Tick(GT.Timer timer)
 {
 Debug.Print("writing range");


 //Ranging
 buffer = new byte[] { 0x70, 0x00, 0x51};
 int i = i2c.Write(buffer, 500);
 Thread.Sleep(readDelay);

 i2c.Read(buffer, 100);
 i2cRead();

 }

 void i2cRead()
 {
 int distance = buffer[0] << 8;
 distance |= buffer[1];
 previousRange = currentRange;
 currentRange = distance;

 Debug.Print("previous " + previousRange);
 Debug.Print("current " + currentRange);

 }

Can you show the code where you are creating I2C device including it configuration?

Also are you sure the address is 0x70 . Spec shows that it can be only one of these:

E0, E2, E4, E6, E8, EA, EC, EE, F0, F2, F4, F6, F8, FA, FC or FE

with E0 being the default one.

Yep, they’re quoting an 8-bit address (because they don’t understand I2C !!! Gah, when will they learn!?) so the 7-bit address is 0x70. Assuming you haven’t changed it on the device :slight_smile:

Thank for your prompt’s reply. I have initially tried to construct I2CBus with 0xE0.

I received following error.

Using mainboard GHI Electronics FEZSpider version 1.0
Program Started
writing range
#### Exception System.ArgumentException - 0xfd000000 (1) ####
#### Message:
#### Microsoft.SPOT.Hardware.I2CDevice::Execute [IP: 0000] ####
#### Gadgeteer.Interfaces.I2CBus::Execute [IP: 001a] ####
#### Gadgeteer.Interfaces.I2CBus::Write [IP: 0012] ####
#### UltrasonicSample.Program::timer_Tick [IP: 002f] ####
#### Gadgeteer.Timer::dt_Tick [IP: 0018] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 0020] ####
A first chance exception of type ‘System.ArgumentException’ occurred in Microsoft.SPOT.Hardware.dll
Exception performing Timer operation

In one of the Arduino forum, Nicholas Zambetti http://www.zambetti.com wrote this.
// step 1: instruct sensor to read echoes
Wire.beginTransmission(112); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it’s 112

I used following constructor in my code. It can write with the i2cBus.


  void ProgramStarted()
        {
            
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            GT.Socket socket = GT.Socket.GetSocket(10, true, null, null);
            i2c = new GTI.I2CBus(socket, 0x70, 40, null);

           
             GT.Timer timer = new GT.Timer(500); // every second (1000ms)
             timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
             timer.Start();

        }

output windows shows

Using mainboard GHI Electronics FEZSpider version 1.0
Program Started
writing range
previous 0
current 1280
writing range
previous 1280
current 1280
writing range

Is there anyway I know the correct distance I am reading? or How do I read the data? Appreciate your advice.

You need to use WriteRead method with two one byte buffers
First (“write”) buffer will have register number you want to read.
Second will have the returned byte after method is returned.

Oh and your “Ranging” command should look like this:

//Ranging
 buffer = new byte[] { 0x00, 0x51};
 int i = i2c.Write(buffer, 500);

Hi,

I have change my read to WriteRead with two buffers. But the result return the same. Do I need to relook into i2cRead() method. Thank for your time.


 void timer_Tick(GT.Timer timer)
        {
            Debug.Print("writing range");
                             
            //Ranging
            buffer = new byte[] { 0x70, 0x00, 0x51};
            int i = i2c.Write(buffer, 500);
            Thread.Sleep(readDelay);

            buffer = new byte[] { 0x70, 0x01};
            readbuffer = new byte[2];
            i2c.WriteRead(buffer, readbuffer, 500);

            i2cRead();     
        }

 void i2cRead()
        {
            int distance = readbuffer[0] << 8;
            distance |= readbuffer[1];
            previousRange = currentRange;
            currentRange = distance;
                                  
            Debug.Print("previous " + previousRange);
            Debug.Print("current  " + currentRange);
          
        }

Try this:

        void timer_Tick(GT.Timer timer)
        {
            Debug.Print("writing range");

            //Ranging
            buffer = new byte[] { 0x00, 0x51 };
            int i = i2c.Write(buffer, 500);
            Thread.Sleep(readDelay);

            buffer = new byte[] { 0x02 };
            readbuffer = new byte[1];
            i2c.WriteRead(buffer, readbuffer, 500);

            int distance = readbuffer[0] << 8;

            buffer[0] = 0x03;
            i2c.WriteRead(buffer, readbuffer, 500);

            distance |= readbuffer[0];

            Debug.Print("current  " + distance);
        }

Thank all. After I changed the command with two bytes as per your advice and read from register 0x02 I managed to get it works.
Advise me where I could share this tiny little code.

You can share here or on Codeshare.