首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >增强Arduino/Radio通信的8字节命令字符串解析器(预计类型转换会出现问题)

增强Arduino/Radio通信的8字节命令字符串解析器(预计类型转换会出现问题)
EN

Code Review用户
提问于 2014-02-20 10:28:34
回答 1查看 291关注 0票数 1

由于我的无线电和设备的吞吐量是有限的,我想压缩我的控制字符串。我决定将命令压缩为一个8字节(准)字符串(节流阀高、节气门低、螺距、滚、偏航加/减、偏航值、校验和、停止字节),并在解析后使用四个变量:

  • 螺距( -45°至45°)
  • 轧辊( -45°至45°之间)
  • 偏航( -180°至180°)
  • 节流阀( 1000到1900之间)

由于某些数字范围不适合于单个字节(0到255个数字范围),所以我使用了两个字节(油门:一个字节表示数百个字节(1-9个)和一个字节表示十个字节(1-99);偏角:一个字节表示正负,一个字节表示0°- 180°)。我将这些字节作为字符发送和读取。然后我把它们转换成数字(0-255)。

我注意到,有时一些读取完全超出范围(例如值:-31001),但是校验和测试是可以的。我不知道为什么(可能是收音机,也许是因为这里的类型转换导致了意想不到的行为)。这就是为什么我做了一个额外的距离测试。现在遥控器似乎是可靠的。

然而,我并不觉得很好,因为我确实签署了/没有签署和!数字范围转换,校验和函数也不是很可靠。也许有人对如何使代码更好提出了建议。

代码(存储在缓冲区中的命令已经正确红色,直到停止字节并在长度上有效):

代码语言:javascript
复制
bool Receiver::parse_radio(char *buffer) {
  int16_t throttle_high  = (uint8_t)buffer[0];       // 1. 1 - 9
  int16_t throttle_low   = (uint8_t)buffer[1];       // 2. 0 - 99
  int16_t pit            = (uint8_t)buffer[2] - 127; // 3. -45° - 45°
  int16_t rol            = (uint8_t)buffer[3] - 127; // 4. -45° - 45°
  int16_t yaw_pm         = (uint8_t)buffer[4] - 127; // 5. -1 || +1
  int16_t yaw_val        = (uint8_t)buffer[5];       // 6. yaw angle in degrees 180°

  int16_t chk            = (uint8_t)buffer[6];       // 7. checksum

  int16_t thr            = 1000 + (throttle_high * 100) + throttle_low;
  int16_t yaw            = yaw_val * yaw_pm;

  // Calculate checksum
  uint8_t checksum = 0;
  for(int i = 0; i < 6; i++) {
    checksum = (checksum + buffer[i]) << 1; // % 256 can be saved because of the uint8_t
  }

  // Validity check: 
  // First checksum
  if(checksum != chk)
    return false;
  // Later other values
  if(yaw_pm < -1 || yaw_pm > 1)
    return false;
  if(rol > 45 || rol < -45)
    return false;
  if(pit > 45 || pit < -45)
    return false;
  if(yaw > 180 || yaw < -180)
    return false;
  if(thr > RC_THR_80P || thr < RC_THR_MIN)
    return false;

  // Do rest here
  return true;
}
EN

回答 1

Code Review用户

发布于 2014-05-09 11:25:06

我建议您将缓冲区元素转换为int16_t而不是uint8_t。

下面是一个例子

代码语言:javascript
复制
#include <stdio.h>
#include <inttypes.h>

int main()
{
    char buffer = -45;
    printf("Original = %d\n", buffer);
    printf("uint8_t  = %d\n", (uint8_t)buffer);
    printf("int16_t  = %d\n", (int16_t)buffer);

    int16_t a = (uint8_t)buffer - 127;
    int16_t b = (int16_t)buffer - 127;
    printf("a = %d\n", a);
    printf("b = %d\n", b);
}

输出:

代码语言:javascript
复制
Original = -45
uint8_t  = 211
int16_t  = -45
a = 84
b = -172

正如您在第二行中所看到的,当您将负整数更改为无符号整数时,它不能保留其负值状态,而是变成一个大的正数。

编辑:对不起,我没有意识到这个问题的日期。我想我还是别管它了。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/42282

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档