How to track orientation with arduino and adxl345 accelerometer

Blog

Делай сам

Очень важный момент: все выпущенные в рамках проекта ScratchDuino продукты являются открытым железом (open hardware). Необходимая для их изготовления информация есть на сайте Edumandriva. Пользователям доступны не только списки необходимых элементов, принципиальные схемы и схемы разводки плат, но и раскрой лазерной резки для изготовления корпусов и тому подобная информация. «Мы надеемся, что люди будут делать эти устройства сами и как-то их улучшать, — говорит Фролов. — Сейчас и в нашей стране, и по всему миру MIT продвигает концепцию Fab Lab. Продукты ScratchDuino спроектированы таким образом, чтобы их почти полностью можно было произвести в подобной лаборатории».

Элементы робоплатформы можно печатать на 3D-принтерах

Есть и другие проекты, создающие открытые робоплатформы, но в российских продуктах упор сделан на простоту изготовления и модификации устройств — ScratchDuino можно назвать продолжателем идей Arduino. Хотя отечественный робоконструктор уступает по возможностям LEGO Mindstorms NXT, он более открытый и модульный — совершенствовать ScratchDuino можно как угодно. Никто не мешает, скажем, подключить к шилду более мощный вычислитель или создать собственного исполнителя.

«Мы ожидаем, что к проекту подключатся технические вузы и помогут сделать шагающую платформу, летающую платформу, плавающую платформу со множеством открытых датчиков, приводов и манипуляторов», — говорит руководитель «Мезон.Ру».

Обзор аппаратного обеспечения акселерометра ADXL335

Основой модуля является небольшой трехосный MEMS акселерометр с низким энергопотреблением и с чрезвычайно низким уровнем шума от Analog Devices – ADXL335. Датчик имеет полный диапазон чувствительности ±3g. Он может измерять статическое ускорение, вызванное силой тяжести в приложениях, чувствительных к наклону, а также динамическое ускорение, вызванное движением, ударом или вибрацией.

Рисунок 5 – Обзор аппаратного обеспечения модуля акселерометра ADXL335

Датчик работает при питании от 1,8 до 3,6 В (оптимально 3,3 В) и обычно потребляет ток всего 350 мкА. Однако встроенный стабилизатор 3,3 В делает его идеальным выбором для взаимодействия с микроконтроллерами 5 В, такими как Arduino.

Эта дружественная макетная плата разводит каждый вывод ADXL335 на 6-выводный разъем с шагом 0,1 дюйма. Сюда входят 3 аналоговых выхода для измерений по осям X, Y и Z, 2 вывода питания и вывод самотестирования, который позволяет проверить работу датчика в конечном приложении.

Аналоговые выходы являются относительными, что означает, что выходной сигнал 0g номинально равен половине напряжения питания 3,3 В (1,65 В), -3g соответствует выходному напряжению 0 В, и 3g соответствует 3,3 В с полным масштабированием между ними.

Ниже приведена таблица с основными характеристиками микросхемы акселерометра ADXL335.

Характеристики микросхемы акселерометра ADXL335.
Рабочее напряжение 1,8 В — 3,6 В
Рабочий ток 350 мкА (типовой)
Диапазон чувствительности ±3g (полная шкала)
Диапазон температур от -40° до + 85° C
Чувствительные оси 3 оси
Чувствительность от 270 до 330 мВ/g (относительно)
Ударопрочность до 10000g
Размер 4мм х 4мм х 1,45 мм

Расчет угла с помощью гироскопа mpu6050

Данные с гироскопа имеют вид:

В дальнейшем в статье мы будем рассматривать все на примере оси x. Для расчета угла необходимо проинтегрировать переменную “gyro_x_scalled”

является количеством итераций

Так же стоит отметить, что на каждом временном промежутке цикла значение “gyro_x_scalled” остается одинаковым. Существует насколько подходов и методов интегрирования для компенсации и этой погрешности, но мы их детально не будем рассматривать.

Для реализации дискретного интегрирования, будем использовать метод Эйлера как один из самых популярных алгоритмов. Математически интегрирование методом Эйлера можно записать следующим образом:

Мы предполагаем, что начальные углы относительно осей x, y, z после калибровки равны 0, 0 и 90 градусов соответственно, так что для итерации n=0:

Значение T (время каждой итерации) и динамика самого гироскопа (как быстро и насколько нелинейно изменяются углы), значительным образом влияет на точность расчетов. Чем медленнее изменяются углы и чем меньше промежуток между итерациями, тем более точным будет результат. В этом смысле жаль, что платы Arduino достаточно медленные, кристаллы у них работают с частотой 16 МГц и снятие измерений каждые 10-20 мс становится достаточно затруднительным (учитывая тот факт, что процессор занят не только расчетом угла, но и другими параллельными задачами). Мы можем использовать T в виде переменной или константы, я, лично, предпочитаю использовать константу для каждого цикла. В проекте динамические факторы не учитывались, просто использовалась частота итераций с разрывом в 20 мс (0.02 с).

Arduino Program:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void displaySensorDetails(void)
{
sensor_t sensor;
accel.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" m/s^2"); 
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}

void displayDataRate(void)
{
Serial.print ("Data Rate: ");

switch(accel.getDataRate())
{
case ADXL345_DATARATE_3200_HZ:
Serial.print ("3200 "); 
break;
case ADXL345_DATARATE_1600_HZ:
Serial.print ("1600 "); 
break;
case ADXL345_DATARATE_800_HZ:
Serial.print ("800 "); 
break;
case ADXL345_DATARATE_400_HZ:
Serial.print ("400 "); 
break;
case ADXL345_DATARATE_200_HZ:
Serial.print ("200 "); 
break;
case ADXL345_DATARATE_100_HZ:
Serial.print ("100 "); 
break;
case ADXL345_DATARATE_50_HZ:
Serial.print ("50 "); 
break;
case ADXL345_DATARATE_25_HZ:
Serial.print ("25 "); 
break;
case ADXL345_DATARATE_12_5_HZ:
Serial.print ("12.5 "); 
break;
case ADXL345_DATARATE_6_25HZ:
Serial.print ("6.25 "); 
break;
case ADXL345_DATARATE_3_13_HZ:
Serial.print ("3.13 "); 
break;
case ADXL345_DATARATE_1_56_HZ:
Serial.print ("1.56 "); 
break;
case ADXL345_DATARATE_0_78_HZ:
Serial.print ("0.78 "); 
break;
case ADXL345_DATARATE_0_39_HZ:
Serial.print ("0.39 "); 
break;
case ADXL345_DATARATE_0_20_HZ:
Serial.print ("0.20 "); 
break;
case ADXL345_DATARATE_0_10_HZ:
Serial.print ("0.10 "); 
break;
default:
Serial.print ("???? "); 
break;
} 
Serial.println(" Hz"); 
}

void displayRange(void)
{
Serial.print ("Range: +/- ");

switch(accel.getRange())
{
case ADXL345_RANGE_16_G:
Serial.print ("16 "); 
break;
case ADXL345_RANGE_8_G:
Serial.print ("8 "); 
break;
case ADXL345_RANGE_4_G:
Serial.print ("4 "); 
break;
case ADXL345_RANGE_2_G:
Serial.print ("2 "); 
break;
default:
Serial.print ("?? "); 
break;
} 
Serial.println(" g"); 
}

void setup(void) 
{
Serial.begin(9600);
Serial.println("Accelerometer Test"); Serial.println("");

/* Initialise the sensor */
if(!accel.begin())
{
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
while(1);
}

/* Set the range to whatever is appropriate for your project */
accel.setRange(ADXL345_RANGE_16_G);
// displaySetRange(ADXL345_RANGE_8_G);
// displaySetRange(ADXL345_RANGE_4_G);
// displaySetRange(ADXL345_RANGE_2_G);

/* Display some basic information on this sensor */
displaySensorDetails();

/* Display additional settings (outside the scope of sensor_t) */
displayDataRate();
displayRange();
Serial.println("");
}

