Sending an Integer (int) throught I2C

Hi everyone,
first, let me just say I am new to the word of Arduino protoyping and I just love it so far ! I am currently trying to pass an integer from one arduino to another using the I2C protocol.

I got the arduino network up and running using the Wire lib and it works great using Char, Byte... the problem is I want to use this I2C link to send the sensor values from one arduino to the other (for processing).

I was wondering if it is even possible...

I did some thinking and I played a bit with the type : byte and the << , | operator to act directly on the bits but it didnt work. I was thinking of something like :

int turn = 0;
//SOMETHING// c = Wire.receive();
int buffer = 0x00000000;
buffer = buffer | c;
buffer << 8;
if turn = 4
Serial.println(buffer)

Could someone please help me on that ?

Thanks !

Ah dude, is that pseudo-code? Why don't you try coding your idea, see if it works and does what you expected. If it doesn't, please post the code here saying what were you expecting it to do, and what does it do instead.
Good luck :slight_smile:

edit:
To send an int in two bytes you'll probably send the least significant byte first, then shift the int 8 bits right (buffer = buffer >> 8) and sent the least significant byte again

then shift the int 8 bits right (buffer = buffer >> 8)

I think you mean buffer = buffer << 8
In pseudo code:-

read msb
read lsb
value = (msb << 8) | lsb

Umm, no. I'm pretty sure I meant what I wrote :smiley:

If you can send only one byte a time, and this byte is the lsb, then:

send(buffer) - will send the lsb of buffer
buffer = buffer >> 8 - will shift buffer 8 bits right, ie discard the previous lsb and put the second-lsb at the lsb place
send(buffer) - will send the new lsb of buffer

Or am I missing something crucial here?

Thankyou ! It works ! One thing wierd : it only works for positive numbers between 0 and 32767 (shouldn't it be between [ch8722]2,147,483,648 to +2,147,483,647 ?) anyway. I dont really need more than that so I guess it's okay. But If anyone know what happened I would be interested to know what's up.

I will post the code that I made if anyone is interested :

The I2C 7 bit sender :

#include <Wire.h>
// MAX INT 32767
void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestInt); // register event
}

int byteSending = 1;
int toTransfer = 32767;
int Shift = toTransfer;
int mask = 0xFF;
unsigned char toSend = 0;

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestInt()
{
  if (byteSending == 1) //send packet 1
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 2;
  }
  else if (byteSending == 2) //send packet 2
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 3;
  }
  else if (byteSending == 3) //send packet 3
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 4;
  }
  else if (byteSending == 4) //send packet 4
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 1;
    //initialization for next turn
    Shift = toTransfer;
    mask = 0xFF;
    toSend = 0;
  }
}

and the I2C 7bit receiver

#include <Wire.h>
// MAX INT 32767
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
int output = 0;

void loop()
{
  Wire.requestFrom(2, 1);   // the first byte
  while(Wire.available())
  { 
    unsigned char received = Wire.receive();
    output = received;
  }
  
  for (int i = 0 ; i < 3 ; i++) // next 3 bytes
  {
     Wire.requestFrom(2, 1);   
     while(Wire.available())
     { 
        unsigned char received = Wire.receive();
        output |= (received << 8);
     }
  }
  Serial.print(output);
  Serial.println(".");

  delay(500);
}

int page on Arduino reference says it's range is -32,768 to 32,767 (15 bits for the number and one sign bit) which means 2 bytes for an int, and not 4 like on big machines :wink: But I'm afraid I can't tell you why it covers the positive range only

So I guess I would get the same result by doing what's in my ''for loop'' only once... ?

Umm, it's two bytes, so I think you'll need to do it twice.

yea exactly, but since I did it once before my ''for-loop'', I would end up doing it 2 times total...

I guess I will test that then! About those negative number tho, could it be because I use a unsigned char when i receive the values , as in :

     Wire.requestFrom(2, 1);   
     while(Wire.available())
     {
        unsigned char received = Wire.receive();
        output |= (received << 8);
     }

Oh yeah, my bad. unsigned means without a sign :slight_smile: that is only positive numbers

I changed the unsigned char for a char and it now work for negative number. The only downside is that we loose a bit for the value itself. Here are the final codes if anyone needs it :

SIGNED 6 bit Receiver

#include <Wire.h>
// MAX INT -16382 to 16382

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
int output = 0;

void loop()
{
  Wire.requestFrom(2, 1);   // the first byte
  while(Wire.available())
  { 
    char received = Wire.receive();
    output = received;
  }
  
  for (int i = 0 ; i < 3 ; i++) // next 3 bytes
  {
     Wire.requestFrom(2, 1);   
     while(Wire.available())
     { 
        char received = Wire.receive();
        output |= (received << 8);
     }
  }
  Serial.print(output);
  Serial.println(".");

  delay(500);
}

SIGNED 6 bit Sender :

#include <Wire.h>
// MAX INT -16382 to 16382
void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestInt); // register event
}

int byteSending = 1;
int toTransfer = 32766;
int Shift = toTransfer;
int mask = 0xFF;
char toSend = 0;

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestInt()
{
  if (byteSending == 1) //send packet 1
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 2;
  }
  else if (byteSending == 2) //send packet 2
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 3;
  }
  else if (byteSending == 3) //send packet 3
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 4;
  }
  else if (byteSending == 4) //send packet 4
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 1;
    //initialization for next turn
    Shift = toTransfer;
    mask = 0xFF;
    toSend = 0;
  }
}

UNSIGNED 7 bit Sender :

#include <Wire.h>
// MAX INT 32767
void setup()
{
  Wire.begin(2);                // join i2c bus with address #2
  Wire.onRequest(requestInt); // register event
}

int byteSending = 1;
int toTransfer = 32767;
int Shift = toTransfer;
int mask = 0xFF;
unsigned char toSend = 0;

void loop()
{
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestInt()
{
  if (byteSending == 1) //send packet 1
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 2;
  }
  else if (byteSending == 2) //send packet 2
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 3;
  }
  else if (byteSending == 3) //send packet 3
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 4;
  }
  else if (byteSending == 4) //send packet 4
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 1;
    //initialization for next turn
    Shift = toTransfer;
    mask = 0xFF;
    toSend = 0;
  }
}

UNSIGNED 7 bit Receiver :

#include <Wire.h>
// MAX INT 32767
void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}
int output = 0;

void loop()
{
  Wire.requestFrom(2, 1);   // the first byte
  while(Wire.available())
  { 
    unsigned char received = Wire.receive();
    output = received;
  }
  
  for (int i = 0 ; i < 3 ; i++) // next 3 bytes
  {
     Wire.requestFrom(2, 1);   
     while(Wire.available())
     { 
        unsigned char received = Wire.receive();
        output |= (received << 8);
     }
  }
  Serial.print(output);
  Serial.println(".");

  delay(500);
}