首页 文章

Arduino到arduino i2c代码

提问于
浏览
3

我有一个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()
{
}

2 回答

  • 1

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

    • 只有master可以启动读或写请求 .

    • 读取或写入请求必须是同步的 . 这意味着,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

  • 3

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

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

    然后才减少到 int .

相关问题