Pages: [1]   Go Down
Author Topic: MultiMaster send/receive an array over I2C  (Read 2352 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 2
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I am having trouble sending an array over I2C. I am a newbie  and starting with a simple sketch that passes a 1x6 array between 3 arduinos.

the communication is initiated by pressing a button attached to arduino#1,  arduino#1 blinks an LED the amount of times indicated by thisArray[0], adds one to all the elements in thisArray and then send the array to
arduino#2, which blinks an LED the amount of times indicated by thisArray[0], adds 1 to each element and then passes thisArray to arduino#3 where same happens and then goes back to arduino#1.
I am also having the program print to the serial monitor at every stage so that I know that the code is being read...

Right now, my LED on arduino#1 blinks when I push the button, the value of thisArray is printed to the serial monitor as well as all of the string notes at every stage. However, arduino#2's LED never blinks which I am guessing means that the array is not being received by arduino#2.

I think my issue may be in this part of the code:

***

void receiveEvent(int howMany){
 while (Wire.available() > 0){
   thisArray[6] = Wire.receive();

***

I'm not sure if Wire.receive can receive an array of integers.
I tested the above and it only receives the 6th value in the 1x6 array. I want it to receive all 6 values though. if I just put thisArray[] = Wire.receive(); I get an error message.

any help would be greatly appreciated.

my full code:

//MultiMaster communication
//add 1 to each element in the array, blink LED, print array to serial
//& send array to next arduino

#include <Wire.h>
#define LED 13
#define BUTTON 10
#define THIS_ADDRESS 1
#define OTHER_ADDRESS 2

boolean last_state = HIGH;

int lastArray[]={
  0,1,2,3,4,5};  
byte thisArray[]={
  0,1,2,3,4,5};  

void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  Wire.begin(THIS_ADDRESS);
  Wire.onReceive(receiveEvent);
  pinMode(BUTTON, INPUT);
  digitalWrite(BUTTON, HIGH);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(BUTTON) != last_state){
    for (int i=0; i< 6; i++) {
      thisArray = thisArray + 1;
    }
  }

  if(thisArray[0] != lastArray[0]) {
    for (int j=0; j<thisArray[0]; j++) {
      digitalWrite(LED, HIGH);
      delay(200);
      digitalWrite(LED, LOW);
      delay(200);
    }
    Serial.print("[");
    for (int k=0; k< 6; k++) {
      int n = thisArray[k];
      Serial.print(n);
      Serial.print(",");
    }
    Serial.println("]");

    Serial.println("increment array");
    for (int m=0; m< 6; m++) {  
      thisArray[m] = thisArray[m] + 1;
    }
    Serial.println("transmit array");
    Wire.beginTransmission(OTHER_ADDRESS);
    Wire.send(thisArray,6);
    Wire.endTransmission();

    Serial.println("lastarray=thisarray");
    for (int h=0; h< 6; h++) {  //make lastArray = thisArray
      lastArray[h] = thisArray[h];
    }
    Serial.println("wait for response");
  }
}

void receiveEvent(int howMany){
  while (Wire.available() > 0){
    thisArray[6] = Wire.receive();
  }
}


**code for arduino#2 and #3 is the same but without the button and strings printed to serial monitor.





Logged

0
Offline Offline
Newbie
*
Karma: 2
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I figured out what I was doing wrong. its porb just a newbie mistake but I thought I would post it in case anyone else gets stuck like I did.

to receive an array of integers you need a for loop since I guess Wire.receive can only receive one int at a time. (but sending an array all at once wasn't a problem, go figure)

so here is what you need to write to get the whole array:

void receiveEvent(int howMany){
  while (Wire.available() > 0){
    for (int p=0; p< 6; p++) {  //receive and replace all elements of new thisArray
      thisArray[p] = Wire.receive();  
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I guess Wire.receive can only receive one int at a time. (but sending an array all at once wasn't a problem, go figure)
You guess correctly. The sending is done in a loop, one at a time. I know, hard to believe.

Your original code was actually better, in that it only tried to receive what was actually available. The problem with it was that it stuck all the data in the 7th element of a 6 element array.

Your newer code sees that there is some data available, how much is not clear, and then attempts to read all 6 values.

Code:
byte index = 0;
while(Wire.available() > 0 && index < 6)
{
   thisArray[index] = Wire.receive();
   index++;
}
This code reads all available data, and stores in in the proper places in the array, checking that there is space in the array.

One question, though. Why are thisArray and lastArray different types?
« Last Edit: January 12, 2011, 04:12:47 am by PaulS » Logged

0
Offline Offline
Newbie
*
Karma: 2
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Paul, thanks for the response. My code seems to work ok. At least it seems to be since the array being received and printed to the serial monitor seems to be correct. All the numbers are where they should be.

But I tried your way and that worked too!
Since I am new to this I am going to trust your judgement and stick to your way. Hopefully I will understand it better eventually smiley-grin

I am working up to filling the arrays with sensor data and definitely need to make sure that the data is being put in the correct position in the array.

hmmm, not sure why thisArray and lastArray are different types. I started with another example that had it that way and just kept it because it worked. Do you see any issues with that? Should they both be byte? int?

I am tracking my progress with my project on my blog. Any comments/ suggestions would be welcome.

http://www.alivingarchitecture.com/


 


Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Should they both be byte? int?
Wire.receive() actually receives bytes, not ints. So, storing the data that was retrieved as a byte in a byte array makes more sense than storing it in a (larger) int array.

For 6 values, the savings in memory are minimal. For 500 values, the savings might make the difference between failure and success.
Logged

0
Offline Offline
Newbie
*
Karma: 2
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oh dear, I forgot the part about how I can only send and receive bytes. I am working up to storing photosensor data in the array. I've seen those values run around 0 to 1000. So I guess that means I have to scale my numbers so I can send them as bytes? Any easier way to do it?

Thanks for pointing out the waste of storing as int. I will definitely revise that as I think it will become a problem later.

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
So I guess that means I have to scale my numbers so I can send them as bytes? Any easier way to do it?
No scaling needed. ints are 2 bytes. There are two functions, highByte() and lowByte() that extract the two bytes that make up an int.

Send the two bytes.

On the receiving end, multiply the high byte by 256 and add the low byte, to make the original (unsigned) integer.
Logged

Pages: [1]   Go Up
Jump to: