top of page

How to connect Arduino with IO Expander (PCF8574) using Matlab Simulink?

 

Last time, I've got PCF8574 device. It's IO expander that can be controlled by I2C protocole. It's very useful indeed, because it helps saving pins - instead of 8, you need only 2. So, what could I do with that thing? Of course connect it with Arduino and check how to implement it in Matlab Simulink.

 

PCF8574 is widely known IO Expander that can be controlled by I2C. Main documentation can be find here:

http://www.nxp.com/documents/data_sheet/PCF8574.pdf

 

Because of its simplicity in use, price and supporting libraries, you can find many examples how to use it with Arduino. I recommend this library: https://github.com/skywodd/pcf8574_arduino_library. However, it can be used in much simpler way, like below:

 

#include <Wire.h>

#define SLAVE_ADDRESS 0x20

 

void setup()

{

  Wire.begin(); // join i2c bus (address optional for master)

  Serial.begin(9600);  // start serial for output

}

 

byte x = 0;

 

void loop()

{

  Wire.beginTransmission(SLAVE_ADDRESS); // transmit to device #4

  Wire.write(0x0A);              // sends one byte  

  Wire.endTransmission();    // stop transmitting

  delay(500);

  

  Wire.beginTransmission(SLAVE_ADDRESS); // transmit to device #4

  Wire.write(0x05);              // sends one byte  

  Wire.endTransmission();    // stop transmitting

  delay(500);  

  

  Wire.requestFrom(SLAVE_ADDRESS, 1);    // request byte from slave device

 

  while(Wire.available())    // slave may send less than requested

  { 

    char c = Wire.read(); // receive a byte as character

    Serial.println((uint8_t)c);         // print the character

    

  }

 

}

 

My idea was to do the same but using Arduino Support from Simulink. Mainly, I took advante from my previous tutorial.

 

Arduino connected with IO Exapander:

 

Next step was to create model in Simulink. Due to being more clear, I've wirtten recipe where I'm describing step by step everything:

  1. It was necessary to copy Twi and Wire libraries to directory of Arduino Support from Simulink (C:\MATLAB\SupportPackages\R2013a\arduino-1.0\hardware\arduino\cores\arduino). 

  2. Add S-Function Builder to Simulink window and open it.

  3. Open Data Properties panel

  • Enter "1" in "Number of discrete states"

  • Select sample mode: "Discrete" and enter "1" in "Sample time value": 0.05

  • Add as inputs: I2C address and I2C input data; outputs: I2C output data. All data should be uint8 type.

  • In "Libraries" put:

 

#ifndef MATLAB_MEX_FILE

#define ARDUINO 100

#include <Arduino.h>

#include <Wire.h>

 

#endif

 

  • In "Outputs" put:

 

#ifndef MATLAB_MEX_FILE

if(xD[0] == 1)

{

        //I2C

        Wire.beginTransmission(SLAVE_ADDRESS[0]); // transmit to device #4

        Wire.write(DATA_INPUT[0]);              // sends one byte  

        Wire.endTransmission();    // stop transmitting

        

        Wire.requestFrom((uint8_t) SLAVE_ADDRESS[0], (uint8_t)1);    // request byte from slave device

        while(Wire.available())    // slave may send less than requested

        { 

            DATA_OUTPUT[0] = Wire.read(); // receive a byte as character

        }        

}

#endif

 

  • In "Dicrete Update" put:

 

if (xD[0]!=1)

{

    Wire.begin(); // join i2c bus (address optional for master)

    xD[0]=1;

}

 

  • Try to build. There can be an error: "Wire: undeclared indentifier". To solve it - at first - comment line Wire.begin(); in "Dicrete Update" and build it - error should disappear. Then, uncomment Wire.begin(); and rebuild it again. It is necesary, because in another case, Simulink will not compile model and will not create sfArduinoI2C.mexw64 file. 

  • Go to Project folder and change type of wrapper file from _wrapper.c to _wrapper.cpp

  • Open _wrapper.cpp file and add extern "C" in front of every wrapper function - in this case it will be sfArduinoI2C_Outputs_wrapper and sfArduinoI2C_Update_wrapper. Save changes.

  • Go to Simulink, select External mode and Build model. Have a fun!

 

During building wrapper functions, Simulink can generate broken definitions of functions. To solve it, it is necessary to update Arduino Support from Simulink from this site:

http://www.mathworks.com/support/bugreports/1006532

 

More info you can find here:

 

And more details you will watch here:

bottom of page