Im want to get my Pi to communicate with the DUE over I2C.
I have several data bytes on my Due which I want to read out.
For example, the brightness sensor is on the same bus and is read like this:
i2cbus.read_byte_data(dev_address, DATAMSB)
where dev_adress is the adress of the sensor and DATAMSB is the Register the data is stored in.
How do you read a specific register from my Due?
I looked into the MasterReader example, but there is just a "Wire.onRequest(requestEvent)" which is called on a request.
Is the "selection of the register" a write to the Slave and I have to write my own function to send the selected register on the due?
Thanks!
EDIT:
would that work? Can I read the bus when the "requestEvent" is fired? Or will the "onReceive" Event start first and then the "requestEvent" ?
#include <Wire.h>
void setup()
{
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}
void loop()
{
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
char requestedbyte;
while(1 < Wire.available()) // loop through all but the last
{
requestedbyte = Wire.read(); // receive byte as a character
}
switch (requestedbyte) {
case 1:
//do something when requestedbyte equals 1
Wire.write("timer1");
break;
case 2:
//do something when requestedbyte equals 2
Wire.write("timer2");
break;
}
}
I'm not sure about the Due, but on the AVR models, the "onReceive" is when you get the data from the master. Then in "requestEvent" you respond. Basically the I2C bus has switched from "send to slave" mode to "receive from slave" mode. You would not read data in requestEvent.
I got it to work and here is my sketch. Pretty simple in retrospect.
//********** I2C functions **********//
void requestEvent()
{
switch (requestedbyte) {
case 2:
//do something when requestedbyte equals 1
Wire.write(2);
break;
case 3:
//do something when requestedbyte equals 2
Wire.write(3);
break;
}
}
void receiveEvent(int howMany)
{
while(Wire.available())
{
// read I2C value
requestedbyte = Wire.read();
}
}
}
The next problem I have is to send Integer. I tried to divide them into msb and lsb but this only works for values up to 255, it wraps back to 0 when I send 256.
Here is my Arduino Code:
void requestEvent()
{
uint8_t val = 260;
byte lsb = val & 0xff; // lsb = Least significant byte
byte msb = val >> 8; // msb = Most significant byte
byte buf [2] = { lsb, msb};
Wire.write(buf, sizeof buf);
}
And this is my Python (Raspberry Code)
def test(self,byte):
data = i2cbus.read_word_data(dev_address, byte)
return data
long read_word_data(int addr,char cmd)
is defined as 16bit reading
It works only with one Byte. When I change val to different values:
When I change it to 255, I get 255
When I change it to 256, I get 0
When I change it to 260, I get 4
When I change it to 1024, I get 0
When I change it to 1124, I get 100
Woops, I didnt see that, Thanks for the hint! It works now
Next thing is to also send negative numbers
I changed the code to the following
int16_t val = -1124;
int8_t lsb = val & 0xff; // lsb = Least significant byte
int8_t msb = val >> 8; // msb = Most significant byte
int8_t buf [2] = { lsb, msb};
Wire.write(buf, sizeof buf);
But I get the following error when compiling
Analog_Board.ino: In function 'void requestEvent()':
Analog_Board.ino:138:33: error: call of overloaded 'write(int8_t [2], unsigned int)' is ambiguous
Analog_Board.ino:138:33: note: candidates are:
In file included from Analog_Board.ino:2:0:
C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\libraries\Wire/Wire.h:48:17: note: virtual size_t TwoWire::write(const uint8_t*, size_t) <near match>
virtual size_t write(const uint8_t *, size_t);
^
C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\libraries\Wire/Wire.h:48:17: note: no known conversion for argument 1 from 'int8_t [2] {aka signed char [2]}' to 'const uint8_t* {aka const unsigned char*}'
In file included from C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\cores\arduino/Stream.h:26:0,
from C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\libraries\Wire/Wire.h:27,
from Analog_Board.ino:2:
C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\cores\arduino/Print.h:54:12: note: size_t Print::write(const char*, size_t) <near match>
size_t write(const char *buffer, size_t size) {
^
C:\Users\email_000\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\cores\arduino/Print.h:54:12: note: no known conversion for argument 1 from 'int8_t [2] {aka signed char [2]}' to 'const char*'
call of overloaded 'write(int8_t [2], unsigned int)' is ambiguous