Send/Read more variables using I2C (SOLVED!!!)

I have a problem when I try to read from a slave.

How could I send more values from a slave and receive correctly in the master?
Now I can read only receive just ONE value. :roll_eyes:
Where is the problem?

lets see your code

Here it is:
Slave:

#include <Wire.h>

void setup()
{
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}
byte x=5;
byte y=6;
byte z=7;
void loop()
{
delay(100);
}

void requestEvent()
{
Wire.write(x);

Wire.write(y);
Wire.write(z);
}

Master:
#include <Wire.h>

void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}

void loop()
{
Wire.requestFrom(2, 3);

byte a = Wire.read();
Serial.print(a);
byte b = Wire.read();
Serial.print(b);
byte c = Wire.read();
Serial.print(c);

delay(500);
}

Anyone... pleeeeease! :blush:

slave

#include <Wire.h> //starts the library
#define LED_2 11
int x = 0; // give a value to the varable to be change with I/Os
int y = 0;

void setup() {
 // Serial.begin(9600); // used to debug
  Wire.begin(2); // Start I2C Bus as a Slave (Device Number 9)
  Wire.onReceive(receiveEvent); // register event
   pinMode(LED_2, OUTPUT);
    digitalWrite(LED_2, LOW);
}

void loop ()
{
    if (x == 1) {
    digitalWrite(LED_2, HIGH);
    delay(200);
    digitalWrite(LED_2, LOW);
    delay(200);
  }
}

void receiveEvent(int howMany)
{
   x = Wire.read();    // receive byte as an integer
 y = Wire.read();    // receive byte as an integer
}

Master

#include <Wire.h> //starts the library
int INRead = A0;
int x = 0; // give a value to the varable to be change with I/Os
int y = 0;

void setup() {

  pinMode(13, OUTPUT);
  pinMode(INRead, INPUT);

  Wire.begin(1);
}
void loop(){
{
  x = analogRead(INRead);
}

  Wire.beginTransmission(2);
  Wire.write(x);

  Wire.endTransmission();
}

I just wrote this - so take it for whats its worth :slight_smile:
There is alot left out ,, youll have to add your own code from there

I've done this part. It works good (for now).

My problem is when I want to read FROM a slave (the slave sends data to the master) MORE than 1 variable!!!! I don't know how to build the code to read all the variables is sending the slave. With 1 variable, works; when I send more than 1, it (the master) reads just the last one. How do I solve this??

Thank you!

change your byte to int

Nope! Doesn't works!
This is the code for MASTER:

#include <Wire.h>

void setup()
{
Wire.begin();
Serial.begin(9600);
}

int a;
int b;

void loop()
{
Wire.requestFrom(2, 2);

while(Wire.available())
{
a=Wire.read();
Serial.println(a);
b=Wire.read();
Serial.println (b);
}

delay(500);
}


And this is the code for SLAVE:

#include <Wire.h>

void setup()
{
Wire.begin(2);
Wire.onRequest(requestEvent);
}
int x=100;
int y=80;

void loop()
{
delay(100);
}

void requestEvent()
{
Wire.write(x);
Wire.write(y);

}

And this is what I receive:

255
80
255
80
255
80
.... and so on

:frowning:

#include <Wire.h>

void setup()
{
  Wire.begin(2);        
  Serial.begin(9600);
Wire.onReceive(receiveEvent); // register event  
}

int a = 0;
int b = 0;

void loop()
{
}
 // Wire.requestFrom(2, 2);    
void receiveEvent(int howMany)
  //while(Wire.available())    
  { 
    a=Wire.read(); 
    Serial.println(a);    
    b=Wire.read();
    Serial.println (b); 
 delay(500);   
  }
#include <Wire.h>

void setup()
{
  Wire.begin(2);                
 // Wire.onRequest(requestEvent); 
}
int x=100;
int y=80;

void loop()
{
  delay(100);



//void requestEvent()
Wire.beginTransmission(2);
  Wire.write(x); 
  Wire.write(y);
 Wire.endTransmission();                      
}

Sorry i modded your code

But this code is for Master sender
This is not my problem! My problem is for MASTER READER / SLAVE SENDER with more variables. With one, yes it works.
Anyway, thank you very much for your interest in my problem.

So, anyone knows how to send more than 1 variable from a slave (slave - sender) to a master (master - reader) via I2C???

so im guessing you didnt try it ,, sence its sending 100 and 80 is that not what u wanted ?

Yes, is that I want. But in the code above, you send from a MASTER to a SLAVE. What I want is to send from a SLAVE to a MASTER. I want to send to the master the state of some pins of the slave.
I hope that you did understood me. :slight_smile: If not, please tell me where I'm not clear to intent to explain it because I'm stuck in this problem and I need a solution quite quickly.
Thanks a lot! :slight_smile:

lol you can call the Drunk1 and Drunk2 for all tha it matters ,,, Just put the code the the one your reading data from as master , and the other as as slave,, but Calling the units what ever you want has nothign to do with it...... its all about the code of who is doing what.
But if you need to read all about I2C Gammon Forum : Electronics : Microprocessors : Buttons, I2C, interrupts and port-expanders to get enough info , here is the link and since ive already done this Road Pins Are there ever enough - #12 by system - IDE 1.x - Arduino Forum Good luck

But in my case, the master needs to "write" and to "read" too. It reads from the slave the state of some pins and in function of the state of this pins it sends back to the slave what other pins needs to drive up!
This is why I can't swap the code. I'll be in the same situation.
Thank you for everything!

PS If you have any idea, just shoot and I'll try it because I'm out of any idea and I don't find anything that could help me.

hm - this one may require some more thought, or some one that has ran that required setup , im only controlling a solar array a lcd and a Relay bank VIA a Ir remote, with two UNOs ,sounds like your trying to do more than that :slight_smile:

:slight_smile:

I want to build a kind of PLC to control a industrial machine. In some cases I'll use more than 3 Atmega328.
I hope that somebody who knows more about programming an I2C protocol will see my post and have the kindness to explain me how should I do.
Thank you very much Woody! :slight_smile:

Look what I've found:

Warning - because of the way the Wire library is written, the requestEvent handler can only (successfully) do a single send. The reason is that each attempt to send a reply resets the internal buffer back to the start. Thus in your requestEvent, if you need to send multiple bytes, you should assemble them into a temporary buffer, and then send that buffer using a single Wire.send. For example:

void requestEvent()
{

byte buf [2];

buf [ 0 ] = 42;
buf [ 1 ] = 55;

Wire.send(buf, sizeof buf); // send 2-byte response
}

For UNO Wire.send became Wire.write.
I've tried the example given and didn't work! So... it's impossible (I think)!

SOLVED!!!

So, to transmit more than 1 value via I2C, I'm doing like this:
I give to all the chips an address (Wire.begin(address)); when I want to send something, I use Wire.beginTransmission(address). I build a "void receiveEvent(int howMany)" in each of the chips. Now the question I had was "how could the receiver knows who is sending data". It's simple: every time when I send something, first I send a "address". Than I use the "if" function (in the receiver) to recognize the sender.
That's all! It functions just GREAT!

If someone else has an alternate idea, post it. Could be better than mine.

Hi. Could you post and example about how you did?