11 years, 1 month ago.

I2C master and slave

Hello.

I am new to mbed and I am trying to send data between two mbeds using i2c, and i am very confused as to what the arguments of i2c.write mean. Can someone please clear it up for me thanks. This is what i have tried and i am not getting the results i want.

/media/uploads/hauwa_m/_scaled_screen_shot_2013-03-21_at_6.35.10_pm.png

/media/uploads/hauwa_m/screen_shot_2013-03-21_at_6.36.36_pm.png

Thank you.

4 Answers

11 years, 1 month ago.

I think write expects the address of the data. So &x i.o. x

11 years, 1 month ago.

Aditionally you don't need to send start and stop messages if you use that write command, they are sent automatically.

Hauwa Lawan
poster
11 years, 1 month ago.

Okay. Sorry I'm still a bit confused. So the first parameter is the address, the second is the data, and what exactly is the third?

the number of bytes in the data

posted by Ad van der Weiden 22 Mar 2013

Hello again. Im sorry im very bad at programming.I have spent the last three hours trying to understand this, but i am still not sure. This is what i understand so far.

You need to define the slava address. Then you need to create am array if char for the data. The first element in the array is the register address and the rest is the data you want to send. How do i know what the register address is?

posted by Hauwa Lawan 22 Mar 2013

That is generally the way you communicate with I2C sensors, but if you just want to send data between two mbeds that isn't required, so it is just the data in that array.

posted by Erik - 22 Mar 2013

Thanks Erik. This is what i have tried, but i get nothing being printed.

/media/uploads/hauwa_m/screen_shot_2013-03-22_at_4.54.47_pm.png

posted by Hauwa Lawan 22 Mar 2013

You can just copy the code and put <<code>> <</code>> around it, that is alot easier for you and for us.

Anyway you say nothing is printed, do you mean zeros are printed, or really nothing? If nothing, make sure you got serial drivers for your mbed installed (each mbed needs them seperately installed). But that problem would be unrelated to I2C.

If you mean it prints only zeros, that is good, that means the other mbed received your data and acknowledged it.

posted by Erik - 22 Mar 2013

Thank you Erik. When I try writing only the data to the i2c bus like this,

i2c.write(0x40);

i do get zeros being printed out. However, when i try to write to a particular address,

i2c.write(address, data, 1);

i get nothing at all being printed out. I'm not sure what the problem is.

posted by Hauwa Lawan 22 Mar 2013

In the first case a zero isn't good, that means no ACK was received, with that one you want a one.

Weird nothing is printed in the second case, I would try removing the connections to your second mbed and trying if it works with only pull-up resistors (then it should return something non-zero).

posted by Erik - 22 Mar 2013

I tried it with only the pull up resistors, and i get zeros for writing only data, and 32 for writing to an address. Im guessing that means no ACK was received still. Could it be the value for the pull up resistors? I am currently using 10k resistors.

posted by Hauwa Lawan 22 Mar 2013

While that is a bit higher than recommended, I don't really expect problems from it. You could try something like 2k if it is easy to switch just to be sure.

Then I would try writing to it with the second mbed connected, but just running a blinking led program or something similar.

posted by Erik - 22 Mar 2013

Thank You very much for all your help Erik. I'll try that.

posted by Hauwa Lawan 22 Mar 2013

I have changed the resistors and tried almost everything, but i still cant get this i2c thing working. The code i have is pretty simple and i really don't understand what the problem is.

#include "mbed.h"

I2C    i2c( p9, p10 );        // sda, scl

int main()
{
    char    data[3];
    int x;
    while(1) {
        data[0]   = 0x16;
        data[1]   = 0x55;
        data[2]   = 0x55;

        x = i2c.write( 0xC0,data,1);
        printf("%d\n",x);
    }
}

In the serial monitor, i still get 32 being printed out. When i try this

i2c.write(0x45);

i get 0 printed out.

So far, i am only checking from the master end.

ANy help at all would be appreciated. Thanks so much.

posted by Hauwa Lawan 27 Mar 2013

Well at least it still prints. But what is running on your second mbed now? If it is just a blinking LED program that is correct.

posted by Erik - 27 Mar 2013

Yes it is just a blinking LED on the slave.

posted by Hauwa Lawan 27 Mar 2013
11 years, 1 month ago.

This is my slave program. which works,

#include "mbed.h"

BusOut myled(LED1,LED2,LED3,LED4);
BusIn  MyInPort (p17,p18,p19,p20);
//DigitalOut Led4 (LED4);

I2CSlave slave(p28, p27);
SPI spi(p5, p6, p7); // mosi, miso, sclk
DigitalOut cs(p8);



 int K = 0xaa;

 int main() 
 {
     char buf[10];
     char msg[] = "Slave!";
     char Tmsg [16];
     
     spi.format(16,3);

     
     printf("\r\n>> Start .. Slave .. \r\n");
     
     myled = 0xff;

    slave.address(0xA0);
     
     while (1) 
     {
         int i = slave.receive();
         switch (i) 
         {
             case I2CSlave::ReadAddressed:
             
                // read MAX6675
                
                cs = 0;
                int Temp = spi.write(0);
                cs = 1;
                if (Temp & 4) Temp = (9876 * 32);
                Temp = (Temp >> 3);
                
                float fTemp = Temp;
                fTemp = fTemp/4;
                
                sprintf (Tmsg,"%3.2f",fTemp);
                
                //printf ("Temp .. %04d  %s  \r\n", Temp,buf);             
             
                 slave.write(Tmsg, strlen(Tmsg) + 1); // Includes null char
                 
                 printf ("Temp .. %04d  %s  \r\n", Temp>>2,Tmsg);             
                 
                 break;
                 
             case I2CSlave::WriteGeneral:
                 slave.read(buf, 10);
                 printf("Read G: %s\r\n", buf);
                 break;
                 
             case I2CSlave::WriteAddressed:
                 slave.read(buf, 10);
                 printf("Read A: %s\r\n", buf);
                 break;
         } // switch ..
         
         for(int i = 0; i < 10; i++) 
         {
            buf[i] = 0;    // Clear buffer
            myled = MyInPort;
         }
     }
 }


when the master preforms a read,
the slave, gets a reading from a temperature sensor (on SPI Bus)
and then replyes to master, with a 'text' formatted respons.

Note: there is very little time for the slave to do stuff ,
so I would recomend that the response is already avalable.

Hope this helps,

Ceri

Can you post the SPI Master point of view to complement / understand the example? Thanks.

posted by JULIAN RODRIGUEZ 29 Mar 2013