[英]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.