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:
-
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).
-
Add S-Function Builder to Simulink window and open it.
-
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:
-
http://www.mathworks.se/hardware-support/arduino-simulink.html
-
http://www.mathworks.com/matlabcentral/fileexchange/39354-device-drivers
And more details you will watch here: