Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

В этом уроке мы узнаем, как работают MEMS-акселерометр, гироскоп и магнетометр, и как использовать их с платой Arduino. Также с помощью среды Processing IDE мы создадим несколько практических приложений с использованием этих датчиков. Вы можете посмотреть следующее видео или прочитать письменный урок ниже.

Что такое MEMS?

MEMS — это очень маленькие системы или устройства, состоящие из микрокомпонентов размером от 0.001 мм до 0.1 мм. Эти компоненты изготавливаются из кремния, полимеров, металлов и/или керамики, и они обычно комбинируются с ЦПУ (микроконтроллером) для завершения системы.

Теперь мы кратко объясним, как работает каждый из этих микроэлектромеханических систем (MEMS) датчиков.

MEMS-акселерометр

Он измеряет ускорение, измеряя изменение емкости. Его микроструктура выглядит примерно так. У нее есть масса, прикрепленная к пружине, которая ограничена движением в одном направлении, и фиксированные внешние пластины. Когда в определенном направлении применяется ускорение, масса движется, и емкость между пластинами и массой меняется. Это изменение емкости измеряется, обрабатывается и соответствует определенному значению ускорения.

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

MEMS-гироскоп

Гироскоп измеряет угловую скорость, используя эффект Кориолиса. Когда масса движется в определенном направлении с определенной скоростью, и когда применяется внешняя угловая скорость (как показано зеленой стрелкой), возникает сила (как показано красно-синей стрелкой), которая вызывает перпендикулярное смещение массы. Как и в акселерометре, это смещение вызывает изменение емкости, которое измеряется, обрабатывается и соответствует определенной угловой скорости.

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

Микроструктура гироскопа выглядит примерно так. Масса, которая постоянно движется или колеблется, и когда применяется внешняя угловая скорость, гибкая часть массы движется и создает перпендикулярное смещение.

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

MEMS-магнетометр

Он измеряет магнитное поле Земли, используя эффект Холла или магниторезистивный эффект. На самом деле почти 90% датчиков на рынке используют эффект Холла, и вот как это работает.

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

Если у нас есть проводящая пластина, как показано на фото, и мы пропускаем через нее ток, электроны будут течь прямо от одной стороны пластины к другой. Теперь, если мы приблизим какое-то магнитное поле к пластине, мы нарушим прямое течение, и электроны отклонятся к одной стороне пластины, а положительные полюса — к другой. Это означает, что если мы сейчас подключим вольтметр между этими двумя сторонами, мы получим некоторое напряжение, которое зависит от силы магнитного поля и его направления.

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

Другие 10% датчиков на рынке используют магниторезистивный эффект. Эти датчики используют материалы, чувствительные к магнитному полю, обычно состоящие из железа (Fe) и никеля (Ni). Поэтому, когда эти материалы подвергаются воздействию магнитного поля, они меняют свое сопротивление.

Arduino и MEMS-датчики


Хорошо, теперь подключим эти датчики к плате Arduino и сделаем из них пользу. В качестве примера я буду использовать плату расширения GY-80, которая имеет следующие датчики: ADXL345 3-осевой акселерометр, L3G4200D 3-осевой гироскоп, MC5883L 3-осевой магнетометр, а также барометр и термометр, которые мы не будем использовать в этом уроке.

Вы можете приобрести эти компоненты на любом из сайтов ниже:

  • ADXL345 3-осевой акселерометр………………………………………………………
  • 2 в 1: MPU6050 6-осевой гироскоп и акселерометр …………………
  • 3 в 1: GY-80 9-осевой магнитное поле, ускорение, гироскоп……… Amazon
  • 3 в 1: GY-86 10DOF MS5611 HMC5883L MPU6050 Модуль……… Banggood / AliExpress
Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

Эта плата использует протокол связи I2C, что означает, что мы можем использовать все датчики всего с двумя проводами. Чтобы обеспечить связь между Arduino и датчиками, нам нужно знать их уникальные адреса устройств и адреса их внутренних регистров для получения данных из них. Эти адреса можно найти в даташитах датчиков:

  • Даташит акселерометра ADXL345
  • Даташит гироскопа L3G4200D
  • Даташит магнетометра MC5883L

