我正在从传感器读取数据,该传感器将它们作为两个8位值发送,用户必须将它们转换为一个带符号的16位值。我将这些值保存到一个5400个元素的数组中(传感器是加速度计+陀螺仪+磁力计,所以是9个轴,所以最后每个轴都有300个值)。所以可以说我需要从加速度计的X轴读取数据。在我的数组中,我将它们保存在前两个位置,因此我的accX读数分别位于索引0,1,然后是18,19,然后是36,37,依此类推..... 现在,我需要将它们提取到具有300个元素的新16位数组中,这些元素将仅代表加速度计的X轴。我的想法如下:
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.sessionId = this.route.snapshot.queryParams['token']
}
我的AccX数组中的值是我不希望出现的值。知道可能出了什么问题吗?传感器是LSM9DS1。
编辑:对不起,我没有提供有关该设备的更多信息。我肯定知道这可行:
uint8_t rawData[5400]={0};
int16_t *AccX = malloc(300*sizeof(int16_t));
for(int i=0;i<300;i++){
AccX[i]=(rawData[i+1+i*17]<<8 | rawData[i+0+i*17]);
}
//do some calculations
free(AccX);
我还检查了rawData数组,它包含正确的数据。当我尝试将数据填充到AccX阵列时出错
答案 0 :(得分:3)
查看datasheet。本质上,一个包装中有两个独立的设备。
您需要加速度计/陀螺仪设备寄存器:
21和22(0x15和0x16)的温度
陀螺仪X轴的24和25(0x18和0x19)
陀螺仪Y轴的26和27(0x1A和0x1B)
陀螺仪Z轴的28和29(0x1C和0x1D)
加速度计X轴的40和41(0x28和0x29)
加速度计X轴的42和43(0x2A和0x2B)
加速度计Z轴的44和45(0x2C和0x2D)
对于磁场,您需要磁传感器寄存器:
40和41(0x28和0x29)
Y轴磁场强度的42和43(0x2A和0x2B)
Z轴磁场强度的44和45(0x2C和0x2D)
这些都是二进制补码格式,最低有效字节在前。
由于几乎所有微控制器都对二进制整数使用二进制补码格式(STM32确实如此,包括所有Arduino的ARM和AVR一样),因此您可以编写五个简单的辅助函数。在伪C中:
static int16_t temperature;
static int16_t gyro_x, gyro_y, gyro_z;
static int16_t accel_x, accel_y, accel_z;
static int16_t mag_x, mag_y, mag_z;
static uint8_t buf[6];
static void update_temperature(void)
{
/* Read 2 bytes from registers 0x15 and 0x16 (21 and 22)
from the accelerometer/gyroscope device, to buf[] */
temperature = (int16_t)((((unsigned int)buf[1]) << 8) | (unsigned int)(buf[0]));
}
static void update_gyro(void)
{
/* Read 6 bytes from registers 0x18..0x1D (24 through 29)
from the accelerometer/gyroscope device, to buf[] */
gyro_x = (int16_t)((((unsigned int)buf[1]) << 8) | (unsigned int)(buf[0]));
gyro_y = (int16_t)((((unsigned int)buf[3]) << 8) | (unsigned int)(buf[2]));
gyro_z = (int16_t)((((unsigned int)buf[5]) << 8) | (unsigned int)(buf[4]));
}
static void update_accel(void)
{
/* Read 6 bytes from registers 0x28..0x2D (40 through 45)
from the accelerometer/gyroscope device, to buf[] */
accel_x = (int16_t)((((unsigned int)buf[1]) << 8) | (unsigned int)(buf[0]));
accel_y = (int16_t)((((unsigned int)buf[3]) << 8) | (unsigned int)(buf[2]));
accel_z = (int16_t)((((unsigned int)buf[5]) << 8) | (unsigned int)(buf[4]));
}
static void update_mag(void)
{
/* Read 6 bytes from registers 0x28..0x2D (40 through 45)
from the magnetic sensor device, to buf[] */
mag_x = (int16_t)((((unsigned int)buf[1]) << 8) | (unsigned int)(buf[0]));
mag_y = (int16_t)((((unsigned int)buf[3]) << 8) | (unsigned int)(buf[2]));
mag_z = (int16_t)((((unsigned int)buf[5]) << 8) | (unsigned int)(buf[4]));
}
static void update_all(void)
{
update_temperature();
update_gyro();
update_accel();
update_mag();
}
这些分配看起来很时髦,但是编译器应该优化它们以使机器代码合理。
您可能需要编写一个辅助函数来进行实际的读取(或者可能是三个函数;一个函数用于将2个字节从加速度计/陀螺仪设备读取到buf [],一个函数用于将6字节从加速度计/陀螺仪读取到buf []的设备,以及一个从磁传感器设备向buf []读取6个字节的设备,所有这些都是从连续寄存器中获得的,该连续寄存器作为函数的参数提供)。
这种方法使用26字节的RAM,并且应适用于所有8位(AVR)和32位(STM32,ARM)微控制器。上面的代码对微控制器的字节顺序(字节序)不敏感。
如果您的设备通过USB或串行方式将陀螺仪,加速度计和磁传感器值发送到计算机,则需要知道输出值的字节顺序(字节序)。
传感器本身首先以最低有效字节的形式提供它们。据我所知,STM32也是little-endian,因此它也应该首先提供最低有效字节。
因此,假设您从设备收到18*N
个字节,首先是陀螺仪轴,然后是加速度计轴,最后是磁传感器轴读数。以下应该将这些值转换为带符号的整数,以便于操作:
#include <stdlib.h>
#include <inttypes.h>
static inline void extract16toint(int *const to,
const unsigned char *const from,
const size_t n,
const size_t stride)
{
const unsigned char *const end = from + n * stride;
const unsigned char *src = from;
int *dst;
while (src < end) {
*(dst++) = (int16_t)( (unsigned int)(src[0])
| ((unsigned int)(src[1]) << 8) );
src += stride;
}
}
static void extract_gyroX(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 0, n, 18);
}
static void extract_gyroY(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 2, n, 18);
}
static void extract_gyroZ(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 4, n, 18);
}
static void extract_accelX(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 6, n, 18);
}
static void extract_accelY(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 8, n, 18);
}
static void extract_accelZ(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 10, n, 18);
}
static void extract_magX(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 12, n, 18);
}
static void extract_magY(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 14, n, 18);
}
static void extract_magZ(int *const to,
const unsigned char *const data,
const size_t n)
{
extract16toint(to, data + 16, n, 18);
}
在OP的情况下,调用类似
int *accelX = malloc(300 * sizeof (int));
extract_accelX(accelX, rawData, 300);
应该工作。