I2C Bus on PLC Arduino for industrial automation
Using the Inter-Integrated Circuit Bus (I2C)
11 February, 2020 by
I2C Bus on PLC Arduino for industrial automation
Boot & Work Corp. S.L., Support Team


        In this post we will see the I2C bus, one of the communications available in our entire range of Arduino-based industrial controllers.

        The I2C bus is of interest because, similar to what happened with the SPI bus, a large number of devices have an I2C connection, such as accelerometers, compasses, displays, etc.

        Resultado de imagen de I2C bus symbol


        In the sketch example we have used an M-Duino 21+, but all of the industrial Arduino PLCs range of Industrial Shields can also be used to perform the same example:

        - WiFi & Bluetooth Controller Family

        - 20 I/Os Controller Family 

        - Ethernet Controller Family

        - GPRS / GSM Controller Family

        I2C protocol

        This standard protocol (Inter-Integrated Circuit) was developed by Philips in 1982 for internal communication of electronic devices  in its articles. Subsequently it was gradually adopted by other manufacturers until it became a market standard.

        On the I2C bus, each device has an address, which is used to access the devices individually. This address can be set by hardware (in which case, frequently, the last 3 bits can be modified by jumpers or switches) or entirely by software.

        In general, each device connected to the bus must have a unique address. If we have several similar devices we will have to change the address or, if is not possible, implement a secondary bus.

        The I2C bus has a master-slave architecture. The master device initiates communication with the slaves, and can send or receive data from the slaves. Slaves cannot initiate communication (the master has to ask them), nor speak to each other directly.

        The I2C bus is synchronous. The master provides a clock signal, which keeps all devices on the bus synchronized. This eliminates the necessity for each device to have his own clock, to have to agree on a transmission speed and mechanisms to keep the transmission synchronized (as in UART).

        To be able to communicate with one only one data cable, the I2C bus uses a broad frame. The communication consists in: 

        - 7 bits to the address of the slave device with we want to communicate.

        - A remaining bit indicates if we want to send or receive information.

        - A validation bit.

        - One or more bytes are the data sent or received from the slave.

        - A validation bit.

        The I2C protocol provides for Pull-up resistors of the Vcc lines.

        Using soft resistors means that the rising edges of the signal will be less fast, which means that we can use lower speeds and lower communication distances. If we want to use higher speeds or transmission distances, we must physically put pull-up resistors between 1k and 4K7.

        Here you can find I2C resistors with DIN Rail adapter.

         Advantages and Disadvantages



        • It requires few cables.

        • It has mechanisms to verify that the signal has arrived correctly.


        • Its speed is medium-low.

        • It is not full duplex.

        • There is no verification system that tell us that the content of the message is correct.

        Typical I2C connections

        As we can see in this picture, the way to make the connection is just putting each SDA and SCL pins from the devices to general lines of the master. Here you can check our I2C Pull-Up Resistor with DIN Rail adapter.


        Every Industrial Shields programmable logic controller has the SCL and SDA pins. Check the User Manual of your industrial PLC controller version to see where this pins are located. Here you have the M-Duino 21+ controller arduino example:


        To use the Wire port on Arduino the IDE Standard provides the library "Wire.h" that contains the functions needed to control the integrated I2C hardware.

        Begin Function:

        Wire.begin();            // Starts the I2C bus as master or slave

         To request bytes from a slave device, used by the master.

        Wire.requestFrom();             // If true, sends a stop message after the request, releasing the I2C bus.

                                                              // If true, sends a restart message after the request, the bus won't be released, which prevents another master                                                             device from requesting between messages. This allows one master device to send multiple request while in                                                                             control.  The default value is true.

        It begins a transmission to the I2C slave device with the given address.

        Wire.beginTransmission();          // The 7-bit address of the device to transmit.

        It ends a transmission to a slave device that was begun by beginTransmission() transmits the bytes that were queued by write().

        Wire.endTransmission();        // If true, endTransmission() sends a stop message after transmission, releasing the I2C bus.
                                       // If false, endTransmission() sends a restart message after transmission. The bus won't be released, which
                                          prevents another master device from transmitting between messages. This allows one master device to send
                                          multiple transmissions while in control.

        It writes data from a slave device in response to a request from a master, or queues bytes for transmission from a master to slave device (in-between calls to beginTransmission() and endTransmission().

        Wire.write();                   // Will return the number of bytes written, though reading that number is optional.

        It returns the number of bytes available for retrieval with read(). This should be called on a master device after a call to requestFrom() or on a slave inside the onReceive() handler.

        Wire.available();                // Will return the number of bytes available for reading.

        It reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted from a master to a slave. read() inherits from the Stream utility class.

        Wire.read();                     // Will return the next byte received.

        This function modifies the clock frequency for I2C communication. I2C slave devices have no minimum working clock frequency, however 100KHz is usually the baseline.

        Wire.setClock();                 // ClockFrequency: the value of desired communication clock. 
                                            Accepted values are 100000(std mode) and 400000(fast mode).    
                                            Also some processors support 10000(low speed mode),1000000(fast mode plus) and 3400000(high speed mode).

        It registers a function to be called when a slave device receives a transmission from a master.

        Wire.onReceive(handler);          // handler: the function to be called when the slave receives data; this should take as parameter the number
                                             of bytes read from the master and returns nothing.

        It registers a function to be called when a master requests data from this slave device.

        Wire.onRequest(handler);           // handler: the function to be called, takes no parameters and returns nothing
        handler: the function to be called, takes no parameters and returns nothing.


        Take a look at the SPARTANS Range

        The Spartan family was created from the analysis of our top selling products.

        The sum of the most common configuration among our customers and the optimization of production processes results in a fully functional, robust and reliable equipment, designed for industrial environment and at a very low cost

        I2C Bus on PLC Arduino for industrial automation
        Boot & Work Corp. S.L., Support Team
        11 February, 2020
        Share this post

        Looking for your ideal PLC?

        Take a look at this product comparison with other industrial controllers Arduino-based.

        We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.

        Industrial PLC comparison >>

        Do you want more information?

        Just fill the form!

        Tell me more!