Arduino to arduino i2c code
Asked Answered
L

3

6

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()
{
}
Loxodromic answered 11/6, 2014 at 16:49 Comment(0)
D
5

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

Dialecticism answered 2/2, 2016 at 7:16 Comment(0)
G
1

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.

Garik answered 12/1, 2015 at 21:25 Comment(0)
S
0

In Arduino I2C, you can only send and receive one byte, and it is necessary to combine them in their equivalent data type.

Susurrant answered 24/7, 2020 at 2:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.