本帖最后由 xble 于 2017-9-18 22:18 编辑
自己是以“Iot可穿戴设备移动轨迹见图功能和系统电源管理功能”为题目申请的Warp7开发板,这里总结一下这将近三个月的收获。
根据当时申请的计划一项一项来说明一下情况
1.下载源代码,编译,下载镜像到WaRP7。
此项基本完成,关键是yocto框架入门,也是这次试用艰难重重的主要原因。下面是与yocoto相关的三个帖子:
https://bbs.elecfans.com/forum.php?mod=viewthread&tid=1145950&extra= https://bbs.elecfans.com/forum.php?mod=viewthread&tid=1152106&extra=
https://bbs.elecfans.com/forum.php?mod=viewthread&tid=1156392&extra=
2. 研究A7核与M4核之间的架构关系。
对于此问题进行了一些研究,下载freeOS的源代码下载,编译运行,但是没有将M4跟随A7开机一起运行,找到一些资料希望后面有机会可以继续研究一下。
3.使能wifi可以连接到已知AP上,定义wifi传输协议。
这个项目感觉完成一半,在yocoto框架下可以开机自动连接某个ap,但是一旦这个ap找不到则通过串口方式无法进入系统。wifi传输协议没有时间实现。https://bbs.elecfans.com/forum.php?mod=viewthread&tid=1230627&extra=
4. 使能“多重感知”设备磁力-加速计,气压计,陀螺仪。并将数据简单处理然后通过wifi发送给固定PC。
这个项目感觉完成一半,加计,气压计,陀螺都已经在本地获取数据,并且验证趋势正确性,并且下面会具体分析陀螺的数据与实际操作的关系来最终结项。https://bbs.elecfans.com/forum.php?mod=viewthread&tid=1310836&extra=
5. 研究系统电源管理模块,并将某些电池数据时时显示在LCD上。
LCD始终都没有时间点亮是一个遗憾。简单分析了电源管理的低功耗功能实现的原理和处理流程,也简单分析了BC3770电池的一些属性。https://bbs.elecfans.com/forum.ph ... &tid=1382475&extra=
6. 将“多重感知”数据通过PC上的ros工具RVIZ画图。
软件出身的自己对于惯导算法理解不深,磕磕绊绊终于弄明白了陀螺仪的实现原理,下面会通过陀螺仪水平转圈操作来分析其实现原理和通过抓取数据分析,通过matlib来将数据图形化。
陀螺仪实现原理 陀螺仪又叫角速度传感器,它不同于加速度计(G-sensor),他的测量物理量是偏转、倾斜时的转动角速度。陀螺仪则可以对转动、偏转的动作做很好的测量,这样就可以精确分析判断出使用者的实际动作。下图左侧是陀螺的三轴坐标系的建立和转到角度方向。右侧则是实际的硬件设备的x,y,z轴的示意图。
FXAS21002C设备使用原理和相关读取代码实现
上面两个图我们确定了FXAS21001C的IIC设备地址。
测试流程:将warp7水平放置,静止大约20秒左右,逆时针旋转90度再次静止大约20秒左右,继续逆时针旋转90度再次静止大约20秒,旋转270度,旋转360度,最后还是静止大约20秒,加上旋转时间大约90秒左右。将每次陀螺的前一百次求平均值,从100次开始每次Z轴数据减去前100此的平均值然后相加,运行次数,时间戳,x,y,z和前面的求和都保存到文件中,以便后面进行分析。
陀螺旋转视频地址:http://v.youku.com/v_show/id_XMzAzMTM0ODY0OA==.html?spm=a2h3j.8428770.3416059.1#paction
具体代码如下:
- /* *************************************************************
- * File name:
- * Function:
- * Description:
- *
- * *************************************************************/
- #include "i2c_io.h"
- static int fd;
- char I2C_DevName_String[] = "/dev/i2c-3";
- char *I2C_DevName = I2C_DevName_String;
- unsigned int I2C_SLAVE_Address = 0x20;
- #define SENSOR_IOCTL_BASE 'S'
- #define SENSOR_GET_MODEL_NAME _IOR(SENSOR_IOCTL_BASE, 0, char *)
- #define SENSOR_GET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 2, int)
- #define SENSOR_SET_POWER_STATUS _IOR(SENSOR_IOCTL_BASE, 3, int)
- #define SENSOR_GET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 4, int)
- #define SENSOR_SET_DELAY_TIME _IOR(SENSOR_IOCTL_BASE, 5, int)
- #define SENSOR_GET_RAW_DATA _IOR(SENSOR_IOCTL_BASE, 6, short[3])
- #define FXAS21002C_WHOAMI_VALUE 0xD7
- #define FILENAME ("//home/root/gyro.txt")
- #define FXAS21002C_OUT_X_MSB 0x1
- #define FXAS21002C_OUT_X_LSB 0x2
- #define FXAS21002C_OUT_Y_MSB 0x3
- #define FXAS21002C_OUT_Y_LSB 0x4
- #define FXAS21002C_OUT_Z_MSB 0x5
- #define FXAS21002C_OUT_Z_LSB 0x6
- #define FXAS21002C_WHO_AM_I 0x0C
- typedef struct _SRAWDATA {
- int16_t x;
- int16_t y;
- int16_t z;
- } SRAWDATA;
- /*********************************************
- *FXAS21002C chip id
- *FXAS21002C_chipid
- *
- *
- * erro -> -1 sucess -> 0
- **********************************************/
- int FXAS21002C_read_chip_id(int fd,int* FXAS21002C_chipid)
- {
- char buf;
- int ret;
-
- ret= iic_read(fd,&buf,FXAS21002C_WHO_AM_I,1);
- if(ret < 0){
- printf(" FXAS21002C_chip_id failed n");
- return ret;
- }
-
- if(buf != FXAS21002C_WHOAMI_VALUE){
- *FXAS21002C_chipid = 0;
- return -1;
- }
-
- //return FXAS21002C_chipid value
- *FXAS21002C_chipid = buf;
- printf(" FXAS21002C_chip_id:0x%xn", *FXAS21002C_chipid);
- return 0;
- }
- static int read_register(int file, unsigned char address, unsigned char reg, unsigned char *data)
- {
- unsigned char input_buffer, output_buffer;
- struct i2c_rdwr_ioctl_data packets;
- struct i2c_msg messages[2];
- output_buffer = reg;
- messages[0].addr= address;
- messages[0].flags = 0;
- messages[0].len = sizeof(output_buffer);
- messages[0].buf = &output_buffer;
- messages[1].addr= address;
- messages[1].flags = I2C_M_RD;
- messages[1].len = sizeof(input_buffer);
- messages[1].buf = &input_buffer;
- packets.msgs= messages;
- packets.nmsgs = 2;
- if(ioctl(file, I2C_RDWR, &packets) < 0) {
- perror("Error sending data");
- return 1;
- }
- *data = input_buffer;
-
- return 0;
- }
- int main(int argc, char* argv[])
- {
- int i = 0;
- int ret = 0;
- int fd = 0;
- int fd_mag = 0;
- int file = 0;
- unsigned char FXAS21002C_chipid;
- char gyrobuf[128] = "";
- int tmp_m*** = 0;
- int tmp_l*** = 1;
- int* nStatus = &tmp_l***;
- struct timeval tStart;
- struct timeval tEnd;
- struct timeval tCurrent;
- int nDifftime = 0;//ms
- long long difftime = 0;
- fxas2100_data_axis mfxas2100_data_axis;
- fxas2100_data_axis* pfxas2100_data_axis;
- pfxas2100_data_axis = &mfxas2100_data_axis;
- static double sumWz=0.0;
- static double sumWzPercent=0.0;
- int del_t = 5;//ms
- int sumWzPercentNum = 100;//ms
- double dGyro_z = 0;//ms
-
- gettimeofday(&tStart, NULL);
- // printf("Test for FXAS21002C (3-axis linear accelerometer)n");
- printf("Please check the device ID (Should be 0xD7)n");
- if ((file = open("/dev/i2c-3", O_RDWR)) < 0)
- {
- perror("Error openning file!");
- exit(1);
- }
- if(read_register(file, I2C_SLAVE_Address, FXAS21002C_WHO_AM_I, &FXAS21002C_chipid))
- exit(1);
- else
- {
- {
- printf("GET:Register[0x%02X]: whoami-deviceID=0x%02Xn" , 0x20 , FXAS21002C_chipid);
- }
- }
- close(file);
- system("echo 1 > /sys/devices/virtual/misc/FreescaleGyroscope/enable");
- if ((fd = open("/dev/FreescaleGyroscope", O_RDWR)) < 0)
- {
- perror("Error openning /dev/FreescaleGyroscope!");
- exit(1);
- }
- FILE *fp = NULL;
- int write_length = 0;
- fp = fopen(FILENAME, "ab+");
- if(fp == NULL)
- {
- return 0;
- }
- memset(gyrobuf, 0, 128);
-
-
- pfxas2100_data_axis->x = 0;
- pfxas2100_data_axis->y = 0;
- pfxas2100_data_axis->z = 0;
- printf("=1= pfxas2100_data_axis->x=%d, pfxas2100_data_axis->y=%d, pfxas2100_data_axis->z=%dn", pfxas2100_data_axis->x, pfxas2100_data_axis->y, pfxas2100_data_axis->z);
- gettimeofday(&tEnd, NULL);
- for(i = 0; i < 18000; i++)
- {
- gettimeofday(&tCurrent, NULL);
- ret = ioctl(fd,SENSOR_GET_RAW_DATA,pfxas2100_data_axis); //I2C
- dGyro_z = (double)(pfxas2100_data_axis->z);
- if(i <= sumWzPercentNum)
- {
- sumWzPercent = sumWzPercent + dGyro_z * 1 / 1;
- }
- else
- {
- sumWz = sumWz + dGyro_z * 1 / 1 - (sumWzPercent / sumWzPercentNum);
- }
- memset(gyrobuf, 0, 128);
- gettimeofday(&tEnd, NULL);
- difftime = (long long)((tEnd.tv_sec * 1000 + tEnd.tv_usec / 1000) - (tStart.tv_sec * 1000 + tStart.tv_usec / 1000));
- snprintf(gyrobuf, 128, "%d t %lld t %dt %dt %d t %8.1f tn", i, difftime, pfxas2100_data_axis->x, pfxas2100_data_axis->y, pfxas2100_data_axis->z, sumWz);
- write_length = fwrite(gyrobuf, 1, strlen(gyrobuf), fp);
- gettimeofday(&tEnd, NULL);
- nDifftime = (int)((tEnd.tv_sec * 1000 + tEnd.tv_usec / 1000) - (tCurrent.tv_sec * 1000 + tCurrent.tv_usec / 1000));
- if(i % 1000 == 0)
- printf("=i=%d= pfxas2100_data_axis->x=%d, pfxas2100_data_axis->y=%d, pfxas2100_data_axis->z=%d dGyro_z=%lf sumWz=%lfn",
- i, pfxas2100_data_axis->x, pfxas2100_data_axis->y, pfxas2100_data_axis->z, dGyro_z, sumWz);
- usleep(5 * 1000 - nDifftime); //5ms
- }
- close(fd);
- fclose(fp);
- fp = NULL;
- printf("write_length closen");
- return 0;
- }
复制代码
陀螺仪水平转圈后数据分析:
测试数据比较大,放到后面的附件中。
通过matlib分析测试数据抓取下图,左侧是陀螺Z轴旋转一周所得示意图,右侧是Z轴每次数据图形化,根据数据分析处理的结论都是符合陀螺的理论。
试用总结:
1)Yocoto框架学习;Yocto框架跟所以的开源软件博大精深,不是短短三个月的业务时间可以搞清楚,只是了解了一些皮毛,而且只是一个操作的皮毛,其编译,组件等等精髓都没有涉及。
2)惯导器件学习;前面了解了bmi160和bmm150,跟FXAS21002C,fxos8700和mpl3115a2有相似之处,原理一样,也有差异,比如意见的精度。其实惯导期间相对简单,读取数据的方法比较简单,难点在于根据实际需要拿到理论上的数据。
3)陀螺仪实现原理学习;我认为陀螺的算法模型与加计和磁力计很类似,都是x,y,z三个轴的数据,只是x,y,z所表示的意义各不相同。
不足:
1)多核开发板没有将A7和M4两个cpu同时跑起来是有一个遗憾;
2)没有电亮LCD是一个遗憾;
建议:
1)系统更新是一个大问题,繁琐的操作步骤让自己不愿意在搞A7和M4同时启动的问题。
2)电源管理和其他很多功能尚未完成,也许是试用的原因,总觉得warp7这块开发板比imax6的支持差很多。
|