I2c Programming Query

I decided to have a try at configuring two Arduino Uno’s together using I2c. First, I had the master turning on and off the pin 13 LED on the slave, then the master reading some individual characters by requesting 1 byte per character. Secondly, I then attempted to get my slave to read an analog light sensor followed by the master retrieving the value and printing it out to the serial monitor.

At first, this didn’t work properly as the value for the sensor is an Int mapped to the usual 0 - 1023 steps as I am requesting 1 byte in my masters code. I then remapped the light sensor value to 100 - 0 steps. Shortly, the master seemed to be retrieving numbers that looked familiar (0 no light, 100 max) to it running on just one board. Is this because I am requesting a byte, and a byte has 0-255 combinations? Also what if I want to retrieve an integer like my first attempt, or a string variable?

Later, I decided to attempt to read 2 integer variables from the slave (light and an incremental variable), but now the light sensor value is reading 255, whilst the incremental variable is incrementing, although both values seem to be printing out in a reverse order through the serial monitor.

I’ve provided both sketches below:

//  I2c Master Code (UNO)

#include <Wire.h>

void setup() {

  Serial.begin(9600);

  Wire.begin();
}

void loop()
{

  Wire.requestFrom(5, 2);

  int lightVal = Wire.read();
  int increment = Wire.read();

  Serial.print(lightVal) + Serial.print("\t") + Serial.println(increment);

  delay(1000);

}
//  I2c Slave Code (UNO)

#include <Wire.h>

#define lightPin 0

int lightVal; 
int increment = 1;

void setup() {

  //  Give it the I2c address of 5
  Wire.begin(5);

  Wire.onRequest(myRequestEvent);

}

void loop()
{

  lightVal = analogRead(lightPin);
  lightVal = map(lightVal, 0, 1023, 100, 0);

  increment++;

  delay(900);
}

void myRequestEvent()
{
  Wire.write(lightVal);
  Wire.write(increment);
}

daz1761:
Also what if I want to retrieve an integer like my first attempt, or a string variable?

For an int, you can use highByte() and lowByte() to extract the two bytes from the int and send them individually. On the receiver you can use word() to recombine them.

Later, I decided to attempt to read 2 integer variables from the slave (light and an incremental variable), but now the light sensor value is reading 255, whilst the incremental variable is incrementing, although both values seem to be printing out in a reverse order through the serial monitor.

255 likely means that there is no data to be read, but you're telling it to read the data anyway. You shouldn't be reading the data unless Wire.available() says there is data to read.

For an int, you can use highByte() and lowByte() to extract the two bytes from the int and send them individually. On the receiver you can use word() to recombine them.

I’ll have to have a play with them functions as It been a while since I used them, but I get the concept as in integer is 2 bytes. I imagine for a string you would have to find out how many characters or the size of it before you could request the correct number of bytes.

255 likely means that there is no data to be read, but you’re telling it to read the data anyway. You shouldn’t be reading the data unless Wire.available() says there is data to read.

I’ve added what you recommended, but I’m still getting the same results in the console:

//  I2c Master Code (UNO)

#include <Wire.h>

void setup() {

  Serial.begin(9600);

  Wire.begin();
}

void loop()
{

  Wire.requestFrom(5, 2);
  
  while(Wire.available())
  {

  int lightVal = Wire.read();
  int increment = Wire.read();

  Serial.print(lightVal) + Serial.print("\t") + Serial.println(increment);
  }
  
  delay(1000);

}

In the mean time I’ll keep experimenting :slight_smile:

See here: Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino

On that page is a small library that lets you transfer other data types (eg. int) easily.

void myRequestEvent()
{
  Wire.write(lightVal);
  Wire.write(increment);
}

You can't return separate bytes like that, see my page above.

Many thanks, will check it out after my many jobs!