- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 ISO 9141-2 协议(protocol)从 ECU 读取数据。我使用的电缆是OBD2转USB,使用FT232R芯片。我正在运行的程序是用 C 编写的。
当我向串行端口(ttyUSB0)写入命令时,它写入得很好,但是当它读回接收到的数据时,它只返回相同的数据。我不确定它为什么要这样做,而不是从 ECU 返回数据。
任何帮助都很棒,谢谢。
示例代码 - 尝试设置波特率等,但也没有成功。
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
char *port = "/dev/ttyUSB0";
char receivedData[100];
int n, fd;
fd = open(port, O_RDWR | O_NOCTTY);
if(fd > 0){
n = write(fd, "AT I\r\n", 10);
read(fd, receivedData, 10);
printf("%s\n", receivedData);
close(fd);
}
else{
printf("failed to open device\n");
}
return 0;
}
最佳答案
尽管这不是问题的直接答案,但这么多代码不适合评论部分。
我使用这些函数来初始化串行线:
#include <stdio.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
struct baud_map {
int baud;
speed_t speed;
};
struct baud_map baudmap[] = {
{ 50 , B50 },
{ 75 , B75 },
{ 110 , B110 },
{ 134 , B134 },
{ 150 , B150 },
{ 200 , B200 },
{ 300 , B300 },
{ 600 , B600 },
{ 1200 , B1200 },
{ 1800 , B1800 },
{ 2400 , B2400 },
{ 4800 , B4800 },
{ 9600 , B9600 },
{ 19200 , B19200 },
{ 38400 , B38400 },
{ 57600 , B57600 },
{ 115200 , B115200 },
{ 230400 , B230400 },
{ 0, 0 }
};
int dbits_map[] = { 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 };
enum parity_t {
PARITY_NO_PARITY,
PARITY_ODD,
PARITY_EVEN
};
int baud_to_speed(int baud, speed_t *speed)
{
if(speed == NULL)
return 0;
struct baud_map *map = baudmap;
while(map->baud)
{
if(map->baud == baud)
{
*speed = map->speed;
return 1;
}
map++;
}
return 0;
}
/*
* tty: "/dev/ttyUSB0"
* baud: baudrate, for example 9600
* parity: see enum parity_t
* stop_bits: 1 or 2
* data_bits: [5-8]
*
* return the fd on success, -1 on failure
*/
int openSerial_long(const char *tty, int baud, enum parity_t parity, int stop_bits, int data_bits)
{
int fd;
speed_t speed;
if(baud_to_speed(baud, &speed) == 0)
{
fprintf(stderr, "Invalid baudrate %d\n", baud);
return 0;
}
fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd == -1)
{
fprintf(stderr, "Could not open %s as a tty: %s\n", tty, strerror(errno));
return -1;
}
struct termios termios;
if(tcgetattr(fd, &termios) == -1)
{
fprintf(stderr, "Could not get tty attributes from %s: %s\n", tty, strerror(errno));
close(fd);
return -1;
}
// setting common values
termios.c_iflag &= ~ICRNL; // do not translate \r into \n
termios.c_oflag &= ~OPOST; // do not map \n to \r\n
termios.c_cflag |= (CREAD | CLOCAL); // enable receiver & ignore model ctrl lines
termios.c_lflag |= (ISIG | ICANON); // enable signals and noncanonical mode
termios.c_lflag &= ~ECHO; // disable echo
cfsetispeed(&termios, speed);
cfsetospeed(&termios, speed);
switch(parity)
{
case PARITY_NO_PARITY:
termios.c_cflag &= ~PARENB;
break;
case PARITY_ODD:
termios.c_cflag |= PARENB;
termios.c_cflag |= PARODD;
break;
case PARITY_EVEN:
termios.c_cflag |= PARENB;
termios.c_cflag &= ~PARODD;
break;
default:
fprintf(stderr, "invalid parity\n");
break;
}
if(stop_bits == 1)
termios.c_cflag &= ~CSTOPB;
else if(stop_bits == 2)
termios.c_cflag |= CSTOPB;
else
fprintf(stderr, "Invalid stop bit\n");
int bits;
switch(data_bits)
{
case 5:
case 6:
case 7:
case 8:
bits = dbits_map[data_bits];
break;
default:
bits = -1;
}
if(bits != -1)
{
termios.c_cflag &= ~CSIZE;
termios.c_cflag |= bits;
} else
fprintf(stderr, "Invalid data size\n");
if(tcsetattr(fd, TCSANOW, &termios) == -1)
{
fprintf(stderr, "Could not get tty attributes from %s: %s\n", tty, strerror(errno));
close(fd);
return -1;
}
return fd;
}
/**
* tty: "/dev/ttyUSB0"
* baud: baudrate, for example 9600
* mode: a string like 8N1 where
* the first character is the number of data bits (range from 5-8)
* the second character is N (no parity), O (odd), E (even)
* the third character is the number of stop bits (1 or 2)
*/
int openSerial(const char *tty, int baud, const char *mode)
{
if(tty == NULL || mode == NULL)
return -1;
if(strlen(mode) != 3)
{
fprintf(stderr, "invalid mode\n");
return -1;
}
int stop_bits = mode[2];
if(stop_bits != '1' && stop_bits != '2')
{
fprintf(stderr, "Invalid stop bits\n");
return -1;
}
stop_bits -= '0';
enum parity_t parity;
switch(mode[1])
{
case 'n':
case 'N':
parity = PARITY_NO_PARITY;
break;
case 'o':
case 'O':
parity = PARITY_ODD;
break;
case 'e':
case 'E':
parity = PARITY_EVEN;
break;
default:
fprintf(stderr, "Invalid parity\n");
return -1;
}
int data_bits = mode[0] - '0';
if(data_bits < 5 || data_bits > 8)
{
fprintf(stderr, "invalid data bits\n");
return -1;
}
return openSerial_long(tty, baud, parity, stop_bits, data_bits);
}
最常见的模式是“8N1”
(8位数据,无奇偶校验,1个停止位),我打开串行线与
int fd = open("/dev/ttyUSB0", 9600, "8N1");
if(fd == -1)
{
fprintf(stderr, "Error, could not initialize serial line\n");
exit(EXIT_FAILURE);
}
我不知道您必须使用哪些串行设置,请在手册中查找。
还要注意这样的事情
n = write(fd, "AT I\r\n", 10);
是错误的,这是未定义的行为,因为 write
读取超出了范围字符串文字的。最好这样做:
const char *cmd = "AT I\r\n";
n = write(fd, cmd, strlen(cmd));
然后您将写入正确的数据量。
就像我在评论中所说的,我已经对 ISO 9141-2 进行了谷歌搜索,我可以没有找到任何关于它是否使用AT命令的可靠信息。所以,请检查您正在尝试阅读的 OBDII 芯片的手册。
Wikipedia says
ISO 9141-2. This protocol has an asynchronous serial data rate of 10.4 kbit/s. It is somewhat similar to RS-232; however, the signal levels are different, and communications happens on a single, bidirectional line without additional handshake signals. ISO 9141-2 is primarily used in Chrysler, European, and Asian vehicles.
在我看来,这个协议(protocol)只是类似于RS232,也许你需要支持此波特率的另一个转换器(FT232R 除外)。 This页面还指出波特率为 10400 位/秒,这不是默认支持。我找到了这个post这也表明你应该使用两个转换器,一个用于OBD2和转换器之间的通信以 10.4 kbit/s 传输,转换器和 PC 之间以标准波特率传输比如 19.2 kbits/s。
或者,您可以尝试设置自定义波特率,如 here 中所述。和 here 。我从来没有使用过自定义波特率,所以我不知道这是否有效。
关于c - 尝试将 AT 命令写入 USB 转 OBDii 电缆,使用 FT232R 读取 ECU 数据 (ISO 9141-2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49221630/
我在一本名为 "USB in a NutShell" 的相当棒的书中找到了中断传输提供可靠的传输(通过错误检测和自动重试)。 但我想知道,这能保证有一天不会按顺序交换转移吗?至于总线是串行的,我的猜测
USB 2.0 specifies 4 种传输类型(在第 5.4 节传输类型中): 控制转移 同步传输 中断传输 批量转账 第 5.8 节说批量传输提供: Access to the USB on a
在我正在研究的 SoC 中,有 USB EHCI 兼容 Controller 。 所有 EHCI Controller 都可以作为主机或设备工作吗? EHCI Linux 驱动程序是否涵盖此类 Con
我有一个 USB 调制解调器,它经常掉线。发生这种情况时,我将其从 USB 端口拔出并重新插入,它会立即返回信号;我可以编写一个程序来执行此操作而无需物理断开调制解调器与端口的连接吗? 最佳答案 正如
我正在尝试使用 libusb 与 USB 设备通信,但我觉得自己在比赛的第一站被绊倒了。我确切地知道我需要与哪些端点交谈,等等,但我什至做不到那么远。本质上,我有: usb_device *dev =
是否有工具可以验证在枚举过程中读取的 USB 设备描述符?我遇到过这样的情况,我购买的设备(实验室设备)的 USB 设备描述符不是很有效,并且无法被操作系统正确识别为“加载设备描述符失败”。我知道这并
我正在从事一个需要将信号从外部世界传输到计算机的项目。我有一个生成模拟信号的源,这个信号需要通过 USB 在 PC 上传输。这是我的问题:什么是接口(interface)? 我从源头获得的模拟信号,是
我想知道降低/提高 USB 端口的输出功率在技术上是否可行? 我自己也持怀疑态度,但我要求确定。 最佳答案 如上所述,是的。要获得超过 500mA (USB 2.0) 的电流,请使用组合电缆并联两个或
我正在尝试制作一个 HID USB 设备。我搜索了一下,发现键盘的输出有 8 个字节。第一个字节是修饰符,第二个字节是保留字节,其余 6 个字节是关键代码。我认为在某些情况下,例如“prtsc”,需要
我们正在寻找一个虚拟 USB 链接模拟器;这个程序或服务应该 链接虚拟COM port到仅接受 USB 作为数据链路的应用程序。 virtual COM port是 VSPE来自 Eterlogic
我一直在尝试监视何时插入或移除 USB 设备,它似乎工作得很好。现在唯一困扰我的是,每次我插入或移除设备时,都会多次触发该事件。 我可以毫无问题地将事件分组,但我很好奇为什么它首先发生。 这是我正在使
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 6年前关闭。 Improve this questi
我正在为 USB 设备编写代码。假设 USB 主机开始控制读取传输以从设备读取一些数据,并且请求的数据量(设置数据包中的 wLength)是端点 0 最大数据包大小的倍数。那么在主机接收到所有数据后(
我们正在开发一个带有 arm7(current: LPC2368) 的发送器设备。 本设备采样一个 mv 信号,A/D,并需要将此信号数据发送到 PC。(连续) 同时,PC 需要向 arm7 发送命令
我希望能够使用通过 USB 连接到 PC 的 IR 远程传感器打开和关闭我的 PC。该传感器是使用 AVR 微处理器和 V-USB 软件 USB 实现实现的定制 PCB。 现在,用软件关掉电脑是没有问
我正在使用 STM32L151 与使用 USB CDC 的 PC 进行通信。我使用 STM32 HAL 库来创建我的项目。 我发现 USB 以 1 ms 的间隔发送数据,每次发送 64 个字节。那么,
我们有一个设备要求我们在插入之前安装驱动程序,否则我们需要删除 Windows 8 和 10 自动下载的驱动程序。 我们如何制作一个无论先插还是不插都能正确安装的USB驱动安装器? 最佳答案 在 Wi
我需要填充 USB 存储器,我希望其他人能够以简单的方式重复此操作。所以我不想写“找到一个填满内存的文件”,所以他们必须四处寻找这样的文件。 我想生成 X MB 的数据并将其写入一个文件,然后可以将其
我有一个 Android 平板电脑,它有一个迷你 USB 端口和一个 USB 端口,我想编写一个与 USB key 通信的应用程序。我写了一个demo来找出U盘,但是没有任何反应。 令我不安的是,如果
我正在尝试使用 Android USB Host API 读取我的 USB 游戏 Controller 数据,一旦我让它工作,我将连接其他设备进行测试。我的游戏 Controller 使用 OTG 线
我是一名优秀的程序员,十分优秀!