简体   繁体   English

Arduino作为I2C从属与RPi交谈

[英]Arduino as I2C slave talk to RPi

I use an Arduino as I2C slave to treat some Ultrasonic sensors and send revelant data to a Raspberry. 我使用Arduino作为I2C从设备来处理一些超声波传感器,并将相关数据发送到Raspberry。 The code running on Arduino : 在Arduino上运行的代码:

void setup() {
  // initialize i2c as slave
  Serial.begin(9600);
  Wire.begin(SLAVE_ADDRESS);
  // define callbacks for i2c communication
  Wire.onReceive(receiveData);
  Wire.onRequest(sendData);

  // useless
}

void loop() {
    // useless
} 

// callback for received data
void receiveData(int byteCount) {
  int i = 0;
  while (Wire.available()) {
    number[i] = (char) Wire.read();
    i++;
  }
  number[i] = '\0';
  Serial.println(atoi(number));
  if(atoi(number) != 0) { caseN = atoi(number); }
}  

int SonarSensor(int trigPin,int echoPin)
{
    // uselesss
}

// callback for sending data
void sendData() {
  if(caseN == 1) { Wire.write(distance1);}
  else if(caseN == 2) { Wire.write(distance2);}
  else if(caseN == 3) { Wire.write(distance3);}
  else if(caseN == 4) { Wire.write(distance4);}
  else if(caseN == 5)
  {
    if(state == 0)
    {
      state = 1;
      digitalWrite(ledPin, HIGH);
    }
    else
    {
      state = 0;
      digitalWrite(ledPin, LOW);
    }
  }
  else { Wire.write(0); }
}

I do a first version of the bus "chat" with Python and it works very well : 我使用Python制作了总线“聊天”的第一个版本,并且效果很好:

import smbus
import time

bus = smbus.SMBus(1)


address = 0x04

def writeNumber(value):
    bus.write_byte(address, value)
    return -1

def readNumber():
    number = bus.read_byte_data(address, 1)
    return number

while True:
    data = raw_input("Enter the data to be sent : ")
    data_list = list(data)
    for i in data_list:
        writeNumber(int(ord(i)))
        time.sleep(.1)

    writeNumber(int(0x0A))

I am trying to do the same in C but it looks a little bit more difficult : 我试图在C中做同样的事情,但看起来有点困难:

#include "i2c-dev.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <string.h>

int main() {
    const int adapter_nr = 1;
    char filename[20];
    snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
    const int file = open(filename, O_RDWR);
    if (file < 0) {
        printf("Unable to connect to Atmega, I2C plugged ? DC ok ?");
        exit(EXIT_FAILURE);
    }

    // Atmega address
    const int addr = 0x04;

    if(ioctl(file, I2C_SLAVE, addr) < 0) 
    {
        printf("Fail to reach Atmega");
        exit(EXIT_FAILURE);
    }

    const __u8 add = 5; // Ask to "distance 5"
    i2c_smbus_write_byte_data(file, 0x04, add); // What is the adress ?


    const __u8 reg = 0x0A;
    const __s32 result = i2c_smbus_read_byte_data(file, reg);
    if(result < 0) 
    {
        printf("Fail to reach Atmega reg");
        exit(EXIT_FAILURE);
    } 
    else 
    {
        printf("Distance %d cm \n", result);
    }

    close(file);

    return(EXIT_SUCCESS);
}

As I mentionned in the code, I don't know which register adress my Arduino slave has. 正如我在代码中提到的,我不知道Arduino从站拥有哪个寄存器地址。 I can see in the Arduino COM terminal a lot of 0 and only 0. 我可以在Arduino COM终端中看到很多0,只有0。

I hope you will understand my problem. 希望你能理解我的问题。 Thanks. 谢谢。

Why not define the slave address so you will know exactly what it is. 为什么不定义从站地址,以便您确切知道它是什么。 Plus this will allow you to set different address if in the future you use more than 1 arduino. 另外,如果将来您使用1个以上的arduino,则可以设置不同的地址。

Run this line of code before Setup on the arduino. 在arduino上进行安装之前,请运行此代码行。 You can change the address to anything you want as long as it isn't used by another system on the I2C connection. 只要I2C连接上的另一个系统不使用该地址,就可以将其更改为所需的任何地址。

#define  SLAVE_ADDRESS           0x29  //slave address,any number from 0x01 to 0x7F

Here is a Tutorial discussing using Arduino as a slave 这是讨论使用Arduino作为奴隶的教程

You need to know the correct I2C slave address that your Arduino is using. 您需要知道Arduino使用的正确的I2C从设备地址。

Luckily, Raspberry Pi has can detect any I2C device connected and show you their address using the following command: 幸运的是,Raspberry Pi可以检测到任何连接的I2C设备,并使用以下命令向您显示其地址:

sudo i2cdetect -y 1

or 要么

sudo i2cdetect -y 0

Note: The first command works for all the latest Raspberry Pi3 and Pi2 (models A, B, B +) and Pi Zero. 注意:第一个命令适用于所有最新的Raspberry Pi3和Pi2(型号A,B,B +)和Pi Zero。 The second command is only if you are using older models. 仅当您使用旧型号时,才使用第二条命令。

For more information you can have a look at here (Enable I2C) or here (Configuring I2C). 有关更多信息,请参见此处 (启用I2C)或此处 (配置I2C)。 Both are similar and you can just skip to the bottom where they explain how to use the above command. 两者都是相似的,您可以跳到底部,在那里他们解释如何使用上述命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM