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;
//}
//********************
}
}
}