Loading...
Pages: [1]   Go Down
Author Topic: Multiple Wire.OnRequest handlers  (Read 331 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 44
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

Im just playing with some ideas at the moment for a project where I know the code/sram usage will be too much for a single 328 and pin usage will be high. I know pin usage can be resolved with shift registers etc but I am really liking the idea of using a couple of 328s over I2C and keeping things very modular.

I'd really like to be able to make different requests to a 328, as an example, one handler for writing data to an SD card and some other handlers to read, interpret and return that data in different ways.

I havent come across any examples on how this might be achieved so wondered if it is even possible?

oooh, would I do something like

Code:
beginTransmission(),
send('someMethodName'),
endTransmission()
requestFrom()

Having a the onRequest handler read the string that was sent with send() and call some function based on that?

Thanks in advance.

« Last Edit: June 01, 2011, 06:01:13 pm by outofsight » Logged

NZ
Offline Offline
Sr. Member
****
Karma: 0
Posts: 376
Turtle in a hard shell
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I hope I have interpreted your question correctly....

One of my projects requires different information to be sent/received from arduino to arduino, and what I did was basically how you have indicated.

Code:
Wire.beginTransmission(Address);
Wire.send(Command);
Wire.endTransmission();
Wire.requestFrom(Address, 1);      // request 1 bytes from slave device

So basically you send a 'Command' from the Master to the Slave, and then you request data from it. In the Slave you save the command that you received, and then when the request for data comes in, you send the information based on what the command was.

If that makes sense.

So in the slave, in simple terms, I do this:

Code:
void setup()
{
  Wire.begin(Address);    //Slaves Address
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
}

void loop()
{
   //calculate stuff
}

void receiveEvent(int HowMany)
{
   if(Wire.available() > 0)
   {
      CMD = Wire.receive();
   }
}

void requestEvent()
{
  if(CMD == 0x01)
  {
    //Send Stuff
  }
  if(CMD == 0x02)
  {
    //Send other Stuff
  }
}

Hope you get the idea.
Thats how I have done it anyway and it works well.

James
« Last Edit: June 01, 2011, 06:35:42 pm by WanaGo » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 44
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


So basically you send a 'Command' from the Master to the Slave, and then you request data from it. In the Slave you save the command that you received, and then when the request for data comes in, you send the information based on what the command was.

If that makes sense.

Yeah that's exactly what I need to do smiley

My only concern with what you have proposed is that the request handler function could grow quite large, do you know if it's possible to set the request event handler in the receive event based on the command passed in or do they both have to be declared in setup?

Cheers,
Logged

Netherlands
Offline Offline
Tesla Member
***
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
My only concern with what you have proposed is that the request handler function could grow quite large

Use a 2 stage architecture:

The requesthandler should only dispatch the request to the right function, something like below.
This keeps the requestEvent rather small and focussed. Every command has its own function.
Code:
void requestEvent()
{
  switch(CMD)
  {
  case 0x01: ABC(); break;
  case 0x02: XYZ(); break;
  case 0x03: PQR(); break;
  case 0x04: KLM(); break;
  default: break; // do nothing
  }
}

void ABC()
{
  byte value = readsensor();
  send(value);
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Offline Offline
Newbie
*
Karma: 0
Posts: 44
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


The requesthandler should only dispatch the request to the right function, something like below.
This keeps the requestEvent rather small and focussed. Every command has its own function.


That's just perfect. Thanks.
Logged

Netherlands
Offline Offline
Tesla Member
***
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

even better

  default: break; // do nothing

you could light up some error LED here iso doing nothing, to show that a not supported command was send. (think debug)
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

NZ
Offline Offline
Sr. Member
****
Karma: 0
Posts: 376
Turtle in a hard shell
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
My only concern with what you have proposed is that the request handler function could grow quite large

Use a 2 stage architecture:

The requesthandler should only dispatch the request to the right function, something like below.
This keeps the requestEvent rather small and focussed. Every command has its own function.
Code:
void requestEvent()
{
  switch(CMD)
  {
  case 0x01: ABC(); break;
  case 0x02: XYZ(); break;
  case 0x03: PQR(); break;
  case 0x04: KLM(); break;
  default: break; // do nothing
  }
}

void ABC()
{
  byte value = readsensor();
  send(value);
}

Yup what he said smiley
Logged

Pages: [1]   Go Up
Print
 
Jump to: