GY-271 не могу запустить

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

День добрый. Я недавно начал разбиратся с ардуино. Купил на aliexpress два GY-271 модуля. Не получается получить с них данные.

Пробовал запустить вот такой скетч:

#include "Wire.h"
#include "HMC5883L.h"

HMC5883L compass; //Copy the folder "HMC5883L" in the folder "C:\Program Files\Arduino\libraries" and restart the arduino IDE.

float xv, yv, zv;

void setup()
{   
  Serial.begin(9600);
  Wire.begin();  
  compass = HMC5883L();  
  setupHMC5883L();       
}

void loop()
{
  getHeading();

  Serial.flush();
  Serial.print(xv);
  Serial.print(",");
  Serial.print(yv);
  Serial.print(",");
  Serial.print(zv);
  Serial.println();

  delay(100);
}

void setupHMC5883L()
{  
  compass.SetScale(0.88);
  compass.SetMeasurementMode(Measurement_Continuous);
}
 
void getHeading()
{
  MagnetometerRaw raw = compass.ReadRawAxis();
  xv = (float)raw.XAxis;
  yv = (float)raw.YAxis;
  zv = (float)raw.ZAxis;
}

но в вывод порта приходят только вот такие строки: 1636.00,1634.00,1635.00

Пробовал сканировать i2c шину, модуль отозвался на 0x0D адрес. Пробовал менять адресс 0x1E (в библотеке) на полученный 0x0D результат такой же.

Сам модуль выглядит так:

Сильно смущает надпись с обратной стороны платы: GY-271 HW-246

На корпусе микросхемы написано: 5883

Второй модуль ведет себя аналогично.

В стандартном примере Adafruit, вывод останавливается на строке: mag.getEvent(&event);

Подскажите в чем может быть причина моей беды?

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

похоже я нашел причину. там чип стоит 5883 а не 5883l , старых библиотек ни у кого не имеется?

olegivani4
Offline
Зарегистрирован: 18.02.2017

Всем привет!

У меня такая же беда. Перекопал кучу библиотек, ниодна не работает с адресом 0x0D.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Всем привет!

У меня такая же беда. Перекопал кучу библиотек, ниодна не работает с адресом 0x0D.

У вас тоже на обратной стороне платы есть надпись hw-246 ?

Navigator
Navigator аватар
Offline
Зарегистрирован: 26.01.2016

Ищите примеры с использованием "магмастер".

Было видио от ArduiniLab, если не ошибаюсь.

Там, по указаниям программы "магмастер" ориентируете магнитометр последовательно в шести плоскостях, снимаются значения и рассчитываются поправки.

Затем остается их занести в матрицу в скетче.

Показания получаются достаточно точные.

И соответственно все делать вдали от электроприборов для исключения их влиян

Navigator
Navigator аватар
Offline
Зарегистрирован: 26.01.2016

Невнимательно прочитал, думал, что у вас неточные показания.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

--

olegivani4
Offline
Зарегистрирован: 18.02.2017

Нет, надписи hw-246 у меня не, но модуль внешне один в один как Вашь. На чипе написанно DA 5883 6011. У меня 2 таких модуля, в обоих случаях одинаковое поведение. Отзываються по адресу 0х0D.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Нет, надписи hw-246 у меня не, но модуль внешне один в один как Вашь. На чипе написанно DA 5883 6011. У меня 2 таких модуля, в обоих случаях одинаковое поведение. Отзываються по адресу 0х0D.

Просто я подумал что HW это hardwire i2c версии 2, 4 или 6 , что кстати уже проверил, не помогло. Пробовал разговаривать как с чипом htc5883 (без L) тоже не помогло. Кстати на hmc5883L маркировка должна быть L883 как я понял. Гугол по этому вопросу вывел на немецкий форум где немцы пытались разабратся в этой проблеме и они пришли к выводу что это подделка на этом все и остановилось. Я больше чем уверен что модули рабочие все абсалютно, только на них нужна настоящая китайская спецификация, задал продавцу этот вопрос он не отвечает. Так что советую вам если вы делали заказ в китае попросить даташит у своего продовца, может адекватный попадется. На моем модуле такая же маркировка как у вас, только вот на нижней строке написано 6012, скорей всего это или год выпуска или серия (или и то и другое). Если это год выпуска то по видимому китайские производители избавляются от остатков старья. И пожалуста если найдете решение этой проблемы не забутьте о товарищах )

olegivani4
Offline
Зарегистрирован: 18.02.2017

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

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

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

это вам бот отвечает.

вот похоже то что нужно http://wapa-gov.com/file/YbCDRad9 там два архива, те же буковки что надо (hw-246) и без них. Скачать не могу ибо китайский не знаю.

Если перевести имя архива то там написано на китайском - ускоренная передача. А это скорей всего то что я думаю (hardwire i2c protocol).

Если у кого то получится скачать обязательно поделитесь.

olegivani4
Offline
Зарегистрирован: 18.02.2017

Методом брутфорса я вычислил, что модуль начинает работать, когда в 9 регистр вписываешь 1.
Так же обратил внимание, что после активыции меняються значения в первых 8 регистрах.

Вот работающий у меня скеч:

#include <Wire.h> //I2C Arduino Library
#define addr 0x0D //I2C Address for The HMC5883

void setup() {
  Serial.begin(9600);
  Wire.begin();

  Wire.beginTransmission(addr); //start talking
  Wire.write(9); // Set the Register
  Wire.write(1); // Write value to register
  Wire.endTransmission();
}

void loop() {
  int x, y, z, t; //triple axis data
  byte a;
  Wire.beginTransmission(addr);
  Wire.write(0);              // start reading from first register
  Wire.requestFrom(addr, 8);  // request 8 bytes from device
  while (Wire.available())
  {
    x = Wire.read() << 8; //MSB  x
    x |= Wire.read(); //LSB  x
    z = Wire.read() << 8; //MSB  z
    z |= Wire.read(); //LSB z
    y = Wire.read() << 8; //MSB y
    y |= Wire.read(); //LSB y
    t = Wire.read() << 8; //MSB t
    t |= Wire.read(); //LSB t
  }
  Wire.endTransmission();

  // Show Values
  Serial.print("X: ");
  Serial.print(x);
  Serial.print(" Y: ");
  Serial.print(y);
  Serial.print(" Z: ");
  Serial.print(z);
  Serial.print(" T: ");
  Serial.print(t);
  Serial.println();
}

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

Так же интересно, что именно отображает в моем скече параметр Т. В большинстве случаев он ростет при неподвижном модуле, как будто это время, иногда скачет в перед/назад. Хотя несколько раз замечал, что значение начинало убывать.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Методом брутфорса я вычислил, что модуль начинает работать, когда в 9 регистр вписываешь 1.
Так же обратил внимание, что после активыции меняються значения в первых 8 регистрах.

Вот работающий у меня скеч:

#include <Wire.h> //I2C Arduino Library
#define addr 0x0D //I2C Address for The HMC5883

void setup() {
  Serial.begin(9600);
  Wire.begin();

  Wire.beginTransmission(addr); //start talking
  Wire.write(9); // Set the Register
  Wire.write(1); // Write value to register
  Wire.endTransmission();
}

void loop() {
  int x, y, z, t; //triple axis data
  byte a;
  Wire.beginTransmission(addr);
  Wire.write(0);              // start reading from first register
  Wire.requestFrom(addr, 8);  // request 8 bytes from device
  while (Wire.available())
  {
    x = Wire.read() << 8; //MSB  x
    x |= Wire.read(); //LSB  x
    z = Wire.read() << 8; //MSB  z
    z |= Wire.read(); //LSB z
    y = Wire.read() << 8; //MSB y
    y |= Wire.read(); //LSB y
    t = Wire.read() << 8; //MSB t
    t |= Wire.read(); //LSB t
  }
  Wire.endTransmission();

  // Show Values
  Serial.print("X: ");
  Serial.print(x);
  Serial.print(" Y: ");
  Serial.print(y);
  Serial.print(" Z: ");
  Serial.print(z);
  Serial.print(" T: ");
  Serial.print(t);
  Serial.println();
}

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

Так же интересно, что именно отображает в моем скече параметр Т. В большинстве случаев он ростет при неподвижном модуле, как будто это время, иногда скачет в перед/назад. Хотя несколько раз замечал, что значение начинало убывать.

 

немножко вывода можно увидеть? на поворот реагирует или в покое рандом выдает?

olegivani4
Offline
Зарегистрирован: 18.02.2017

В покое рандом выдает. Результаты выложу немного позже

olegivani4
Offline
Зарегистрирован: 18.02.2017

