Float I2c

That worked.

I added the following function to I2C_Anything.h

template <typename T> int I2C_singleWriteAnything (const T& value) {
  int size = sizeof value;
  byte vals[size];
  const byte* p = (const byte*) &value;
  unsigned int i;
  for (i = 0; i < sizeof value; i++) {
    vals[i] = *p++;
  }
  
  Wire.write(vals, size);
  return i;
}

And it works perfectly, even in the onRequest handler.

Thanks 4.2 zillions!

Eric Rombokas

Thanks a lot! it works perfectly with the last addition. MasterWrite works great even with Due. But requestEvent is not working with Due :frowning: it always prints only "0.00", it doesn't matter if you connect a slave to the master..help please! =(

thannks for respon, :slight_smile:

Sorry to dig this thread back up after been dead for do long as I was searching how to send a float over I2C.
I've got the code working posted by Nick in post for just sending 2 example values of 6.75 (fnum) & 29.31(foo) and I would like to add another slave to send example values of 13.32(fnum) & 3.25(foo).
I know I would have to alter the MY_ADDRESS say to 43 but the part I'm not sure of is how to get the master to read more than one slave unit.

Is this possible ??
if so how could I do it

Steveiboy:
Sorry to dig this thread back up after been dead for do long as I was searching how to send a float over I2C.
I've got the code working posted by Nick in post for just sending 2 example values of 6.75 (fnum) & 29.31(foo) and I would like to add another slave to send example values of 13.32(fnum) & 3.25(foo).
I know I would have to alter the MY_ADDRESS say to 43 but the part I'm not sure of is how to get the master to read more than one slave unit.

Is this possible ??
if so how could I do it

Wire.requestFrom (SLAVE_ADDRESS,number_bytes,TRUE);

Controls which slave is being communicated with. Just create multiple request with different Slave Addresses. Of course you need 'slave' Arduinos with the same addresses.

Example Master Code Fragment

#define SLAVE_ADDRESS_1 0x58

#define SLAVE_ADDRESS_2 0x59

#define SLAVE_ADDRESS_3 0x5A

   float foo;
   long fnum;

   uint8_t datalen = (sizeof foo)+(sizeof fnum);

   // get info from the First Slave
   Wire.requestFrom (SLAVE_ADDRESS_1,datalen,true);
   if(Wire.available()==datalen){ // got correct size of packet
     I2C_readAnything (fnum);
     I2C_readAnything (foo);
     }
  
 // get info from the second Slave
   Wire.requestFrom (SLAVE_ADDRESS_2,datalen,true);
   if(Wire.available()==datalen){ // got correct size of packet
     I2C_readAnything (fnum);
     I2C_readAnything (foo);
     }
   // get info from the Third Slave
   Wire.requestFrom (SLAVE_ADDRESS_3,datalen,true);
   if(Wire.available()==datalen){ // got correct size of packet
     I2C_readAnything (fnum);
     I2C_readAnything (foo);
     }

The order you call I2C_readAnything(fnum), I2C_readAnything(foo) needs to match the order in the Slaves onRequest event handler.

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

Thanks chuck that should get me going, I will try it in the week

Once again for your support

I think I need to read up more, I've tried to add a second slave but it receives nothing from both salves
So I went back to basic with one salve
If I use this Wire.begin (SLAVE_ADDRESS_1); only with one slave it works
but if I just use this Wire.begin (); then nothing happens
tried to add this but same nothing comes through
Wire.begin (SLAVE_ADDRESS_1);
Wire.begin (SLAVE_ADDRESS_2);
This is what I've tried

void loop()
{
  uint8_t datalen = (sizeof foo) + (sizeof fnum); // get info from the First Slave
  Wire.requestFrom (SLAVE_ADDRESS_1, datalen, true);
  if (Wire.available() == datalen) { // got correct size of packet
    I2C_readAnything (fnum);
    I2C_readAnything (foo);
  }

  Wire.requestFrom (SLAVE_ADDRESS_2, datalen, true);
  if (Wire.available() == datalen) { // got correct size of packet
    I2C_readAnything (fnum);
    I2C_readAnything (foo);
  }



  if (haveData)
  {
    Serial.print ("Received 0x58 = ");
    Serial.println (fnum);
    Serial.print ("Received 0x58 = ");
    Serial.println (foo);
   Serial.print ("Received 0x59 = ");
    Serial.println (fnum);
    Serial.print ("Received 0x59 = ");
    Serial.println (foo);
  haveData = false;

  }  // end if haveData
}  // end of loop

The other thing I'm struggling to understand is how to display the 4 floats are displayed via the serial terminal as there are only one fnum and foo to send.

Steveiboy:
I think I need to read up more, I've tried to add a second slave but it receives nothing from both salves
So I went back to basic with one salve
If I use this Wire.begin (SLAVE_ADDRESS_1); only with one slave it works

The other thing I'm struggling to understand is how to display the 4 floats are displayed via the serial terminal as there are only one fnum and foo to send.

Steveiboy,

The Wire library has a problem. When the onRequestevent() is triggered (inside ISR), the code only transmits the last Wire.write() data. if your onRequestEvent() is like this:

void onRequestEvent(){
   Wire.write(1);
   Wire.write(2);
   Wire.write(3);
   Wire.write(4);
   Wire.write(5);
   Wire.write(6);
   Wire.write(7);
}

and the Master's code was

Wire.requestFrom(slave,7);
  while(Wire.available()){
     Serial.print(Wire.read(),HEX);
     Serial.print(' ');
     }

the Monitor would print:

7 FF FF FF FF FF FF

Not what you expected right?

I changed the code in my library to fix this and another Issue.

C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire\utility\twi.c

/* 
 * Function twi_transmit
 * Desc     fills slave tx buffer with data
 *          must be called in slave tx event callback
 * Input    data: pointer to byte array
 *          length: number of bytes in array
 * Output   1 length too long for buffer
 *          2 not slave transmitter
 *          0 ok
 */
uint8_t twi_transmit(const uint8_t* data, uint8_t length)
{
  uint8_t i;

  // ensure data will fit into buffer
  //if(TWI_BUFFER_LENGTH < length){ // original
  if(TWI_BUFFER_LENGTH < (length+twi_txBufferLength)){ //chuck 15JUN2015
    return 1;
  }
  
  // ensure we are currently a slave transmitter
  if(TWI_STX != twi_state){
    return 2;
  }
  
  // set length and copy data into tx buffer
  //twi_txBufferLength = length; original
  for(i = 0; i < length; ++i){ 
  //  twi_txBuffer[i] = data[i]; original
    twi_txBuffer[twi_txBufferLength++] = data[i]; //chuck 15Jun2015
    }
   return 0;
}

Appended are my update twi.c and two test Sketches that work.

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

twi.c (17.5 KB)

slave.ino (1.69 KB)

master.ino (3.01 KB)

I2C_anyThing.zip (547 Bytes)

Wow, Thanks chuck this is a massive help, I've compiled and upload I now can send and receive data from both slaves, I will also learn loads more by reading through your code and playing with it.
I shall now study and play around with the code.
Hopefully I can get it working. I see when I ground A0 it just receives data from slave one only I will try and get it to read both slaves and display both slaves with different values.
many thanks for your time and help
Steve

Steveiboy:
Hopefully I can get it working. I see when I ground A0 it just receives data from slave one only I will try and get it to read both slaves and display both slaves with different values.
many thanks for your time and help
Steve

Now for one more complication. You do realize that an arduino can be both a Master and a Slave at the same time?

just add the onRequest, onReceive events to the Master Sketch, change the Wire.begin() in the Master to Wire.begin(thirdslaveaddress);add the Wire.onReceive(),onRequest(). One more thing, put the volatile prefix on fnum, and foo. They will now be access in a ISR.

