i2c question

Hiya,

dont know if this is the right place to ask but i guess.

I've got a question about the i2c protocol.
My idea,

I want to hold a master arduino which controls multiple slaves.
The master is communicating with the World Wide Web through a password protected website.
From the website i do click a relais and then the master must communicate with the slave device with that relais to toggle.

But i cant really find out if its possible to send a request to a slave adress with a extra data so it just toggle 1 relais instead of all the relais who are on the arduino..

Is that possible and could maybe someone tell me how., or knows a way to do it on a another way.

Hopefully someone could help me.

Greetings,

Spikie

this might help to get started - http://arduino.cc/en/Tutorial/MasterReader -

Thanks for your response.
But thats what my problem is..

If you start with the master a i2c request to a number ( slave id) then the slave just do a programmed loop..
What i want is that i send the slave id + a extra command and that the slave reads that he is that ID and he reacts to the extra command so a relais 1 goes in.

example:
master got 3 slaves on the line.
Slave 1 got 3 relais on his atmega.

Master says Slave ID 1 relais 2.
Slave 1 : digitalWrite( 3, HIGH);

and the rest of the relais need to be on the state they were.

Master says Slave ID 2 Relais 1
Slave 2 digitalWrite(1,HIGH);

and i really cant find the way i give that extra command and the slave the read of an extra command.

Greets,

Spikie

OK I got it,
needs some checking to do
BRB

// not tested but this is how I would start it, you should get the idea.

#include <Wire.h>

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

void loop()
{
  Wire.beginTransmission(2);
  Wire.write(10);  // command code  or other command.
  int rv = Wire.endTransmission();

  while(Wire.available())    // slave may send less than requested
  { 
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }
  delay(5000);
}

// also not tested :slight_smile:

void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
}

void loop()
{
  while(Wire.available() == 0);  // wait for request
  int command = Wire.read();
  switch(command)
  {
     case 10: // handle command 10
      Wire.write(sensor.value);
      break;
     case 11: // handle command 11
      RelayON();
      Wire.write(relay.state);
      break;
     case 12: 
      RelayOFF();
      Wire.write(relay.state);
      break;
    default:
      break;
  }
}

You just need to setup up your own communication protocol. I would just send it a byte with which relays to turn on as individual bits.

robtillaart:
OK I got it,
needs some checking to do
BRB

// not tested but this is how I would start it, you should get the idea.

#include <Wire.h>

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

void loop()
{
  Wire.beginTransmission(2);
  Wire.write(10);  // command code  or other command.
  int rv = Wire.endTransmission();

while(Wire.available())    // slave may send less than requested
  {
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }
  delay(5000);
}




// also not tested :)


void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
}

void loop()
{
  while(Wire.available() == 0);  // wait for request
  int command = Wire.read();
  switch(command)
  {
     case 10: // handle command 10
      Wire.write(sensor.value);
      break;
     case 11: // handle command 11
      RelayON();
      Wire.write(relay.state);
      break;
     case 12:
      RelayOFF();
      Wire.write(relay.state);
      break;
    default:
      break;
  }
}

YAY! thats it! gonna test it tomorrow on my workplace but i didnt see the read and write!:smiley: thanks alot !
was already thinking of using rs232 and then all the rx's of the slaves togheter and then let the master talk with a write 1 for slave 1 and next the command i want. but this is better! :smiley: thanks alot!

Greets,

Spikie

Please post the code when you got it really working for future reference,
Thanks

Well, im trying at the moment but something happens what i dont understand.

i did abit of changing the code to get it working but its not really getting that far.

i've changed the slave code to

#include <Wire.h>

void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Serial.begin(9600);
}

void loop()
{
  while(Wire.available() == '0');  // wait for request
  int command = Wire.read();
Serial.println(command);
}

i changed so i could read out what is comming from the read. also i did change the

  while(Wire.available() == '0');  // wait for request, the 0 between ' ' =)

otherwise it isnt even working..

I do get out of my serial this:

-1
-1
-1
and futher.

Maybe you know what happens?

EDIT:
after long searching i still doesnt know what happens.. it looks like they dont understand each other.. and it gets wrong on the slave side, i guess.. i can only see what he does after the wire.read cause i can print that in serial... does anyone knows an other idea?

For those who wanted to know how it works by now, i've made it as i wanted and going futher in the raspberry pie but that wasnt the problem;)

here is the code for Master arduino.

int val = 4; // random value

#include <Wire.h>

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

void loop()
{

  Wire.beginTransmission(10); // start talking to slave 10. 
  Wire.write(val);
  Wire.endTransmission();
  delay(500);
}

and this for the slave's with all diffrent adresses;)

#include <Wire.h>
int c;
void setup()
{
  pinMode(2,OUTPUT);
  pinMode(4,OUTPUT);
  Wire.begin(30);                
  Serial.begin(9600);

}

void loop()
{


    Wire.onReceive(info); // when the master is talking to this slave.

}

void info(int command){
  c = Wire.read();
  Serial.println(c);
  if (c == 2){
    digitalWrite(2,HIGH);

  }
  else{
    digitalWrite(2,LOW); 

  }
  if (c == 4){
   digitalWrite(4,HIGH); 
  }else{
   digitalWrite(4,LOW); 
  }
  
}