void loop(void) 
{
/* Get a new sensor event */ 
sensors_event_t event; 
accel.getEvent(&event);

/* Display the results (acceleration is measured in m/s^2) */
Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" ");
Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" ");
Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(" ");Serial.println("m/s^2 ");
delay(500);
}

Related Links:

  • Character LCD with large/ big fonts using Arduino
  • Downloading a webpage from internet using Arduino
  • Group Messaging made easier using Smart Reminder and Notifier (SRN) – Android App
  • Reset Arduino using Programming
  • Interfacing Water Flow Sensor with Arduino
  • Interfacing GPS Shield for Arduino(ublox NEO-6M-0-001) with Arduino Mega 2560
  • Fetching Google Search using MATLAB
  • Interfacing SD Card with Arduino using SD Card Module

2Работа с цифровым акселерометром ADXL345 по интерфейсу SPI

Акселерометр ADXL345 поддерживает 3- и 4-проводные варианты интерфейса SPI. Мы рассмотрим только 4-проводное подключение. Кроме того, акселерометр работает в режиме 3 интерфейса SPI (помните, мы уже обсуждали: CPOL=1, CPHA=1). Диаграмма, показывающая обмен с акселерометром ADXL345 по 4-проводному интерфейсу SPI:

Работа с ADXL345 по SPI

Здесь бит MB – это признак того, что мы собираемся читать много байтов за раз (если бит установлен в 1). Для тестирования работы с SPI устройствами и быстрого освоения порядка обмена с ними я обычно использую отладочную плату с микросхемой FT2232H. Эта микросхема поддерживает множество режимов, в том числе I2C и SPI. Управление работой микросхемы FT2232H – с помощью программы SPI via FTDI, о которой я уже неоднократно рассказывал.

Подключим акселерометр к отладочной плате и прочитаем регистр DEVID, в котором хранится постоянное значение-идентификатор акселерометра ADXL345. Значение идентификатора должно быть 0xE5.

ADXL345 соединён с отладочной платой на FT2232H

Не забудем перед чтением записать команду 0x80, которая укажет акселерометру, что мы собираемся читать, начиная с регистра по адресу 0x0 (см. диаграмму выше, рисунок 38 – SPI 4-Wire Read):

Чтение регистра ID акселерометра ADXL345 по SPI

Видно, что в регистре содержится число 0xE5, которое и является значением идентификатора акселерометра ADXL345, согласно техническому описанию (datasheet). Вот как это выглядит на временной диаграмме:

Временная диаграмма чтения регистра ID акселерометра ADXL345 по SPI

Устройство отвечает, всё нормально. Теперь нам нужно перевести акселерометр в режим измерений. Для этого необходимо записать в регистр POWER_CTL (адрес регистра 0x2D) число 0x08 (установить бит Measure в HIGH). После этого можно начинать читать регистры с 0x32 по 0x37, в которых хранятся данные об ускорениях по трём осям. Сделаем это с помощью Arduino. Напишем такой скетч:

Скетч для чтения данных ADXL345 по SPI (разворачивается)

#include <SPI.h>

const byte READ = 0x80; // бит маркер чтения
const byte MB = 0x40; // бит MB (многобайтовая передача)
const int CS = 10; // пин выбора ведомого

void setup() {
  Serial.begin(115200);
  SPI.begin(); 
  SPI.setClockDivider(SPI_CLOCK_DIV32); // делитель частоты 500 кГц
  SPI.setDataMode(SPI_MODE3); // задаём 3-ий режим SPI
    
  byte id;
  readRegister(0x00, 1, id); // читаем регистр DEVID
  Serial.print("ID = ");
  Serial.println(id, HEX);
  
  writeRegister(0x2D, 0x08); // переводим ADXL345 в режим измерения
}