Now one proviso, The master CANNOT talk to itself successfully. if you put this new sketch into multiple Arduino's you could have them access each other.

If you added this complexity you would need to start monitoring the results from endTransmission(), requestFrom(). your transfers might get aborted if the transaction looses arbitration. you could no longer assume the master will always suceed.

multiple Master can be on the bus at the same time. Two masters can talk to the same slave at the same time. The master that wins is the one that transfers a byte with a low bit first.

Here is a good reference on the I2C buss Philips Electronics I2C Specs

Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

I'm making progress but the foo value is not increasing as I though it would here is the codes, might be a bit messy and a better way of doing it but it's working(I will tidy up code in a bit) I'm doing it as building blocks as I want to measure a voltage from 4 locations and send it to one unit but first thought make sure it send float values, My ADC code works so I think it's just the case of adding it bit by bit
Master

#include <Wire.h>
#include <I2C_anyThing.h> // Template from Nick Gammon

long fnum;   // volatile Not Need because variable will be Not be accessed during an interrupt ISR
float foo;   //  same thing.
long fnum1;
long foo1;
#define DATALEN (sizeof fnum) + (sizeof foo)
#define SLAVE_ADDRESS_1 0x58   // slave 1change this for each slave
#define SLAVE_ADDRESS_2 0x59   // slave 2

void setup() {
  Wire.begin();  // not a slave
  Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
  //we will send debug messages.
}

void debug_out( char msg[]) {
  Serial.println(msg);
  Serial.print("foo=");
  Serial.println(foo);
  Serial.print("fnum=");
  Serial.println(fnum);
  Serial.println("**************");

}

void loop() {
  slave_one();
  slave_two();
  delay(1000);
}

float slave_one() {
  Wire.requestFrom(SLAVE_ADDRESS_1, DATALEN);
  if (Wire.available() == DATALEN) {
    I2C_readAnything(fnum);
    I2C_readAnything(foo);
    debug_out("SLAVE ONE");
  }
  else debug_out("Tried to Read from Slave 1, Failed.");
}
float slave_two() {
  Wire.requestFrom(SLAVE_ADDRESS_2, DATALEN);
  if (Wire.available() == DATALEN) {
    I2C_readAnything(fnum);
    I2C_readAnything(foo);
    debug_out("SLAVE TWO");
  }
  else debug_out("Tried to Read from Slave 1, Failed.");
}

Slave_one (two is the same apart from address and values)

#include <Wire.h>
#include <I2C_anyThing.h> // Template from Nick Gammon

volatile long fnum; // volatile because variable will be accessed during an interrupt ISR
volatile float foo;  //  same thing.
volatile uint8_t newData; // flag to detect I2C activity

#define DATALEN (sizeof fnum) + (sizeof foo)

#define SLAVE_ADDRESS 0x58   // change this for each slave

void onRequestEvent(void) {
  /* Wire.write(1);
   Wire.write(2);
   Wire.write(3);
   Wire.write(4);
   Wire.write(5);
   Wire.write(6);
   Wire.write(7);
   Wire.write(8);
  */
  I2C_writeAnything(fnum);
  I2C_writeAnything(foo);
  // newData = newData | 1; // set bit 0 to mark I2C Sent data
}

void onReceiveEvent(int numbytes) {
  if (numbytes == DATALEN) { // Masters beginTransmission(SLAVE_ADDRESS);Write();endTransmission();
    // sent the correct number of bytes
    I2C_readAnything(fnum);
    I2C_readAnything(foo);
    // newData = newData | 2; // set bit 1 to mark I2C Received Data.
  }
}

void setup() {
  //newData = 0;
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(onReceiveEvent);
  Wire.onRequest(onRequestEvent);
  Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
  //we will send debug messages.
}

void loop() {

  foo = 12.36 + 0.01;
  fnum = 24;
}

Why is not the foo value increasing ?

chucktodd:
Now for one more complication. You do realize that an arduino can be both a Master and a Slave at the same time?

just add the onRequest, onReceive events to the Master Sketch, change the Wire.begin() in the Master to Wire.begin(thirdslaveaddress);add the Wire.onReceive(),onRequest(). One more thing, put the volatile prefix on fnum, and foo. They will now be access in a ISR.

Now one proviso, The master CANNOT talk to itself successfully. if you put this new sketch into multiple Arduino's you could have them access each other.

If you added this complexity you would need to start monitoring the results from endTransmission(), requestFrom(). your transfers might get aborted if the transaction looses arbitration. you could no longer assume the master will always suceed.

multiple Master can be on the bus at the same time. Two masters can talk to the same slave at the same time. The master that wins is the one that transfers a byte with a low bit first.

Here is a good reference on the I2C buss Philips Electronics I2C Specs

Chuck.

I did think about that but not was 100% sure about it, Now you got me worried and think may have bit of more than I can chew but the main ting is I'm having fun it seems to be working ok here a sample of the data coming in

SLAVE ONE
foo=12.37
fnum=24
**************
SLAVE TWO
foo=12.36
fnum=50
**************
SLAVE ONE
foo=12.37
fnum=24
**************
SLAVE TWO
foo=12.36
fnum=50
**************
SLAVE ONE
foo=12.37
fnum=24
**************
SLAVE TWO
foo=12.36
fnum=50
**************
SLAVE ONE
foo=12.37
fnum=24
**************
SLAVE TWO
foo=12.36
fnum=50
**************

Thanks for the link it will be interesting bedtime reading :slight_smile:

EDIT... I got it counting set foo to read 12.36 then in the loop I added foo = foo + 0.01;

Steveiboy:
EDIT... I got it counting set foo to read 12.36 then in the loop I added foo = foo + 0.01;

Feels good when you figure it out :grin:

Enjoy!
Chuck.


Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

chucktodd:
Steveiboy,

The Wire library has a problem. When the onRequestevent() is triggered (inside ISR), the code only transmits the last Wire.write() data. if your onRequestEvent() is like this:

void onRequestEvent(){

Wire.write(1);
  Wire.write(2);
  Wire.write(3);
  Wire.write(4);
  Wire.write(5);
  Wire.write(6);
  Wire.write(7);
}




and the Master's code was


Wire.requestFrom(slave,7);
  while(Wire.available()){
    Serial.print(Wire.read(),HEX);
    Serial.print(' ');
    }




the Monitor would print:

7 FF FF FF FF FF FF

Not what you expected right?

I changed the code in my library to fix this and another Issue.


C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire\utility\twi.c


