|
在本篇文章中,我们将学习MEMS加速度计、陀螺仪和磁力计的工作原理以及如何将它们与Arduino开发部一起使用。通过使用Processing IDE,我们将使用传感器进行一些实际应用。
MEMS概述 MEMS是非常小的系统或器件,由尺寸范围为0.001mm至0.1mm的微小元件组成。这些组件由硅、聚合物、金属和/或陶瓷制成,并且它们通常与CPU(微控制器)组合以完成系统。现在我们将简要解释每个微电子机械系统(MEMS)传感器的工作原理。
MEMS加速度计 它通过测量电容的变化来测量加速度。它的微观结构看起来像下图所示。它具有附着在弹簧上的质量块,弹簧被限制为沿一个方向移动并固定在外板。因此,当施加特定方向上的加速度时,质量块将移动,然后外板和质量块之间的电容将改变。这种电容变化将被测量,处理,并且它将对应于特定的加速度值。
MEMS陀螺仪 陀螺仪使用科里奥利效应Coriolis Effect测量角速率。当质量以特定的速度在特定方向上移动时,并且施加外部角速率时,如绿色箭头所示,将产生力,如蓝色红色箭头所示,这将导致质量的垂直位移。与加速度计类似,这种位移将引起电容的变化,该电容将被测量和处理,这些变化对应于特定的角速率。
陀螺仪的微观结构类似于下图。质量块不断移动或振荡,当外部角速率施加时,质量的柔性部分将移动并产生垂直位移。
MEMS磁力计 它通过使用霍尔效应或磁阻效应来测量地球磁场。实际上,市场上几乎90%的传感器都使用霍尔效应,以下是它的工作原理。
如果我们有一个像照片中所示的导电板,我们设置电流流过它,电子将直接从板的一侧流到另一侧。现在,如果我们在板附近带来一些磁场,我们就会扰乱直流,电子会偏转到板的一侧,而正极则偏向板的另一侧。这意味着如果我们现在在这两侧之间放置一个电表,我们将获得一些电压,该电压取决于磁场强度及其方向。
市场上另外10%的传感器使用磁阻效应。这些传感器使用对磁场敏感的材料,通常由铁(Fe)和镍(Ne)组成。因此,当这些材料暴露在磁场中时,它们会改变它们的电阻。
Arduino示例 好了,现在让我们将这些传感器连接到Arduino开发板并使用它们。作为一个例子,我将使用GY-80扩展板,该电路板带有以下传感器:3轴加速度计ADXL345 、3轴陀螺仪L3G4200D、3轴磁力计MC5883L以及气压计和温度计。 本示例所需的组件如下所示: ● 3轴加速器ADXL345 ● 2合1:MPU6050 6轴陀螺仪和加速度计. ● 3合1:GY-80 9轴磁场加速陀螺仪 ● 3合1:GY-86 10DOF MS5611 HMC5883L MPU6050模块.
该扩展板使用I2C通信协议,这意味着我们可以使用只有两根线的所有传感器。因此,为了在Arduino和传感器之间进行通信,我们需要知道它们唯一的设备地址和它们的内部寄存器地址,以便从中获取数据。这些地址可以从传感器的数据手册中找到: ● ADXL345加速度计数据手册 ● L3G4200D陀螺仪数据手册 ● MC5883L磁力计数据手册
源代码 现在让我们看一下从传感器获取数据的代码。我们将从加速度计开始,每个代码前都会有一些解释,以及代码注释中的一些其他描述。
Arduino加速度计代码 首先,我们需要包含Arduino Wire Library并定义传感器的寄存器地址。在setu函数部分,我们需要初始化Wire Library并启动串行通信,因为我们将使用串行监视器来显示结果。此外,我们需要激活传感器,或者通过向Power_CTL寄存器发送适当的字节来启用测量,以下是具体过程。使用Wire.beginTransmission()函数,我们选择将要讨论的传感器,本例中是3轴加速度计。然后使用Wire.write()函数告诉我们将与哪个内部寄存器通信。在此之后,我们将发送适当的字节以启用测量。使用Wire.endTransmission()函数,我们将结束传输,并将数据传输到寄存器。
在loop函数中,我们需要读取每个轴的数据。我们将从X轴开始。首先,我们将选择我们将要通信的寄存器,也就是两个X轴内部寄存器。然后使用Wire.requestFrom()函数,我们将从两个寄存器请求传输的数据或两个字节。 Wire.available()函数将返回可用于检索的字节数,如果该数字与我们请求的字节匹配,本例中是2个字节,使用Wire.read()函数,我们将从两个X轴寄存器中读取字节。
寄存器的输出数据是二进制补码,X0作为最低有效字节,X1作为最高有效字节,因此我们需要将这些字节转换为从-1到+1的浮点值,具体取决于X轴的相对方向地球加速度或重力。我们将为另外两个轴重复此过程,最后我们将在串行监视器上打印这些值。 - #include <Wire.h>
- //--- Accelerometer Register Addresses
- #define Power_Register 0x2D
- #define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
- #define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
- #define Y_Axis_Register_DATAY0 0x34
- #define Y_Axis_Register_DATAY1 0x35
- #define Z_Axis_Register_DATAZ0 0x36
- #define Z_Axis_Register_DATAZ1 0x37
- int ADXAddress = 0x53; //Device address in which is also included the 8th bit for selecting the mode, read in this case.
- int X0,X1,X_out;
- int Y0,Y1,Y_out;
- int Z1,Z0,Z_out;
- float Xa,Ya,Za;
- void setup() {
- Wire.begin(); // Initiate the Wire library
- Serial.begin(9600);
- delay(100);
-
- Wire.beginTransmission(ADXAddress);
- Wire.write(Power_Register); // Power_CTL Register
- // Enable measurement
- Wire.write(8); // Bit D3 High for measuring enable (0000 1000)
- Wire.endTransmission();
- }
- void loop() {
- // X-axis
- Wire.beginTransmission(ADXAddress); // Begin transmission to the Sensor
- //Ask the particular registers for data
- Wire.write(X_Axis_Register_DATAX0);
- Wire.write(X_Axis_Register_DATAX1);
- Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
- Wire.requestFrom(ADXAddress,2); // Request the transmitted two bytes from the two registers
- if(Wire.available()<=2) { //
- X0 = Wire.read(); // Reads the data from the register
- X1 = Wire.read();
- /* Converting the raw data of the X-Axis into X-Axis Acceleration
- - The output data is Two's complement
- - X0 as the least significant byte
- - X1 as the most significant byte */
- X1=X1<<8;
- X_out =X0+X1;
- Xa=X_out/256.0; // Xa = output value from -1 to +1, Gravity acceleration acting on the X-Axis
- }
- // Y-Axis
- Wire.beginTransmission(ADXAddress);
- Wire.write(Y_Axis_Register_DATAY0);
- Wire.write(Y_Axis_Register_DATAY1);
- Wire.endTransmission();
- Wire.requestFrom(ADXAddress,2);
- if(Wire.available()<=2) {
- Y0 = Wire.read();
- Y1 = Wire.read();
- Y1=Y1<<8;
- Y_out =Y0+Y1;
- Ya=Y_out/256.0;
- }
- // Z-Axis
- Wire.beginTransmission(ADXAddress);
- Wire.write(Z_Axis_Register_DATAZ0);
- Wire.write(Z_Axis_Register_DATAZ1);
- Wire.endTransmission();
- Wire.requestFrom(ADXAddress,2);
- if(Wire.available()<=2) {
- Z0 = Wire.read();
- Z1 = Wire.read();
- Z1=Z1<<8;
- Z_out =Z0+Z1;
- Za=Z_out/256.0;
- }
- // Prints the data on the Serial Monitor
- Serial.print("Xa= ");
- Serial.print(Xa);
- Serial.print(" Ya= ");
- Serial.print(Ya);
- Serial.print(" Za= ");
- Serial.println(Za);
- }
复制代码 |