I2C and 2 ARDUINOS - Totally easy method to send data from one to another

In this example 20 temperatures are sent from one arduino to another over I2C

this example support 64 sensors with sensor data from 0-999

The pitcher

//CODE FOR SENDER
//demonstrates how to capture one or more sensors
//and send them to another unit in the blind
//very simple
//useful for when you know your stuff works
//and you just want A to be sent to B
//and youll know, hey this aint working, cause u aint seeeing updates
//thats the scenario for this simple elegant marvelous solution


//also demos how to encode smaller numeric data of a known length, like temperature
//into aa packet that can be parsed by the rx end to identify the sensor and its value
//in this example 1 to 64 sensors (65 but theres a catch)with sensor data from 0-999

//it is possible to scale this much bigger for a lot more sensors and lot higher values
//have to just change the data types
//i chose uint cause thats what i needed
//u can change it to whatever boats your float :)

#include <Wire.h> //need wire h for i2c

void setup() {

 //start the wire service up, Wire.begin(); starts this unit as amaster
 // this demo will work as a sender to another slave unit as master or slave
 
Wire.begin();
}

void loop() {
  
//we will encode our 2 digit sensor id followed by our 3 digit sensor value in this packet

uint16_t encodedRxPacket; 

//an array to use for transport of two bytes, these are transported to THE LOCAL BUFFER
// the buffer moves to the transport wire only on Wire.endTransmission
//buffer is lmited in size

byte arrayTwoByteTransport[2];

int i;
 
//begin to send new data to another unit, in this case slave 5

Wire.beginTransmission(5);
encodedRxPacket=0;

//transport only happens on Wire.endTransmission, prior to that you are filling a buffer, so you have to 
//pack the buffer without exceeeding it, then send it
//we have 20 sensors so we break them into two transport groups
// in this example using a 2 byte array the buffer limit prior to send is 15 not 10 as used herein.
//10 made the math easier :)


     for (i = 0; i < 10; i++) { //send the first ten sensors
      
     //below, we use random to make a fake temp from 1 to 148 degrees (1 to 3 digit data)
     //we add 10,000 to that value (when i =0, multiply by zero, see math below), so 10012 is sensor 1 with a temp of 12
     //on next pass in for, we add 10,000 and 1,000 (cause i now equals 1) and sensor temp of say 34. 11,034, sensor 1 temp 34
     //all of this is placed in uint16_t encodedRxPacket, it can go to 65k so 64 sensors
     //(can use 65 if sensor data limited to less than a 535 value cause uint 65535 wink) :)  
     
     encodedRxPacket=10000 + (1000*i)+random(1,148);

     //[place encodedRxPacket in local buffer transport array
     arrayTwoByteTransport[0] = (encodedRxPacket >> 8) & 0xFF;
     arrayTwoByteTransport[1] = encodedRxPacket & 0xFF;


     //write loaded and encoded single sensor array to this machines send buffer
     Wire.write(arrayTwoByteTransport, 2);
     encodedRxPacket=0;
     }


// SEND THE BUFFER TO THE OTHER UNIT
Wire.endTransmission(5); 

 


//RINSE REPEAT FOR NEXT 10 SENSORS (IN TESTING USING THIS SIZE OF ARRAY I COULD DO UP TO 15
Wire.beginTransmission(5); // transmit to device #5

encodedRxPacket=0;
     for (i = 10; i < 20; i++) { //<<<NEXT TEN NOT 0 TO 10 BUT 10 TO 20
     encodedRxPacket=10000 + (1000*i)+random(30,148); 
     arrayTwoByteTransport[0] = (encodedRxPacket >> 8) & 0xFF;
     arrayTwoByteTransport[1] = encodedRxPacket & 0xFF;
     Wire.write(arrayTwoByteTransport, 2);
     encodedRxPacket=0;
     }

    
Wire.endTransmission(5); 

//my seed studio v1 slow touch display can only take an update of this much data every 3 seconds, approx 22 a minute
//so i use a 3000 delay, HOWEVER, with no delay this WORKED for more than 36 hours on that same unit, so unsure if delay is needed at all
//i was more concerned about sending stuff that wasnt able to be processed/displayed  in the first place so i added a delay
//to match my display capability

delay(3000); 

}

The catcher

#include <Wire.h>

//make an array to store our incoming sensor data, in this case 20 sensors that will be int values
int arraySensorDataRecieved[20];

void setup() {
Serial.begin(9600); //for debug 

//start your reciver client, client 5 in this case
Wire.begin(5);

// tell the client to fire this if it gets data from sender
Wire.onReceive(receiveEvent);
}

void loop() {
}

void receiveEvent(){
  
int i,ii;
uint16_t encodedRxPacket;
int decodedSensorValue;
byte a,b;



     //for twenty senaor we only for 10 times, cause with a uint16_t bigNum we used two buyes per sensor
     // so we are getting the data in two 10 sensor transmissions of 2 bytes each for 20 per transmission, 40 total
     //so we get ten sensors and process those 20 bytes, we dont know which pack we got, pack of ten 1 or pack of ten 2
     //we dont care

     for (i = 0; i < 10; i++) { 
     a = Wire.read();
     b = Wire.read();
     encodedRxPacket = a;
     encodedRxPacket = encodedRxPacket << 8 | b;
          
Serial.println(encodedRxPacket);//for debug

          //now we process that ten pack, and find out if its pack one or two (or more if you add more than 20 sensors)
          for (ii = 0; ii < 20; ii++) { 

               //decode the data down to sensor id and 1 to 3 digit temp ii=array numbers in our recieve array
               //we know the sensor id from the first the numbers of our number
               // sensor one is 10,000 to 10,999
               // two is 11,000 to 11,099 etc
               
               if (encodedRxPacket >= 10000+(ii*1000)  && encodedRxPacket < 11000+(ii*1000)){ 
                         
               //now we know, using the if statement, which sensor id it is base on the for ii value and the for test statement
              //strip that off and give us our sensor data from 0-999 (in this case, could be much larger numbers if we want)
              
              decodedSensorValue=(encodedRxPacket-(10000+(ii*1000)));
                         
Serial.println(decodedSensorValue);//for debug

              //store the recieved and parsed data into your array
              
              arraySensorDataRecieved[ii]=encodedRxPacket;
              
              //*********************  
                 
              //optional below, compare that to whats already store, only update it if changed.
                   
                   //if(arraySensorDataRecieved[ii]!=encodedRxPacket){
                   //arraySensorDataRecieved[ii]=encodedRxPacket;
                   //}

               //******************** 
                  
               }

               //******************** 
               //also optional, tested, break out if we get 65535, cause thats bogus from the sender, we are overpolling
               // ie you placed receiveEvent somewhere like loop instead of letting it fire when notified by sender
               //and you are getting empty trash 
               
               //if (encodedRxPacket>65534){
               //break;  
               //}
               //******************** 
          }
     }
}