简体   繁体   English

我想使用 I2C 从 arduino 接收多个数据到树莓派

[英]I want to receive multiple data from arduino to raspberry pi using I2C

Thank you to whoever is kind enough to look into this question.感谢任何有礼貌地调查这个问题的人。

I want to receive multiple data from arduino to raspberry pi using I2C.我想使用 I2C 从 arduino 接收多个数据到树莓派。

I can obtain 1 data from arduino, but once I move to more than one data, it fails to do so.我可以从 arduino 获得 1 个数据,但是一旦我移动到多个数据,它就无法这样做。

I have tried multiple methods so far, and I found this method to work the best to obtain data from Arduino.到目前为止,我已经尝试了多种方法,我发现这种方法最适合从 Arduino 获取数据。

My previous attempt in obtaining data from arduino is as follows: I want to read from Arduino using I2C using Raspberry Pi Raspberry Pi's terminal response has weird font that cannot be recognized我之前从 arduino 获取数据的尝试如下: 我想使用 Raspberry Pi 使用 I2C 从 Arduino 读取Raspberry Pi 的终端响应有无法识别的奇怪字体

Which are all solved by now.现在都解决了。 Got Massive Help from link below https://area-51.blog/2014/02/15/connecting-an-arduino-to-a-raspberry-pi-using-i2c/从下面的链接获得大量帮助https://area-51.blog/2014/02/15/connecting-an-arduino-to-a-raspberry-pi-using-i2c/

Arduino Code Arduino 代码

#include <Wire.h>

#define echoPin 7
#define trigPin 8

int number=0;
long duration;
long distance;

void setup()
{
  //Join I2C bus as slave with address 8
  Wire.begin(8);

  //Call SendData & Receive Data
  Wire.onRequest(SendData);
  //Setup pins as output and input to operate ultrasonic sensor
  Serial.begin(9600);
  pinMode(echoPin,INPUT);
  pinMode(trigPin,OUTPUT);
}

void loop ()
{
  digitalWrite(trigPin,LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin,HIGH);
  delayMicroseconds(2);

  digitalWrite(trigPin,LOW);

  duration=pulseIn(echoPin,HIGH);

  distance=duration/58.2;

  Serial.print(distance);
  Serial.println(" cm");
}

void SendData()
{
  Wire.write(distance);
  Wire.write("Why No Work?");
  Wire.write(distance);
}

C++ Code C++代码

//Declare and Include the necessary header files
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>

//Define Address of Slave Address
#define ADDRESS 0x08

//Eliminate the Used of std in the future
using namespace std;

static const char *devName="/dev/i2c-1";

int main(int argc, char **argv)
{
    //Check to see if C++ works
    cout<<"Hello, World!\n";
    cout<<"I2C: Connecting"<<endl;
    int file;

    if ((file = open(devName, O_RDWR))<0)
    {
        fprintf(stderr, "I2C: Failed to access");
        exit(1);
    }

    if (ioctl(file, I2C_SLAVE, ADDRESS)<0)
    {
        cout<<"Failed to Access"<<endl;
    }
    char buf[0];
    char dd;
    for (int i=0; i<100;i++)
    {
        read(file,buf, 3);
        float distance= (int) buf[0];
        dd= buf[1];
        float dist=(int) buf[2];

        cout<<distance<<endl;
        usleep(10000);
        cout<<"doh"<<endl;
        cout<<dd<<endl;
        cout<<dist<<endl;
    }
    return 0;
}

What I would expect from the c++ code would be as follows我对 c++ 代码的期望如下

15
doh
Why No Work?
15

But I get但我明白了

15
doh
weird font can't be recognized
255
Wire.write(distance);

wants to write a long onto the I2C bus.想在 I2C 总线上写一个long For an Arduino This is 32 bits, 4 bytes, of data.对于 Arduino 这是 32 位 4 字节的数据。 I'm not sure exactly what wire.write does because the documentation I can find is substandard to the point of being garbage, but the documentation looks like it's going to send exactly 1 of the 4 bytes you wanted to send.我不确定wire.write到底做了什么,因为我能找到的文档不合标准,甚至可以说是垃圾,但文档看起来会发送你想要发送的4 个字节中的1 个。 In order to send more than one byte, it looks like you need to use the array version: Wire.write(&distance, sizeof (distance));为了发送多个字节,看起来您需要使用数组版本: Wire.write(&distance, sizeof (distance)); , but even this may not be sufficient. ,但即使这样可能还不够。 I'll get back into that later.我稍后再谈。

Wire.write("Why No Work?");

writes a null-terminated string (specifically a const char[13] ) onto the I2C bus.将一个以 null 结尾的字符串(特别是const char[13] )写入 I2C 总线。 I don't know arduino well enough to know if this also sends the terminating null.我不知道 arduino 是否也发送终止 null。

so所以

Wire.write(distance);
Wire.write("Why No Work?");
Wire.write(distance);

needed to write at least 4 + 12 + 4 bytes onto the I2C bus.需要将至少 4 + 12 + 4 个字节写入 I2C 总线。 and probably only wrote 1 + 12 + 1.并且可能只写了 1 + 12 + 1。

On the Pi side,在 Pi 方面,

read(file,buf, 3);

read out 3 bytes.读出 3 个字节。 This isn't enough to get the whole of distance , let alone the array of characters and second write of distance .这还不足以得到完整的distance ,更不用说字符数组和distance的第二次写入了。 You need to read all of the data you wrote, at least 20 bytes.您需要读取您编写的所有数据,至少 20 个字节。

In addition,此外,

char buf[0];

defines an array of 0 length.定义一个长度为 0 的数组。 There isn't much you can do with it as there is no space to store anything here.您无能为力,因为这里没有存储任何东西的空间。 It cannot hold 3 characters, let alone the 20 or 21 necessary.它不能容纳 3 个字符,更不用说必要的 20 或 21 个字符了。 read of 3 bytes wrote into invalid memory and the program can no longer be counted on for sane results . read 3 个字节写入无效 memory 并且程序不能再指望理智的结果

This means that at best这意味着充其量

    float distance= (int) buf[0];
    dd= buf[1];
    float dist=(int) buf[2];

got only one byte of the four bytes of distance and it's dumb luck that the result was the same as expected.只得到了四个字节distance中的一个字节,结果与预期的一样真是太幸运了。 dd got exactly one character, not the whole string, and this is turning out to be nonsense because of one of the preceding mistakes. dd只得到一个字符,而不是整个字符串,由于前面的错误之一,这被证明是无稽之谈。 dist is similarly garbage. dist同样是垃圾。

To successfully move data from one machine to another, you need to establish a communication protocol.要成功地将数据从一台机器移动到另一台机器,您需要建立通信协议。 You can't just write a long onto a wire.你不能只在电线上写一个long字。 long doesn't have the same size on all platforms, nor does it always have the same encoding . long在所有平台上的大小都不相同,也不总是具有相同的 encoding You have to make absolutely certain that both sides agree on how the long is to be written (size and byte order) and read.您必须绝对确定双方就long的写入方式(大小和字节顺序)和读取方式达成一致。

Exactly how you are going to do this is up to you, but here are some pointers and a search term, serialization , to assist you in further research.您将如何执行此操作取决于您,但这里有一些提示和搜索词serialization ,可帮助您进行进一步的研究。

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

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