- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试从 Adafruit 的 Ultimate GPS 模块中读取 GPS NMEA 语句。我在树莓派上使用 C++ 读取模块的串口连接
这是我的阅读功能:
int Linuxutils::readFromSerialPort(int fd, int bufferSize) {
/*
Reading data from a port is a little trickier. When you operate the port in raw data mode,
each read(2) system call will return however many characters are actually available in the
serial input buffers. If no characters are available, the call will block (wait) until
characters come in, an interval timer expires, or an error occurs. The read function can be
made to return immediately by doing the following:
fcntl(fd, F_SETFL, FNDELAY);
The NDELAY option causes the read function to return 0 if no characters are available on the port.
*/
// Check the file descriptor
if ( !checkFileDecriptorIsValid(fd) ) {
fprintf(stderr, "Could not read from serial port - it is not a valid file descriptor!\n");
return -1;
}
// Now, let's wait for an input from the serial port.
fcntl(fd, F_SETFL, 0); // block until data comes in
// Now read the data
int absoluteMax = bufferSize*2;
char *buffer = (char*) malloc(sizeof(char) * bufferSize); // allocate buffer.
int rcount = 0;
int length = 0;
// Read in each newline
FILE* fdF = fdopen(fd, "r");
int ch = getc(fdF);
while ( (ch != '\n') ) { // Check for end of file or newline
// Reached end of file
if ( ch == EOF ) {
printf("ERROR: EOF!");
continue;
}
// Expand by reallocating if necessary
if( rcount == absoluteMax ) { // time to expand ?
absoluteMax *= 2; // expand to double the current size of anything similar.
rcount = 0; // Re-init count
buffer = (char*)realloc(buffer, absoluteMax); // Re-allocate memory.
}
// Read from stream
ch = getc(fdF);
// Stuff in buffer
buffer[length] = ch;
// Increment counters
length++;
rcount++;
}
// Don't care if we return 0 chars read
if ( rcount == 0 ) {
return 0;
}
// Stick
buffer[rcount] = '\0';
// Print results
printf("Received ( %d bytes ): %s\n", rcount,buffer);
// Return bytes read
return rcount;
}
所以我得到的句子如下所示,问题是我得到了一个完整句子的这些“重复”部分,如下所示:
Received ( 15 bytes ): M,-31.4,M,,*61
这里是完整的东西:
Received ( 72 bytes ): GPGGA,182452.000,4456.2019,N,09337.0243,W,1,8,1.19,292.6,M,-31.4,M,,*61
Received ( 56 bytes ): GPGSA,A,3,17,07,28,26,08,11,01,09,,,,,1.49,1.19,0.91*00
Received ( 15 bytes ): M,-31.4,M,,*61
Received ( 72 bytes ): GPGGA,182453.000,4456.2019,N,09337.0242,W,1,8,1.19,292.6,M,-31.4,M,,*61
Received ( 56 bytes ): GPGSA,A,3,17,07,28,26,08,11,01,09,,,,,1.49,1.19,0.91*00
Received ( 15 bytes ): M,-31.4,M,,*61
Received ( 72 bytes ): GPGGA,182456.000,4456.2022,N,09337.0241,W,1,8,1.21,292.6,M,-31.4,M,,*64
Received ( 56 bytes ): GPGSA,A,3,17,07,28,26,08,11,01,09,,,,,2.45,1.21,2.13*0C
Received ( 70 bytes ): GPRMC,182456.000,A,4456.2022,N,09337.0241,W,0.40,183.74,110813,,,A*7F
Received ( 37 bytes ): GPVTG,183.74,T,,M,0.40,N,0.73,K,A*34
Received ( 70 bytes ): GPRMC,182453.000,A,4456.2019,N,09337.0242,W,0.29,183.74,110813,,,A*7E
Received ( 37 bytes ): GPVTG,183.74,T,,M,0.29,N,0.55,K,A*3F
Received ( 32 bytes ): 242,W,0.29,183.74,110813,,,A*7E
Received ( 70 bytes ): GPRMC,182452.000,A,4456.2019,N,09337.0243,W,0.33,183.74,110813,,,A*75
为什么我会收到重复的句子,我该如何解决?我尝试刷新串行端口缓冲区,但事情变得非常难看!谢谢。
最佳答案
我不确定我是否理解您的确切问题。尽管该函数存在一些问题,但可能会解释各种错误。
线条
int absoluteMax = bufferSize*2;
char *buffer = (char*) malloc(sizeof(char) * bufferSize); // allocate buffer.
好像错了。您将通过将读取的字符数与 absoluteMax
进行比较来决定何时增加缓冲区,因此这需要与分配的缓冲区大小相匹配。在重新分配之前,您目前正在超出已分配内存的末尾进行写入。这会导致未定义的行为。如果你幸运的话,你的应用程序会崩溃,如果你不走运,事情似乎可以正常工作,但你会丢失你读取的后半部分数据,因为只有写入你拥有的内存的数据会被移动 realloc
(如果它重新定位您的堆单元)。
此外,您不应从 malloc
(或 realloc
)强制转换返回值,并且可以依赖 sizeof(char)
为 1。
您丢失了读取的第一个字符(在 while
循环之前读取的字符)。这是故意的吗?
当你重新分配buffer
时,你不应该重置rcount
。这会导致与上面相同的错误,您将在再次重新分配之前编写超出 buffer
末尾的内容。同样,这样做的效果是不确定的,但可能包括丢失部分输出。
与您当前关注的错误无关但同样值得注意的是您泄漏了 buffer
和 fdF
。在退出该函数之前,您应该分别free
和fclose
它们。
以下(未经测试的)版本应该可以解决这些问题
int Linuxutils::readFromSerialPort(int fd, int bufferSize)
{
if ( !checkFileDecriptorIsValid(fd) ) {
fprintf(stderr, "Could not read from serial port - it is not a valid file descriptor!\n");
return -1;
}
fcntl(fd, F_SETFL, 0); // block until data comes in
int absoluteMax = bufferSize;
char *buffer = malloc(bufferSize);
int rcount = 0;
int length = 0;
// Read in each newline
FILE* fdF = fdopen(fd, "r");
int ch = getc(fdF);
for (;;) {
int ch = getc(fdF);
if (ch == '\n') {
break;
}
if (ch == EOF) { // Reached end of file
printf("ERROR: EOF!\n");
break;
}
if (length+1 >= absoluteMax) {
absoluteMax *= 2;
char* tmp = realloc(buffer, absoluteMax);
if (tmp == NULL) {
printf("ERROR: OOM\n");
goto cleanup;
}
buffer = tmp;
}
buffer[length++] = ch;
}
if (length == 0) {
return 0;
}
buffer[length] = '\0';
// Print results
printf("Received ( %d bytes ): %s\n", rcount,buffer);
cleanup:
free(buffer);
fclose(fdH);
return length;
}
关于c++ - Raspberry Pi C++ 从 Adafruit 的终极 GPS 模块读取 NMEA 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18175353/
我无法弄清楚使用此语法初始化类实例的好处 Adafruit_8x8matrix matrix = Adafruit_8x8matrix();,而 Adafruit_8x8matrix matrix;
我正在编写读取文件并将其发送到 20x4 LCD 的代码,并且我有按钮,因此我可以在文件中上下移动 ` import math import time import linecache import
我写了一个脚本,使用 adafruit motor hat 库在接收到 433MHz ex 传输代码时控制电机!目前射程很短,但这是我项目的最佳方式! 问题是 433MHz rx/tx 库是 pyth
Adafruit_MQTT 库很棒,但我遇到了问题。我在 Arduino 中将它与 NodeMCU (ESP8266) 一起使用。示例代码一切正常。 (TLS 连接 - WiFiClientSecur
我正在使用带有 AdaFruit pn532 NFC/RFID 防护罩的 Arduino UNO。目标是有一个带假底的鞋盒。在那个假底下面是我的原型(prototype),它希望能够分辨出假底上方盒子
我正在尝试通过 3g 和 TCP 连接向服务器发送数据包。下面是我找到的 .cpp 和 .h 文件的链接: https://os.mbed.com/users/Nels885/code/Adafrui
我正在开发一个项目,需要 GPRS 连接并同时发送短信。 我正在使用 Raspberry Pi 和 adafruit fona。 我按照此 FONA Tethering to Raspberry Pi
我是 Python 新手,目前正在我的 Pi 3 mod b 上开发一个项目。我使用 Adafruit ADC1015 来转换模拟信号。但是,即使我有获取一些伏特测量值的代码,我也会收到“Attrib
我运行安装程序 from this website让我的 arduino 使用 AdaFruit LED。并运行: sudo pip3 install adafruit-circuitpython-n
我有一个 Adafruit (Gemma)/Arduino 和一个 Neopixel LED 环,我想从《魔兽世界》游戏内事件中控制它们。这部分是焊接和工作的。 问题: 有什么方法可以在魔兽世界和 P
我正在尝试将从十六进制字符串转换的字节数组写入 NTAG203 RFID 标签的内存中。我使用的是 Raspberry Pi 3、PN532 芯片和 Adafruit PN532 python lib
将 mbed 操作系统和 stm32 核板与 Adafruit Fona 3g 结合使用,我正在尝试通过 3g 连接将数据发送到服务器。我正在使用此处发布的 .cpp 文件和 .h 文件:https:
我已经成功安装了 Adafruit_Gpio 包,当我尝试运行 adafruit 提供的 bme 传感器的示例文件时,出现以下错误: Traceback (most recent call las
我正在使用 Adafruit Ft232H breakout 将 GPIO 端口添加到我的 Linux 电脑。虽然我在使用 libftdi 和 bitbang 模式闪烁 LED 灯时取得了一些成功,但
我一直在为我的 arduino ATMega2560 试验 I2C 和 mcp23017 IO 扩展器芯片,因为我宁愿使用 arduino 本身上的 IO 来做其他事情,我只是想知道如何使用 adaf
所以我试图将图像的字节数组放入外部 eeprom (c24LC16B) 并使用 Adafruit gfx 库中的 drawBitmap() 函数在 Nokia 3310 LCD(带有 Adafruit
希望你们中的任何一个能帮助我! 我正在尝试使用 Adafruit SHT31-D (一个 i2c 设备)板和我的 Pi2。我要离开 this datasheet指导我的编码工作。我正在使用 Wirin
我是 Arduino 的新手,我正在尝试使用 Adafruit Motor Shield V2.3 运行直流电机。我按照 Adafruit 网站上的说明进行操作,但是当我上传代码时我的电机没有启动。我
关于我关于 SO 的最后一个问题,我正在研究一个由 Arduino Mega 控制的交互式 14x14 LED table (有关设置和代码的更多信息,请查看 here。在解决了数据以错误的顺序到达
我正在尝试编写一个程序来在 Adafruit 60 LED 灯带上显示特定的灯光序列。目标是我将在代码中手动输入一个 DNA 序列,当程序运行时,每个碱基都会在 strip 上显示自己的颜色。这是到目
我是一名优秀的程序员,十分优秀!