Для получения более подробной информации о том, как работает связь I2C, вы можете проверить мой другой урок про протокол связи I2C.

Исходный код

Теперь посмотрим коды для получения данных с датчиков. Мы начнем с акселерометра, и перед каждым кодом будет некоторое объяснение, а также дополнительное описание в комментариях кода.

Код Arduino для акселерометра

Сначала нам нужно подключить библиотеку Arduino Wire и определить адреса регистров датчика. В разделе setup нам нужно инициализировать библиотеку Wire и запустить последовательную коммуникацию, так как мы будем использовать монитор последовательного порта для отображения результатов. Также здесь нам нужно активировать датчик или включить измерение, отправив соответствующий байт в регистр Power_CTL, и вот как это сделать. Используя функцию Wire.beginTransmission(), мы выбираем, с каким датчиком мы будем общаться — в данном случае 3-осевым акселерометром. Затем, используя функцию Wire.write(), мы указываем, с каким внутренним регистром мы будем общаться. После этого мы отправим соответствующий байт для включения измерения. Используя функцию Wire.endTransmission(), мы завершим передачу, и это передаст данные в регистры.

В разделе loop нам нужно прочитать данные для каждой оси. Мы начнем с оси X. Сначала мы выберем, с какими регистрами мы будем общаться — с двумя внутренними регистрами оси X в данном случае. Затем, используя функцию Wire.requestFrom(), мы запросим переданные данные или два байта из двух регистров. Функция Wire.available() вернет количество байтов, доступных для чтения, и если это число совпадает с нашими запрошенными байтами, в нашем случае 2 байта, используя функцию Wire.read() мы прочитаем байты из двух регистров оси X.

Выходные данные из регистров представлены в дополнительном коде, где X0 — младший значащий байт, а X1 — старший значащий байт, поэтому нам нужно преобразовать эти байты в значения float от -1 до +1 в зависимости от направления оси X относительно ускорения Земли или гравитации. Мы повторим эту процедуру для двух других осей, и в конце выведем эти значения на монитор последовательного порта.

#include <Wire.h>
//--- Адреса регистров акселерометра
#define Power_Register 0x2D
#define X_Axis_Register_DATAX0 0x32 // Шестнадцатеричный адрес внутреннего регистра DATAX0.
#define X_Axis_Register_DATAX1 0x33 // Шестнадцатеричный адрес внутреннего регистра DATAX1.
#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; // Адрес устройства, в который также включен 8-й бит для выбора режима, в данном случае чтение.
int X0,X1,X_out; int Y0,Y1,Y_out; int Z1,Z0,Z_out;
float Xa,Ya,Za;

void setup() {
  Wire.begin(); // Инициализация библиотеки Wire
  Serial.begin(9600); delay(100);
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register); // Регистр Power_CTL
  // Включение измерения
  Wire.write(8); // Бит D3 высокий для включения измерения (0000 1000)
  Wire.endTransmission();
}

void loop() {
  // Ось X
  Wire.beginTransmission(ADXAddress); // Начало передачи к датчику
  // Запрос данных из конкретных регистров
  Wire.write(X_Axis_Register_DATAX0); Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission(); // Завершает передачу и передает данные из двух регистров
  Wire.requestFrom(ADXAddress,2); // Запрашивает переданные два байта из двух регистров
  if(Wire.available()<=2) {
    // X0 = Wire.read(); // Читает данные из регистра
    X1 = Wire.read();
    /* Преобразование сырых данных оси X в ускорение оси X - Выходные данные в дополнительном коде
     * X0 как младший значащий байт
     * X1 как старший значащий байт
     */
    X1=X1<<8; X_out =X0+X1; Xa=X_out/256.0; // Xa = выходное значение от -1 до +1, гравитационное ускорение на оси X
  }
  // Ось Y
  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
  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;
  }
  // Вывод данных на монитор последовательного порта
  Serial.print("Xa= "); Serial.print(Xa);
  Serial.print(" Ya= "); Serial.print(Ya);
  Serial.print(" Za= "); Serial.println(Za);
}Язык кода: Arduino (arduino)

