Использование BLE Nano с LSM9DS1
Я пытаюсь использовать BLE Nano для подключения к LSM9DS1 IMU. . Однако, когда я могу подключиться к IMU, значения выходов Nano не обновляются и не имеют смысла.
Я могу подключить и использовать IMU как с Arduino Uno, так и с Edison, поэтому я знаю, что проблема не в самом датчике. Код прикреплен ниже.
#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>
LSM9DS1 imu; // Создаем объект LSM9DS1
// Глобальные переменные для отслеживания частоты обновления
unsigned long startTime;
unsigned int accelReadCounter = 0;
unsigned int gyroReadCounter = 0;
unsigned int magReadCounter = 0;
unsigned int tempReadCounter = 0;
// Глобальные переменные для вывода на последовательный монитор с постоянной скоростью
unsigned long lastPrint = 0;
const unsigned int PRINT_RATE = 500;
uint8_t fax;
uint8_t fay;
Ticker ticker3;
#define TXRX_BUF_LEN 20
BLE ble;
Ticker ticker;
// Северная служба UART
static const uint8_t service1_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
uint8_t tx_value[TXRX_BUF_LEN] = {0,};
uint8_t rx_value[TXRX_BUF_LEN] = {0,};
GattCharacteristic characteristic1(service1_tx_uuid, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE );
GattCharacteristic characteristic2(service1_rx_uuid, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&characteristic1, &characteristic2};
GattService uartService(service1_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
void disconnectionCallBack(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) {
Serial1.println("Disconnected!");
Serial1.println("Restarting the advertising process");
ble.startAdvertising();
}
void setupDevice() {
// [commInterface] определяет, будем ли мы использовать I2C или SPI
// для связи с LSM9DS1.
// Используйте либо IMU_MODE_I2C, либо IMU_MODE_SPI
imu.settings.device.commInterface = IMU_MODE_I2C;
// [mAddress] устанавливает адрес I2C или контакт SPI CS для
// Магнитометр LSM9DS1.
imu.settings.device.mAddress = 0x1E; // Использовать адреса I2C 0x1E
// [agAddress] устанавливает адрес I2C или контакт SPI CS для
// Акселерометр/гироскоп LSM9DS1.
imu.settings.device.agAddress = 0x6B; // адрес I2C 0x6B
}
void setupGyro() {
// [enabled] включает или выключает гироскоп.
imu.settings.gyro.enabled = false; // Включить гироскоп
// [scale] устанавливает полномасштабный диапазон гироскопа.
// масштаб может быть установлен на 245, 500 или 2000
imu.settings.gyro.scale = 245; // Установить масштаб на +/-245 dps
// [sampleRate] устанавливает скорость выходных данных (ODR) гироскопа
// SampleRate может быть установлен в диапазоне от 1 до 6
// 1 = 14,9 4 = 238
// 2 = 59,5 5 = 476
// 3 = 119 6 = 952
imu.settings.gyro.sampleRate = 3; // 59,5 Гц ODR
// [bandwidth] может установить частоту среза гироскопа.
// Допустимые значения: 0-3. Фактическое значение частоты среза
// зависит от частоты дискретизации. (раздел 7.12 таблицы данных)
imu.settings.gyro.bandwidth = 0;
// [lowPowerEnable] включает или выключает режим низкого энергопотребления.
imu.settings.gyro.lowPowerEnable = false; // режим LP выключен
// [HPFEnable] включает или отключает фильтр верхних частот
imu.settings.gyro.HPFEnable = true; // ФВЧ отключен
// [HPFCutoff] устанавливает частоту среза HPF (если включено)
// Допустимые значения: 0-9. Стоимость зависит от ODR.
// (раздел 7.14 таблицы данных)
imu.settings.gyro.HPFCutoff = 1; // Отсечка HPF = 4 Гц
// [flipX], [flipY] и [flipZ] — логические значения, которые могут
// автоматически переключаем положительную/отрицательную ориентацию
// из трех осей гироскопа.
imu.settings.gyro.flipX = false; // Не переворачивать X
imu.settings.gyro.flipY = false; // Не переворачивать Y
imu.settings.gyro.flipZ = false; // Не переворачивать Z
}
void setupAccel() {
// [enabled] включает или выключает акселерометр.
imu.settings.accel.enabled = true; // Включить акселерометр
// [enableX], [enableY] и [enableZ] могут включаться и выключаться
// выбираем оси акселерометра.
imu.settings.accel.enableX = true; // Включить X
imu.settings.accel.enableY = true; // Включить Y
imu.settings.accel.enableZ = true; // Включить Z
// [scale] устанавливает полный диапазон акселерометра.
// шкала ускорения может быть 2, 4, 8 или 16
imu.settings.accel.scale = 8; // Установить шкалу ускорения на +/-8g.
// [sampleRate] устанавливает скорость выходных данных (ODR)
// акселерометр. ПРИМЕНЯЕТСЯ ТОЛЬКО КОГДА ГИРОСКОП
// НЕПОЛНОЦЕННЫЙ! В противном случае частота дискретизации ускорения = частоте дискретизации гироскопа.
// частота дискретизации ускорения может быть 1-6
// 1 = 10 Гц 4 = 238 Гц
// 2 = 50 Гц 5 = 476 Гц
// 3 = 119 Гц 6 = 952 Гц
imu.settings.accel.sampleRate = 2; // Установите ускорение на 10 Гц.
// [bandwidth] устанавливает пропускную способность фильтра сглаживания.
// Частота отсечки ускорения может принимать любое значение от -1 до 3.
// -1 = пропускная способность определяется частотой дискретизации
// 0 = 408 Гц 2 = 105 Гц
// 1 = 211 Гц 3 = 50 Гц
imu.settings.accel.bandwidth = 0; // полоса пропускания = 408 Гц
// [highResEnable] включает или отключает высокое разрешение
// режим для акселерометра.
imu.settings.accel.highResEnable = false; // Отключить ЧСС
// [highResBandwidth] устанавливает частоту среза LP
// акселерометр, если он в режиме высокого разрешения.
// может быть любым значением от 0 до 3
// Отсечка LP устанавливается на коэффициент частоты дискретизации
// 0 = ОДР/50 2 = ОДР/9
// 1 = ОДР/100 3 = ОДР/400
imu.settings.accel.highResBandwidth = 0;
}
void setupMag() {
// [enabled] включает или выключает магнитометр.
imu.settings.mag.enabled = false; // Включить магнитометр
// [scale] устанавливает полномасштабный диапазон магнитометра
// шкала магазина может быть 4, 8, 12 или 16
imu.settings.mag.scale = 12; // Установить шкалу магнита на +/-12Gs
// [sampleRate] устанавливает скорость выходных данных (ODR)
// магнитометр.
// скорость передачи данных может быть 0-7:
// 0 = 0,625 Гц 4 = 10 Гц
// 1 = 1,25 Гц 5 = 20 Гц
// 2 = 2,5 Гц 6 = 40 Гц
// 3 = 5 Гц 7 = 80 Гц
imu.settings.mag.sampleRate = 5; // Установить частоту OD на 20 Гц
// [tempCompensationEnable] включает или отключает
// температурная компенсация магнитометра.
imu.settings.mag.tempCompensationEnable = false;
// [XYPerformance] устанавливает производительность по осям x и y
// магнитометр либо:
// 0 = режим низкого энергопотребления 2 = высокая производительность
// 1 = средняя производительность 3 = сверхвысокая производительность
imu.settings.mag.XYPerformance = 3; // Сверхвысокая производительность.
// [ZPerformance] делает то же самое, но только для z
imu.settings.mag.ZPerformance = 3; // Сверхвысокая производительность.
// [lowPowerEnable] включает или отключает режим пониженного энергопотребления в
// магнитометр.
imu.settings.mag.lowPowerEnable = false;
// [operatingMode] устанавливает режим работы
// магнитометр. OperatingMode может быть 0-2:
// 0 = непрерывное преобразование
// 1 = однократное преобразование
// 2 = питание выключено
imu.settings.mag.operatingMode = 0; // Непрерывный режим
}
void setupTemperature() {
// [enabled] включает или выключает датчик температуры.
imu.settings.temp.enabled = false;
}
uint16_t initLSM9DS1() {
setupDevice(); // Настройка общих параметров устройства
setupGyro(); // Настраиваем параметры гироскопа
setupAccel(); // Настраиваем параметры акселерометра
setupMag(); // Настраиваем параметры магнитометра
setupTemperature(); // Настраиваем параметр датчика температуры
return imu.begin();
}
void writtenHandle(const GattWriteCallbackParams *Handler) {
uint8_t buf[TXRX_BUF_LEN];
uint16_t bytesRead, index;
if (Handler->handle == characteristic1.getValueAttribute().getHandle()) {
ble.readCharacteristicValue(characteristic1.getValueAttribute().getHandle(), buf, &bytesRead);
//Serial1.print("bytesRead: ");
//Serial1.println(bytesRead, HEX);
//для (байтовый индекс = 0; индекс < bytesRead; индекс++) {
//Serial1.write(buf[index]);
}
//Serial1.println("");
// // Обработать данные
// if (buf[0] == 0x01) // Команда для управления выводом цифрового выхода
// {
// если (buf[1] == 0x01)
// digitalWrite(DIGITAL_OUT_PIN, HIGH);
// еще
// цифровая запись (DIGITAL_OUT_PIN, LOW);
// }
// else if (buf[0] == 0xA0) // Команда включает аналоговое чтение
// {
// если (buf[1] == 0x01)
// Analog_enabled = true;
// еще
// Analog_enabled = false;
// }
// иначе если (buf[0] == 0x04)
// {
// Analog_enabled = false;
// цифровая запись (DIGITAL_OUT_PIN, LOW);
// }
}
void m_status_check_handle() {
imu.readAccel();
uint8_t buf[3];
fax = (uint16_t)(imu.readAccel(X_AXIS));
buf[0] = 0x0A;
buf[1] = (fax>>8);
buf[2] = (fax);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 3);
uint8_t bufy[3];
fay = (uint16_t)(imu.readAccel(Y_AXIS));
bufy[0] = 0x0B;
bufy[1] = (fax>>8);
bufy[2] = (fax);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), bufy, 3);
}
void setup() {
// поместите сюда код установки для однократного запуска
Serial1.begin(9600);
ble.init();
ble.onDisconnection(disconnectionCallBack);
ble.onDataWritten(writtenHandle);
// настраиваем adv_data и srp_data
ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)"TXRX", sizeof("TXRX") - 1);
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
// устанавливаем adv_type
ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
// добавляем сервис
ble.addService(uartService);
// установить имя устройства
ble.setDeviceName((const uint8_t *)"LSM9DS1 Accel");
// устанавливаем мощность передачи, допустимые значения -40, -20, -16, -12, -8, -4, 0, 4
ble.setTxPower(4);
// установить adv_interval, 100 мс, кратное 0,625 мс.
ble.setAdvertisingInterval(160);
// устанавливаем adv_timeout в секундах
ble.setAdvertisingTimeout(0);
// запускаем рекламу
ble.startAdvertising();
ticker.attach_us(m_status_check_handle, 2000);
}
void loop() {
// imu.accelAvailable() возвращает 1, если новый акселерометр
// данные готовы к чтению. 0 иначе.
if (imu.accelAvailable()) {
imu.readAccel();
accelReadCounter++;
uint8_t buf[3];
fax = (uint16_t)(imu.readAccel(X_AXIS));
buf[0] = 0x0A;
buf[1] = (fax>>8);
buf[2] = (fax);
ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), buf, 3);
}
// imu.gyroAvailable() возвращает 1, если новый гироскоп
// данные готовы к чтению. 0 иначе.
if (imu.gyroAvailable()) {
imu.readGyro();
gyroReadCounter++;
}
// imu.magAvailable() возвращает 1, если новый магнитометр
// данные готовы к чтению. 0 иначе.
if (imu.magAvailable()) {
imu.readMag();
magReadCounter++;
}
// imu.tempAvailable() возвращает 1, если новый датчик температуры
// данные готовы к чтению. 0 иначе.
if (imu.tempAvailable()) {
imu.readTemp();
tempReadCounter++;
}
}
В этом примере я пытаюсь вывести только значения акселерометра x и y. Оба они выводятся как одно и то же число (B5 в HEX) и не обновляются. Любая помощь приветствуется.
@Tanner, 👍0
Обсуждение1 ответ
▲ 1
Вы установили высокий уровень на контакт 13 DEN_A/G, это активные данные для гироскопа и акселерометра? Если он находится на низком уровне, значение не изменится.
,
@enrico
Смотрите также:
- Можно ли измерить скорость акселерометром? Насколько точно?
- Акселерометр Интернета вещей
- Акклерометр arduino с серводвигателем
- Arduino Pro Micro, получить данные с контакта Tx?
- Хочу создать Bluetooth audio control (увеличение/уменьшение громкости, воспроизведение, пауза и т.д.) для смартфона
- В чем разница между акселерометром, гироскопом и датчиком магнитометра?
- Невозможно подключиться к Bluetooth hc-05.
- Проблемы с надежным подключением с использованием HC-05 в качестве ведущего устройства Bluetooth
Вы установили высокий уровень на контакт 13 DEN_A/G, это активные данные для гироскопа и акселерометра? Если он находится на низком уровне, значение не изменится., @enrico
Возможно, вы захотите попробовать прочитать идентификационный код устройства или аналогичные известные значения и вывести их локально через UART. Затем отдельно запустите что-то еще — возможно, даже медленный счетчик — через BLE и убедитесь, что ваш телефон или то, к чему вы обращаетесь, видит изменения. Это поможет вам выяснить, связана ли проблема с использованием I2C, использованием стека BLE или даже с тем, что телефон, с которого вы запрашиваете, кэширует значения., @Chris Stratton
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что он был заброшен в течение полугода без информации, которая могла бы привести к предоставлению решения., @Chris Stratton