Jp3141
Well-known member
I am trying to get 2 Teensy 3.0s to a talk to each other via I2C. I have that working, but what I really want to do is have the Slave behave similarly to standard I2C slaves with addressable registers and values stored in them. At this stage I don't know if (a) my Master is wrong; b) my Slave is wrong, or c) the I2C Wire library doesn't support what I am trying to do. If anyone has example code, I'd appreciate seeing it.
Basically it's some type of issue with a Repeated Start symbol in the I2C link.
This is my Master Code:
and this is my Slave code:
Without the second Wire.endTransmission() in the Master, there are 4 groups of I2C 8-bit transmissions (as expected), and the Master does get the 'A' transmitted by the slave. But the Slave never gets the message (x) from the Master -- i.e. its receiveEvent is never triggered. I am using x to represent the register that I am asking the slave to respond with.
Conversely, when I enable that line, I do get a receiveEvent triggered, but there are an additional 2 8-bit I2C transmissions on the bus. I want the Slave to accurately reflect a real peripheral (e.g. like MMA8452Q), so want to get this fixed.
Does anyone have working code that is close to what I want ?
Basically it's some type of issue with a Repeated Start symbol in the I2C link.
This is my Master Code:
Code:
#define LEDPIN 13
#define TRIGGER 0
#define I2CAddress 4
#include <Wire.h>
void setup() {
pinMode(TRIGGER, OUTPUT);
pinMode(LEDPIN, OUTPUT);
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
Serial.println("Starting Master");
}
byte x = 0;
void loop() {
digitalWrite(LEDPIN, x % 2); //toggle LED
x++;
delay(500);
Wire.beginTransmission(I2CAddress); // transmit to device
digitalWrite(TRIGGER, HIGH);delayMicroseconds(1);digitalWrite(TRIGGER, LOW);
Wire.write(x); // sends register number
Serial.print("Asking for ");Serial.println(x);
// false here creates a Repeated Start symbol
Wire.endTransmission(false); // stop transmitting
digitalWrite(TRIGGER, HIGH);delayMicroseconds(1);digitalWrite(TRIGGER, LOW);
Wire.requestFrom(I2CAddress, 1); // request 1 byte
while (!Wire.available()); // wait...
char c = Wire.read(); // print the character
Serial.print(c); // print the character
digitalWrite(TRIGGER, HIGH);delayMicroseconds(1);digitalWrite(TRIGGER, LOW);
[B][I]// This line makes a difference, but is it correct ?
[/I][/B]Wire.endTransmission(); // stop transmitting
delay(300);
}
and this is my Slave code:
Code:
#define LEDPIN 13
#define I2CAddress 4
int i=0;
byte I2CRequest;
#include <Wire.h>
void setup() {
Wire.begin(I2CAddress); // join i2c bus with address
Wire.onReceive(receiveEvent); // register event
Wire.onRequest(requestEvent); // register event to send
Serial.begin(9600); // start serial for output
Serial.println("Starting Slave");
}
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) {
Serial.print("receive Event:");Serial.print(howMany);Serial.print(" ");
while(1 < Wire.available()) // loop through all but the last
Serial.print((char) Wire.read()); // receive byte as a character
Serial.print("!");
I2CRequest=Wire.read(); // print the integer
Serial.println((int) I2CRequest); // print the integer
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Serial.print("request"); Serial.println(i++);
Wire.write((byte) 'A'); // respond with 1 byte
}
Without the second Wire.endTransmission() in the Master, there are 4 groups of I2C 8-bit transmissions (as expected), and the Master does get the 'A' transmitted by the slave. But the Slave never gets the message (x) from the Master -- i.e. its receiveEvent is never triggered. I am using x to represent the register that I am asking the slave to respond with.
Conversely, when I enable that line, I do get a receiveEvent triggered, but there are an additional 2 8-bit I2C transmissions on the bus. I want the Slave to accurately reflect a real peripheral (e.g. like MMA8452Q), so want to get this fixed.
Does anyone have working code that is close to what I want ?