Код Arduino для гироскопа

Для получения данных с гироскопа у нас будет похожий код, как и предыдущий. Сначала мы должны определить адреса регистров и некоторые переменные для данных. В разделе setup мы должны разбудить датчик и перевести его в нормальный режим, используя CTRL_REG1, а также выбрать чувствительность датчика. Для этого примера я выберу режим чувствительности 2000 dps.

В разделе loop, аналогично акселерометру, мы прочитаем данные для осей X, Y и Z. Затем сырые данные должны быть преобразованы в угловые значения. Из даташита датчика мы видим, что для режима чувствительности 2000 dps соответствует 70 mdps/цифра. Это означает, что нам нужно умножить сырые выходные данные на 0.07, чтобы получить угловую скорость в градусах в секунду. Затем, если умножить угловую скорость на время, мы получим значение угла. Поэтому нам нужно вычислить временной интервал каждого раздела loop, и мы можем сделать это, используя функцию millis() в начале и в конце раздела loop, и сохраним его значение в эту переменную "dt". Так для каждого выполненного цикла мы вычислим угол и добавим его к конечному значению угла. Мы сделаем то же самое для двух других осей, и в конце выведем результаты в монитор последовательного порта.

#include <Wire.h>
//--- Адреса регистров гироскопа
#define Gyro_gX0 0x28 #define Gyro_gX1 0x29
#define Gyro_gY0 0x2A #define Gyro_gY1 0x2B
#define Gyro_gZ0 0x2C #define Gyro_gZ1 0x2D
int Gyro = 0x69; // Адрес устройства с 8-м битом для выбора режима (чтение)
int gX0, gX1, gX_out; int gY0, gY1, gY_out; int gZ0, gZ1, gZ_out;
float Xg,Yg,Zg; float angleX,angleY,angleZ,angleXc,angleYc,angleZc;
unsigned long start, finished, elapsed; float dt=0.015;

void setup() {
  Wire.begin(); Serial.begin(9600); delay(100);
  Wire.beginTransmission(Gyro); Wire.write(0x20); // CTRL_REG1 - Режим питания
  Wire.write(15); // Нормальный режим: 15d - 00001111b
  Wire.endTransmission();
  Wire.beginTransmission(Gyro); Wire.write(0x23); // CTRL_REG4 - Чувствительность, выбор шкалы
  Wire.write(48); // 2000dps: 48d - 00110000b
  Wire.endTransmission();
}

void loop() {
  start=millis();
  //---- Ось X
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gX0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gX0 = Wire.read(); }
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gX1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gX1 = Wire.read(); }
  //---- Ось Y
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gY0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gY0 = Wire.read(); }
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gY1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gY1 = Wire.read(); }
  //---- Ось Z
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gZ0); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gZ0 = Wire.read(); }
  Wire.beginTransmission(Gyro); Wire.write(Gyro_gZ1); Wire.endTransmission();
  Wire.requestFrom(Gyro,1); if(Wire.available()<=1) { gZ1 = Wire.read(); }
  //---------- Ось X
  gX1=gX1<<8; gX_out =gX0+gX1; // Сырые данные
  Xg=gX_out*0.07; // Угловая скорость (из даташита: 70 mdps/цифра)
  angleXc = Xg*dt; angleX = angleX + angleXc; // Угол
  //---------- Ось Y
  gY1=gY1<<8; gY_out =gY0+gY1; Yg=gY_out*0.07;
  angleYc = Yg*dt; angleY = angleY + angleYc;
  //---------- Ось Z
  gZ1=gZ1<<8; gZ_out =gZ0+gZ1; Zg=gZ_out*0.07;
  angleZc = Zg*dt; angleZ = angleZ + angleZc;
  // Вывод данных на монитор последовательного порта
  Serial.print("angleX= "); Serial.print(angleX);
  Serial.print(" angleY= "); Serial.print(angleY);
  Serial.print(" angleZ= "); Serial.println(angleZ);
  delay(10);
  // Вычисление dt
  finished=millis(); elapsed=finished-start; dt=elapsed/1000.0; start = elapsed = 0;
}Язык кода: Arduino (arduino)

