Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arduino to arduino i2c code

I have an OPT101 connected to a slave arduino to measure light intensity. I want to send the data received from the OPT101 circuit to a master arduino that will print the data on the serial monitor. When I test my code, nothing shows up on the screen. (I know it's not my i2c connection cause I tested it by sending "hello"). I am using an arduino leonardo as the slave and the arduino uno as the master.

The code for the OPT101 circuit is:

#define inPin0 0

void setup() {

  Serial.begin(9600);
  Serial.println();

}

void loop() {

  int pinRead0 = analogRead(inPin0);
  double pVolt0 = pinRead0 / 1024.00 * 5.0;
  Serial.print(pVolt0, 4 );
  Serial.println();

  delay(100);

}

I tired to combine the slave code and my OPT101 code to get this: #include

#define inPin0 0

void setup() {

  Wire.begin(2);

}

void loop() {

  Wire.beginTransmission(2);
  Wire.onRequest(requestEvent);
  Wire.endTransmission();

}

void requestEvent()
{  
  int pinRead0 = analogRead(inPin0);
  int pVolt0 = pinRead0 / 1024.0 * 5.0;
  Wire.write((byte)pVolt0);
}

And this is my master code:

#include <Wire.h>

void setup()
{

  Wire.begin();
  Serial.begin(14400);

  Wire.requestFrom(2, 8);

  while(Wire.available())
  {

    char c = Wire.read();
    Serial.print(c);
  }
}

void loop()
{
}
like image 960
user3730950 Avatar asked Jun 11 '14 16:06

user3730950


People also ask

Can Arduino communicate to I2C?

Arduino supports I2C Communication. If you take a look at the pinout of Arduino UNO from the tutorial “ARDUINO UNO PINOUT”, Analog Input pins A4 and A5 have an alternative function of I2C. The A4 pin acts as SDA while the A5 pin acts as SCL.

How do I connect two Arduinos with I2C?

Follow these steps to connect two Arduino UNOs using I2C: Connect pins A4 and A5 on one Arduino to the same pins on the other one. The GND line has to be common for both Arduinos. Connect it with a jumper.

How do you get two Arduinos to communicate with each other?

When you connect two Arduino with each other, you have to connect their ground. In this tutorial when the Arduino UNO number 1 lights ON the onboard LED, the Arduino UNO number 2 connects to the computer, prints HIGH on the serial port and switches ON the onboard LED. The result is two Arduino UNO that blink together.


2 Answers

You must follow steps described below to communicate between master and slave I2C devices:

  • Only master can initiate read or write request.
  • Read or write requests must be synchronous. It means, slave can only return data after master requests for them and vice versa for write.
  • Do not use slave address from 0 - 7. They are reserved. Use slave address that ranges between 8 to 127.
  • On Arduino I2C, you can only send and receive a byte. To send or receive integer, double that have multiple bytes, you need to split them first and on other side, you have to combine them into its equivalent datatype. (Correct me, if I'm wrong.)

Your code should be like this:

Master Sketch:

#include <Wire.h>
#define SLAVE_ADDRESS 0x40

// This macro reads two byte from I2C slave and converts into equivalent int
#define I2C_ReadInteger(buf,dataInteger) \
    buf[0] = Wire.read(); \
    buf[1] = Wire.read(); \
    dataInteger = *((int *)buf);

// Returns light intensity measured by 'SLAVE_ADDRESS' device
int GetLightIntensity()
{
    byte Temp[2];
    int Result;

    // To get integer value from slave, two are required
    int NumberOfBytes = 2;

    // Request 'NumberOfBytes' from 'SLAVE_ADDRESS'
    Wire.requestFrom(SLAVE_ADDRESS, NumberOfBytes);

    // Call macro to read and convert bytes (Temp) to int (Result)
    I2C_ReadInteger(Temp, Result);

    return Result;
}

void setup()
{
    // Initiate I2C Master
    Wire.begin();

    // Initiate Serial communication @ 9600 baud or of your choice
    Serial.begin(9600);
}

void loop()
{
    // Print light intensity at defined interval
    Serial.print("Light Intensity = ");
    Serial.println(GetLightIntensity());

    delay(1000);
}


Slave Sketch:

#include <Wire.h>
#define SLAVE_ADDRESS 0x40
#define inPin0 0

// Preapres 2-bytes equivalent to its int
#define IntegerToByte(buf,intData) \
  *((int *)buf) = intData;

// Sends int to Master
void I2C_SendInteger(int Data)
{
  byte Temp[2];

  // I2C can only send a byte at a time.
  // Int is of 2bytes and we need to split them into bytes
  // in order to send it to Master.
  // On Master side, it receives 2bytes and parses into
  // equvivalent int.
  IntegerToByte(Temp, Data);

  // Write 2bytes to Master
  Wire.write(Temp, 2);
}

void setup()
{
  // Initiate I2C Slave @ 'SLAVE_ADDRESS'
  Wire.begin(SLAVE_ADDRESS);

  // Register callback on request by Master
  Wire.onRequest(requestEvent);
}


void loop()
{
}

//
void requestEvent()
{  
  // Read sensor
  int pinRead0 = analogRead(inPin0);
  int pVolt0 = pinRead0 / 1024.0 * 5.0;

  // Send int to Master
  I2C_SendInteger(pVolt0);
}

This code is tested on Arduino Version: 1.6.7. For more information regarding I2C communication, refer Arduino Example: Master Reader

like image 117
Anurag Vasanwala Avatar answered Oct 11 '22 17:10

Anurag Vasanwala


Why are you putting the while loop in the setup() function instead of using the loop() function ?

But more confusing is this line int pVolt0 = pinRead0 / 1024.0 * 5.0;. In the initial code the variable is not int but double. I suggest you try to recode using the original line: double pVolt0 = pinRead0 / 1024.00 * 5.0;

And only then reduce to int.

like image 25
MAC Avatar answered Oct 11 '22 18:10

MAC