[英]I want to receive multiple data from arduino to raspberry pi using I2C
感谢任何有礼貌地调查这个问题的人。
我想使用 I2C 从 arduino 接收多个数据到树莓派。
我可以从 arduino 获得 1 个数据,但是一旦我移动到多个数据,它就无法这样做。
到目前为止,我已经尝试了多种方法,我发现这种方法最适合从 Arduino 获取数据。
我之前从 arduino 获取数据的尝试如下: 我想使用 Raspberry Pi 使用 I2C 从 Arduino 读取Raspberry Pi 的终端响应有无法识别的奇怪字体
现在都解决了。 从下面的链接获得大量帮助https://area-51.blog/2014/02/15/connecting-an-arduino-to-a-raspberry-pi-using-i2c/
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++代码
//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;
}
我对 c++ 代码的期望如下
15 doh Why No Work? 15
但我明白了
15 doh weird font can't be recognized 255
Wire.write(distance);
想在 I2C 总线上写一个long
。 对于 Arduino 这是 32 位 4 字节的数据。 我不确定wire.write
到底做了什么,因为我能找到的文档不合标准,甚至可以说是垃圾,但文档看起来会发送你想要发送的4 个字节中的1 个。 为了发送多个字节,看起来您需要使用数组版本: Wire.write(&distance, sizeof (distance));
,但即使这样可能还不够。 我稍后再谈。
Wire.write("Why No Work?");
将一个以 null 结尾的字符串(特别是const char[13]
)写入 I2C 总线。 我不知道 arduino 是否也发送终止 null。
所以
Wire.write(distance);
Wire.write("Why No Work?");
Wire.write(distance);
需要将至少 4 + 12 + 4 个字节写入 I2C 总线。 并且可能只写了 1 + 12 + 1。
在 Pi 方面,
read(file,buf, 3);
读出 3 个字节。 这还不足以得到完整的distance
,更不用说字符数组和distance
的第二次写入了。 您需要读取您编写的所有数据,至少 20 个字节。
此外,
char buf[0];
定义一个长度为 0 的数组。 您无能为力,因为这里没有存储任何东西的空间。 它不能容纳 3 个字符,更不用说必要的 20 或 21 个字符了。 read
3 个字节写入无效 memory 并且程序不能再指望理智的结果。
这意味着充其量
float distance= (int) buf[0];
dd= buf[1];
float dist=(int) buf[2];
只得到了四个字节distance
中的一个字节,结果与预期的一样真是太幸运了。 dd
只得到一个字符,而不是整个字符串,由于前面的错误之一,这被证明是无稽之谈。 dist
同样是垃圾。
要成功地将数据从一台机器移动到另一台机器,您需要建立通信协议。 你不能只在电线上写一个long
字。 long
在所有平台上的大小都不相同,也不总是具有相同的 encoding 。 您必须绝对确定双方就long
的写入方式(大小和字节顺序)和读取方式达成一致。
您将如何执行此操作取决于您,但这里有一些提示和搜索词serialization ,可帮助您进行进一步的研究。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.