Browse our Blog. You will find multiple applications, solutions, code examples. Navigate using the tag cloud or search using specific criteris

I2C Bus on PLC Arduino for industrial automation

Using the Inter-Integrated Circuit Bus (I2C)

         Introduction


        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

        Requirements


        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

                     

        Advantages:

        • It requires few cables.

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

        Disadvantages: 

        • 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.


        Hardware

        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:




        Software

        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.



         

        Do you want more information?

        Open Source technology allows you to develop your installations.

        Just fill the form and we will contact you as soon as we can.

        Send