Вот что модуль выдает в статичном положении. Данные очень сильно скачут. Видимо как-то не так считываю. Модуль при считывании в полуметре от компьютера лежал. пробовал его на обе стороны переварачивать, результат такой-же.

olegivani4
Offline
Зарегистрирован: 18.02.2017

Вот еще немного хаоса. На графике видно, что через какое-то время успокоился, а потом снова начало скокать в крайности.

olegivani4
Offline
Зарегистрирован: 18.02.2017

Понял в чем дело. начинать считывать надо было с 1го регистра а не с 0го. Сейчас при статичном положении помех почти нет а при движении модуля есть четкое изменение данных. Как пойму, как это дело преобразовать в геометрические еденици измерения, выложу свой код.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Понял в чем дело. начинать считывать надо было с 1го регистра а не с 0го. Сейчас при статичном положении помех почти нет а при движении модуля есть четкое изменение данных. Как пойму, как это дело преобразовать в геометрические еденици измерения, выложу свой код.

Ну да там всего их три (А, Б, Ц) ) но рабочий код очень хочется посмотреть, выложите последний вариант, если он работает то со скалингом я попробую вам помочь

olegivani4
Offline
Зарегистрирован: 18.02.2017

Вот работающий код. Проверил, при вращении модуля вокруг X оси меняются значения Y и Z, вокруг Z - X и Y, а вокруг Y - X и Z.

#include <Wire.h> //I2C Arduino Library
#define addr 0x0D //I2C Address for The HMC5883

void setup() {
  Serial.begin(9600);
  Wire.begin();

  Wire.beginTransmission(addr); //start talking
  Wire.write(9); // Set the Register
  Wire.write(1); // Write value to register
  Wire.endTransmission();
}

void loop() {
  int x, y, z; //triple axis data

  Wire.beginTransmission(addr);
  Wire.write(1);              // start reading from first register
  Wire.requestFrom(addr, 6);  // request 6 bytes from device
  while (Wire.available())
  {
    x = Wire.read() << 8; //MSB  x
    x |= Wire.read(); //LSB  x
    y = Wire.read() << 8; //MSB  z
    y |= Wire.read(); //LSB z
    z = Wire.read() << 8; //MSB y
    z |= Wire.read(); //LSB y
  }
  Wire.endTransmission();

  Serial.print("[");
  Serial.print(x);
  Serial.print(",");
  Serial.print(y);
  Serial.print(",");
  Serial.print(z);
  Serial.println("]");

  delay(250);
}

 

olegivani4
Offline
Зарегистрирован: 18.02.2017

Диапазон значений по осям, который получилось снять с модуля:
x:[-5324, 8419]
y:[-1798, 11769]
z:[0, 15360]

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Диапазон значений по осям, который получилось снять с модуля:
x:[-5324, 8419]
y:[-1798, 11769]
z:[0, 15360]

Вот что у меня получилось. Для правильных показаний надо покрутить его по всем осям

 

#include <Wire.h> //I2C Arduino Library
#define addr 0x0D //I2C Address for The HMC5883

int x_min, x_max, y_min, y_max, z_min, z_max; 
int range_x, range_y, range_z;

void setup() {
  x_min = x_max = y_min = y_max = z_min = z_max = 0;
  Serial.begin(9600);
  Wire.begin();

  Wire.beginTransmission(addr); //start talking
  Wire.write(0x09); // Set the Register
  Wire.write(0x01); // Write value to register
  Wire.endTransmission();
}

