Transmitting an integer over I2C


i'd transmit integers via i2c, , have found other people have been interested in doing so. using solution below, have run problem. loop run transmit integer looking 4 times , transmit gobbledegook 12 times. while recognize may because have 2 loops running 4 times each, manipulating these loops run different times no longer transmits desired numbers.

to clarify operation, sender breaks number 1 bit characters, , receiver reads individual chars , compiles them 1 integer again.

i'll include code below, , post results of test runs tomorrow when have access arduino boards. thank help.

this master controller code
code: [select]
#include <wire.h>
// max int -16382 16382
int output = 0;

void setup()
{
  wire.begin();        // join i2c bus (address optional master)
  serial.begin(115200);  // start serial output
}

void loop()
{
  wire.requestfrom(1, 1);   // first byte
  while(wire.available())
  {
    char received = wire.read();
    output = received;
  }
 
  (int = 0 ; < 3 ; i++) // next 3 bytes
  {
     wire.requestfrom(1, 1);   
     while(wire.available())
     {
        char received = wire.read();
        output |= (received << 8);
     }
  }
  serial.println(output);
  //serial.println("loop");
  //serial.println(".");
  delay(500);
}


this slave devices code (a temperature sensor uses wheatstone bridge measure resistance on temperature resistive element):
code: [select]
#include <wire.h>
int analogpin1 = 1; // potentiometer wiper (middle terminal) connected analog pin 3
// outside leads ground , +5v
int analogpin0 = 0; // (analog)
int inputpin = 2; // 5 volt source (digital)
int vout;        // variable store output voltage
int deviceid = 1; // i2c address
int bytesending = 1;
int totransfer;
int shift = totransfer;
int mask = 0xff;
char tosend = 0;

void setup()
{
  wire.begin(deviceid);
  wire.onrequest(requestevent);
  //serial.begin(115200);             // setup serial
  pinmode (inputpin,output);
  serial.begin(115200);
}

void loop()
{
  requestevent();
  //  serial.println(volta);
  delay(2000);
}

void requestevent()
{
  int totransfer = takevoltage();
  if (bytesending == 1) //send packet 1
  {
    tosend = shift & mask;
    shift = shift >> 8;
    wire.write(tosend);
    bytesending = 2;
  }
  else if (bytesending == 2) //send packet 2
  {
    tosend = shift & mask;
    shift = shift >> 8;
    wire.write(tosend);
    bytesending = 3;
  }
  else if (bytesending == 3) //send packet 3
  {
    tosend = shift & mask;
    shift = shift >> 8;
    wire.write(tosend);
    bytesending = 4;
  }
  else if (bytesending == 4) //send packet 4
  {
    tosend = shift & mask;
    shift = shift >> 8;
    wire.write(tosend);
    bytesending = 1;
    //initialization next turn
    shift = totransfer;
    mask = 0xff;
    tosend = 0;
  }
}
int takevoltage()
{
  digitalwrite(inputpin,high); // supply voltage voltage divider
  int voltageread1 = analogread(analogpin1);    // reads voltage input pin
  int voltageread2 = analogread(analogpin0);     // reads voltage input pin
  //delay(1000);
  digitalwrite(inputpin,low);
  int rawvoltage = voltageread1-voltageread2;
  //serial.println(rawvoltage);
  //int voltage = (5.0 / 1023.0) * rawvoltage;
  return rawvoltage;
}

you made several errors in sketch. first variable of type "int" 15 bits in size plus 1 sign bit. recommend use explicit types (int16_t, uint32_t, etc.) correct size.

in case don't need 32 bit because result of analogread() call 10 bit integer.


the next error in main loop():

code: [select]
  wire.requestfrom(1, 1);   // first byte
  while(wire.available())
  {
    char received = wire.read();
    output = received;
  }
 
  (int = 0 ; < 3 ; i++) // next 3 bytes
  {
     wire.requestfrom(1, 1);   
     while(wire.available())
     {
        char received = wire.read();
        output |= (received << 8);
     }
  }


the code "received << 8" produces result of 0 because received of type char , char has 8 bits. move 8 bits out of variable 0 left. if you're lucky, compiler noticed mistake , switched 16 bit value result you're or'ing 3 bytes same result byte producing unexpected outputs.

so switch unsigned 16 bit integers sketch , use unions this:

code: [select]
union {
  uint16_t    intval;
  uint8_t     bytes[2];
};


this way can fill in bytes , read out unsigned integer value.


Arduino Forum > Using Arduino > Networking, Protocols, and Devices (Moderator: fabioc84) > Transmitting an integer over I2C


arduino

Comments

Popular posts from this blog

Convierte tu Raspberry en un NAS. Firmware fvdw-sl 15.3 - Raspberry Pi Forums

How to format a Get Request

avrdude: verification error, first mismatch at byte 0x0000 0x0c != 0x62