Arduino到arduino i2c代码

时间:2014-06-11 16:49:00

标签: arduino arduino-uno

我有一个OPT101连接到一个从属arduino来测量光强度。我想将从OPT101电路接收的数据发送到主arduino,该主arduino将在串行监视器上打印数据。当我测试我的代码时,屏幕上没有任何内容。 (我知道它不是我的i2c连接,因为我通过发送"你好"来测试它。我使用arduino leonardo作为奴隶,而arduino uno作为主人。

OPT101电路的代码是:

#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);

}

我厌倦了将奴隶代码和我的OPT101代码结合起来得到这个:     #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);
}

这是我的主代码:

#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()
{
}

3 个答案:

答案 0 :(得分:3)

您必须按照下述步骤在主I2C设备之间进行通信:

  • 只有主人才能发起读写请求。
  • 读取或写入请求必须是同步的。这意味着,slave只能在主请求之后返回数据,反之亦然,以便写入。
  • 不要使用0到7之间的从地址。它们是reserved。使用范围在8到127之间的从站地址。
  • 在Arduino I2C上,您只能发送和接收一个字节。要发送或接收具有多个字节的整数,double,您需要先将它们拆分,而在另一侧,必须将它们组合成等效的数据类型。 (纠正我,如果我错了。)

您的代码应如下所示:

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);
}
  

此代码在Arduino版本上测试: 1.6.7 。   有关I2C通信的更多信息,请参阅Arduino   示例:Master Reader

答案 1 :(得分:1)

为什么要将while循环放在setup()函数中而不是使用loop()函数?

但更令人困惑的是这一行int pVolt0 = pinRead0 / 1024.0 * 5.0;。在初始代码中,变量不是int,而是double。我建议你尝试使用原始行重新编码:     double pVolt0 = pinRead0 / 1024.00 * 5.0;

然后才减少到int

答案 2 :(得分:0)

在Arduino I2C中,您只能发送和接收一个字节,并且有必要将它们组合为等效的数据类型。