精华内容
下载资源
问答
  • 无线传感网常用的振动加速度传感器有以下几种:MEMS 振动加速度传感器,机械式振动加速度传感器,压电、光纤式振动加速度传感器。其中,MEMS 振动加速度传感器又分为压阻式和电容式两种,而光纤式振动加速度传感器...
  • CA-YD-185-TNC 型传感器说明书 振动加速度传感器特性
  • 针对煤矿井下大型设备振动信号难以采集的问题,设计了一种矿用振动加速度传感器信号调理装置。详细介绍了该信号调理装置中振动加速度传感器的选型设计,振动信号调理板中的供电模块、激励电路、滤波电路设计及防护设计...
  • 富索克 LHC01振动加速度传感器 用户手册pdf,富索克 LHC01振动加速度传感器 用户手册
  • 暑假里老师给布置了个任务,希望能够避开云端,使用移动端来获取 WeMos D1 上传感器的数据。 那么这里大致的思路就是: 通过串口获取传感器的数据; 在WeMos D1上开启服务以供移动端访问 编写移动端APP 2 系统设计...

    1 介绍

    暑假里老师给布置了个任务,希望能够避开云端,使用移动端来获取 WeMos D1 上传感器的数据。
    那么这里大致的思路就是:

    • 通过串口获取传感器的数据;
    • 在WeMos D1上开启服务以供移动端访问
    • 编写移动端APP

    2 系统设计与实现

    2.1 系统整体架构设计

    本系统主要以WeMos D1为核心,在其上开启Socket服务,将通过串口获得的传感器数据,提供给移动端。
    系统整体架构设计

    2.2 WeMos D1端

    俗话说便宜没好货,WeMos D1这块板子就符合这个道理,在博主拿到这块板子和传感器的时候,就发现了一个问题——板子的硬件串口就只有一个,而且这个串口是另有用途的,所以不能用来获取传感器的数据,因此在这里我们需要用到软串口。所幸的是,在Arduino IDE这个编程环境中,已经给我们提供了软串口1的库,我们只需要像硬件串口一样对其他引脚进行操作便可。对软串口不懂的朋友,可以看下注释1的链接。
    这里博主选用了引脚0和引脚16来作为软串口的RX和TX,如图:
    在这里插入图片描述
    为了让移动端能够点对点连接上WeMos D1,这里WeMos D1需要开启AP模式,以使得移动端连接其WiFi构建局域网。
    接着使用Arduino IDE中ESP8266的库函数2来开启Socket服务。不知道怎么开启的,请看注释2的链接。

    2.3 移动端

    移动端的构建非常简单,就是一个很普通的Socket客户端。
    其布局如图所示:
    在这里插入图片描述
    因为移动端博主还有其它用途,所以这个布局有点多余的功能,各位看客要写的话,是不需要那么多的按钮的。
    这里IP和Port在代码中已经有默认输入,所以不输入直接点击采集数据即可。

    3 代码

    3.1 获取JY-901加速度数据

    在购买JY-901九轴加速度传感器时,店家随了一份传感器资料过来,其中有一份用Arduino UNOR3获取JY-901串口数据的代码,该代码使用Arduino IDE进行编写,首先看工程文件“JY901Serial.ino”:

    #include <Wire.h>
    #include <JY901.h>
    /*
    Test on Uno R3.
    JY901   UnoR3
    TX <---> 0(Rx)
    */
    void setup() 
    {
      Serial.begin(9600);
    }
    
    void loop() 
    {
      //print received data. Data was received in serialEvent;
      Serial.print("Time:20");Serial.print(JY901.stcTime.ucYear);Serial.print("-");Serial.print(JY901.stcTime.ucMonth);Serial.print("-");Serial.print(JY901.stcTime.ucDay);
      Serial.print(" ");Serial.print(JY901.stcTime.ucHour);Serial.print(":");Serial.print(JY901.stcTime.ucMinute);Serial.print(":");Serial.println((float)JY901.stcTime.ucSecond+(float)JY901.stcTime.usMiliSecond/1000);
                   
      Serial.print("Acc:");Serial.print((float)JY901.stcAcc.a[0]/32768*16);Serial.print(" ");Serial.print((float)JY901.stcAcc.a[1]/32768*16);Serial.print(" ");Serial.println((float)JY901.stcAcc.a[2]/32768*16);
      
      Serial.print("Gyro:");Serial.print((float)JY901.stcGyro.w[0]/32768*2000);Serial.print(" ");Serial.print((float)JY901.stcGyro.w[1]/32768*2000);Serial.print(" ");Serial.println((float)JY901.stcGyro.w[2]/32768*2000);
      
      Serial.print("Angle:");Serial.print((float)JY901.stcAngle.Angle[0]/32768*180);Serial.print(" ");Serial.print((float)JY901.stcAngle.Angle[1]/32768*180);Serial.print(" ");Serial.println((float)JY901.stcAngle.Angle[2]/32768*180);
      
      Serial.print("Mag:");Serial.print(JY901.stcMag.h[0]);Serial.print(" ");Serial.print(JY901.stcMag.h[1]);Serial.print(" ");Serial.println(JY901.stcMag.h[2]);
      
      Serial.print("Pressure:");Serial.print(JY901.stcPress.lPressure);Serial.print(" ");Serial.println((float)JY901.stcPress.lAltitude/100);
      
      Serial.print("DStatus:");Serial.print(JY901.stcDStatus.sDStatus[0]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[1]);Serial.print(" ");Serial.print(JY901.stcDStatus.sDStatus[2]);Serial.print(" ");Serial.println(JY901.stcDStatus.sDStatus[3]);
      
      Serial.print("Longitude:");Serial.print(JY901.stcLonLat.lLon/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLon % 10000000)/1e5);Serial.print("m Lattitude:");
      Serial.print(JY901.stcLonLat.lLat/10000000);Serial.print("Deg");Serial.print((double)(JY901.stcLonLat.lLat % 10000000)/1e5);Serial.println("m");
      
      Serial.print("GPSHeight:");Serial.print((float)JY901.stcGPSV.sGPSHeight/10);Serial.print("m GPSYaw:");Serial.print((float)JY901.stcGPSV.sGPSYaw/10);Serial.print("Deg GPSV:");Serial.print((float)JY901.stcGPSV.lGPSVelocity/1000);Serial.println("km/h");
      
      Serial.println("");
      delay(500);
    }
    /*
    SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available.
    */
    void serialEvent() 
    {
      while (Serial.available()) 
      {
        JY901.CopeSerialData(Serial.read()); //Call JY901 data cope function
      }
    }
    

    阅读这么一个工程文件,第一步先看setup函数,只有一个以波特率9600打开串口的操作,第二步loop函数,以本博客要获取的加速度数据为例:

    Serial.print("Acc:");Serial.print((float)JY901.stcAcc.a[0]/32768*16);Serial.print(" ");Serial.print((float)JY901.stcAcc.a[1]/32768*16);Serial.print(" ");Serial.println((float)JY901.stcAcc.a[2]/32768*16);
    

    可看到loop函数中都是输出对象JY901中数据的语句,由此推测JY901中存放的便是传感器获取到的数据。而后第三步serialEvent函数,这个函数的作用是获取串口数据,并用函数CopeSerialData对串口数据进行处理并存入对象JY901中,注释中也提到,serialEvent函数在loop函数循环时,同步运行。
    下面是函数CopeSerialData源码:

    void CJY901 ::CopeSerialData(unsigned char ucData)
    {
    	static unsigned char ucRxBuffer[250];
    	static unsigned char ucRxCnt = 0;	
    	
    	ucRxBuffer[ucRxCnt++]=ucData;
    	if (ucRxBuffer[0]!=0x55) 
    	{
    		ucRxCnt=0;
    		return;
    	}
    	if (ucRxCnt<11) {return;}
    	else
    	{
    		switch(ucRxBuffer[1])
    		{
    			case 0x50:	memcpy(&stcTime,&ucRxBuffer[2],8);break;
    			case 0x51:	memcpy(&stcAcc,&ucRxBuffer[2],8);break;
    			case 0x52:	memcpy(&stcGyro,&ucRxBuffer[2],8);break;
    			case 0x53:	memcpy(&stcAngle,&ucRxBuffer[2],8);break;
    			case 0x54:	memcpy(&stcMag,&ucRxBuffer[2],8);break;
    			case 0x55:	memcpy(&stcDStatus,&ucRxBuffer[2],8);break;
    			case 0x56:	memcpy(&stcPress,&ucRxBuffer[2],8);break;
    			case 0x57:	memcpy(&stcLonLat,&ucRxBuffer[2],8);break;
    			case 0x58:	memcpy(&stcGPSV,&ucRxBuffer[2],8);break;
    		}
    		ucRxCnt=0;
    	}
    }
    

    因此只要能够从串口读到传感器数据,并用CopeSerialData函数对串口数据进行处理,即可获得需要的加速度数据。

    3.2 在WeMos D1端启动服务

    WeMos D1端代码解释请看注释,代码如下:

    #include<ESP8266WiFi.h>
    #include<SoftwareSerial.h>
    
    #define AP_SSID     "ESP8266WiFi"
    #define AP_PSW      "88888888"
    #define SERVER_MAX  1
    
    IPAddress ip(192,168,4,22);
    IPAddress gateway(192,168,4,9);
    IPAddress subnet(255,255,255,0);
    SoftwareSerial mySerial(0,16);//软串口定义,引脚0表示RX,引脚16表示TX
    
    WiFiServer server(8000);//定义socket服务,端口8000
    WiFiClient clients[SERVER_MAX];//管理与socket服务相连的客户端
    struct Acceleration
    {
      short acc[3];//因为只需要加速度传感器,所以不必如传感器资料里一样定义一个类,只需定义一个代表加速度的结构体即可
      short Time;
    }acceleration;
    
    void setup() {
      mySerial.begin(9600);
      //开启热点,移动移动端连接WiFi,与WeMos D1构建局域网
      WiFi.mode(WIFI_AP);//修改模式为AP
      WiFi.softAPConfig(ip, gateway, subnet);//设置AP相关网络参数
      //启动socket服务
      server.begin();
      server.setNoDelay(true);//关闭小包合并包功能,不会延时发送数据
    }
    
    void loop() {
      uint8_t i;
      if(server.hasClient()){
        //如果有新客户端连接,释放客户端列表中失效客户端,并将新客户端加入
        for(i=0;i<SERVER_MAX;i++){
          if(!clients[i]||!clients[i].connected()){
            if(clients[i]){
              clients[i].stop();
            }
            clients[i]=server.available();
            break;
          }
        }
        //若客户端列表已满,则拒绝新客户端连接
        if(i==SERVER_MAX){
          WiFiClient _client=server.available();
          _client.stop();
        }
      }
      if(mySerial.available()){
        //读取串口数据,并使用CopeSerialData函数进行处理
        if(CopeSerialData(mySerial.read())){
          //将获取到的加速度数据经过处理,通过socket发送给移动端
          //在要发送的数据前后分别加上begin和end,以供移动端更容易的识别数据头尾
          char sbuf0[10]="begin ",sbuf1[10],sbuf2[10],sbuf3[10],sbuf4[10]="end\n";
          //将加速度类型由浮点型转化为字符串
          dtostrf((float)acceleration.acc[0]/32768*16,2,2,sbuf1);
          dtostrf((float)acceleration.acc[1]/32768*16,2,2,sbuf2);
          dtostrf((float)acceleration.acc[2]/32768*16,2,2,sbuf3);
          //将加速度数据依次发送给每一个连接的客户端
          for(i=0;i<SERVER_MAX;i++) {
            if(clients[i]&&clients[i].connected()) {
              clients[i].write(sbuf0, 6);
              clients[i].write(sbuf1, Judge(sbuf1));
              clients[i].write(sbuf2, Judge(sbuf2));
              clients[i].write(sbuf3, Judge(sbuf3));
              clients[i].write(sbuf4, 4);
              delay(1);
            }
          }
        }
      }
    }
    
    bool CopeSerialData(unsigned char ucData){
      static unsigned char ucRxBuffer[250];
      static unsigned char ucRxCnt = 0;
      ucRxBuffer[ucRxCnt++]=ucData;
      //JY-901传感器规定有效数据由0x55开始
      if(ucRxBuffer[0]!=0x55){
        ucRxCnt = 0;
        return false;
      }
      //规定每11个数据为一次有效数据
      if(ucRxCnt<11){
        return false;
      }
      else{
        switch(ucRxBuffer[1]){
          //只需要加速度数据,因此只需判断0x51即可,若要获取别的数据,请看上面完整的CopeSerialData函数源码
          case 0x51:
            memcpy(&acceleration,&ucRxBuffer[2],8);
            break;
        }
        ucRxCnt=0;
        return true;
      }
    }
    
    int Judge(char str[]){
      //计算socket连接中发送消息的长度,并在消息后面补上一个空格
      int len;
      for(len=0;len<10;len++){
        if(str[len]=='-'||(str[len]>='0'&&str[len]<='9')||str[len]=='.'){
          continue;
        }
        else{
          break;
        }
      }
      str[len]=' ';
      return len+1;
    }
    

    3.3 移动端获取数据

    移动端最主要的就是一个socket连接问题,首先是socket建立:

    protected void SocketConnect() {
        ip = inputIP.getText().toString();
        port = inputPort.getText().toString();
        //WeMos D1的IP地址和端口一开始就有默认值,但也可由用户自行输入
        if (!IsIPPortLegal()) {
            Toast.makeText(MainActivity.this, "填写不正确,已使用默认IP和端口", Toast.LENGTH_SHORT).show();
            ip = "192.168.4.22";
            port = "8000";
        }
        //Android开发中socket连接必须要以线程的方式才可以进行
        Thread thread = new Thread("Connect") {
            @Override
            public void run() {
                super.run();
                if (!socketStatus) {
                    try {
                        socket = new Socket(ip, Integer.parseInt(port));
                        if (socket != null) {
                            //socket建立成功
                            inputStream = socket.getInputStream();
                            outputStream = socket.getOutputStream();
                            //socketStatus是一个标志,避免socket还未连接就用socket获取数据的错误
                            socketStatus = true;
                        }
                    } catch (IOException e) {
                        //socket建立失败
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
    }
    

    接着就是利用socket获取数据:

    protected void SocketGetData() {
        //同样要新建一个线程
        Thread thread = new Thread("GetData") {
            @Override
            public void run() {
                super.run();
                //判断socket是否已经连接
                while(!socketStatus){};
                if (socketStatus) {
                    try {
                        //获取数据
                        int len = 0;
                        byte[] buf = new byte[1024];
                        String tmp = "";
                        int count = 0;
                        while (getDataStatus && ((len = inputStream.read(buf)) != -1)) {
                            String _tmp = new String(buf, 0, len);
                            tmp += _tmp;
                            count++;
                            if (count == 10) {
                                DealWithInputStream(tmp);
                                count = 0;
                                tmp = "";
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
    }
    
    protected void DealWithInputStream(String tmp) {
        //按照与WeMos D1约定的格式,使用正则表达式提取加速度数据,并存入文件dataCenter中
        Pattern pattern = Pattern.compile("begin .* end");
        Matcher matcher = pattern.matcher(tmp);
    
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            out = openFileOutput("dataCenter", Context.MODE_APPEND);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            while (matcher.find()) {
                String _tmp = "" + System.currentTimeMillis() + " " + matcher.group() + (dataStatus ? " 1\r\n" : " 0\r\n");
                Log.d("tag", _tmp);
                writer.write(_tmp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    4 遇到的问题

    • 一开始使用Micropython写的代码,但是它没有软串口的库,IIC有关的例子又少,没看懂,后来换了C语言,用Arduino IDE编写代码,果然这种硬件有关的东西还是C语言好用啊。
    • 写APP的时候,代码明明没错,但是Socket却总是建立失败,而后排查问题发现,是没有获取权限的问题。
    • 有天开机的时候电脑挂了【ps:神舟电脑伤不起…】,而后重装电脑,将Android Studio重装,导入之前的项目,发现怎么都运行不了,谷歌了好久都没解决,后来灵机一动,新建了个项目,把代码复制粘贴进去,运行成功。
    • 在写APP的时候数据持久化遇到了个问题,存下来的数据找不到了,谷歌后才知道是在data/data/包名/file文件夹下面
    • 暂时想不起别的问题了。
    • 各位看官有问题请留言。

    1. 软串口通信——SoftwareSerial库的使用 ↩︎

    2. 博哥零基础教你玩转ESP8266 ↩︎

    展开全文
  • 研究论文-一种RIM 型低频振动光纤加速度传感器的设计
  • 压电式加速度传感器就是利用了压电晶体的正压电效应,将机械能转换为电能,从而实现对振动加速度信号的测量。  压电式加速度传感器常见的结构形式有中心压缩式、环形剪切式、三角剪切式。测量被测对象振动大小时,...
  • 加速度传感器是一种能够测量加速力的电子设备。加速力就是当物体在加速过程中作用在物体上的力,就好比地球引力,也就是...目前工业现场典型采用IEPE型加速度传感器,及内置IC电路压电加速度传感器,传感器输出与振动
  • 设计了一种反射式光强调制光纤传感器(RIM-FOS),用于测量低频振动加速度信号 。由于只采用一根单模 光纤用于发射和接收,整体结构紧凑小巧且在一定条件和范围内使其数学模型相对简练,通过数字和线性化处理可 不失真地...
  • 无线加速度传感器

    2018-11-27 14:21:38
    关于无线加速度传感器的使用说明 MMS-F-A01无线加速度传感器采用最...引进欧洲专利技术的三轴加速度传感单元,具有结构固定、功耗低、稳定性好等特点,无线加速度传感器使用简单,可用于振动测 试、撞击测试等领域。
  • 现在,加速度传感器广泛应用于游戏控制、手柄振动和摇晃、汽车制动启动检测、地震检测、工程测振、地质勘探、振动测试与分析以及安全保卫振动侦察等多种领域。下面就举例几种应用场景,更好的认识加速度传感器。 ...
  • 加速度传感器原理

    2021-01-19 16:15:42
    加速度传感器甚至可以用来分析发动机的振动。  通过测量由于重力引起的加速度,你可以计算出设备相对于水平面的倾斜角度。通过分析动态加速度,你可以分析出设备移动的方式。但是刚开始的时候,你会发现光测量倾角...
  •  现在,加速度传感器广泛应用于游戏控制、手柄振动和摇晃、汽车制动启动检测、地震检测、工程测振、地质勘探、振动测试与分析以及安全保卫振动侦察等多种领域。下面就举例几个例子,更好的认识加速度传感器。  ...
  • 为了提高安防报警系统的报警准确率,开发了一种基于加速度传感器的微振动报警系统。本文阐述了系统的工作原理、硬件组成和软件架构,实现对微振动信号的准确采集。利用Hilbert变换完成对原始非平稳信号进行特征参数...
  • 加速度传感器的原理

    2021-01-19 16:18:09
    加速度传感器甚至可以用来分析发动机的振动。  通过测量由于重力引起的加速度,你可以计算出设备相对于水平面的倾斜角度。通过分析动态加速度,你可以分析出设备移动的方式。但是刚开始的时候,你会发现光测量倾角...
  • 现在,加速度传感器广泛应用于游戏控制、手柄振动和摇晃、汽车制动启动检测、地震检测、工程测振、地质勘探、振动测试与分析以及安全保卫振动侦察等多种领域。下面就举例几个例子,让大家更好的认识加速度传感器。 ...
  • 现在,加速度传感器广泛应用于游戏控制、手柄振动和摇晃、汽车制动启动检测、地震检测、工程测振、地质勘探、振动测试与分析以及安全保卫振动侦察等多种领域。下面就举例几个例子,让大家更好的认识加速度传感器。 ...
  • 探讨了在汽车防盗系统中,将美国AD公司生产的加速度传感器ADXL202同时作为振动传感器和倾角传感器的两种不同的敏感器件设计方案,并对采用该传感器的信息处理方法进行了探讨。  关键词:汽车防盗加速度传感器振动...
  • 现在,加速度传感器广泛应用于游戏控制、手柄振动和摇晃、汽车制动启动检测、地震检测、工程测振、地质勘探、振动测试与分析以及安全保卫振动侦察等多种领域。下面就举例几个例子,让大家更好的认识加速度传感器
  • 三轴加速度传感器

    2018-11-27 14:08:07
    巷道结构振动监测系统采用三轴加速度传感器对巷道各点的振动进行监测,能够准确测量各点的三轴方向上的振动波形,通过对波形进行频域的转化,可以得到不同阶的振动频率,特别是1阶频率的测量,可以有效判断巷道的...
  • MMA8451是一款低电压供电,电容式微机械全数字式的传感器,可测量三轴方向的加速度。基于这款高性能的传感器,设计出主从式振动检测仪器。文中介绍了整个电路的设计思路与组成结构,给出了作为前端传感器在虚拟仪器...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 464
精华内容 185
关键字:

振动加速度传感器