/*

  • Function twi_transmit
  • Desc    fills slave tx buffer with data
    *          must be called in slave tx event callback
  • Input    data: pointer to byte array
    *          length: number of bytes in array
  • Output  1 length too long for buffer
    *          2 not slave transmitter
    *          0 ok
    /
    uint8_t twi_transmit(const uint8_t
    data, uint8_t length)
    {
      uint8_t i;

// ensure data will fit into buffer
  //if(TWI_BUFFER_LENGTH < length){ // original
  if(TWI_BUFFER_LENGTH < (length+twi_txBufferLength)){ //chuck 15JUN2015
    return 1;
  }
 
  // ensure we are currently a slave transmitter
  if(TWI_STX != twi_state){
    return 2;
  }
 
  // set length and copy data into tx buffer
  //twi_txBufferLength = length; original
  for(i = 0; i < length; ++i){
  //  twi_txBuffer[i] = data[i]; original
    twi_txBuffer[twi_txBufferLength++] = data[i]; //chuck 15Jun2015
    }
  return 0;
}






Appended are my update twi.c and two test Sketches that work. 

Chuck.


---


Check out my Kickstarter Project [Memory Panes](https://www.kickstarter.com/projects/1052400055/mega2560-expansion-ram-arduino-compatible-xmem) an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.

i'm the new, how to do with your library and the twi file. Thanks

I've started to play around again with this again, Not sure what's happened as the last time it was working but now I just get it displaying -1 and nan on the LCD and serial port, I've done nothing to the code since it was working last time other than reloaded it into the board's. I'm only using one slave at the moment and highlighted out slave two if/when I get it working I will see about adding 3 other slaves.
I'm using version 1.67 and replaced the twi.c file as I did the last time to get it working when I add the same issue with the previous version of the IDE
Master code

#include <Wire.h>
#include <I2C_anyThing.h> // Template from Nick Gammon
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

float fnum;   // volatile Not Need because variable will be Not be accessed during an interrupt ISR
long foo;   //  same thing.
float fnum1;
float foo1;
#define DATALEN (sizeof fnum) + (sizeof foo)
#define SLAVE_ADDRESS_1 0x58   // slave 1change this for each slave
#define SLAVE_ADDRESS_2 0x59   // slave 2

void setup() {
  Wire.begin();  // not a slave
  Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
  lcd.begin (20,4); // for 16 x 2 LCD module
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.clear();
  //we will send debug messages.
}

void debug_out( char msg[]) {
  Serial.println(msg);
  Serial.print("foo=");
  Serial.println(foo);
  Serial.print("fnum=");
  Serial.println(fnum);
  Serial.println("**************");
lcd.setCursor(0, 0);
lcd.print(foo);
  lcd.print("  ");
  lcd.setCursor(0, 1);
  lcd.print(fnum);
  lcd.print("  ");

}
void debug_out1( char msg1[]) {
  Serial.println(msg1);
  Serial.print("foo=");
  Serial.println(foo1);
  Serial.print("fnum=");
  Serial.println(fnum1);
  Serial.println("**************");
lcd.setCursor(0, 2);
lcd.print(foo1);
  lcd.print("  ");
  lcd.setCursor(0, 3);
  lcd.print(fnum1);
  lcd.print("  ");

}
void loop() {
  slave_one();
 // slave_two();
 delay(200);
}

float slave_one() {
  Wire.requestFrom(SLAVE_ADDRESS_1, DATALEN);
  if (Wire.available() == DATALEN) {
    I2C_readAnything(fnum);
    I2C_readAnything(foo);
    debug_out("SLAVE ONE");
  }
  else debug_out("Tried to Read from Slave 1, Failed.");
}
float slave_two() {
  Wire.requestFrom(SLAVE_ADDRESS_2, DATALEN);
  if (Wire.available() == DATALEN) {
    I2C_readAnything(fnum1);
    I2C_readAnything(foo1);
    debug_out1("SLAVE TWO");
  }
  else debug_out1("Tried to Read from Slave 2, Failed.");
}

Slave code

#include <Wire.h>
#include <I2C_anyThing.h> // Template from Nick Gammon
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
float vout = 0.0;
int inputPin = A0;
volatile float fnum; // volatile because variable will be accessed during an interrupt ISR
volatile long foo;  //  same thing.
volatile uint8_t newData; // flag to detect I2C activity
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
#define DATALEN (sizeof fnum) + (sizeof foo)

#define SLAVE_ADDRESS 0x58   // change this for each slave

void onRequestEvent(void) {
  /*	Wire.write(1);
  	Wire.write(2);
  	Wire.write(3);
  	Wire.write(4);
  	Wire.write(5);
  	Wire.write(6);
  	Wire.write(7);
  	Wire.write(8);
  */
  I2C_writeAnything(fnum);
  I2C_writeAnything(foo);
   newData = newData | 1; // set bit 0 to mark I2C Sent data
}

void onReceiveEvent(int numbytes) {
  if (numbytes == DATALEN) { // Masters beginTransmission(SLAVE_ADDRESS);Write();endTransmission();
    // sent the correct number of bytes
    I2C_readAnything(fnum);
    I2C_readAnything(foo);
     newData = newData | 2; // set bit 1 to mark I2C Received Data.
  }
}