void loop() {
  byte buff;
  readRegister(0x32, 6, buff); // читаем значения по осям X, Y, Z
  
  int x = ((int)buff }

// записывает значение в регистр
void writeRegister(byte reg, byte value) {
  digitalWrite(CS, LOW);
  SPI.transfer(reg); 
  SPI.transfer(value); 
  digitalWrite(CS, HIGH);
}

// читает из регистра заданное число байтов
void readRegister(byte reg, int bytesToRead, byte *outBuff) {
  digitalWrite(CS, LOW);
  reg = reg | READ; // покажем акселерометру, что хотим из него читать
  if (bytesToRead > 1) {
     reg = reg | MB; // и читать хотим много байтов
  }
  SPI.transfer(reg); // записываем адрес регистра, с которого начинаем чтение
  for (int i=0; i}

Вот так выглядит временная диаграмма работы этого скетча:

Временная диаграмма чтения значений по осям X, Y, Z акселерометра ADXL345

Ясно, почему первый байт передачи от Arduino при чтении значений ускорений по осям – число 0xF2? Это адрес первого регистра, с которого начинаем чтение (0x32), объединённый по ИЛИ с 0x80 – маркером чтения READ – и с 0x40 – маркером многобайтовой передачи MB: 0x32 OR 0x80 OR 0x40 = 0011_0010 OR 1000_0000 OR 0100_0000 = 1110_1101 = 0xF2

Что означают считанные значения? Этот вопрос рассматривается в последнем разделе статьи. Кроме того, существует ряд библиотек для Arduino, которые упрощают настройку и чтение данных с акселерометра, позволяя не думать о таких низкоуровневых вещах как регистры, биты и байты. Ссылки на библиотеки также приведены в конце статьи.

Окончательный расчет угла наклона и подбор коэффициентов усиления для фильтра

Результаты снимались для различных параметров коэффициентов усиления фильтра и приведены на рисунках по порядку. Коэффициент усиления 1 означает, что фактически идут измерения только с гироскопа. Можно заметить, что в конце angle_x и angle_y отклоняются от значений, рассчитанных с помощью значений с акселерометра.

В моем случае, для дальнейшего проекта использовался коэффициент усиления 0.95. В зависимости от динамики системы, можно его повышать, но не до 1, так как значения будут сильно отклоняться от истинных.

Позволяет определять ускорение действующее в направлении осей X, Y, Z и применяется для определения ориентации объекта в пространстве: углов крена и тангажа.

Код

Код для нашего устройства ниже. Помните, что красный светодиод должен загораться при расстоянии менее 4 см.

/* Arduino HC-SR04 ультразвуковой датчик расстояния VCC подключается к 5v, GND к GND Echo к 13 пину на Arduino, Trig к 12 пину на Arduino Позитивная нога красного светодиода к 11 пину на Arduino Позитивная нога зеленого светодиода к 10 пину на Arduino */ #define trigPin 13 #define echoPin 12 #define led 11 #define led2 10 void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(led, OUTPUT); pinMode(led2, OUTPUT); } void loop() { long duration, distance; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = (duration/2) / 29.1; if (distance < 4) { // На этом этапе происходит вкл/выкл светодиода digitalWrite(led,HIGH); // когда загорается красный, зеленый обязан выключится digitalWrite(led2,LOW); } else { digitalWrite(led,LOW); digitalWrite(led2,HIGH); } if (distance >= 200 || distance <= 0){ Serial.println(«Out of range»); // Вне диапазона } else { Serial.print(distance); Serial.println(» cm»); // тут тоже можно указать » см» } delay(500); }

Единственное, о чем стоит помнить, – далеко не все функции и библиотеки написаны профессионалами. Многие из них создаются такими новичками, как и вы, соответственно, старайтесь просматривать код, прежде чем заключать, что датчик не работает или выдаёт неправильные данные.

Но значительно лучше будет изучить основы программирования и С++, чтобы в дальнейшем самостоятельно писать многие вещи самому.

ADXL345 Accelerometer Calibration

Nevertheless, once we read the data, we can simply print it on the serial monitor to check whether the values are as expected. In my case, the values I was getting were not exactly as they should be, especially the Z-axis which had a noticeable error of 0.1g.

To solve this issue, we need to calibrate the accelerometer using the 3 offset calibration registers, and here’s how we can do that. So, we need to position the sensor flat, and print the RAW values without dividing them by 256.

From here now we can notice the how much the outputs are off, in my case, the Z output was around 283. That’s difference of 27 in positive. Now we need to divide this value by 4, and that will give use the number that we need to write to the Z-axis offset register. If we upload the code now, the Z-axis output will be exactly 256, or 1g as it should be.

If needed we should calibrate the other axis using the same method. And just a quick note that this calibration is not permanently written to the registers. We need to do write these values to the registers at each power up of the sensor.

Once we are done with the calibration, we can now finally calculate the Roll and Pitch, or the rotation around the X-axis and the rotation around the Y axis in degrees, using these two formulas.

For more details how these formulas work, you can check this Freescale Semiconductor application note.

Глобальные переменные

Данный заголовочный файл включает в себя следующие глобальные переменные:

int accel_x_OC — Содержит измерения положения акселерометра относительно оси x при калибровке

int accel_y_OC — Содержит измерения положения акселерометра относительно оси y при калибровке

int accel_z_OC — Содержит измерения положения акселерометра относительно оси z при калибровке

int gyro_x_OC — Содержит измерения положения гироскопа относительно оси x

int gyro_y_OC — Содержит измерения положения гироскопа относительно оси y

int gyro_z_OC — Содержит измерения положения гироскопа относительно оси z

float temp_scalled — Содержит абсолютное значение температуры в градусах цельсия

float accel_x_scalled — данные оси x акселерометра минус данные калибровки

float accel_y_scalled — данные оси y акселерометра минус данные калибровки

float accel_z_scalled — данные оси z акселерометра минус данные калибровки

float gyro_x_scalled — данные гироскопа относительно оси x минус данные калибровки

float gyro_y_scalled — данные гироскопа относительно оси y минус данные калибровки

float gyro_z_scalled — данные гироскопа относительно оси z минус данные калибровки

Подключение акселерометра к Arduino

Акселерометр – это устройство, которое измеряет ускорение, с которым двигается объект. Сейчас мы рассмотрим, как подключить акселерометр к Arduino и использовать его для измерения и анализа ускорения.

Для подключения акселерометра к Arduino понадобится несколько проводов и плата с акселерометром. На плате акселерометра будут выведены соединительные контакты, которые нужно будет подключить к Arduino.

Прежде всего, нужно подключить питание к акселерометру. Для этого используйте провод, подключив его к контакту VCC акселерометра и к контакту питания на Arduino. Убедитесь, что напряжение питания совпадает с требованиями акселерометра (обычно 3.3V или 5V).

Далее, подключите землю акселерометра к земле Arduino. В Arduino для этого есть отведенный контакт GND. Используйте провод для подключения контакта GND акселерометра ко второму контакту земли на Arduino.

Также, вам нужно подключить выходные контакты акселерометра к аналоговым или цифровым входам Arduino, чтобы получать данные с акселерометра. На плате акселерометра будут выведены соответствующие контакты для осей X, Y и Z. Подключите эти контакты к соответствующим контактам на Arduino.

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

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

Исходный код программы (скетча)

Arduino

/*
Arduino and ADXL345 Accelerometer Tutorial
by Dejan, https://howtomechatronics.com
*/

#include <Wire.h> // Wire library — used for I2C communication

int ADXL345 = 0x53; // The ADXL345 sensor I2C address

float X_out, Y_out, Z_out; // Outputs

void setup() {
Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
Wire.begin(); // Initiate the Wire library
// Set ADXL345 in measuring mode
Wire.beginTransmission(ADXL345); // Start communicating with the device
Wire.write(0x2D); // Access/ talk to POWER_CTL Register — 0x2D
// Enable measurement
Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
Wire.endTransmission();
delay(10);
}

void loop() {
// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;

Serial.print(«Xa= «);
Serial.print(X_out);
Serial.print(» Ya= «);
Serial.print(Y_out);
Serial.print(» Za= «);
Serial.println(Z_out);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

/*
    Arduino and ADXL345 Accelerometer Tutorial
     by Dejan, https://howtomechatronics.com
*/
 
#include <Wire.h>  // Wire library — used for I2C communication
 

intADXL345=0x53;// The ADXL345 sensor I2C address

floatX_out,Y_out,Z_out;// Outputs

voidsetup(){

Serial.begin(9600);// Initiate serial communication for printing the results on the Serial monitor

Wire.begin();// Initiate the Wire library

// Set ADXL345 in measuring mode

Wire.beginTransmission(ADXL345);// Start communicating with the device

Wire.write(0x2D);// Access/ talk to POWER_CTL Register — 0x2D

// Enable measurement

Wire.write(8);// (8dec -> 0000 1000 binary) Bit D3 High for measuring enable

Wire.endTransmission();

delay(10);

}
 

voidloop(){

// === Read acceleromter data === //

Wire.beginTransmission(ADXL345);

Wire.write(0x32);// Start with register 0x32 (ACCEL_XOUT_H)

Wire.endTransmission(false);

Wire.requestFrom(ADXL345,6,true);// Read 6 registers total, each axis value is stored in 2 registers

X_out=(Wire.read()|Wire.read()<<8);// X-axis value

X_out=X_out256;//For a range of +-2g, we need to divide the raw values by 256, according to the datasheet

Y_out=(Wire.read()|Wire.read()<<8);// Y-axis value

Y_out=Y_out256;

Z_out=(Wire.read()|Wire.read()<<8);// Z-axis value

Z_out=Z_out256;

Serial.print(«Xa= «);

Serial.print(X_out);

Serial.print(»   Ya= «);

Serial.print(Y_out);

Serial.print(»   Za= «);

Serial.println(Z_out);

}

ADXL345 Acceleromter Calibration

Nevertheless, once we read the data, we can simply print it on the serial monitor to check whether the values are as expected. In my case, the values I was getting were not exactly as they should be, especially the Z-axis which had a noticeable error of 0.1g.

To solve this issue, we need to calibrate the accelerometer using the 3 offset calibration registers, and here’s how we can do that. So, we need to position the sensor flat, and print the RAW values without dividing them by 256.

From here now we can notice the how much the outputs are off, in my case, the Z output was around 283. That’s difference of 27 in positive. Now we need to divide this value by 4, and that will give use the number that we need to write to the Z-axis offset register. If we upload the code now, the Z-axis output will be exactly 256, or 1g as it should be.

// This code goes in the SETUP section
// Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E);  // X-axis offset register
  Wire.write(1);
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F); // Y-axis offset register
  Wire.write(-2);
  Wire.endTransmission();
  delay(10);
  
  //Z-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20); // Z-axis offset register
  Wire.write(-7);
  Wire.endTransmission();
  delay(10);

If needed we should calibrate the other axis using the same method. And just a quick note that this calibration is not permanently written to the registers. We need to do write these values to the registers at each power up of the sensor.

Once we are done with the calibration, we can now finally calculate the Roll and Pitch, or the rotation around the X-axis and the rotation around the Y axis in degrees, using these two formulas.

// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
  roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
  pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;

For more details how these formulas work, you can check this Freescale Semiconductor application note.

Акселерометр ADXL335

ADXL335 представляет собой 3-осевой аналоговый акселерометр, принцип работы которого основан на обнаружении изменения емкости. ADXL335 имеет небольшие размеры, потребляет мало мощности и содержит внутри себя поликристаллический кремниевый датчик и схему обработки сигналов от данного датчика. Данный акселерометр может измерять как статическое, так и динамическое ускорение. В нашем проекте счетчика шагов на Arduino акселерометр ADXL335 будет выполнять роль датчика шагов.

Акселерометр является устройством, которое преобразует ускорение в любом направлении в соответствующее изменение напряжения. Это достигается при помощи использования конденсаторов внутри акселерометра, при ускорении емкость этих конденсаторов изменяется, что приводит к изменению напряжения.

На следующем рисунке показан внешний вид передней и задней частей акселерометра.

Назначение контактов акселерометра ADXL335: Vcc – контакт для подачи напряжения постоянного тока 5 В. X-OUT – выход акселерометра по оси x. Y-OUT – выход акселерометра по оси y. Z-OUT – выход акселерометра по оси z. GND – общий провод (земля). ST – этот контакт используется для установки чувствительности датчика.

На нашем сайте вы можете посмотреть следующие проекты с использованием акселерометра ADXL335:

Необходимые компоненты для подключения акселерометра

Для подключения акселерометра к Arduino вам понадобятся следующие компоненты:

  • Arduino (любая модель)
  • Акселерометр (например, модуль ADXL345 или MMA8452)
  • Провода (для подключения акселерометра к Arduino)
  • Резисторы (если требуется сопротивление для подключения акселерометра)

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

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

Провода необходимы для соединения акселерометра с Arduino. Обычно используются провода мужчина-мужчина или мужчина-женщина. Это позволяет легко соединять пины акселерометра с соответствующими пинами на плате Arduino.

Если вам требуется сопротивление для подключения акселерометра, вам понадобятся резисторы. Их значения зависят от конкретного акселерометра и требований вашего проекта.

Функции в программе Arduino для работы с mpu6050

MPU6050_ReadData()

Эта функция считывает данные с акселлерометра, гироскопа и датчика температуры. После считывания данных, значения переменных (temp_scalled, accel_x_scalled, accel_y_scalled, accel_z_scalled, gyro_x_scalled, gyro_y_scalled and gyro_z_scalled) обновляются.

MPU6050_ResetWake()

Эта функция сбрасывает настройки чипа на значения по-умолчанию. Рекомендуется использовать сброс настроек перед настройкой чипа на выполнения определенной задачи.

MPU6050_SetDLPF(int BW)

Эта функция настраивает встроенный фильтр низких частот. Переменная int BW должна содержать значения (0-6). Пропускная способность фильтра будет изменяться в соответствии с представленной ниже таблицей.

Если int BW не в диапазоне 0-6, фильтр низких частот отключается, что соответствует установке – бесконечность.

MPU6050_SetGains(int gyro,int accel)

Эта функция используется для установки максимального значения шкалы измерений

int gyro Макс. знач.[угол/с] int accel Макс. знач. [м/с 2 ]
250 2g
1 500 1 4g
2 1000 2 8g
3 2000 3 16g

MPU6050_ReadData()

Эта функция использует масштабные коэффициенты для расчета результата. Если не используются значения (0-3), MPU6050_ReadData() отобразит необработанные значения с датчика с погрешностью калибровки. Для получения обработанных значений, установите переменные для калибровки (accel_x_OC, accel_y_OC, accel_z_OC, gyro_x_OC, gyro_y_OC and gyro_z_OC) в нуль.

MPU6050_OffsetCal()

Эта функция позволяет откалибровать акселерометр и гироскоп. Рассчитанные значения записываются в переменные accel_x_OC, accel_y_OC, accel_z_OC, gyro_x_OC, gyro_y_OC и gyro_z_OC для дальнейшей коррекции. Для проведения калибровки необходимо расположить оси x и y axes платы MPU6050 в горизонтальной плоскости, а ось z – перпендикулярно к основанию. Даже незначительные перемещения платы во время калибровки понижают точность расчета базовой точки. Ось z калибруется относительно силя земного притяжения — 9.81 м/с 2 (1g), что учтено в коде.

Как подключить акселерометр к Arduino?

Выбор акселерометра

Перед тем, как подключать акселерометр, важно выбрать подходящую модель. Определяйте параметры, которые вам необходимы, такие как диапазон измерения, разрешение и скорость обновления

В зависимости от ваших потребностей выбирайте соответствующий акселерометр.

Схема подключения

Для подключения акселерометра к Arduino нужно использовать провода и брекет. Первый пин акселерометра подключите к заземлению Arduino, второй пин — к питанию (5V для большинства моделей). Третий и четвертый пины акселерометра подключаются к аналоговым пинам Arduino.

Программное подключение

Для того чтобы Arduino мог использовать акселерометр, нужно написать соответствующую программу. Сначала нужно определить пины, к которым подключен акселерометр с помощью функции pinMode. Затем нужно прочитать данные с акселерометра при помощи функции analogRead и произвести необходимые вычисления.

Пример программы:

  • int x,y,z;
  • float xg,yg,zg;
  • int pinX = A0;
  • int pinY = A1;
  • int pinZ = A2;
  • void setup() {
  • pinMode(pinX, INPUT);
  • pinMode(pinY, INPUT);
  • pinMode(pinZ, INPUT);
  • Serial.begin(9600);
  • }
  • void loop() {
  • x = analogRead(pinX);
  • y = analogRead(pinY);
  • z = analogRead(pinZ);
  • xg = (x — 512) / 256.0;
  • yg = (y — 512) / 256.0;
  • zg = (z — 512) / 256.0;
  • Serial.print(«Xg: «);
  • Serial.print(xg);
  • Serial.print(» Yg: «);
  • Serial.print(yg);
  • Serial.print(» Zg: «);
  • Serial.println(zg);
  • }

Проверка работы акселерометра

Чтобы проверить работу акселерометра, загрузите программу на Arduino и подключите ее к компьютеру. Откройте монитор последовательного порта в Arduino IDE и вы должны увидеть значения для X, Y, Z координат.

Поздравляем, вы успешно подключили акселерометр к Arduino!

Настройка и конфигурация акселерометра

Перед тем, как начать использовать акселерометр с Arduino, необходимо выполнить несколько шагов для его настройки и конфигурации.

1. Подключите акселерометр к Arduino. Для этого используйте соответствующие провода или плату для подключения по протоколу I2C или SPI. Убедитесь, что соединения выполнены правильно и акселерометр подключен к нужным выводам платы Arduino.

2. Загрузите библиотеку для работы с акселерометром. В Arduino IDE откройте менеджер библиотек, найдите и установите подходящую библиотеку для вашего конкретного модуля акселерометра. Это позволит вам использовать готовые функции и методы для работы с акселерометром.

3. Настройте параметры акселерометра. В зависимости от конкретного модуля акселерометра, вам может потребоваться задать определенные параметры, такие как диапазон измерения, частота обновления данных и другие. Обратитесь к документации по вашему акселерометру, чтобы узнать, как установить нужные параметры.

4. Программируйте Arduino для обработки данных акселерометра. Используйте функции и методы, предоставляемые библиотекой, чтобы получить данные с акселерометра и обработать их по вашим потребностям. Вы можете использовать Arduino IDE или другую программную среду для написания и загрузки программы на Arduino.

5. Проверьте работу акселерометра. Подключите Arduino к компьютеру и запустите программу. Используйте монитор порта для вывода данных с акселерометра и проверьте, что акселерометр работает корректно и вы получаете нужные данные.

Следуя этим шагам, вы сможете настроить и сконфигурировать акселерометр для работы с Arduino и использовать его в своих проектах.

Распиновка акселерометра ADXL335

Прежде чем погрузиться в подключения и примеры кода, давайте сначала взглянем на распиновку модуля акселерометра.

Рисунок 6 – Распиновка модуля акселерометра ADXL335

Вывод VCC обеспечивает питание для акселерометра, который может быть подключен к 5 В на Arduino.

Вывод Выход X выводит аналоговое напряжение, пропорциональное ускорению, приложенному к оси X.

Вывод Выход Y выводит аналоговое напряжение, пропорциональное ускорению на оси Y.

Вывод Выход Z выводит аналоговое напряжение, пропорциональное ускорению на оси Z.

Вывод GND подключается к выводу GND на Arduino

Вывод ST (Self-Test) контролирует функцию самопроверки. Эта функция подробно обсуждается в конце.

Понравилась статья? Поделиться с друзьями:
Зинг-Электро
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: