After a long time ago i was starting again with my arduino and I2C
My idea is that i want a slave arduino that holds an array of multiple names and that needs to go to the master arduino where is should get back in an array to get placed on the right LCD
I did want to send from the master which array i want but that didnt work as i wanted.
so i did write a send command from master to set a buffer ready on the slave side and after that i ask the slave to give me the info in the buffer.
i get stuck each time when i try to send and receive the multiple array's
Maybe someone sees directly where it goes wrong?
Slave arduino
char* ding[5] = {"", "Dit is display 1" , "Dit is display 2" , "Dit is display 3" , "Dit is display 4"};
char dataIn[16] = "";
#include <Wire.h>
void setup() {
Wire.begin(1); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
Serial.println("hoi");
}
void loop() {
delay(100);
}
void requestEvent() {
Wire.write(dataIn);
}
void receiveEvent(int howMany) {
while (1 < Wire.available()) {
char c = Wire.read();
}
int x = Wire.read();
strcpy(dataIn, ding[x]);
}
Master Arduino
#include <Wire.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
char dataIn[16] = "";
char* Receive[9] = {" ", " ", " ", " ", " ", " ", " ", " ", " "};
#include <Wire.h>
void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
//SendToDisplay();
}
void loop() {
// SendToDisplay();
ShowArray();
delay(1000);
}
void ShowArray() {
GetText(3);
GetText(2);
Serial.println(Receive[0]);
Serial.println(Receive[1]);
Serial.println(Receive[2]);
Serial.println(Receive[3]);
Serial.println(Receive[4]);
}
int GetText(int x) {
Wire.beginTransmission(1);
Wire.write(x);
Wire.endTransmission();
Wire.begin();
Wire.requestFrom(1, 16); // request 6 bytes from slave device #8
for (byte i = 0; i < 16 && Wire.available(); ++i)
{
dataIn[i] = Wire.read();
}
Wire.endTransmission();
Receive[x] = dataIn;
return dataIn;
delay(1000);
}
this is what i get from the serial monitor on the master
Dit is display 2Dit is display 2
Dit is display 2Dit is display 2
Dit is display 2Dit is display 2
Dit is display 2Dit is display 2
Dit is display 2Dit is display 2
Dit is display 2Dit is display 2
Your Master (MEGA) and Slave (UNO) codes are simplified slightly. Now, the Master requests the Slave at every 1-sec interval to send the item-3 and item-2 of the array of the arrays. You may consult these codes to get rid of your confusion. (It is recommended to use values 0x08 to 0x7F as slave address.)
=================
Dit is display 2
Dit is display 2
=================
maybe good to know what the idea should be.
the array's should be placed in that way because the LCD on I2C should grab there info for the display out of that array.
it does look like he just copy the last to both array places..
Wire.requestFrom(1, 16); // request 6 bytes from slave device #8
That is NOT what that code does!
for (byte i = 0; i < 16; ++i)
{
dataIn[i] = Wire.read();
}
Read 16 bytes, regardless of whether or not ANY bytes are available. Does that REALLY seem like a good idea?
After the execution of Wire.requestFrom(1, 16); instruction, the Master brings 16-byte data (n bytes from the Slave and 16-n bytes are always 0xFFs if Slave has less than 16-byte to deliver) in its local buffer from the Slave buffer. The execution of Wire.available() instruction always returns 16 (the 2nd argument). Under this circumstance, is it really necessary to check the status of 'data availability' by executing the instruction Wire.available().
Wire.requestFrom(1, 16); // request [s]6[/s] 16 bytes from slave device [s]#8[/s] #1
Serial.println(Wire.available()); //shows: 16
for (byte i = 0; i < 16; ++i)
{
dataIn[i] = Wire.read();
}
After the execution of Wire.requestFrom(1, 16); instruction, the Master brings 16-byte data (n bytes from the Slave and 16-n bytes are always 0xFFs if Slave has less than 16-byte to deliver) in its local buffer from the Slave buffer.
How soon after? Are there guaranteed to be 16 bytes to be read as soon as the requestFrom() method ends?
PaulS:
How soon after? Are there guaranteed to be 16 bytes to be read as soon as the requestFrom() method ends?
It is always guaranteed if the working principle of the requestFrom() method stands as:
1. The Wire.requestFrom(slaveAddress, 16); instruction asserts the slaveAddress and keeps waiting for the ACK signal which has not yet been generated by the Slave. In this sense, the Wire.requestFrom() is a looping instruction.
2. The Slave goes to the void sendEvent(int howmany) routine (ISR) and stores n-byte data (as has been designed by the programmer) in its local buffer by executing Wire.write() instructions.
3. The Slave returns to the calling program (the Main Line Program) and generates the ACK signal.
4. The Master senses/samples the ACK signal, and it brings 16-byte ( n bytes from the Slave and 16-n bytes are always 0xFFs if Slave has less than 16-byte to deliver) data into its buffer from the buffer of the Slave.
5. After the execution of Step-4, the Master executes the next instructions that follows the requestFrom() method.
6. Therefore, the 16-byte is ready there in the buffer of the Master whether we execute this byte n = Wire.available(); instruction or not?
Wire.requestFrom(1, 16); // request 6 bytes from slave device #8
byte n = Wire.available();
Serial.println(n); //shows: 16
for (byte i = 0; i < 16; ++i)
{
dataIn[i] = Wire.read();
}
Thanks for your response and did some reading about it.
but i need to say, i think im a newb:(
Could you maybe give me a bit of help in the right direction.
Problem is i need to receive the right information and place it in the array so i can later use the array for the next futher programming.
need to receive the 4x text from the i2c slave to the master and the master needs to place it in 4 diffrent places in the array of maybe something else to use the text later to transmit that texts to the diffrent i2c displays.
for (byte i = 0; i < 16; ++i)
{
dataIn[i] = Wire.read();
}
Here, you are reading 16 bytes from the device, and storing the data in an array.
Receive[x] = dataIn;
Here, you are making the xth element of an array point to that array.
GetText(1);
GetText(3);
Once this code is done executing, Receive[ 1 ] and Receive[ 3 ] point to the SAME global array. This is like writing, on a card, that the current US president lives at 1600 Pennsylvania Ave., twice.
No one would realistically expect these two statements to print different things. That would be like reading the two cards, and finding the Nixon and Trump live at the same place. No surprise there, even though one is dead and the other only brain-dead.
Try again to explain what you are trying to do, in English, NOT in code.
I suspect, though, that you want to COPY the data in dataIn to two (or more) different places. That will NOT be done using pointers. You MUST allocate space for all the copies.