Код Arduino для магнетометра

Снова мы будем использовать технику, похожую на предыдущую. Сначала нам нужно определить адреса регистров, и в разделе setup перевести датчик в режим непрерывного измерения. В разделе loop мы получим сырые данные для каждой оси тем же методом, что и для предыдущих датчиков.

Затем нам нужно преобразовать сырые данные в значение магнитного поля или в единицы Гаусса. Из даташита датчика мы видим, что режим чувствительности по умолчанию составляет 0.92 мГс/цифра. Это означает, что нам нужно умножить сырые данные на 0.00092, чтобы получить магнитное поле Земли в Гауссах. В конце мы выведем значения на монитор последовательного порта.

#include <Wire.h> // Библиотека I2C Arduino
#define Magnetometer_mX0 0x03 #define Magnetometer_mX1 0x04
#define Magnetometer_mZ0 0x05 #define Magnetometer_mZ1 0x06
#define Magnetometer_mY0 0x07 #define Magnetometer_mY1 0x08
int mX0, mX1, mX_out; int mY0, mY1, mY_out; int mZ0, mZ1, mZ_out;
float Xm,Ym,Zm;
#define Magnetometer 0x1E // I2C 7-битный адрес HMC5883

void setup(){
  // Инициализация последовательной и I2C связи
  Serial.begin(9600); Wire.begin(); delay(100);
  Wire.beginTransmission(Magnetometer); Wire.write(0x02); // Выбор регистра режима
  Wire.write(0x00); // Режим непрерывного измерения
  Wire.endTransmission();
}

void loop(){
  //---- Ось X
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mX0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mX0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mX1 = Wire.read(); }
  //---- Ось Y
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mY0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mY0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mY1 = Wire.read(); }
  //---- Ось Z
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ1); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mZ0 = Wire.read(); }
  Wire.beginTransmission(Magnetometer); Wire.write(Magnetometer_mZ0); Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); if(Wire.available()<=1) { mZ1 = Wire.read(); }
  //---- Ось X
  mX1=mX1<<8; mX_out =mX0+mX1; // Сырые данные
  Xm = mX_out*0.00092; // Единицы Гаусса
  //* Магнитное поле Земли варьируется от 0.25 до 0.65 Гаусса, так что эти значения нам нужно получить примерно.
  //---- Ось Y
  mY1=mY1<<8; mY_out =mY0+mY1; Ym = mY_out*0.00092;
  //---- Ось Z
  mZ1=mZ1<<8; mZ_out =mZ0+mZ1; Zm = mZ_out*0.00092;
  // Вывод значений каждой оси
  Serial.print("x: "); Serial.print(Xm);
  Serial.print(" y: "); Serial.print(Ym);
  Serial.print(" z: "); Serial.println(Zm);
  delay(50);
}Язык кода: Arduino (arduino)

Вот крутое приложение датчика — MEMS цифровой компас, сделанный с использованием Processing IDE. Вы можете найти больше деталей и исходный код этого примера по следующей ссылке:

Исследование MEMS-датчиков: Акселерометры, гироскопы и магнетометры для проектов на Arduino

Производственный процесс

  1. Что такое магнитометр? Основы, принципы и реальные применения
  2. Использование данных в Интернете надежности: стратегии эффективного управления
  3. Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
  4. Интерактивный гироскопический LED-дисплей на NeoPixel Ring и Arduino
  5. Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
  6. Устройство для общения глухосліпых людей с помощью 1Sheeld и Arduino
  7. Умная копилка: управление монетоприёмником на Arduino Nano
  8. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  9. Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
  10. Интерактивный HMI-проект на Nextion с Arduino Mega и датчиками