void loop() {
  int x, y, z; //triple axis data
  
  Wire.beginTransmission(addr);
  Wire.write(0x01);             
  Wire.requestFrom(addr, 6);  

  
  while (Wire.available()){
    x = Wire.read() << 8; 
    x |= Wire.read(); 

    if (x_min < x) x_min = x;
    if (x_max > x) x_max = x;

    y = Wire.read() << 8; 
    y |= Wire.read(); 

    if (y_min < y) y_min = y;
    if (y_max > y) y_max = y;
    
    z = Wire.read() << 8; 
    z |= Wire.read(); 

    if (z_min < z) z_min = z;
    if (z_max > x) z_max = z;
  }
  
  Wire.endTransmission();
  
  range_x = abs(x_min) + abs(x_max);
  range_y = abs(y_min) + abs(y_max);
  range_z = abs(z_min) + abs(z_max);

  float price_x = range_x / 360;
  float price_y = range_y / 360;
  float price_z = range_z / 360; 

  float real_x = x / price_x;
  float real_y = y / price_y;
  float real_z = z / price_z;

  Serial.print(" range_x: ");
  Serial.print(range_x);
  Serial.print("\t\trange_y: ");
  Serial.print(range_y);
  Serial.print("\t\trange_z: ");
  Serial.print(range_z);
  Serial.println();

  Serial.print(" price_x: ");
  Serial.print(price_x);
  Serial.print("\t\tprice_y: ");
  Serial.print(price_y);
  Serial.print("\t\tprice_z: ");
  Serial.print(price_z);
  Serial.println();

  Serial.print("       x: ");
  Serial.print(x);
  Serial.print("\t\t      y: ");
  Serial.print(y);
  Serial.print("\t\t      z: ");
  Serial.print(z);
  Serial.println();

  Serial.println();
  Serial.println("------------------------------degrees-----------------------------------");
  
  Serial.print(" x: ");
  Serial.print(real_x);
  Serial.print("\t\t      y: ");
  Serial.print(real_y);
  Serial.print("\t\t      z: ");
  Serial.print(real_z);
  Serial.println();

  Serial.println("________________________________________________________________________");
  
  delay(500);
}

Осталось только найти тангенс углов.

olegivani4
Offline
Зарегистрирован: 18.02.2017

Математика не совсем правильная. Диапазон по Х оси это не 360, а 180, так как пол оборота значение ростет, а другую половину падает.
И на севере у Х самое большое значение, значит для вычисления в градусах необходимо инвертировать значение.
А по значению Y уже определять, в какой половине круга мы находимся, меньше 180 или больще.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

Математика не совсем правильная. Диапазон по Х оси это не 360, а 180, так как пол оборота значение ростет, а другую половину падает.
И на севере у Х самое большое значение, значит для вычисления в градусах необходимо инвертировать значение.
А по значению Y уже определять, в какой половине круга мы находимся, меньше 180 или больще.

да верно 180. думаю теперь несложно подставить формулу из тех же примеров для нормального модуля (тангенс между x и y) и получить этот минус (ну или > 180 градусов).

теперь надо придумать как откалибровать его чуствительность, ибо у меня по оси Z где то 100 единиц всего.

olegivani4
Offline
Зарегистрирован: 18.02.2017

perfect пишет:

теперь надо придумать как откалибровать его чуствительность, ибо у меня по оси Z где то 100 единиц всего.

Да, странно. У меня диапазоны по всем осям очень похожи.

olegivani4
Offline
Зарегистрирован: 18.02.2017

 Вот как я преобразую данные с модуля в градусы

range_x = x_max - x_min;
range_y = y_max - y_min;

int center_x = range_x / 2;
int center_y = range_y / 2;

int angle = atan2(y - center_y, x - center_x) * 180 / PI;

Результат в диапазоне [-180 - 0 - 180]

Не совсем верно показывает, где север. но это проблема колибрации. Меня другое огорчило.
В статичном положении показания с X и Y осей очень сильно прыгают, при этом ось Z давольно спокойно себя ведет. В результате показани в градусах прыгают в диапазоне 5 градусов.

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

 Вот как я преобразую данные с модуля в градусы

range_x = x_max - x_min;
range_y = y_max - y_min;

int center_x = range_x / 2;
int center_y = range_y / 2;

int angle = atan2(y - center_y, x - center_x) * 180 / PI;

Результат в диапазоне [-180 - 0 - 180]

Не совсем верно показывает, где север. но это проблема колибрации. Меня другое огорчило.
В статичном положении показания с X и Y осей очень сильно прыгают, при этом ось Z давольно спокойно себя ведет. В результате показани в градусах прыгают в диапазоне 5 градусов.

я пока не дома. нужно делить не на 360 а на 180, а потом делить на два это будет середина (90 градусов)

вот это поменяй:

 

float price_x = range_x / 180;
float price_y = range_y / 180;
float price_z = range_z / 180;

потом

 

atan(real_x,  real_y) ...

 

atan2 это для радианов

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

градусах прыгают в диапазоне 5 градусов.

я накосячил в коде. вот новый вариант:

 

#include <Wire.h> // I2C 
#define addr 0x0D // I2C адресс HMC5883
#define how_units_in_range 180.0 // сколько градусов на диапозон от минимального до максимального значений

int x_min, x_max, y_min, y_max, z_min, z_max; 
float range_x, range_y, range_z;
int count;

void setup() {
  x_min = y_min = z_min = 32767;
  x_max = y_max = z_max = -32768;
  count = 0;

  Serial.begin(9600);
  Wire.begin();

  Wire.beginTransmission(addr); 
  Wire.write(0x09); 
  Wire.write(0x01); 
  Wire.endTransmission();
}

void loop() {
  int x, y, z; //triple axis data
  
  Wire.beginTransmission(addr);
  Wire.write(0x01);             
  Wire.requestFrom(addr, 6);

  ++count;

  if (count < 3){
    x_min = y_min = z_min = 32767;
    x_max = y_max = z_max = -32768;
    Serial.println("----------------->>>>>>>>initial");
  }

  
  while (Wire.available()){   
    x = Wire.read() << 8; 
    x |= Wire.read(); 

    if (x_min > x){ x_min = x; Serial.print("x_min udate = "); Serial.println(x); }
    if (x_max < x){ x_max = x; Serial.print("x_max udate = "); Serial.println(x); }

    y = Wire.read() << 8; 
    y |= Wire.read(); 

    if (y_min > y){ y_min = y; Serial.print("y_min udate = "); Serial.println(y); }
    if (y_max < y){ y_max = y; Serial.print("y_max udate = "); Serial.println(y); }

    z = Wire.read() << 8; 
    z |= Wire.read(); 

    if (z_min > z){ z_min = z; Serial.print("z_min udate = "); Serial.println(z); }
    if (z_max < x){ z_max = z; Serial.print("z_max udate = "); Serial.println(z); }
  }
    
  
  Wire.endTransmission();
  
  range_x = x_max - x_min; 
  range_y = y_max - y_min;
  range_z = z_max - z_min;

  float position_x = x_max - x;
  float position_y = y_max - y;
  float position_z = z_max - z;
 
  float real_x = (position_x * how_units_in_range) / range_x;
  float real_y = (position_y * how_units_in_range) / range_y;
  float real_z = (position_z * how_units_in_range) / range_z;

  Serial.print(" range_x: ");
  Serial.print(range_x);
  Serial.print("\t\trange_y: ");
  Serial.print(range_y);
  Serial.print("\t\trange_z: ");
  Serial.print(range_z);
  Serial.println();

  Serial.print("   pos_x: ");
  Serial.print(position_x);
  Serial.print("\t\t  pos_y: ");
  Serial.print(position_y);
  Serial.print("\t\t  pos_z: ");
  Serial.print(position_z);
  Serial.println();
/*
  Serial.print("       x: ");
  Serial.print(x);
  Serial.print("\t\t      y: ");
  Serial.print(y);
  Serial.print("\t\t      z: ");
  Serial.print(z);
  Serial.println();
*/
  Serial.println();
  Serial.println("------------------------------degrees-----------------------------------");
  
  Serial.print(" x: ");
  Serial.print(real_x);
  Serial.print("\t\t      y: ");
  Serial.print(real_y);
  Serial.print("\t\t      z: ");
  Serial.print(real_z);
  Serial.println();

  Serial.println("________________________________________________________________________");

//Serial.println();
  delay(1000);
}

С помощью :

how_units_in_range

вы можете указывать диапозон вывода от нуля и до этого значения.

В моем модуле рывки еще больше чем у вас.....

olegivani4
Offline
Зарегистрирован: 18.02.2017

я себе заказал другой :) GY-273

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

я себе заказал другой :) GY-273

ну не один ты такой умный ))))

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

Пришел еще один модуль GY-271. На этот раз оригинальный. От подделки отличается наличием iic адреса 0x1E и маркировкой чипа L883. В остальном внешний вид (и все надписи) совпадают с подделкой (или наоборот )))  ).

Работает очень стабильно без танцов с бубном.

Жалко потраченого времени и денег подареных бессовестному китайскому продавцу. Повелся на халявные 20 рублей...

olegivani4
Offline
Зарегистрирован: 18.02.2017

У меня не так успешно. Заказывал GY-273 - прислали такую же хрень. Переписывался на ebay с разными продавцами, спрашивал, есть ли на их чипе маркировка L883 или они продают модули с местным аналогом. Один ответил, что вроде оригинальный - купил, сейчас жду сам модуль.
А у кого Вы заказывали?

ivan-lkt
Offline
Зарегистрирован: 28.08.2017

Может кто-нибудь подсказать, почему мы считывать начинаем с 0x01, а не с 0x03 ?

