No announcement yet.

I2C communication with Arduino Slave problems

  • Filter
  • Time
  • Show
Clear All
new posts

  • I2C communication with Arduino Slave problems

    Hi there,

    I have an arduino which i am using as an I2C slave for the uVGAIII because it is faster than Serial. Using the uVGAIII as a master, i can easily send information to the arduino, but i cannot seem to send data back.

    using the I2C_Read() command it returns 0 when the arduino is on and sending, if i put the arduino into reset the output from I2C_Read() returns 255. i can only get those two number despite sending an incrementing value from the arduino using Wire.write(x); (where x is an incrementing variable)

    Am i using the I2C library on the uVGAIII wrong?

    any help would be great thanks!

  • #2
    On the Arduino, are you definitely starting it as an I2C slave (i.e. providing an address to the 'begin')?

    From a quick read of the Arduino Wire library it is not clear how a slave sends data to a master, the documentation says 'begintransmission' is for talking to a slave.

    Perhaps the example with two arduinos talking to each other makes it clearer, I haven't looked.


    • #3
      thanks for the reply, the arduino code is a modified example of slave transmit code. it works fine with another arduino and receives data from the uVGAIII fine.

      when the arduino requests data from a salve there is a single command which includes the address of the slave and the amount of information it expects to receive. I am not sure how this is actually physically done by the arduino or what the arduino is sending back, but either way the equivalent on the uVGAIII doesn't seem to be doing anything predictable.

      from what i understand of I2c is that it is a hardware system like serial in which it stores information sent even while the microprocessor is doing other things, then the microprocessor can come and read the information when it is ready but reading using the uVGAIII returns only 255 or 0 and never anything else.

      here is the code running on the slave arduino

      #include <Wire.h>
      int x = 0;
      void setup()
        pinMode(13, OUTPUT);  
      void loop()
      void receiveEvent(int howMany)
        while(0 < Wire.available())
          int c =; // receive a byte as character
          Serial.println(c);         // print the character
          if (c>250)digitalWrite(13,HIGH);
          if (c<10)digitalWrite(13,LOW);


      • #4
        An I2C master is responsible for all clocking, it only generates clocks when it is sending or receiving something.

        Hence an I2C slave cannot truly 'write', it can only respond when the master generates the clock for it to respond.

        If you had a scope it should be easy to see if the Arduino is operating in the correct manner for a slave.

        But really whilst I2C has a higher clock speed, I feel serial makes up for it with the ability to have TX and RX buffers and the inherently lower overheads.


        • #5
          ok so what is it in the I2C protocol that sets the master up to listen to the slave? if the master can request information from the slave it must send a message and wait for a reply? I have got the master sending messages but it never seems to wait for a reply. surely there must be a specific command in the library to receive information from a slave? in the arduino library the master sends a message with the slave address and buffer size of information it is requesting, then it waits for information to come back. but the 4D library seems to only have commands for sending, sending once with the slave address and then using the same command to send a register address, but nothing to specify that it is expecting a reply from the slave.

          doesn't I2C also have buffers? at least the master has a buffer right?

          Serial is really nice to work with, i don't think i have ever had problems with it, but it consumes a serial port, (of which the arduino only has one) and is overkill for what i need. I want the arduino to collect information and have that information ready when the master polls it. the arduino will not really be talking to the master, the master will simply be scanning it for data. currently i have the uVGAIII sending messages to the Arduino at 1Mhz speed, which is amazingly fast and exactly the kind of speed i want. the whole system will lag in other areas and i am trying to reduce the lag as much as possible.

          thanks for your help


          • #6
            From the master's perspective the first byte written after the 'start' (or 'restart') is the address of the device to be addressed, The R/W bit in that address specifies the direction of the information flow. That is why Picaso only needs a single write command, it is the position in the stream that indicates 'data' or 'address'. As the master a write generates both the clock and the data to be output.

            When an I2C_Read() is done, Picaso generates the clock and reads the SDA pin at the appropriate time to detect the byte being written by the slave.

            Due to the ability to ACK and NAK every byte generally there isn't much use for buffers.

            But the slave must have a buffer as it needs the byte ready to be sent, assuming it needs to respond to the Master's 'read'.

            (The above is probably a very simplistic description)

            That's why I wonder if 'wire.write' is correct as I think that is the 'master' type write, not the slave.

            Actual the doco implies that the slave needs a Wire.onRequest handler to respond to reads from the master.



            • #7
              ah ok, thanks that is starting to make a bit more sense, so maybe the command i am sending is wrong and doesn't contain the right direction flow information?

              with the arduino i already have the reply linked to an interrupt request so that is fine.

              i think i have to work out what message i need to send from the Picaso so that it also listens for information from the arduino


              • #8
                The correct command is I2C_Read(). I'll see if someone can create an example.


                • #9
                  ok sorry i am not sure i understand. so when using the command I2C_Read() the master will send a message and the slave will reply? because if that is true then how do you use that command to specify a memory address?

                  if the command is I2C_Write("byte"); then first of all the byte must be the right byte for the Picaso to expect a reply, but also how do you then read the byte if the byte is sent by the slave as soon as it receives? surely that means that the master has a buffer where it stores things received from the slave so that the information can be checked when I2C_Read() is called?

                  I am assuming that whatever byte is sent must include both the address of the slave, the memory register address, and the information flow direction, is that right?

                  thanks again for your help, it feels like i am almost there,


                  • #10
                    The address of the slave is the first byte written after the start (or restart) every slave sees this and this ignores or pays attention to further reads or writes until the next start (or restart).

                    Thus when the master does a further read or write the relevant slave knows that it is being addressed and responds accordingly.

                    When the master does a read the clock is generated and the data is read 'in sync' with those clock pulses, hence the master doesn't need to buffer anything as the slave responds as part of the read issued by the master


                    • #11
                      i think i understand. so basically the start command will set which slave to communicate with, and everything after the start command will between that particular slave and the master, then a I2C_Write("byte"); is sent to specify which register to read from, and then a I2C_Read() command will allow the slave to send a reply.

                      so if that is true then my problem lies with when the arduino sends its response. if it is simply sending information on the interrupt then that means it will send its reply when it receives the register byte and not when the I2C_Read() command opens a reply channel.

                      if that is true then that explains why i would always get a 0 reply from the arduino, because the arduino has already sent its information before the master had chance to open a conduit.

                      I assume that adding a delay to the arduino wouldn't work either, because its all about the arduino being in sync with the master...


                      • #12
                        Hi NeX,

                        Here is a basic example. Please try and see if it works for you. Also, below is a link to a tutorial on the I2C protocol that you might find helpful.


                        Hope this helps and regards.
                        Attached Files


                        • #13
                          you guys are great! that worked perfectly! now i have something to work with. thanks for all your help, i will try and post up some simple code so other people can use this too, thanks again!