void setup() {
  newData = 0;
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(onReceiveEvent);
  Wire.onRequest(onRequestEvent);
  Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
  //we will send debug messages.
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings)
    // ...wrap around to the beginning:
    readIndex = 0;

  // calculate the average:
  vout = total / numReadings;
  foo = (vout * 5.0) / 1024.0; // see text
  fnum = 12;
  delay(200);
}

Steveiboy:
I've started to play around again with this again, Not sure what's happened as the last time it was working but now I just get it displaying -1 and nan on the LCD and serial port, I've done nothing to the code since it was working last time other than reloaded it into the board's. I'm only using one slave at the moment and highlighted out slave two if/when I get it working I will see about adding 3 other slaves.
I'm using version 1.67 and replaced the twi.c file as I did the last time to get it working when I add the same issue with the previous version of the IDE
Master code

#include <Wire.h>

#include <I2C_anyThing.h> // Template from Nick Gammon
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

float fnum;   // volatile Not Need because variable will be Not be accessed during an interrupt ISR
long foo;   //  same thing.
float fnum1;
float foo1;
#define DATALEN (sizeof fnum) + (sizeof foo)
#define SLAVE_ADDRESS_1 0x58   // slave 1change this for each slave
#define SLAVE_ADDRESS_2 0x59   // slave 2

