In between the wire.beginTransmission() and the wire.endTransmission() calls, you can call wire.write() (or wire.send(), depending on IDE version) to send the slave additional data, that it can read to decide what to return.
It might be easier for the master to just request the slave to send all data, and have the slave return the time and message. The master can then sort out the time from the message.
You should send something and then request a response. ie.
Wire.beginTransmission(SLAVE);
Wire.send ("T"); // tell it you want the time
Wire.endTransmission();
// get response
Wire.requestFrom(SLAVE,8); // get 8 bytes back
// receive up to 8 bytes
if (Wire.available () >= 8)
{
rcv_bytes = Wire.receive();
// and so on for another 7
}
BUT, can you setup an arduino act as 2 I2C slaves?
What do you mean? A slave will respond to a request from any master, and you can have more than one master.
What do you mean? A slave will respond to a request from any master, and you can have more than one master.
I thought, I wouldn't be able to ask for 2 different kinds of data packages. But thanks to your example on your link (@Nick Gammon), I now understand you can have your master ask for specific data and let your slave answer accordingly.
Now reading that link, I came across this:
It isn't currently mentioned in the documentation, but the internal buffer used for I2C communications is 32 bytes. That means you can transfer a maximum of 32 bytes in one transaction.
It also isn't particularly clear, but the functions Wire.beginTransmission and Wire.send don't actually send anything. They simply prepare an internal buffer (with a maximum length of 32 bytes) for the transmission. This is so that the hardware can then clock out the data at a high rate. For example:
I have to send about 96 bytes, now what? do I have to split up? 3 x 32 ?
or maybe I could ask 3 times for M1, M2 and M3 and use buffer[97] where M1 is buffer[0 till 31], M2 is buffer[32-63] and M3 is buffer [64-95]
You can increase the buffer by changing a couple of spots in the library, but be warned that the library makes five copies of the buffer, so your overhead will go from 5 * 32 (160 bytes) to 5 * 96 (480) bytes. This is out of around 2048 bytes of RAM, assuming you have an Atmega328 or similar.
You could split up your messages into three parts, as you suggest. You might look into if you really need 96 bytes.
You might try some sort of compression scheme. For example, if the message is fairly fixed (ie. not completely free-form) then "fixed" words like "starting up" or "error" could be rendered with a dictionary lookup. For example, you might use bytes 0x80 to 0xFF to be dictionary words, giving you 128 of them.
You might also simply send a length byte first, and then as many packets as necessary to make up that length. So if the message changes, then the first byte could be the length (eg. 24) followed by 24 bytes of message. And then you only send a second packet if you exceed the limit (31 in this case because you need 1 for the length).
Thanks again. I'll be testing this after New Year.
The text messages are free submitted on a webpage form and have a max of 96 bytes. So they can be 1 till 96 bytes large. I do have an END of TEXT character that's been added by my code into the buffer. And bufferlength gets adapted accordingly. So this means bufferlength is automatically set to 5 (+1) when you type: HELLO (well you actually always do, but my buffer is filled with spaces, before it get's filled with the actual message, otherwise shorter text gets mangled up with a previous longer message)
Handy because, I really do know how big my buffer is at the moment I have to send it. This means I can make a piece of code that checks actual bufferlength and acts as indicated like:
if (bufferlenght < 32){
Wire.beginTransmission(4);
for (int i = 0; i < (bufferlength +1); i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
}
if (bufferlenght > 31 && bufferlenght < 64){
Wire.beginTransmission(4);
for (int i = 0; i < 32; i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
Wire.beginTransmission(4);
for (int i = 32; i < (bufferlength +1); i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
}
if (bufferlenght > 63){
Wire.beginTransmission(4);
for (int i = 0; i < 32; i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
Wire.beginTransmission(4);
for (int i = 32; i < 64; i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
Wire.beginTransmission(4);
for (int i = 64; i < (bufferlength +1); i++;){
Wire.write() = buffer[i];
}
Wire.endTransmission();
}
I'll only have to add a recognize byte as first. maybe I can add 'A' 'B' and 'C'. So the slave knows witch part it is receiving and can then put all parts back together in 1buffer ready to be shown on a DOT matrix