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
this slave devices code (a temperature sensor uses wheatstone bridge measure resistance on temperature resistive element):
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():
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:
this way can fill in bytes , read out unsigned integer value.
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
Post a Comment