MATLAB Answers

Simulink, Arduino as slave-receiver in I2C

7 views (last 30 days)
Daniel Gelman
Daniel Gelman on 12 Aug 2020
Commented: David Goodmanson on 12 Aug 2020
I have 2 Arduinos:
One Arduino MEGA is master-writer in an I2C bus, providing data at ~20 Hz.
The other is an Arduino DUE in a slave-receiver configuration, meaning it will read incoming bytes of data as soon as they are sent by the master-writer. Everything is in working order, I vereified it using standard Arduino IDE programming.
I would now like to replicate the DUE receiving data in Simulink. Simulink has a Master Read block, but it seems that it polls the slave to receive data - I do not want this. I want the DUE in a slave-receiver configuration.
Is there a way to do this in Simulink or to use S-functions? In the context of S-functions, I would like to implement the slave-reciever code shown below, but it uses a receiveEvent() ISR that I dont know how to implement in the s-function builder.
#include <Wire.h>
void setup()
{
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop()
{
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
Thank you

Answers (1)

Walter Roberson
Walter Roberson on 12 Aug 2020
Are you wanting Simulink to emulate receiving data for modeling purposes? If so is there a predetermined queue of data that is to be delivered as quickly as feasible? Is there a predetermined array of time signals with the block to emulate receiving a value at the preset times? Are bytes to be generated randomly according to some distribution? Is there a signal from "somewhere" that the block should emulate having been delivered by wire? Is there a udp connection that will be used as the real carrier and then the block should emulate having received the data by wire? Is there a Stateflow chart that should be used to generate bytes to be emulated as having been read by wire?
... Because remember that your PC is unlikely to have an accessible physical i2c that Simulink could be reading real wire bytes from.
Oddly enough, it turns out that a lot of common graphics cards have a built-in i2c that can be connected to with appropriate header. Common enough that Windows has an API to make it possible to read i2c from such a header, so a driver could be written for it. I have not figured out yet what the actual use case is for those i2c, but you might actually have an i2c physical receiver on the graphics card. (Just like how nearly all laptop and desktop Mac over the decade have a built-in infrared receiver that I have never seen anyone actually use...). It would probably require creating a custom Simulink block to use.
  1 Comment
David Goodmanson
David Goodmanson on 12 Aug 2020
Hello Walter,
You are really getting close! Maybe tomorrow?

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!