void setup() {
 Wire.begin();  // not a slave
 Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
 lcd.begin (20,4); // for 16 x 2 LCD module
 lcd.setBacklightPin(3, POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.clear();
 //we will send debug messages.
}

void debug_out( char msg[]) {
 Serial.println(msg);
 Serial.print("foo=");
 Serial.println(foo);
 Serial.print("fnum=");
 Serial.println(fnum);
 Serial.println("**************");
lcd.setCursor(0, 0);
lcd.print(foo);
 lcd.print("  ");
 lcd.setCursor(0, 1);
 lcd.print(fnum);
 lcd.print("  ");

}
void debug_out1( char msg1[]) {
 Serial.println(msg1);
 Serial.print("foo=");
 Serial.println(foo1);
 Serial.print("fnum=");
 Serial.println(fnum1);
 Serial.println("**************");
lcd.setCursor(0, 2);
lcd.print(foo1);
 lcd.print("  ");
 lcd.setCursor(0, 3);
 lcd.print(fnum1);
 lcd.print("  ");

}
void loop() {
 slave_one();
// slave_two();
delay(200);
}

float slave_one() {
 Wire.requestFrom(SLAVE_ADDRESS_1, DATALEN);
 if (Wire.available() == DATALEN) {
   I2C_readAnything(fnum);
   I2C_readAnything(foo);
   debug_out("SLAVE ONE");
 }
 else debug_out("Tried to Read from Slave 1, Failed.");
}
float slave_two() {
 Wire.requestFrom(SLAVE_ADDRESS_2, DATALEN);
 if (Wire.available() == DATALEN) {
   I2C_readAnything(fnum1);
   I2C_readAnything(foo1);
   debug_out1("SLAVE TWO");
 }
 else debug_out1("Tried to Read from Slave 2, Failed.");
}



Slave code


#include <Wire.h>
#include <I2C_anyThing.h> // Template from Nick Gammon
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
float vout = 0.0;
int inputPin = A0;
volatile float fnum; // volatile because variable will be accessed during an interrupt ISR
volatile long foo;  //  same thing.
volatile uint8_t newData; // flag to detect I2C activity
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
#define DATALEN (sizeof fnum) + (sizeof foo)

#define SLAVE_ADDRESS 0x58   // change this for each slave

void onRequestEvent(void) {
 /* Wire.write(1);
  Wire.write(2);
  Wire.write(3);
  Wire.write(4);
  Wire.write(5);
  Wire.write(6);
  Wire.write(7);
  Wire.write(8);
 */
 I2C_writeAnything(fnum);
 I2C_writeAnything(foo);
  newData = newData | 1; // set bit 0 to mark I2C Sent data
}

void onReceiveEvent(int numbytes) {
 if (numbytes == DATALEN) { // Masters beginTransmission(SLAVE_ADDRESS);Write();endTransmission();
   // sent the correct number of bytes
   I2C_readAnything(fnum);
   I2C_readAnything(foo);
    newData = newData | 2; // set bit 1 to mark I2C Received Data.
 }
}

void setup() {
 newData = 0;
 Wire.begin(SLAVE_ADDRESS);
 Wire.onReceive(onReceiveEvent);
 Wire.onRequest(onRequestEvent);
 Serial.begin(9600); // if USB is connected to this slave and Serial monitor is on
 //we will send debug messages.
 for (int thisReading = 0; thisReading < numReadings; thisReading++)
   readings[thisReading] = 0;
}

void loop() {
 // subtract the last reading:
 total = total - readings[readIndex];
 // read from the sensor:
 readings[readIndex] = analogRead(inputPin);
 // add the reading to the total:
 total = total + readings[readIndex];
 // advance to the next position in the array:
 readIndex = readIndex + 1;

// if we're at the end of the array...
 if (readIndex >= numReadings)
   // ...wrap around to the beginning:
   readIndex = 0;

// calculate the average:
 vout = total / numReadings;
 foo = (vout * 5.0) / 1024.0; // see text
 fnum = 12;
 delay(200);
}

Steveiboy,
I haven't looked at any of the newer Arduino's past 1.65, you should install the newest version and compare my version of twi.c with the 'new' library, all of my edits are commented, you should be able to see the differences.

Also,I changed Wire.h, Wire.cpp, and twi.c. if you just updated twi.c I can see where this problem would rear it's head. In the Wire.write() is were the buffer count is overwritten if the write() is during a onRequest() event.

Instead of overwriting twi.c inside of the Arduino environment, just use the Arduino Environment to install whole modified Wire library.

Sketch\include Library\add .Zip Library...

That way, you can easily remove it by just deleting the whole subdirectory.

The Arduino environment will create a directory {sketchesFolder}\libraries\Wire

My {sketchesFolder} happens to be "C:\Users\User\Documents\Arduino".

When you have My wire library install, any sketch that uses Wire will display this warning when it is compiled:

Multiple libraries were found for "Wire.h"
 Used: C:\Users\user\Documents\Arduino\libraries\Wire
 Not used: C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire

Your locations may be different, mine are under 32bit Win7.

Chuck.

Something has changed from version 1.60 to 1.67,1.69,
Chuck I've tried what you said with 1.67 and 1.69 installed your files but both programs will not complie I get errors, I deleted the library and they complie. I uninstalled 1.69 and re-installed 1.60 copied only the twi file over and everything is working like it was before. Strange, I will re-install 1.69 tomorrow and copy the errors as I could not understand the errors. I think it's something to do with the I2Canything library
As its late here I will continue tomorrow
Thanks for your help
Steve

Steveiboy:
Something has changed from version 1.60 to 1.67,1.69,
Chuck I've tried what you said with 1.67 and 1.69 installed your files but both programs will not complie I get errors, I deleted the library and they complie. I uninstalled 1.69 and re-installed 1.60 copied only the twi file over and everything is working like it was before. Strange, I will re-install 1.69 tomorrow and copy the errors as I could not understand the errors. I think it's something to do with the I2Canything library
As its late here I will continue tomorrow
Thanks for your help
Steve

Steve,

Look in my Wire.h, I included Nick Gannons I2C_anything. You probably don't need to re include his templates.

Chuck.

chucktodd:
Steve,

Look in my Wire.h, I included Nick Gannons I2C_anything. You probably don't need to re include his templates.

Chuck.

Hi Chuck
Sorry for the delay and late reply, I had some time and got back onto this project and I've managed to get it working the way you said, The new errors where caused by including the I2C_writeanything still been there I removed this and it now compiles and is working I will add the 3 other salves later and see how it goes

thanks for your help