Go Down

Topic: Sending an Integer (int) throught I2C (Read 3845 times) previous topic - next topic

lpcmen2001

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 :

Code: [Select]

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 !

   

MeLight

#1
Mar 22, 2010, 10:01 pm Last Edit: Mar 22, 2010, 10:04 pm by MeLight Reason: 1
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 :)

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

Grumpy_Mike

Quote
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


MeLight

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

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?

lpcmen2001

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 :

Code: [Select]
#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
------------------

Code: [Select]
#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);
}

MeLight

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 ;) But I'm afraid I can't tell you why it covers the positive range only

lpcmen2001

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

MeLight

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

lpcmen2001

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 :

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

MeLight

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

lpcmen2001

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

Code: [Select]
#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 :

Code: [Select]
#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 :

Code: [Select]
#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 :

Code: [Select]
#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);
}

Go Up