f.cpu
Offline
Зарегистрирован: 05.11.2017

Подскажут :) Qmh5883

f.cpu
Offline
Зарегистрирован: 05.11.2017

QMC5883

f.cpu
Offline
Зарегистрирован: 05.11.2017

QMC5883

f.cpu
Offline
Зарегистрирован: 05.11.2017

f.cpu@yandex.ru пишите вышлю даташит

perfect
perfect аватар
Offline
Зарегистрирован: 11.02.2017

olegivani4 пишет:

У меня не так успешно. Заказывал GY-273 - прислали такую же хрень. Переписывался на ebay с разными продавцами, спрашивал, есть ли на их чипе маркировка L883 или они продают модули с местным аналогом. Один ответил, что вроде оригинальный - купил, сейчас жду сам модуль.
А у кого Вы заказывали?

https://ru.aliexpress.com/store/product/GY-271-HMC5883L-Module-Compass-Three-axis-Magnetic-Field-Sensor/1544094_32676016078.html?spm=a2g0v.12010615.0.0.2a21ac87yw1i7h

с первого раза завелся (оригинальный с буквой L). вот в этом магазине всегда адекватно отвечают на вопросы. если есть проблемы помогают.  было такое что я заказ раньше времени закрыл, а там на 150 рублей товар не доложили, так когда я им сказал об этом то они не полинились мне его дослать. покупал у них arduino конструктор на коробке их логотип и название магазина. Я так понимаю это не одиночный  мелкий торговец  а что то покрупнее.

 

 
 
 

 

Fendor
Offline
Зарегистрирован: 17.11.2017

Пришёл мне мой GY-271 с надписью HW-246 сзади. Больше ничего известно не было, перепробовал кучу скетчей с разных сайтов, всегда либо не работало, либо выдавало слишком неточные показания даже в статичном положении. По всем признакам китайская подделка, уже расстроился и стал подумывать, где бы заказать оригинал, но вдруг наткнулся на аналогичную стандартной библиотеку на Гитхабе:

Mecha_QMC5883L https://github.com/keepworking/Mecha_QMC5883L

Заливаю себе её и запускаю приложенный к библиотеке пример и ЧУДО, ОНО ЗАРАБОТАЛО. Показания выровнялись!

Было (последний скетч в этой теме товарища perfect, библиотеку брал отсюда http://amperkot.ru/static/3236/uploads/libraries/HMC5883L.zip ):

x: 38.73       y: 158.15       z: nan
x: 17.60       y: 180.00       z: nan
x: 26.41       y: 133.18       z: nan
x: 29.93       y: 125.38       z: nan
x: 160.20     y: 145.14       z: nan
x: 180.00     y: 150.35       z: nan
x: 119.27     y: 106.13       z: nan

Стало (скетч ниже, библиотека с гитхаба):

x: 587 y: -211 z: -1585 a: 340
x: 595 y: -211 z: -1558 a: 340
x: 567 y: -203 z: -1580 a: 340
x: 585 y: -178 z: -1582 a: 343
x: 572 y: -206 z: -1580 a: 340
x: 577 y: -220 z: -1590 a: 339
x: 580 y: -222 z: -1590 a: 339
 
Показания меняются от -1500 до 1500 по всем осям, т.е если загрубить до -180 +180, то погрешность вообще будет минимальной.
 
#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  qmc.init();
  //qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}

void loop() {
  int x, y, z;
  int azimuth;
  //float azimuth; //is supporting float too
  qmc.read(&x, &y, &z,&azimuth);
  //azimuth = qmc.azimuth(&y,&x);//you can get custom azimuth
  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" y: ");
  Serial.print(y);
  Serial.print(" z: ");
  Serial.print(z);
  Serial.print(" a: ");
  Serial.print(azimuth);
  Serial.println();
  delay(100);
}

Так что рекомендую попробовать этот вариант, если другие скетчи не помогли.

 
f.cpu
Offline
Зарегистрирован: 05.11.2017

Вы не правы.

<<Показания меняются от -1500 до 1500 по всем осям, т.е если загрубить до -180 +180, то погрешность вообще будет минимальной.>>

значения двух байтное 65535 т.е. с учетом минуса, показания меняются-32767  до +32767

замерял шумы составят 46 от значения 32767 

2) Значение 32767 делим на 3000 (при выбраном значении  8 Gauss)  у меня мериет почти до 11 Gauss. Полные два бита АЦП

f.cpu
Offline
Зарегистрирован: 05.11.2017

К стате значения температуры снимаемые с датчика QMC5883 (платы GY-271)дают шумы от (+-) 0,04 С до (+-) 0,1  градуса цельсия

JS
Offline
Зарегистрирован: 31.12.2017

Fendor пишет:
Так что рекомендую попробовать этот вариант, если другие скетчи не помогли.

Попробовал эту библиотеку, была аналогичная ситуация. Показания действительно выровнялись и плавают в приемлемом допуске 5 град. Да вот незадача: шкала азимута нелинейная, весь круг 360 град, но поворот на ровно 90 показывает 60, на 180 показывает 235. Максимальный размах не как у вас 1500, а 900. Смещение на 10 см в сторону всё меняет. Иногда Азимут по кругу не составляет 360. Бред какой-то, хоть и стабильный, и идёт прямо с регистров GY-271. Показания по X и Y стабильные +/- , но странно имеют две точки нуля, причём не в 180 поворота разницы, а где-то градусов 140. Помехи-наводки... близко особо ничего нет, хоть и первый этаж, в то же время компас в смартфоне параллельно показывает примерно верно и стабильно, там тоже чип.

Я хотел спросить, как у вас спустя месяц впечатление? Нормально работает?

У меня чип DA 5883 6015.

Fendor
Offline
Зарегистрирован: 17.11.2017

Нормально настроить так и не получилось. Если при чистой связке Ардуино+гироскоп он ещё более менее работал стабильно, то при подключении в общую систему (был проект по заказу от военных с поворотной антенной на ардуино, хотел добавить новую функцию по возврату в установленное положение при механическом повороте антенны) от этой идеи пришлось отказаться, так как модуль окончательно заглючил, ничего не выдавал или выдавал всякий мусор. В будущем закажу ещё несколько модулей от разных продавцов и отпишусь здесь, что выйдет.

JS
Offline
Зарегистрирован: 31.12.2017

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

vladrw
Offline
Зарегистрирован: 14.05.2016

Здравствуйте. Являюсь обладатем QMC5883l на DA5883. Есть ли возможность подружить библиотеку Mecha_QMC5883L с прошивкой для квадрокоптера (например Multiwii)?

f.cpu
Offline
Зарегистрирован: 05.11.2017

Fendor пишет:

Нормально настроить так и не получилось. Если при чистой связке Ардуино+гироскоп он ещё более менее работал стабильно, то при подключении в общую систему (был проект по заказу от военных с поворотной антенной на ардуино, хотел добавить новую функцию по возврату в установленное положение при механическом повороте антенны) от этой идеи пришлось отказаться, так как модуль окончательно заглючил, ничего не выдавал или выдавал всякий мусор. В будущем закажу ещё несколько модулей от разных продавцов и отпишусь здесь, что выйдет.

Заказ от военных на ардуино?!  Вы серьезно ??? ) ха) ха) ха))))))))))))))))

 

JS
Offline
Зарегистрирован: 31.12.2017

Тут нашёл ещё одну библиотеку для QMC5883l на DA5883 более универсальную https://github.com/DFRobot/DFRobot_QMC5883

Она сама определяет чип и работает для обоих. Однако ситуация с чипом неважная. Старый оригинал от Honeywell- HMC5883L якобы остановлено производство, а этот DA5883 - китайская бадяга.

Подбирал настройки (а они отличаются от HMC5883L) все из возможных, получилось значительно стабильнее, но точность +/- 30 градусов. Кстати на Али видел ссылку, тут кто-то собирался искать GY-273, так он так же на чипе 5883L, будет ли стабильнее не факт.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Пробую сейчас как раз GY-273, вот что у меня получается (интересует только ось Z как датчик угла поворота фрамуги). Вводные: модуль микрухой вверх при старте, потом кручу его вокруг оси Z. Выхлоп такой:

Цитата:

x: -651 y: 662 z: -1303
x: -597 y: 687 z: -1370
x: -670 y: 606 z: -1410
x: -1088 y: 613 z: -1332
x: -1303 y: 383 z: -631
x: -1327 y: 343 z: -201
x: -1308 y: 331 z: 12
x: -1260 y: 106 z: 198
x: -1227 y: -15 z: 328
x: -1037 y: -167 z: 695
x: -736 y: -282 z: 1008
x: -433 y: -280 z: 1211
x: -183 y: -312 z: 1287
x: -151 y: -348 z: 1292
x: -125 y: -346 z: 1287
x: -137 y: -353 z: 1285
x: -153 y: -358 z: 1287
 

