I've got boards up and running with i2C. I'm wanting to use use a master reader type program on an arduino mega and a slave sender on a 328 arduino. I'm sending out a request for 2 bytes and trying to receive them into 2 different variables but I cant split them up. it just prints gibberish. Does anybody know how to do this?
Master code:
#include <Wire.h>
int t;
boolean w;
void setup()
{
Wire.begin();
// join i2c bus (address optional for master)
Serial.begin(9600);
// start serial for output
}
void loop()
{
Wire.requestFrom(2,2); // request 1 byte from slave device #2
while(Wire.available()) // slave may send less than requested
{
t=Wire.receive();
Serial.print(t);
w = Wire.receive(); // receive a byte as character
//delay(100);
Serial.print(w); // print status
}
delay(500);
}
void receiveEvent(int howmany)
{
Wire.requestFrom(2,2); // request 2 bytes from slave device #2
while(Wire.available()<2)
{
int t=Wire.receive(); // receives t integer
}
while(Wire.available()<1)
{
boolean w=Wire.receive(); // receives w boolean
}
delay(10);
Serial.print(t);
Serial.print(w);
}
Slave Code:
#include <Wire.h>
int t;
boolean w;
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()
{
t=4;
w=0;
Wire.send(t); // respond with a message of 1 byte
Wire.send(w); // sends boolean w
}
Wire.requestFrom([glow]2[/glow],2); // request [glow]1[/glow] byte from slave device #2
while(Wire.available()) // slave may send less than requested
{
t=Wire.receive();
Serial.print(t);
w = Wire.receive(); // receive a byte as character
//delay(100);
Serial.print(w); // print status
}
Your comment notes that the slave may send less than the requested number of bytes. You test that there is at least one byte, then read two. The second is not available, so wire.receive() is returning a -1, which you are then trying to print. The print function defaults to printing characters, in the absence of any contrary directive. The -1, as a character, prints a y with the two dots above it.
while(Wire.available()<1)
{
boolean w=Wire.receive(); // receives w boolean
}
Receive every byte, and stuff it in a local variable that goes out of scope immediately, as long as there is nothing to receive. This makes no sense at all.
while(Wire.available()<2)
{
int t=Wire.receive(); // receives t integer
}
Receive every byte, and stuff it in a local variable that goes out of scope immediately, as long as there is less than two bytes to receive. This makes little sense.
You need to study the purpose of while loops, which are not the same as if tests, and you need to study scope.
oh so you're saying that my variables are only being staying declared in my while loop? I figured they would stay unless I changed them. I was just messing around with different wire.available combinations trying to find a way to split up the data I sent in over the bus.
Ok, here's what I've got. I've made some changes but still don't understand why it doesn't receive a 4 then a 1.
Slave sender:
#include <Wire.h>
int t;
int w;
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()
{
t=4;
w=1;
Wire.send(t);
Wire.send(w); // sends w
}
Master Receiver:
#include <Wire.h>
int t;
int w;
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
I'm not sure what you are referring to. You have to include the address of the slave device when you initialize and also when you request data from the slave. Other than that, I'm not sure where I would be missing any address information.
Ok, I got some help from a friend and feel like I'm getting much closer. I am now receiving a 4 for t and blank space for w. Maybe someone will see what is happening and causing me not to get a 0 for w.
Slave Sender:
#include <Wire.h>
int t;
boolean w;
byte dataOut[2];
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()
{
t=4;
w=0;
dataOut[0] = t;
dataOut[1] = w;
Wire.send(dataOut, 2);
}
Master Receiver:
#include <Wire.h>
int t,i;
boolean w;
byte dataIn[2];
void setup()
{
Wire.begin();
// join i2c bus (address optional for master)
Serial.begin(9600);
// start serial for output
}
void loop()
{
receiveEvent();
delay(500);
}
void receiveEvent()
{
Wire.requestFrom(2,2); // request 2 bytes from slave device #2
while(Wire.available())
{
for(i=0;i<=1;i++)
{
dataIn[i] = Wire.receive();
}
}
t = dataIn[0];
w = dataIn[1];
Serial.print(t);
delay(1000);
Serial.print(w);
}