精华内容
下载资源
问答
  • 那么,要如何以最简单,最高效的方式使用这些种类繁多,操作复杂的传感器呢?本文将为大家一一介绍。传感器作为一种检测装置,它的应用早已渗透到诸如工业生产、宇宙探索、海洋探测、环境保护、资源调查、医学诊断、...

    传感器作为各个领域最重要的设备之一,产品种类之多,应用领域之广,随着“智能时代”的到来,传感器的使用将发挥更加关键的作用。那么,要如何以最简单,最高效的方式使用这些种类繁多,操作复杂的传感器呢?本文将为大家一一介绍。

    传感器作为一种检测装置,它的应用早已渗透到诸如工业生产、宇宙探索、海洋探测、环境保护、资源调查、医学诊断、生物工程、甚至文物保护等等极其之广泛的领域。可以毫不夸张地说,从茫茫的太空,到浩瀚的海洋,以及各种复杂的工程系统,几乎每一个现代化项目,都离不开传感器。

    目前,市面上已经存在大量各种类型,各种型号,不同厂家生产的各种传感器,例如,温度、湿度、电压、电流、压强、光照、加速度、角速度等等。它们的应用场景、产品参数、使用方法都不尽相同,这往往使许多项目开发人员在使用传感器时举步维艰:添加一个传感器,就要编写对应的驱动,提供一套访问这个传感器的接口。

    通常情况下,在一个复杂的系统中,传感器往往不止一个,可能存在几个或几十个甚至更多不同种类的传感器,若这些传感器的使用接口都不相同,那么可想而知,软件方面的工作量和复杂度又会有多大?无形中又增加了很大的开发难度。不仅如此,若基于多种传感器开发的应用程序想跨平台复用,而底层各个传感器的接口却千奇百怪,那么,这样的工作量和复杂度又会上升到什么程度?

    为了解决这些问题,AWorks定义了通用的传感器接口,适用于各式各样的传感器,只要是挂载在AWorks系统中的传感器,都可以通过相同的操作接口来访问。同时,只要是基于这些通用接口开发的应用程序,都不会与具体的硬件设备绑定,换句话说,底层更换使用不同型号的传感器,对应用程序不会造成影响,应用程序可以不做任何改动。

    从功能上看,传感器实现了对真实世界中某种物理信号(温度、湿度、气压等)的采集,在使用传感器时,最重要的操作就是从传感器中获取出相应的数据。接下来,进一步介绍如何通过接口获取传感器数据作。

    1、传感器通道ID

    在介绍接口的使用方法之前,需要简单了解一个概念,AWorks之所以能够实现使用一套相同的接口访问所有类型的传感器,是因为AWorks对系统中的传感器进行了统一的管理。为了实现对各式各样的传感器进行统一管理,在AWorks中,定义了“传感器通道”的抽象概念,一路传感器通道用于完成一路物理信号的采集,系统为每个传感器通道分配了一个唯一的ID。例如,若此时系统中存在三个传感器,分别为温湿度传感器HTS221(能为系统提供一路温度和一路湿度通道),三轴磁传感器LIS3MDL(能位系统提供X,Y,Z轴三路磁数据通道和一路温度通道)和光照传感器BH1730(能为系统提供一路光照度采集通道),则对应的ID分配范例详见表

    1。

    表1 传感器通道id分配

    9716f4188600b411907d01c7957ac175.png

    按照以上的传感器通道ID分配方式,理论上,系统中可以挂载无数个各种类型的传感器,新加入的传感器通道只需按照以上方式依次向后分配ID即可。通常情况下,该ID号的分配已经由系统完成,无需我们自行分配,我们只需简单知道当前系统中的有效ID号所对应的传感器通道类型即可。例如,当前AWorks系统中存在的传感器如表1所示,有三个传感器,ID号为0~6,下文中函数接口ID的使用将以此为例。

    2、获取传感器数据

    基于以上对传感器ID的描述,此时若想获取传感器的数据,只需在应用程序中调用获取传感器数据的函数接口即可,获取传感器数据的函数接口如下:

    b310f651b11316a2f6be9bfc71d3f173.png

    其中,id即为传感器通道ID号,p_val为存放对应ID的传感器数据。此处aw_sensor_val_t类型为一个结构体,只需知道它是一个保存传感器数据的变量即可。

    基于此,获取系统中任意传感器通道的数据只需调用该接口即可,例如,每隔500ms获取一次温度采样数据的程序范例如下:

    58a524a6bcfb662542b1f47b90630083.png

    同样,若想获取光照度传感器采样数据,程序范例如下:

    ca445f501779ccbd08e6ec11b6dd84b1.png

    以此类推,只需要调用这一个相同的接口,便可以依次获取系统中所有传感器的数据。此时,或许有人会疑问,系统中那么多传感器,一个一个调用该接口,会不会显得繁琐?对于该问题,AWorks系统当然给出了答案,那就是提供同时获取多通道或者所有通道传感器数据的接口,该接口原型如下:

    07438ecaba0866267a0a62a9bbee7750.png

    其中,p_ids为指向传感器通道id列表的指针;num表示通道的数目,即id列表的大小;p_buf指向用于存储各通道数据的缓存,缓存大小与num一致。基于该接口,可以同时获取多个或所有系统中传感器的采样数据,例如,每隔500ms获取当前表

    1中所有的传感器通道采样数据的程序范例如下:

    638c842ab5c49ec52a7a026adc84134b.png

    基于此,AWorks系统的传感器接口已经完美的实现了使用同种接口获取所有传感器采样数据的功能。此时,或许有人又会提出疑问,这两个接口采用的似乎都是轮询的方式获取传感器数据,若在效率要求较高的场合,调用该接口是不是不太好呢?再者说,如今的许多传感器都可以采用中断触发的方式获取数据,这样可以大大提高应用程序的效率,那么能不能实现这种功能呢?当然!AWorks同样提供了这种接口,而且接口的调用非常方便,简洁。接下来将为你一一揭秘。

    展开全文
  • pixhawk/px4如何获取及使用传感器数据

    千次阅读 2018-05-24 23:51:20
    pixhawk/px4如何获取及使用传感器数据第一步:读取传感器数据上一篇博文已经介绍了如何给pixhawk/px4创建一个应用程序,现在我们在上一个应用程序的基础上使用传感器数据。应用程序为了实现一些有用的功能,需要订阅...

    pixhawk/px4如何获取及使用传感器数据

    第一步:读取传感器数据

    上一篇博文已经介绍了如何给pixhawk/px4创建一个应用程序,现在我们在上一个应用程序的基础上使用传感器数据。

    应用程序为了实现一些有用的功能,需要订阅输入和发布输出(比如电机或舵机输出的命令)。注意在这里,PX4平台真正的硬件抽象的概念在这里体现---当硬件平台或者传感器升级更新,你完全不需要和传感器驱动打交道,也不需要更新你的应用程序或者更新传感器驱动程序。

    PX4中,应用程序间发送信息的独立通道叫做“topics”,在本教程中,我们关心的话题是“多传感器间的uORB消息机制”(sensor_combinedtopic)。这些消息机制使得整个系统能够同步传感器数据。

    订阅一个消息十分快速简洁:

    1. #include<uORB/topics/sensor_combined.h>  
    2.   
    3. ..  
    4.   
    5. int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));  

    sensor_sub_fd”是一个消息句柄,能够十分有效处理新数据的到来之前的延迟等待。当前线程会休眠,直到新的传感器数据到来时,被调度器唤醒,并且在等待时不需要占用任何的CPU时间。为了实现这个功能,我们使用poll()函数POSIX系统调用。

    在消息读取中加入“poll()”机制,完整程序如下

    1. /**************************************************************************** 
    2.  * 
    3.  *   Copyright (c) 2012-2015 PX4 Development Team. All rights reserved. 
    4.  * 
    5.  * Redistribution and use in source and binary forms, with or without 
    6.  * modification, are permitted provided that the following conditions 
    7.  * are met: 
    8.  * 
    9.  * 1. Redistributions of source code must retain the above copyright 
    10.  *    notice, this list of conditions and the following disclaimer. 
    11.  * 2. Redistributions in binary form must reproduce the above copyright 
    12.  *    notice, this list of conditions and the following disclaimer in 
    13.  *    the documentation and/or other materials provided with the 
    14.  *    distribution. 
    15.  * 3. Neither the name PX4 nor the names of its contributors may be 
    16.  *    used to endorse or promote products derived from this software 
    17.  *    without specific prior written permission. 
    18.  * 
    19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    20.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
    22.  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
    23.  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
    24.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
    25.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
    26.  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
    27.  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
    28.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
    29.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
    30.  * POSSIBILITY OF SUCH DAMAGE. 
    31.  * 
    32.  ****************************************************************************/  
    33.   
    34. /** 
    35.  * @file px4_simple_app.c 
    36.  * Minimal application example for PX4 autopilot 
    37.  * 
    38.  * @author Example User <mail@example.com> 
    39.  */  
    40.   
    41. #include <px4_config.h>  
    42. #include <px4_tasks.h>  
    43. #include <px4_posix.h>  
    44. #include <unistd.h>  
    45. #include <stdio.h>  
    46. #include <poll.h>  
    47. #include <string.h>  
    48.   
    49. #include <uORB/uORB.h>  
    50. #include <uORB/topics/sensor_combined.h>  
    51. #include <uORB/topics/vehicle_attitude.h>  
    52.   
    53. __EXPORT int px4_simple_app_main(int argc, char *argv[]);  
    54.   
    55. int px4_simple_app_main(int argc, char *argv[])  
    56. {  
    57.     /* subscribe to sensor_combined topic */  
    58.     int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));  
    59.     orb_set_interval(sensor_sub_fd, 1000);  
    60.   
    61.   
    62.   
    63.     /* one could wait for multiple topics with this technique, just using one here */  
    64.     px4_pollfd_struct_t fds[] = {  
    65.         { .fd = sensor_sub_fd,   .events = POLLIN },  
    66.         /* there could be more file descriptors here, in the form like: 
    67.          * { .fd = other_sub_fd,   .events = POLLIN }, 
    68.          */  
    69.     };  
    70.   
    71.     int error_counter = 0;  
    72.   
    73.     for (int i = 0; i < 5; i++) {  
    74.         /* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */  
    75.         int poll_ret = px4_poll(fds, 1, 1000);  
    76.   
    77.         /* handle the poll result */  
    78.         if (poll_ret == 0) {  
    79.             /* this means none of our providers is giving us data */  
    80.             PX4_ERR("[px4_simple_app] Got no data within a second");  
    81.   
    82.         } else if (poll_ret < 0) {  
    83.             /* this is seriously bad - should be an emergency */  
    84.             if (error_counter < 10 || error_counter % 50 == 0) {  
    85.                 /* use a counter to prevent flooding (and slowing us down) */  
    86.                 PX4_ERR("[px4_simple_app] ERROR return value from poll(): %d"  
    87.                     , poll_ret);  
    88.             }  
    89.   
    90.             error_counter++;  
    91.   
    92.         } else {  
    93.   
    94.             if (fds[0].revents & POLLIN) {  
    95.                 /* obtained data for the first file descriptor */  
    96.                 struct sensor_combined_s raw;  
    97.                 /* copy sensors raw data into local buffer */  
    98.                 orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);  
    99.                 PX4_WARN("[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f",  
    100.                      (double)raw.accelerometer_m_s2[0],  
    101.                      (double)raw.accelerometer_m_s2[1],  
    102.                      (double)raw.accelerometer_m_s2[2]);  
    103.   
    104.             }  
    105.   
    106.         }  
    107.     }  
    108.         PX4_INFO("exiting");  
    109.     return 0;  
    110. }  


    编译应用程序:

     
    make
    注意,make命令要在Firware目录下执行,因为Makfile文件在该目录下,结果如下图所示。
     

    第二步:测试uORB消息读取机制

    最后一步,运行你的应用程序,并且切换到后台应用。注意这需要把程序重新编译上传到飞控板,拔掉sd卡,然后连接nsh控制台,运行以下命令。

    [plain] view plain copy
    1. px4_simple_app &  

    你的应用程序会向串口输出当前传感器的值:

      [px4_simple_app]
    Accelerometer:   0.0483          0.0821          0.0332
      [px4_simple_app]
    Accelerometer:   0.0486          0.0820          0.0336
      [px4_simple_app]
    Accelerometer:   0.0487          0.0819          0.0327
      [px4_simple_app]
    Accelerometer:   0.0482          0.0818          0.0323
      [px4_simple_app]
    Accelerometer:   0.0482          0.0827          0.0331
     
    [px4_simple_app]
    Accelerometer:   0.0489          0.0804          0.0328
    我测试的结果如下图所示
     

    它会在输出5次数据后退出。接下来会介绍如何编写一个能通过命令行控制的后台应用。

    第三步:打印数据

       为了能获取到计算后的数据,下一步就是“打印”这些结果。如果我们知道某一个消息是使用mavlink协议转发给地面控制站的,我们可以通过这个消息去查看结果。例如我们通过这个方法来获得高度信息的消息。

    接口非常简单--初始化消息的结构体,然后广播这条消息:

    #include
    <uORB/topics/vehicle_attitude.h>
    ..
    /*
    advertise attitude topic */
    struct
    vehicle_attitude_s att;
    memset(&att,
    0, sizeof(att));
    orb_advert_t
    att_pub_fd = orb_advertise(ORB_ID(vehicle_attitude), &att);

    在主循环中,当消息准备好时,打印这条消息。

    orb_publish(ORB_ID(vehicle_attitude),
    att_pub_fd, &att);

    修改后的完整的示例代码如下:

    1. /**************************************************************************** 
    2.  * 
    3.  *   Copyright (c) 2012-2015 PX4 Development Team. All rights reserved. 
    4.  * 
    5.  * Redistribution and use in source and binary forms, with or without 
    6.  * modification, are permitted provided that the following conditions 
    7.  * are met: 
    8.  * 
    9.  * 1. Redistributions of source code must retain the above copyright 
    10.  *    notice, this list of conditions and the following disclaimer. 
    11.  * 2. Redistributions in binary form must reproduce the above copyright 
    12.  *    notice, this list of conditions and the following disclaimer in 
    13.  *    the documentation and/or other materials provided with the 
    14.  *    distribution. 
    15.  * 3. Neither the name PX4 nor the names of its contributors may be 
    16.  *    used to endorse or promote products derived from this software 
    17.  *    without specific prior written permission. 
    18.  * 
    19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    20.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
    22.  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
    23.  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
    24.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
    25.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
    26.  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
    27.  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
    28.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
    29.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
    30.  * POSSIBILITY OF SUCH DAMAGE. 
    31.  * 
    32.  ****************************************************************************/  
    33.   
    34. /** 
    35.  * @file px4_simple_app.c 
    36.  * Minimal application example for PX4 autopilot 
    37.  * 
    38.  * @author Example User <mail@example.com> 
    39.  */  
    40.   
    41. #include <px4_config.h>  
    42. #include <px4_tasks.h>  
    43. #include <px4_posix.h>  
    44. #include <unistd.h>  
    45. #include <stdio.h>  
    46. #include <poll.h>  
    47. #include <string.h>  
    48.   
    49. #include <uORB/uORB.h>  
    50. #include <uORB/topics/sensor_combined.h>  
    51. #include <uORB/topics/vehicle_attitude.h>  
    52.   
    53. __EXPORT int px4_simple_app_main(int argc, char *argv[]);  
    54.   
    55. int px4_simple_app_main(int argc, char *argv[])  
    56. {  
    57.     /* subscribe to sensor_combined topic */  
    58.     int sensor_sub_fd = orb_subscribe(ORB_ID(sensor_combined));  
    59.     orb_set_interval(sensor_sub_fd, 1000);  
    60.   
    61.     /* advertise attitude topic */  
    62.     struct vehicle_attitude_s att;  
    63.     memset(&att, 0, sizeof(att));  
    64.     orb_advert_t att_pub = orb_advertise(ORB_ID(vehicle_attitude), &att);  
    65.   
    66.     /* one could wait for multiple topics with this technique, just using one here */  
    67.     px4_pollfd_struct_t fds[] = {  
    68.         { .fd = sensor_sub_fd,   .events = POLLIN },  
    69.         /* there could be more file descriptors here, in the form like: 
    70.          * { .fd = other_sub_fd,   .events = POLLIN }, 
    71.          */  
    72.     };  
    73.   
    74.     int error_counter = 0;  
    75.   
    76.     for (int i = 0; i < 5; i++) {  
    77.         /* wait for sensor update of 1 file descriptor for 1000 ms (1 second) */  
    78.         int poll_ret = px4_poll(fds, 1, 1000);  
    79.   
    80.         /* handle the poll result */  
    81.         if (poll_ret == 0) {  
    82.             /* this means none of our providers is giving us data */  
    83.             PX4_ERR("[px4_simple_app] Got no data within a second");  
    84.   
    85.         } else if (poll_ret < 0) {  
    86.             /* this is seriously bad - should be an emergency */  
    87.             if (error_counter < 10 || error_counter % 50 == 0) {  
    88.                 /* use a counter to prevent flooding (and slowing us down) */  
    89.                 PX4_ERR("[px4_simple_app] ERROR return value from poll(): %d"  
    90.                     , poll_ret);  
    91.             }  
    92.   
    93.             error_counter++;  
    94.   
    95.         } else {  
    96.   
    97.             if (fds[0].revents & POLLIN) {  
    98.                 /* obtained data for the first file descriptor */  
    99.                 struct sensor_combined_s raw;  
    100.                 /* copy sensors raw data into local buffer */  
    101.                 orb_copy(ORB_ID(sensor_combined), sensor_sub_fd, &raw);  
    102.                 PX4_WARN("[px4_simple_app] Accelerometer:\t%8.4f\t%8.4f\t%8.4f",  
    103.                      (double)raw.accelerometer_m_s2[0],  
    104.                      (double)raw.accelerometer_m_s2[1],  
    105.                      (double)raw.accelerometer_m_s2[2]);  
    106.   
    107.                 /* set att and publish this information for other apps */  
    108.                 att.roll = raw.accelerometer_m_s2[0];  
    109.                 att.pitch = raw.accelerometer_m_s2[1];  
    110.                 att.yaw = raw.accelerometer_m_s2[2];  
    111.                 orb_publish(ORB_ID(vehicle_attitude), att_pub, &att);  
    112.             }  
    113.   
    114.             /* there could be more file descriptors here, in the form like: 
    115.              * if (fds[1..n].revents & POLLIN) {} 
    116.              */  
    117.         }  
    118.     }  
    119.   
    120.     PX4_INFO("exiting");  
    121.   
    122.     return 0;  
    123. }  


    第四步:运行整个示例

    在nsh终端运行你的应用程序:

    px4_simple_app
    

     如果打开地面站QGroundControl,你就能通过实时绘图(Tools-> Analyze)来获得实时的传感器数据。

    注意事项:

    1.打开nsh前需要拔掉sd卡.

    2.连接nsh时不要地面站qgc运行.

    3.连接地面站时需要插上sd卡.

    4.运行编译命令是要在含有Makefile的.../Firware/目录下进行.

    参考资料

    First App Tutorial (Hello Sky)



    展开全文
  • 我用onsensorchange来获取方向传感器的三个数据,想用ondraw画一个矩形, 但是这两个部分在不同的activity里,我想用方向传感器获取数据在另一个activity里使用,画图那个activity是继承view类的 我还是个小白,谢...
  • 本文以Xsens MTi-300为例,介绍如何通过串口获取传感器数据。 二、开发平台 硬件平台:Xsens MTi-300 调试工具:Serial Port Utility 串口参数:115200 8N2 三、具体步骤 进入配置 GotoConfig: Send:FA FF ...

    一、简介

    本文以Xsens MTi-300为例,介绍如何通过串口获取传感器数据。


    二、开发平台

    • 硬件平台:Xsens MTi-300   
    • 调试工具: Serial Port Utility
    • 串口参数:115200 8N2

    三、具体步骤

    1. 进入配置 GotoConfig:
      Send:FA FF 30 00 D1
      Recv:FA FF 31 00 D0
    2. 设置输出配置 SetOutputConfiguration:{(PacketCounter, Freq: 65535), (EulerAngles|Float|ENU, Freq:   100)}
      【具体参考MT Low-level Communication Protocol Documentation.pdf(Pa29:SetOutputConfiguration)】
      Send:FA FF C0 08 10 20 FF FF 20 30 00 64 57
      Recv:FA FF C1 08 10 20 FF FF 20 30 00 64 56
    3. 进入测量 GotoMeasurement:
      Send:FA FF 10 00 F1
      Recv:FA FF 11 00 F0

    展开全文
  • 最近在做室内定位相关研究,希望通过手机传感器数据判断人的姿态和手机位置。之前很多研究只用到了加速度数据,但是判别的准确度偏低。本次我们的研究准备将加速度传感器、角速度传感器、方位传感器、压力传感器等...

    最近在做室内定位相关研究,希望通过手机传感器数据判断人的姿态和手机位置。之前很多研究只用到了加速度数据,但是判别的准确度偏低。本次我们的研究准备将加速度传感器、角速度传感器、方位传感器、压力传感器等数据结合起来,用于提高判别的准确度。
    具体如何采集这些数据,网上并没有相关代码。在这里把自己的实现方法分享出来,供大家参考。
    首先是建立加速度的类AccData(本文只涉及传感器数据采集相关代码,AccData类中从数据库获取数据的代码已经略去):

    /**
     * Created by Maolin Liu on 2016/3/12.
     */
    public class AccData {
        public long timestamp;
        public double ax;
        public double ay;
        public double az;
    
        public static final String TABLE_NAME = "AccData";
        public static final String _ID = "_id";
        public static final String TIMESTAMP = "timestamp";
        public static final String AX = "ax";
        public static final String AY = "ay";
        public static final String AZ = "az";
    
        //生成表的sql语句
        public static String tableCreateSQL() {
            StringBuffer sql = new StringBuffer();
            sql.append("create table ");
            sql.append(TABLE_NAME);
            sql.append(" (");
            sql.append(_ID);
            sql.append(" integer primary key autoincrement,");
            sql.append(TIMESTAMP);
            sql.append(" long,");
            sql.append(AX);
            sql.append(" double,");
            sql.append(AY);
            sql.append(" double,");
            sql.append(AZ);
            sql.append(" double");
            sql.append(" )");
            return sql.toString();
        }
    
        public long insertDataBase(SQLiteDatabase sqLiteDatabase) {
            ContentValues values = new ContentValues();
            values.put(TIMESTAMP, timestamp);
            values.put(AX, ax);
            values.put(AY, ay);
            values.put(AZ, az);
            return(sqLiteDatabase.insert(TABLE_NAME, null, values));
        }
    
        public AccData clone() {
            AccData accData = new AccData();
            accData.timestamp = timestamp;
            accData.ax = ax;
            accData.ay = ay;
            accData.az = az;
            return accData;
        }
    }

    然后是加速度的SQLiteOpenHelper类,即AccDBOpenHelper:

    /**
     * Created by Maolin Liu on 2016/3/12.
     */
    public class AccDBOpenHelper extends SQLiteOpenHelper {
        private static final String DBNAME = "Acc Data.db3";
        private static final int VERSION = 1;
        public AccDBOpenHelper(Context context){
            super(context,DBNAME,null,VERSION);
        }
    
        public AccDBOpenHelper(Context context, String name,SQLiteDatabase.CursorFactory factory, int version){
            super(context, name, factory, version);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void onCreate(SQLiteDatabase db){
            db.execSQL(AccData.tableCreateSQL());
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
            System.out.println( "----------AccDBOpenHelper onUpdata Called----------" + oldVersion + "-->" + newVersion);
        }
    }

    按照和上面类似的方法为角速度数据、方位数据、压力数据建立数据类和对应的SQLiteOpenHelper类。
    下面是具体的实现了。如果将采集数据的的代码放在Activity中,用户体验不是特别好。所以我们在后台Service中进行数据采集。需要注意几个地方,第一,往数据库中存储大量数据的时候最好添加事务,这样会提高存储效率;第二,方向数据要通过计算获得,而不是通过传感器直接获取,如果需要用到azimuth、pitch和roll数据需要特别注意这一点(详情点击:Android Orientation Sensor(方向传感器)详解与应用)。第三,API等级在19以上,可以自由设置传感器的采样频率,注意单位是微秒(10 -6秒)。
    下面是Service具体代码:

    /**
     * Created by Maolin Liu on 2016/3/12.  
     */
    public class DataAcquireService extends Service {
        private SensorManager sensorManager;
        private MySensorBinder mySensorBinder;
        private Timer updateTimer;
    
        private AccDBOpenHelper accDBOpenHelper;
        private SQLiteDatabase accDB;
        private List<AccData> accDataList;
        private AccData accData;
        private float accValues[];
    
        private GyrDBOpenHelper gyrDBOpenHelper;
        private SQLiteDatabase gyrDB;
        private List<GyrData> gyrDataList;
        private GyrData gyrData;
        private float gyrValues[];
    
        private MagAndOriDBOpenHelper magAndOriDBOpenHelper;
        private SQLiteDatabase magAndOriDB;
        private List<MagAndOriData> magAndOriDataList;
        private MagAndOriData magAndOriData;
    
        private PreDBOpenHelper preDBOpenHelper;
        private SQLiteDatabase preDB;
        private List<PreData> preDataList;
        private PreData preData;
        private float preValue;
    
        private float magValues[];
    
        private boolean isRecord ;             //开始存储或者关闭存储的Boolean值
        public static final String ACTION_STATE_COLLECT_SERVICE = "edu.geosis.service.DATA_ACQUIRE_SERVICE";
    
        @Override
        public IBinder onBind(Intent intent) {
            System.out.println("DataAcquireService is binded ! ");
            return mySensorBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            initializeVariables();             
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            System.out.println("DataAcquireService is started ! ");
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            if (accDB != null && accDB.isOpen()) {
                accDB.close();
            }
            if (gyrDB != null && gyrDB.isOpen()) {
                gyrDB.close();
            }
            if (magAndOriDB != null && magAndOriDB.isOpen()) {
                magAndOriDB.close();
            }
            if (preDB != null && preDB.isOpen()) {
                preDB.close();
            }
    
            sensorManager.unregisterListener(mySensorListener);      
            System.out.println("DataAcquireService is destroyed ! ");
            super.onDestroy();
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            System.out.println("DataAcquireService is onUnbinded ! ");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onRebind(Intent intent) {
            System.out.println("DataAcquireService is onRebinded ! ");
            super.onRebind(intent);
        }
    
        private void initializeVariables() {
    
            mySensorBinder = new MySensorBinder();
            sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    
    
            accDBOpenHelper = new AccDBOpenHelper(this, "Acc Data.db3", null, 1);       //存储在默认路径下
            accDB = accDBOpenHelper.getReadableDatabase();
            accDataList = new ArrayList<AccData>();
            accData = new AccData();
    
            gyrDBOpenHelper = new GyrDBOpenHelper(this, "Gyr Data.db3", null, 1);
            gyrDB = gyrDBOpenHelper.getReadableDatabase();
            gyrDataList = new ArrayList<GyrData>();
            gyrData = new GyrData();
    
            magAndOriDBOpenHelper = new MagAndOriDBOpenHelper(this, "MagAndOri Data.db3", null, 1);     
            magAndOriDB = magAndOriDBOpenHelper.getReadableDatabase();
            magAndOriDataList = new ArrayList<MagAndOriData>();
            magAndOriData = new MagAndOriData();
    
            preDBOpenHelper = new PreDBOpenHelper(this, "Pre Data.db3", null, 1);
            preDB = preDBOpenHelper.getReadableDatabase();
            preDataList = new ArrayList<PreData>();
            preData = new PreData();
    
            isRecord = false;
        }
    
        /**
         * Service对应的Activity通过下面的Binder类对采集数据的过程进行控制
         **/
        public class MySensorBinder extends Binder {
    
            public void startRecord() {
                isRecord = true;
            }
    
            public void stopRecord() {
                isRecord = false;
            }
    
            public void clearRecord() {
                accDataList.clear();
                gyrDataList.clear();
                magAndOriDataList.clear();
                preDataList.clear();
            }
    
            public boolean insertDB() {
                //make clear whether it is "||" or "&&"
                if (accDataList.isEmpty() && gyrDataList.isEmpty() && preDataList.isEmpty()&& magAndOriDataList.isEmpty()) {
                    return false;
                } else {
                    //存储时开启事务能大大加快存储速度,否则一条一条地存储特别费时
                    accDB.beginTransaction();
                    try {
                        for (AccData accData: accDataList) {
                            accData.insertDataBase(accDB);
                        }
                        accDB.setTransactionSuccessful();
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                        System.out.println("accData cannot insert into the database !");
                    }
                    finally {
                        accDB.endTransaction();
                    }
    
                    gyrDB.beginTransaction();
                    try {
                        for (GyrData gyrData: gyrDataList) {
                            gyrData.insertDataBase(gyrDB);
                        }
                        gyrDB.setTransactionSuccessful();
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                    finally {
                        gyrDB.endTransaction();
                    }
    
                    magAndOriDB.beginTransaction();
                    try {
                        for (MagAndOriData magAndOriData: magAndOriDataList) {
                            magAndOriData.insertDataBase(magAndOriDB);
                        }
                        magAndOriDB.setTransactionSuccessful();
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                    finally {
                        magAndOriDB.endTransaction();
                    }
    
                    preDB.beginTransaction();
                    try {
                        for (PreData preData: preDataList) {
                            preData.insertDataBase(preDB);
                        }
                        preDB.setTransactionSuccessful();
                    }
                    catch(Exception e) {
                        e.printStackTrace();
                    }
                    finally {
                        preDB.endTransaction();
                    }
    
                    return true;
                }
            }
    
            public void registerListener() {
                boolean result =   sensorManager.registerListener(mySensorListener,
                        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                        SensorManager.SENSOR_DELAY_GAME);                              //最后一个参数用于控制传感器数据获取的频率,频率可以自由调整
                Log.d("maolin",""+result);   //LOG查看监听是否成功注册
    
                sensorManager.registerListener(mySensorListener,
                        sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
                        SensorManager.SENSOR_DELAY_GAME);
    
                sensorManager.registerListener(mySensorListener,
                        sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                        SensorManager.SENSOR_DELAY_GAME);
    
                sensorManager.registerListener(mySensorListener,
                        sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE),
                        SensorManager.SENSOR_DELAY_GAME);
    
    
            }
            public void unregisterListener() {
                sensorManager.unregisterListener(mySensorListener);
                System.out.println("StateCollectService listener is unregistered ! ");
            }
    
        }
    
        //下面是传感器变化监听的关键类
        private SensorEventListener mySensorListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                switch(event.sensor.getType()) {
                    case Sensor.TYPE_ACCELEROMETER:
                        accValues = event.values.clone();
                        synchronized (accData) {
                            accData.timestamp = System.currentTimeMillis();
                            accData.ax = accValues[0];
                            accData.ay = accValues[1];
                            accData.az = accValues[2];
    
                            if (isRecord) {
                                accDataList.add(accData.clone());
                            }
                        }
                        break;
                    case Sensor.TYPE_GYROSCOPE:
                        gyrValues = event.values.clone();
                        synchronized (gyrData) {
                            gyrData.timestamp = System.currentTimeMillis();
                            gyrData.gx = gyrValues[0];
                            gyrData.gy = gyrValues[1];
                            gyrData.gz = gyrValues[2];
    
                            if (isRecord) {
                                gyrDataList.add(gyrData.clone());
                            }
                        }
                        break;
                    case Sensor.TYPE_PRESSURE:
                        preValue = event.values[0];
                        synchronized (preData) {
                            preData.timestamp = System.currentTimeMillis();
                            preData.pressure = preValue;
    
                            if (isRecord) {
                                preDataList.add(preData.clone());
                            }
                        }
                        break;
                    case Sensor.TYPE_MAGNETIC_FIELD:               //加速度、陀螺仪和气压计都可以直接获得,但是磁力计和方位角数据要通过计算才能得到
                        magValues = event.values;
                        break;
                }
            }
    
            @Override
            public void onAccuracyChanged(Sensor sensor, int i) {
            }
        };
    }

    然后就是操作界面DataAcquireActivity :

    /**
     * Created by GeoSIS on 2016/3/12.
     */
    public class DataAcquireActivity extends Activity {
    
        private Chronometer chronometer = null;    //添加一个计时器,知道采集的时长;
        private Button btnStart,btnEnd;
    
        private ServiceConnection dataAcquireConnection;
        private DataAcquireService.MySensorBinder mySensorBinder;
        private ArrayList<Long> savedTime;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_data_acquire);
    
            initializeVariables();
            initializeButton();
        }
    
        @Override
        protected void onStart() {
            super.onStart();
        }
    
        @Override
        protected void onRestart() {
            super.onRestart();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
        }
    
        @Override
        protected void onStop() {
            super.onStop();
        }
    
        @Override
        protected void onDestroy() {
    
            unbindService(dataAcquireConnection);
            super.onDestroy();
        }
    
        private void initializeVariables() {
            // TODO Auto-generated method stub
    
            chronometer = (Chronometer)findViewById(R.id.chronometer);
            btnStart    = (Button)findViewById(R.id.start_pick_up);
            btnEnd      = (Button)findViewById(R.id.end_pick_up);
    
        }
    
        private void initializeButton() {
            // TODO Auto-generated method stub
            btnStart.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    // TODO Auto-generated method stub
                    chronometer.setBase(SystemClock.elapsedRealtime());
                    chronometer.start();
    
                    mySensorBinder.registerListener();
                    mySensorBinder.startRecord();
    
                    btnStart.setClickable(false);                                                 btnStart.setBackgroundColor(getResources().getColor(R.color.yellow));
                }
            });
            btnEnd.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View arg0) {
                    // TODO Auto-generated method stub
                    chronometer.stop();
    
                    mySensorBinder.stopRecord();
                    mySensorBinder.insertDB();
                    mySensorBinder.clearRecord();
                    mySensorBinder.unregisterListener();
    
                   finish();
                }
            });
        }
    }

    Activity对应的XML文件非常简单,上面只有一个计时器(Chronometer)、一个开始采集的按钮(Button)和一个结束采集的按钮(Button),这里就不列出来了。

    展开全文
  • android手机内有多个传感器,比如加速度计、陀螺仪等。 本篇介绍如何获取加速度数据并显示到TextView上。
  • 前文【逗老师带你学IT】PRTG监控通过Python+TCP Modbus获取温湿度传感器数据中我们讲了如何通过Python读取支持TCP Modbus的传感器数据。本章我们讲解下如何读取Modbus RTU传感器的数据。 一、Modbus TCP和RTU的区别 ...
  • 本篇介绍如何获取加速度数据并存储到csv文件中
  • 本主题将带您完成创建罗盘应用程序,该应用程序为您提供罗盘数据的数字显示以及图形表示。本演练还介绍如何实现罗盘校准对话框。罗盘概述可以使用罗盘或磁力计传感器来确定设备相对于地球磁场北极旋转的角度。应用...
  • 本文介绍,Python如何通过TCP Modbus协议获取温湿度传感器数据。并在PRTG监控系统中呈现。 本文主要涉及知识点: 1、Python的ModbusTCP客户端实现 2、常见温湿度传感器中,温度和湿度寄存器的位置 目录一、关于...
  • 本示例应用程序还向您显示如何计算传感器读数的总和来确定设备的累计旋转。陀螺仪概述陀螺仪传感器测量设备沿着其三个主轴的旋转速度。当设备静止时,所有轴的陀螺仪读数都为零。如果设备面向您围绕其中心点旋转,就...
  • 此示例展示了如何获取 Android 移动设备(例如手机或平板电脑)的位置和速度数据。 位置数据由纬度、经度和高度数据组成。 在此示例中,捕获的纬度和经度数据在 MATLAB 中绘制,并使用 Mapping Toolbox 覆盖在来自 ...
  • 我们使用LM35温度传感器获取温度值,并使用DS3231模块获取时间和日期。然后SD卡插入SD卡模块中,在SD卡文件中记录日期、时间和温度。 所需的组件 ● Arduino开发板 ● SD卡模块 ● DS3231S时钟模块 ● ...
  • 传感器数据和服务器的衔接

    千次阅读 2019-10-10 20:41:00
    答:首先传感器数据要数字化,可以通过接口或者模块,传送到本机或者直接用GPRS模块上传到服务器,手机app就可以通过访问服务器实现数据获取了。 2. 如何将传感器采集的数据上传到web服务器中? 答:用个网络模块 esp...
  • 2012/2/9本主题将带您完成创建加速度计应用程序,该应用程序为您提供加速度计数据的数字显示以及图形表示。加速度计概述加速度计测量在某一时刻施加于设备的力。可以使用这些力来确定用户正在向哪个方向移动设备。加...
  • Proj2_AccelerationSaveTest 一个简单的测试应用程序,了解android如何快速保存其加速器传感器数据 该应用程序获取加速数据(大约每秒50次)并将其保存在Root外部存储目录中
  • 接下里我们开始添加I2C设备,添加SHT3x软件包,获取SHT3x温湿度传感器数据。 2. 添加I2C设备 2.1. 打开I2C设备驱动框架 双击左侧 RT-Thread Setting 文件,即可打开RT-Thread图形化配置工具,软件
  • 传感器数据管理器库: : 问题 阅读 给电子邮件 内容 基本库用法示例: 。 运行AsyncTask,这些AsyncTasks从所有传感器获取数据,将其格式化为JSON,然后将结果打印到Log.d。 。 带有选项卡的简单/示例应用程序,...
  • 从串口读取了我想要的距离数据...在程序里实现了但是发现如果有一个数据触发了语音,在播报完之后获取的下一个串口数据不是当前时刻的数据,而是1s前传感器获取数据。发送给串口的数据并不是实时替换的,该如何解决?
  • 这篇笔记会写一下我是如何使用MPU9250传感器,通过Arduino/Genuino101获取传感器数据,并分析该教程中提供的代码文件提供的接口。本人菜鸟新手,这篇文章只是学习记录一些新的知识,以供以后参考。 ...
  • 在本示例中,MATLAB:registered: 用于使用两个 XBee:registered: 系列... 该示例说明了如何控制、获取和分析来自通过 XBee 模块无线连接的传感器数据。 XBee 是 Digi International 的注册商标, http://www.digi.com
  • 上一篇:远程访问传感器获取数据并传入数据库----one今天做的是如何连接数据库,只有数据库连接成功才能传输数据。一、老师给的虚拟机有两个陷阱需要填上,即root用户不能连接和bind-address需要屏蔽掉。解决方法...
  • 但是传感器一直不会传送数据给PC,所以PC端也无法读取相应的数据。 芯片的开发手册和python包的源码都看过了,不过本人是硬件小白,懂python和一点C,看完之后也不知道接下来应该怎么做,才能获取数据。是不是要发送...
  • 产品中传感器数据的保存与处理 产品中传感器的数据的如何保存与分析,首先获取大量(连续的、有效的)数据,数据处理,进行分析。 一:数据获取 可通过数据线缆进行传输(CAN、485串口)到电脑。 也可以KEIL中在...
  • 如何获取传感器数据,如何监听传感器数据变化呢? 先贴一段小程序: //获取传感器管理器 SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //获取环境光线传感器 Sensor lightSensor ...
  • 构建了融合传感器数据的电控柴油机贝叶斯网络综合故障诊断模型,提出了使用传感器数据技术检测电控柴油机工作状态,并结合经验法等估算出各类故障源的先验概率。通过运用贝叶斯网络技术推断查找到故障源的方法,并以...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 344
精华内容 137
关键字:

如何获取传感器数据