В выхлопе повернул модуль на 180 градусов, до состояния "жопка вверх". Тестовый скетч валяется тут: https://drive.google.com/file/d/1Lv2KUwHYo2C0qruAvbFIkvg8UPMdwC9-/view?usp=sharing

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

JS
Offline
Зарегистрирован: 31.12.2017

Может проще смотреть в градусах, по моему так: Degress = atan2(norm.YAxis, norm.XAxis) * 180/PI;

На порядки точнее, надёжнее и проще поставить переменный резистор, привязать к концевикам и смотреть его.

А какой ЧИП в модуле GY-273, что на нём написано?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

JS пишет:

Может проще смотреть в градусах, по моему так: Degress = atan2(norm.YAxis, norm.XAxis) * 180/PI;

На порядки точнее, надёжнее и проще поставить переменный резистор, привязать к концевикам и смотреть его.

А какой ЧИП в модуле GY-273, что на нём написано?

Зачем усложнять лишними вычислениями, если всегда есть диапазон относительных чисел, например, [-100, 200], и в моей задаче, в зависимости от текущего значения по оси Z - всегда можно простейшей арифметикой вычислить процент открытия фрамуги, от 0 до 100%? И тригонометрические функции будут в сохранности, а то, говорят, от частого использования они стареют и выходят из строя :) Я ж не солнечный трекер строю, где без углов наклона, азимутов и пр. - никуда ;)

Насчёт переменного резистора - обсуждали с пользователями, по итогу - отказались в пользу указанного модуля. Я предлагал вариант с переменником с самого начала - забраковали :)

По поводу чипа: на нём написано DA7883 5804 вроде - сложно разглядеть, слаб зрением стал :)

JS
Offline
Зарегистрирован: 31.12.2017

DA7883 (а скорее DA5883) - это левый чип, у него выход плюс-минус лапоть. Он меряет лучше, если его перед снятий показаний повертеть, мне так заметилось. Я брал выборку из полсотни показаний среднюю, но всё равно +/- градусов 10-20. Если устраивает, то велком. Меня, например, в итоге устроило - для робота определять взаиморасположение комнат. Но надо лучше. Я в Китае назаказал разных моделей компасов на пробу, жду.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

JS пишет:

Я брал выборку из полсотни показаний среднюю, но всё равно +/- градусов 10-20. Если устраивает, то велком. 

Мне не надо много градаций открытия - ну может несколько, типа 0%, 25%, 50%, 75%, 100%, так что точностей космических  - не надо.

Потом, ещё раз повторюсь: мне совсем неважно, брешет или нет датчик. Мне важно, чтобы он брехал стабильно на всём протяжении изменения положения по оси Z, что сходу при поверхностном знакомстве - похоже на правду: изменения линейные. А уж что он там кажет и насколько брешет - по барабану, мне главное - иметь более-менее линейный диапазон чиселок, всё. Числовой ряд при этом может быть, как вы понимаете, совершенно любым, и в моём случае - не стоит этот числовой ряд привязывать к градусам, радианам, азимутам и прочему, т.к. эти данные в моём применении - совершенно избыточны.

Вот - взял датчик вертикально, покрутил по часовой и против часовой стрелки (фрамуга с горизонтальным открыванием):

Цитата:

x: 1360 y: 915 z: 475
x: 1360 y: 903 z: 461
x: 1371 y: 908 z: 448
x: 1368 y: 925 z: 463
x: 1347 y: 917 z: 461
x: 1357 y: 930 z: 461
x: 1368 y: 920 z: 458
x: 1288 y: 1100 z: 315
x: 1403 y: 986 z: -116
x: 1373 y: 1026 z: -291
x: 1340 y: 947 z: -531
x: 1352 y: 560 z: -740
x: 1383 y: 322 z: -737
x: 1386 y: 353 z: -730
x: 1388 y: 395 z: -740
x: 1381 y: 412 z: -725
x: 1391 y: 591 z: -697
x: 1371 y: 832 z: -543
x: 1281 y: 1138 z: -310
x: 1306 y: 1177 z: -63
x: 1347 y: 908 z: 482
x: 1406 y: 445 z: 616
x: 1471 y: 290 z: 533
x: 1468 y: -12 z: 510

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