Доброе утро.... Всю ночь пытался подключить HMC5883L... сначала в модуле GY-273 подумал, что неисправен, начал пробывать в модуле MPU-9250 - Результатов нет - не иннициализирует модули и все тут.. ардуино ide 1.8.5. arduino UNO Библиотека с примерами в приложении. Библиотеку видит в IDE.. Подключение VCC - контакт для подключения напряжения питания от 3.3 Вольт. GND - контакт для подключения общего провода. SDA - контакт цифрового интерфейса I2C. Подключается к выводу А4 Arduino. SCL - контакт цифрового интерфейса I2C. Подключается к выводу А5 Arduino. Не могут же они быть оба неисправны (новые пришли вчера с Али)
http://henrysbench.capnfatz.com/hen...y-273-hmc5883l-magnetometer-compass-tutorial/ Тут модуль GY-273 от 5 Вольт запитан. Как правило напряжение сигнальных линий не может превышать напряжение питания модуля. Иначе кирдык модулю. На UNO сигнальное напряжение 5 Вольт! Ваш zip мало кто будет смотреть. Размести всё что нужно в сообщении.
Не понял.., что на UNO где написано 3.3 В, там по факту 5.В? И я убил модуль? Или мне наоборот надо попробывать запитать на 5В?
Выход 3.3 В это 3.3 Вольт но на сигнальных пинах 5 Вольт. Большинство микросхем на сигнальных входах не переносит напряжение, которое превышает напряжение питания. Для согласования 3х и 5ти вольтовой логики нужны специальные цепи или устройства. Код (C++): Пример размещения исходника в сообщении. Открывать прикреплённые файлы мало кому интнресно.
В интернете куча примеров подключения так сказать на "прямую" этих модулеи... Это относится к моим? http://soltau.ru/index.php/arduino/item/453-kak-podklyuchit-tsifrovoj-kompas-hmc5883l-k-arduino Код (C++): /* HMC5883L.h - Header file for the HMC5883L Triple Axis Digital Compass Arduino Library. Version: 1.1.0 (c) 2014 Korneliusz Jarzebski www.jarzebski.pl This program is free software: you can redistribute it and/or modify it under the terms of the version 3 GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef HMC5883L_h #define HMC5883L_h #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #define HMC5883L_ADDRESS (0x1E) #define HMC5883L_REG_CONFIG_A (0x00) #define HMC5883L_REG_CONFIG_B (0x01) #define HMC5883L_REG_MODE (0x02) #define HMC5883L_REG_OUT_X_M (0x03) #define HMC5883L_REG_OUT_X_L (0x04) #define HMC5883L_REG_OUT_Z_M (0x05) #define HMC5883L_REG_OUT_Z_L (0x06) #define HMC5883L_REG_OUT_Y_M (0x07) #define HMC5883L_REG_OUT_Y_L (0x08) #define HMC5883L_REG_STATUS (0x09) #define HMC5883L_REG_IDENT_A (0x0A) #define HMC5883L_REG_IDENT_B (0x0B) #define HMC5883L_REG_IDENT_C (0x0C) typedef enum { HMC5883L_SAMPLES_8 = 0b11, HMC5883L_SAMPLES_4 = 0b10, HMC5883L_SAMPLES_2 = 0b01, HMC5883L_SAMPLES_1 = 0b00 } hmc5883l_samples_t; typedef enum { HMC5883L_DATARATE_75HZ = 0b110, HMC5883L_DATARATE_30HZ = 0b101, HMC5883L_DATARATE_15HZ = 0b100, HMC5883L_DATARATE_7_5HZ = 0b011, HMC5883L_DATARATE_3HZ = 0b010, HMC5883L_DATARATE_1_5HZ = 0b001, HMC5883L_DATARATE_0_75_HZ = 0b000 } hmc5883l_dataRate_t; typedef enum { HMC5883L_RANGE_8_1GA = 0b111, HMC5883L_RANGE_5_6GA = 0b110, HMC5883L_RANGE_4_7GA = 0b101, HMC5883L_RANGE_4GA = 0b100, HMC5883L_RANGE_2_5GA = 0b011, HMC5883L_RANGE_1_9GA = 0b010, HMC5883L_RANGE_1_3GA = 0b001, HMC5883L_RANGE_0_88GA = 0b000 } hmc5883l_range_t; typedef enum { HMC5883L_IDLE = 0b10, HMC5883L_SINGLE = 0b01, HMC5883L_CONTINOUS = 0b00 } hmc5883l_mode_t; #ifndef VECTOR_STRUCT_H #define VECTOR_STRUCT_H struct Vector { float XAxis; float YAxis; float ZAxis; }; #endif class HMC5883L { public: bool begin(void); Vector readRaw(void); Vector readNormalize(void); void setOffset(int xo, int yo); void setRange(hmc5883l_range_t range); hmc5883l_range_t getRange(void); void setMeasurementMode(hmc5883l_mode_t mode); hmc5883l_mode_t getMeasurementMode(void); void setDataRate(hmc5883l_dataRate_t dataRate); hmc5883l_dataRate_t getDataRate(void); void setSamples(hmc5883l_samples_t samples); hmc5883l_samples_t getSamples(void); private: float mgPerDigit; Vector v; int xOffset, yOffset; void writeRegister8(uint8_t reg, uint8_t value); uint8_t readRegister8(uint8_t reg); uint8_t fastRegister8(uint8_t reg); int16_t readRegister16(uint8_t reg); }; #endif Код (C++): /* HMC5883L.cpp - Class file for the HMC5883L Triple Axis Digital Compass Arduino Library. Version: 1.1.0 (c) 2014 Korneliusz Jarzebski www.jarzebski.pl This program is free software: you can redistribute it and/or modify it under the terms of the version 3 GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #include <Wire.h> #include "HMC5883L.h" bool HMC5883L::begin() { Wire.begin(); if ((fastRegister8(HMC5883L_REG_IDENT_A) != 0x48) || (fastRegister8(HMC5883L_REG_IDENT_B) != 0x34) || (fastRegister8(HMC5883L_REG_IDENT_C) != 0x33)) { return false; } setRange(HMC5883L_RANGE_1_3GA); setMeasurementMode(HMC5883L_CONTINOUS); setDataRate(HMC5883L_DATARATE_15HZ); setSamples(HMC5883L_SAMPLES_1); mgPerDigit = 0.92f; return true; } Vector HMC5883L::readRaw(void) { v.XAxis = readRegister16(HMC5883L_REG_OUT_X_M) - xOffset; v.YAxis = readRegister16(HMC5883L_REG_OUT_Y_M) - yOffset; v.ZAxis = readRegister16(HMC5883L_REG_OUT_Z_M); return v; } Vector HMC5883L::readNormalize(void) { v.XAxis = ((float)readRegister16(HMC5883L_REG_OUT_X_M) - xOffset) * mgPerDigit; v.YAxis = ((float)readRegister16(HMC5883L_REG_OUT_Y_M) - yOffset) * mgPerDigit; v.ZAxis = (float)readRegister16(HMC5883L_REG_OUT_Z_M) * mgPerDigit; return v; } void HMC5883L::setOffset(int xo, int yo) { xOffset = xo; yOffset = yo; } void HMC5883L::setRange(hmc5883l_range_t range) { switch(range) { case HMC5883L_RANGE_0_88GA: mgPerDigit = 0.073f; break; case HMC5883L_RANGE_1_3GA: mgPerDigit = 0.92f; break; case HMC5883L_RANGE_1_9GA: mgPerDigit = 1.22f; break; case HMC5883L_RANGE_2_5GA: mgPerDigit = 1.52f; break; case HMC5883L_RANGE_4GA: mgPerDigit = 2.27f; break; case HMC5883L_RANGE_4_7GA: mgPerDigit = 2.56f; break; case HMC5883L_RANGE_5_6GA: mgPerDigit = 3.03f; break; case HMC5883L_RANGE_8_1GA: mgPerDigit = 4.35f; break; default: break; } writeRegister8(HMC5883L_REG_CONFIG_B, range << 5); } hmc5883l_range_t HMC5883L::getRange(void) { return (hmc5883l_range_t)((readRegister8(HMC5883L_REG_CONFIG_B) >> 5)); } void HMC5883L::setMeasurementMode(hmc5883l_mode_t mode) { uint8_t value; value = readRegister8(HMC5883L_REG_MODE); value &= 0b11111100; value |= mode; writeRegister8(HMC5883L_REG_MODE, value); } hmc5883l_mode_t HMC5883L::getMeasurementMode(void) { uint8_t value; value = readRegister8(HMC5883L_REG_MODE); value &= 0b00000011; return (hmc5883l_mode_t)value; } void HMC5883L::setDataRate(hmc5883l_dataRate_t dataRate) { uint8_t value; value = readRegister8(HMC5883L_REG_CONFIG_A); value &= 0b11100011; value |= (dataRate << 2); writeRegister8(HMC5883L_REG_CONFIG_A, value); } hmc5883l_dataRate_t HMC5883L::getDataRate(void) { uint8_t value; value = readRegister8(HMC5883L_REG_CONFIG_A); value &= 0b00011100; value >>= 2; return (hmc5883l_dataRate_t)value; } void HMC5883L::setSamples(hmc5883l_samples_t samples) { uint8_t value; value = readRegister8(HMC5883L_REG_CONFIG_A); value &= 0b10011111; value |= (samples << 5); writeRegister8(HMC5883L_REG_CONFIG_A, value); } hmc5883l_samples_t HMC5883L::getSamples(void) { uint8_t value; value = readRegister8(HMC5883L_REG_CONFIG_A); value &= 0b01100000; value >>= 5; return (hmc5883l_samples_t)value; } // Write byte to register void HMC5883L::writeRegister8(uint8_t reg, uint8_t value) { Wire.beginTransmission(HMC5883L_ADDRESS); #if ARDUINO >= 100 Wire.write(reg); Wire.write(value); #else Wire.send(reg); Wire.send(value); #endif Wire.endTransmission(); } // Read byte to register uint8_t HMC5883L::fastRegister8(uint8_t reg) { uint8_t value; Wire.beginTransmission(HMC5883L_ADDRESS); #if ARDUINO >= 100 Wire.write(reg); #else Wire.send(reg); #endif Wire.endTransmission(); Wire.requestFrom(HMC5883L_ADDRESS, 1); #if ARDUINO >= 100 value = Wire.read(); #else value = Wire.receive(); #endif; Wire.endTransmission(); return value; } // Read byte from register uint8_t HMC5883L::readRegister8(uint8_t reg) { uint8_t value; Wire.beginTransmission(HMC5883L_ADDRESS); #if ARDUINO >= 100 Wire.write(reg); #else Wire.send(reg); #endif Wire.endTransmission(); Wire.beginTransmission(HMC5883L_ADDRESS); Wire.requestFrom(HMC5883L_ADDRESS, 1); while(!Wire.available()) {}; #if ARDUINO >= 100 value = Wire.read(); #else value = Wire.receive(); #endif; Wire.endTransmission(); return value; } // Read word from register int16_t HMC5883L::readRegister16(uint8_t reg) { int16_t value; Wire.beginTransmission(HMC5883L_ADDRESS); #if ARDUINO >= 100 Wire.write(reg); #else Wire.send(reg); #endif Wire.endTransmission(); Wire.beginTransmission(HMC5883L_ADDRESS); Wire.requestFrom(HMC5883L_ADDRESS, 2); while(!Wire.available()) {}; #if ARDUINO >= 100 uint8_t vha = Wire.read(); uint8_t vla = Wire.read(); #else uint8_t vha = Wire.receive(); uint8_t vla = Wire.receive(); #endif; Wire.endTransmission(); value = vha << 8 | vla; return value; }
Сделайте по статье http://soltau.ru/index.php/arduino/item/453-kak-podklyuchit-tsifrovoj-kompas-hmc5883l-k-arduino
Этим кодом. В Serial выводит адреса устройств подключенных по i2c, если их нет также напишет Код (C++): #include <Wire.h> byte error, address; int nDevices; //Кол-во найденных устройств void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); } void loop() { Serial.println("Scanning..."); nDevices = 0; for (address = 1; address < 127; address++ ) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknow error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // Ждем 5 сек. до следующего сканирования }
Пробую Код (C++): #include <Wire.h> // подключаем I2C библиотеку #define addr 0x0D // I2C 7-битный адрес датчика HMC5883 void setup() { Serial.begin(9600); // инициализация последовательного порта Wire.begin(); // инициализация I2C // Задаём режим работы датчика HMC5883: Wire.beginTransmission(addr); Wire.write(0x00); // выбираем регистр управления CRA (00) Wire.write(0x70); // записываем в него 0x70 [усреднение по 8 точкам, 15 Гц, нормальные измерения] Wire.write(0xA0); // записываем в регистр CRB (01) 0xA0 [чувствительность = 5] Wire.write(0x00); // записываем в регистр Mode (02) 0x00 [бесконечный режим измерения] Wire.endTransmission(); } void loop() { Wire.beginTransmission(addr); Wire.write(0x03); // переходим к регистру 0x03 Wire.endTransmission(); Wire.requestFrom(addr, 6); // запрашиваем 6 байтов while( Wire.available() ) { int h = Wire.read(); // старший байт значения по оси X int l = Wire.read(); // младший байт значения по оси X int x = word(h, l); // объединяем в двухбайтовое число int y = Wire.read(); // старший байт значения по оси Y y = y << 8; // сдвигаем влево на 8 битов y = y | Wire.read(); // объединяем с младшим байтом по OR int z = Wire.read() << 8; // читаем байт и сдвигаем влево на 8 битов z |= Wire.read(); // сокращённый синтаксис операции OR Serial.print("X = "); Serial.println(x, DEC); Serial.print("Y = "); Serial.println(y, DEC); Serial.print("Z = "); Serial.println(z, DEC); Serial.println(); } delay(100); } Выдает X=0 Y=0 Z=0
тоже самое попробывал на модуле MPU9250 адрес0х68 выдает X = -10840 Y = 25901 Z = 11274 Соответственно не меняется при поворотах
Ну то что инфа есть это уже хорошо. Но то что ничего кроме одного не выводит это уже есть баг программы, попробуйте найти другую
Адрес, только в одном месте прописывается? И еще адреса регистров с которых берутся данные они могут быть другими? По коду считывания данных с регистра вот такие данные... Код (C++): #include <Wire.h> // подключим стандартную библиотеку I2C #define addr 0x68 // I2C адрес цифрового компаса HMC5883L void setup() { Serial.begin(9600); // инициализация последовательного порта Wire.begin(); // инициализация I2C } void loop() { Wire.beginTransmission(addr); // начинаем связь с устройством по адресу 0x1E Wire.write(0x0A); // регистр, с которого мы начнём запрашивать данные Wire.endTransmission(); Wire.requestFrom(addr, 3, true); // запрашиваем 3 байта у ведомого while( Wire.available() ) { char a = Wire.read(); // считываем байт из регистра 0xA; устройство само переходит к следующему регистру char b = Wire.read(); // считываем байт из регистра 0xB char c = Wire.read(); // считываем байт из регистра 0xС // Выводим считанное в последовательный порт: Serial.print("A = "); Serial.println(a, HEX); Serial.print("B = "); Serial.println(b, HEX); Serial.print("C = "); Serial.println(c, HEX); Serial.println(); } delay(100); } A = FFFFFFE8 B = 0 C = 0
не знаю, с такими устройствами не работал, я просто сказал что дело медет быть в адресе, а что и как с адресами регистров я, увы, не знаю
Я как-то подключал HMC 5983L и они похожие с 5883. Если и2с сканер видит устрой-во то оно точно работает. Вот статья в ней есть скетч и в начале определён адрес уст-ва попробуйте поменять его на свой адрес возможно придётся заменить и адреса регистров данных но китайци пишут что они совпадают. Можете также попробовать оттуда и готовую библиотеку для HMC 5883l.
Судя по даташиту это регистры идентификации. Поменяй тут Код (C++): Wire.write(0x03); // регистр, с которого мы начнём запрашивать данные И вкури даташит