当我们将智能手机从纵向倾斜到横向时……它如何知道我们正在倾斜手机?
那是因为我们智能手机中的加速度计!为了解其工作原理,让我们使用Apache NuttX RTOS(实时操作系统)从PINE64 PinePhone中窥探原始加速度计数据。
按照以下步骤使用 microSD 卡在 PinePhone 上启动 NuttX RTOS(它不会触及内部 eMMC 存储)...
(1) 安装构建先决条件
(2) 下载适用于AArch64 裸机目标的 ARM64 工具链:(跳过测试版部分)aarch64-none-elf
(3) 下载并构建NuttX RTOS for PinePhone ...
git clone https://github.com/apache/nuttx nuttx
git clone https://github.com/apache/nuttx-apps apps
cd nuttx
tools/configure.sh pinephone:sensor
make
cp nuttx.bin Image
rm -f Image.gz
gzip Image
(4) 这会生成 NuttX 图像文件Image.gz
。我们一会儿将它复制到 PinePhone 中。
(5) 下载PinePhone Jumpdrive镜像:pine64-pinephone.img.xz
(6) 使用Balena Etcher或GNOME Disks将下载的镜像写入 microSD 卡。
(7) 还记得Image.gz
之前的事吗?复制并覆盖 microSD 卡上的文件。
(8) 将 microSD 卡插入 PinePhone 并将隐私开关 6(耳机)拨至关闭。
(9) 将PinePhone Serial Console Cable连接到我们的电脑并给PinePhone 上电。
(10) 在我们的电脑上,使用screen
或以115.2 kbps 的速度putty
连接到 PinePhone 串口控制台(假设“usbserial-1410”是 USB 串口)...
screen /dev/tty.usbserial-1410 115200
(11) 在提示符下,输入:ls /dev
NuttShell (NSH) NuttX-12.0.3
nsh> ls /dev
/dev:
console
imu0
null
ram0
ram2
ttyS0
userleds
zero
NuttX 表示,PinePhone 加速度计InvenSense MPU-6050现在可以在. (那是惯性测量单元)/dev/imu0
让我们从 PinePhone 的加速度计中读取原始加速度计数据。
将我们的 PinePhone 竖直放在纵向。输入这个命令...
hexdump /dev/imu0 count=14
这会从加速度计转储 14 个字节的原始数据...
/dev/imu0 at 00000000:
0000: 10 21 00 05 01 6a f7 9e ff d8 00 13 ff fd
现在将我们的 PinePhone 逆时针旋转 90 度,进入横向。输入相同的命令...
hexdump /dev/imu0 count=14
我们将看到一组不同的 14 字节原始数据......
/dev/imu0 at 00000000:
0000: 00 19 f0 48 01 12 f8 80 ff d6 00 0f ff fe
但是这些数字是什么意思?
NuttX 内核将MPU-6050 加速度计数据格式定义为...
/* MPU-6050 Accelerometer Data Format
* (14 bytes, big-endian) */
struct sensor_data_s {
int16_t x_accel; /* Accelerometer X */
int16_t y_accel; /* Accelerometer Y */
int16_t z_accel; /* Accelerometer Z */
int16_t temp; /* Temperature */
int16_t x_gyro; /* Gyroscope X */
int16_t y_gyro; /* Gyroscope Y */
int16_t z_gyro; /* Gyroscope Z */
};
当我们从上面解码数据时,我们得到......
纵向:
横向:
啊哈,加速度计的 X 和 Y 值发生了显着变化!
是的,加速度计测量三轴的加速度......
加速度计检测到加速度发生变化:在我们旋转手机后,从 X 轴到 Y 轴。
但是我们没有水平或垂直“加速”手机?
这是因为重力!地球表面对我们的手机施加向上的法向力。这是在我们旋转手机时由加速度计测量的。
当我们将手机从纵向倾斜到横向时,我们的手机就是这样知道的!
最后,让我们编写一个程序来读取和解释加速度计数据。
我们首先声明MPU-6050 加速度计数据格式:hello_main.c
/* MPU-6050 Accelerometer Data Format
* (14 bytes, big-endian)
* Based on NuttX Kernel: https://github.com/apache/nuttx/blob/master/drivers/sensors/mpu60x0.c#L218-L233 */
struct sensor_data_s
{
int16_t x_accel; /* Accelerometer X */
int16_t y_accel; /* Accelerometer Y */
int16_t z_accel; /* Accelerometer Z */
int16_t temp; /* Temperature */
int16_t x_gyro; /* Gyroscope X */
int16_t y_gyro; /* Gyroscope Y */
int16_t z_gyro; /* Gyroscope Z */
};
接下来我们打开加速度计.../dev/imu0
/* Open the MPU-6050 Accelerometer for reading */
int fd = open("/dev/imu0", O_RDONLY);
assert(fd > 0); /* Check that it exists */
我们从加速度计中读取了14 个字节的数据……
/* Accelerometer Data will have 14 bytes */
struct sensor_data_s data;
assert(sizeof(data) == 14); /* We expect to read 14 bytes */
/* Read the Accelerometer Data (14 bytes) */
int bytes_read = read(fd, &data, sizeof(data));
assert(bytes_read == sizeof(data)); /* We expect 14 bytes read */
但是加速度计数据是Big-Endian Format。我们为 PinePhone 转换为Little-Endian 格式...
/* Flip the bytes from Big-Endian to Little-Endian for PinePhone.
* ntohs() is explained here: https://developer.ibm.com/articles/au-endianc/ */
int16_t x_accel = ntohs(data.x_accel);
int16_t y_accel = ntohs(data.y_accel);
int16_t z_accel = ntohs(data.z_accel);
int16_t temp = ntohs(data.temp);
int16_t x_gyro = ntohs(data.x_gyro);
int16_t y_gyro = ntohs(data.y_gyro);
int16_t z_gyro = ntohs(data.z_gyro);
最后我们打印转换后的数据并关闭加速度计......
/* Print the Accelerometer Data */
printf("Accelerometer X: %d\n", x_accel);
printf("Accelerometer Y: %d\n", y_accel);
printf("Accelerometer Z: %d\n", z_accel);
printf("Temperature: %d\n", temp);
printf("Gyroscope X: %d\n", x_gyro);
printf("Gyroscope Y: %d\n", y_gyro);
printf("Gyroscope Z: %d\n", z_gyro);
/* Close the Accelerometer */
close(fd);
要在 PinePhone 上运行它,请在我们的计算机上查找此源文件...
apps/examples/hello/hello_main.c
通过以下内容覆盖该文件的内容:hello_main.c
为 PinePhone 重建 NuttX RTOS...
make
cp nuttx.bin Image
rm -f Image.gz
gzip Image
按照前面的说明复制到 PinePhone microSD 卡。在 PinePhone 上启动 microSD 卡并输入:Image.gz
hello
当 PinePhone 处于Portrait Orientation时,我们会看到类似...
nsh> hello
Accelerometer X: 4137
Accelerometer Y: -97
Accelerometer Z: 208
Temperature: -1500
Gyroscope X: -29
Gyroscope Y: 66
Gyroscope Z: 12
当我们将 PinePhone 旋转到Landscape Orientation时,Accelerometer X 和 Y 值会发生显着变化......
nsh> hello
Accelerometer X: -143
Accelerometer Y: -4007
Accelerometer Z: -443
是的,我们的程序已经成功读取了 PinePhone 加速度计!
(非常感谢Filipe Cavalcanti启发了本教程!)
要了解更多关于PinePhone 的 NuttX RTOS ...
MPU-6050 在微控制器上也能正常工作……
MPU-6050实际上是一个组合加速度计和陀螺仪...
我们可以计算倾斜角吗?它在 3D 空间中变得复杂,请查看三角函数公式...
MPU-6050 Driver是如何在NuttX Kernel中启动的?
启动时,NuttX Kernel在PinePhone Bringup Function pinephone_bringup中启动MPU-6050 Driver ,并在/dev/imu0注册驱动:pinephone_bringup.c
/* To register the IMU Driver for MPU-6050 Accelerometer at Port TWI1... */
/* Init the Power Management Integrated Circuit */
ret = pinephone_pmic_init();
/* Wait 15 milliseconds for power supply and power-on init */
up_mdelay(15);
/* Allocate the IMU Driver struct */
mpu_config = kmm_zalloc(sizeof(struct mpu_config_s));
mpu_config->i2c = i2c1;
mpu_config->addr = 0x68;
/* Register the IMU Driver at /dev/imu0 */
mpu60x0_register("/dev/imu0", mpu_config);
(mpu60x0_register在 MPU-6050 驱动中定义)
( pinephone_pmic_init来自PinePhone电源管理集成电路的驱动)
什么?i2c1
i2c1
是 Allwinner A64 SoC 上的第二个 I2C 端口,连接到 MPU-6050 加速度计。(PinePhone 原理图,第 12 页)
Allwinner A64 上的 I2C 端口被命名为 TWI0,TWI1,... 所以i2c1
实际上是Allwinner A64 上的端口 TWI1 : pinephone_bringup.c
/* Initialize TWI1 as I2C Bus 1 */
i2c1 = a64_i2cbus_initialize(i2c1_bus);
/* Register I2C Driver for I2C Bus 1 at TWI1 */
ret = i2c_register(i2c1, i2c1_bus);
(TWI表示“双线接口”)
(a64_i2cbus_initialize定义在 Allwinner A64 I2C Driver 中)
这是什么 PMIC?
启动时,NuttX Kernel 会初始化 PinePhone 的电源管理集成电路 (PMIC) ,然后再启动 MPU-6050 Driver: pinephone_bringup.c
/* To register the IMU Driver for MPU-6050 Accelerometer at Port TWI1... */
/* Init the Power Management Integrated Circuit */
ret = pinephone_pmic_init();
/* Omitted: Start the IMU Driver at /dev/imu0 */
(pinephone_pmic_init来自 PMIC 驱动程序)
这是因为 MPU-6050 加速度计由 PinePhone 的 PMIC:X-Powers AXP803 供电。(PinePhone 原理图,第 3 页,DLDO1)
X-Powers AXP803 上的DLDO1 电源为PinePhone 上的 I2C 传感器供电,包括 MPU-6050 加速度计。
我们如何确定 X 轴指向 PinePhone 的顶部边缘?Y 轴指向左边缘?
根据PinePhone Component List, MPU-6050 Accelerometer 的标签为U1202 。
从PinePhone 主板底部布局来看, U1202 在图的左上角。这意味着加速度计位于PinePhone 的左上角。(从正面看时)
U1202 有一个小圆圈,朝向PinePhone 的左下边缘。
当我们参考InvenSense MPU-6050 数据表(第 21 页)时,我们得出结论...
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !