【问题标题】:Arduino SAMD Integer to Byte conversion for LoRaLoRa 的 Arduino SAMD 整数到字节转换
【发布时间】:2021-08-15 21:16:08
【问题描述】:

我正在为 MKRWAN LoRa arduino 板编写一段代码。 使用没有很好记录的 MKRWAN 库。

此代码的目标是接受一些整数,并返回字节,以便它们可以存储在我应该能够通过 LoRa 网络发送的字节数组中。

在 arduino 文档中,它描述了带有 SAMD 芯片的 arduino 将整数存储在 4 个字节中。

在 Arduino Uno(和其他基于 ATmega 的开发板)上,int 存储一个 16 位(2 字节)的值。这会产生 -32,768 到 32,767 的范围(最小值为 -2^15,最大值为 (2^15) - 1)。在基于 Arduino Due 和 SAMD 的板(如 MKR1000 和 Zero)上,一个 int 存储一个 32 位(4 字节)值。这会产生 -2,147,483,648 到 2,147,483,647 的范围(最小值为 -2^31,最大值为 (2^31) - 1)。

来源:https://www.arduino.cc/reference/en/language/variables/data-types/int/

MKRWAN 1310 板使用 SAMD21 芯片。

与其前身 MKR WAN 1300 相比,MKR WAN 1310 带来了一系列改进。虽然仍然基于 Microchip® SAMD21 低功耗处理器、Murata CMWX1ZZABZ LoRa® 模块和 MKR 系列的特征加密芯片(ECC508)、MKR WAN 1310 包括一个新的电池充电器、一个 2MByte SPI 闪存和改进的电路板功耗控制。

来源:https://store.arduino.cc/mkr-wan-1310

但是,当我运行我的代码时,它会吐出一些整数为 4 个字节,而另一些则更少。

-9001 in BINARY = 11010111 11011100 11111111 11111111 
newInt = -9001
13 in BINARY = 1101 0 0 0 
newInt = 13
-1 in BINARY = 11111111 11111111 11111111 11111111 
newInt = -1
250 in BINARY = 11111010 0 0 0 
newInt = 250
-1950 in BINARY = 1100010 11111000 11111111 11111111 
newInt = -1950
13450 in BINARY = 10001010 110100 0 0 
newInt = 13450

我正在使用联合将整数转换为字节。

SAMD 板是否动态存储整数? 我的代码错了吗?

#define ArraySize 4

byte ATA[ArraySize];                      // Air temperature array
byte AHA[ArraySize];                      // Air humidity array
byte GT1A[ArraySize];                     // Ground temperature sensor 1 array
byte GT2A[ArraySize];                     // Ground temperature sensor 2 array
byte GT3A[ArraySize];                     // Ground temperature sensor 3 array
byte GHA[ArraySize];                      // Ground humidty sensor array
byte master[24];                          // message array

union unionForm {                         // werkt naar behoren
  byte myBytes[ArraySize];
  int myInt;
} myUnion;

void setup() {
  // put your setup code here, to run once:
  int int1 = -9001;
  int int2 = 13;
  int int3 = -1;
  int int4 = float_to_int(2.5);
  int int5 = float_to_int(-19.5);
  int int6 = float_to_int(134.5);

  
  
  Serial.begin(115200);
  while(!Serial);

  int_to_bytes(int1, ATA);
  int_to_bytes(int2, AHA);
  int_to_bytes(int3, GT1A);
  int_to_bytes(int4, GT2A);
  int_to_bytes(int5, GT3A);
  int_to_bytes(int6, GHA);

  Combine_Arrays();
  for (int i = 0; i < 24; i++){
    Serial.print(master[i], BIN);
    Serial.print(" ");
  }
  
  Serial.println();
}

void loop(){
  
}

int float_to_int(float floatyboi){
  Serial.print("Float:\t");
  Serial.println(floatyboi);
  int newInt = floatyboi * 100;                     // convert 2 decimal float to int by multiplying by 100 and saving as int
  Serial.print("New Int:\t");
  Serial.println(newInt);
  
  return newInt;
}

void int_to_bytes(int ConvertInt, byte (& MyArray)[ArraySize]){
  myUnion.myInt = ConvertInt;                         // Save int into union
  Serial.print(ConvertInt);
  Serial.print(" in BINARY = ");
  for (int i = 0; i < sizeof(int); i++) {
    Serial.print(myUnion.myBytes[i], BIN);
    Serial.print(" ");

    MyArray[i] = myUnion.myBytes[i];                  // save bits out of union in corresponding array
  }
  Serial.println();
  
  int newInt = myUnion.myInt;
  Serial.print("newInt = ");
  Serial.println(newInt);
}

void Combine_Arrays(){
  Serial.println("Combining Arrays");
  master[0] = ATA[0];
  master[1] = ATA[1];
  master[2] = ATA[2];
  master[3] = ATA[3];
  master[4] = AHA[0];
  master[5] = AHA[1];
  master[6] = AHA[2];
  master[7] = AHA[3];
  master[8] = GT1A[0];
  master[9] = GT1A[1];
  master[10] = GT1A[2];
  master[11] = GT1A[3];
  master[12] = GT2A[0];
  master[13] = GT2A[1];
  master[14] = GT2A[2];
  master[15] = GT2A[3];
  master[16] = GT3A[0];
  master[17] = GT3A[1];
  master[18] = GT3A[2];
  master[19] = GT3A[3];
  master[20] = GHA[0];
  master[21] = GHA[1];
  master[22] = GHA[2];
  master[23] = GHA[3];
}

感谢您的帮助

【问题讨论】:

  • “它吐出一些整数为 4 个字节,而一些则更少”的确切含义是什么。你的问题到底是什么?请举例说明发生了什么问题以及您的期望。
  • 请注意,Arduino 中的byte 是unsigned char,即uint8_t,而您正在使用int 进行转换,这可能是一个负数。
  • 我已经添加了我得到的输出。我会在重新设计时记住未签名的问题。
  • 从您更新的帖子中,数据以little endian 格式正确存储(Arduino 使用小端序),这意味着首先存储 LSB,最后存储 MSB。你需要知道你的 Lora msg 的接收端是一个大端或小端的机器,可能需要在接收到数据后进行转换。

标签: arduino integer byte lora


【解决方案1】:

以这种方式使用联合并不是最好的方式。它让您了解未定义的行为。这是一种双关语。

最好将值移出并移入 32 位字

byte values[4] = {0xff, 0xff, 0xff, 0xff};
int output = values[3] << 24 | values[2] << 16 | values[1] << 8 | values[0];

values[0] = output;
values[1] = output >> 8;
values[2] = output >> 8;
values[3] = output >> 8;

您还应该查看值的签名,因为它们可能会导致问题。

【讨论】:

  • 在研究将整数转换为字节时,如果在这个项目开始时我的技能范围内出现的几件事让我感到困惑,那就是其中之一。我会避开工会并牢记签名!
猜你喜欢
  • 2018-10-01
  • 2015-05-15
  • 2015-10-18
  • 2015-05-12
  • 2015-12-20
  • 2021-06-24
  • 1970-01-01
  • 2021-11-06
  • 2014-07-13
相关资源
最近更新 更多