Подключение HMC5883L

Тема в разделе "Arduino & Shields", создана пользователем Artclonic, 3 мар 2018.

  1. Artclonic

    Artclonic Гик

    Заработал, но выводит только одно значение? Первое? X?
    Может только одно? что ли?
     
  2. Artclonic

    Artclonic Гик

  3. Artclonic

    Artclonic Гик

    Добрый день, подскажите а как изменить чувствительность датчика (если вообще такая возможность? Вроде как по описанию)
    Код (C++):
    #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(0x0B); // Tell the HMC5883 to Continuously Measure
      Wire.write(0x01); // Set the Register
      Wire.endTransmission();
      Wire.beginTransmission(addr); //start talking
      Wire.write(0x09); // Tell the HMC5883 to Continuously Measure
      Wire.write(0x1D); // Set the Register
      Wire.endTransmission();
    }

    void loop() {

      int x, y, z; //triple axis data

      //Tell the HMC what regist to begin writing data into


      Wire.beginTransmission(addr);
      Wire.write(0x00); //start with register 3.
      Wire.endTransmission();

      //Read the data.. 2 bytes for each axis.. 6 total bytes
      Wire.requestFrom(addr, 6);
      if (6 <= Wire.available()) {
        x = Wire.read(); //MSB  x
        x |= Wire.read() << 8; //LSB  x
        z = Wire.read(); //MSB  z
        z |= Wire.read() << 8; //LSB z
        y = Wire.read(); //MSB y
        y |= Wire.read() << 8; //LSB y
      }

      // Show Values
       //Serial.print("X Value: ");
     
      Serial.print(x);
      Serial.print(",");
      Serial.print(y);
      Serial.print(",");
      Serial.print(z);
      Serial.println();

      delay(500);
    }
     
  4. Artclonic

    Artclonic Гик

    Решил поразмыслить, как возможно подключить сразу несколько датчиков GY-273 (HMC5883L). Как осуществить?
    Вариант№1
    Но только, как я понимаю на три датчика (а надо больше 3-х).
    " Берём первый hmc5883l подключаем n контакт к земле адрес изменился на единичку меньше, другой магнитометр подключаем как обычно питание и sda scl и всё (адрес остался как был по умолчанию), третий подключаем n контакт к питанию (например 3.3v)."
    Вариант№2
    А что если внести изменения в "выходные" пины А4 и А5 которые на sda scl, а где они прописываются? Или не реально другие датчики, к другим пинам...

    Или все же как то адреса каждого модуля изменить..
     
  5. Artclonic

    Artclonic Гик

    Подскажите, а как будут выглядеть адреса (в указанном выше коде), Где их менять? (если в случае подключения к земле и к 3,3в).
    Вот тут?
    #define addr 0x0D //I2C Address for The HMC5883
     
  6. mcureenab

    mcureenab Гуру

    У HMC5883L адрес не меняется. Каждый датчик нужно вешать на свою шину I2C. Или через мультиплексор.
    MAX7367
     
    Последнее редактирование: 22 мар 2018
  7. Artclonic

    Artclonic Гик

    Это смена аналоговых пинов "А4,А5"? Вернее дополнение? Иными словами на каждые два пина" А" возможно "посадить" по HMC5883L? Это надо библиотеку шины менять?
    Посмотрел в сети...тут наверное надо поять? Модулей нет готовых? Или есть?
     
  8. mcureenab

    mcureenab Гуру

    Это не аналоговые пины, а пины с функцией I2C SDA, SCL. В МК пинов мало, а функций много. Один и тот же пин может в разное время выполнять разные функции. Библиотека Wire поддерживает только аппаратный модуль I2C. В разных моделях МК этот модуль подключается к разным пинам.

    Для организации I2C на других пинах можно попробовать библиотеку SoftwareWire http://forum.arduino.cc/index.php?topic=318127

    Не плохой вариант - подключить каждый датчик к своей Ардуино и связать их в сеть, например, на шине SPI.
     
  9. Artclonic

    Artclonic Гик

    Интересный вариант.... Немного не пойму логику..
    В нормальном варианте (один датчик) имею
    Код (C++):
    #define addr 0x0D //I2C Address for The HMC5883
    Который по умолчанию A4, A5.
    ПРедлагается установить пины для I2C... вроде логично, ясно
    Код (C++):
    #include <SoftwareWire.h>

    // SoftwareWire constructor.
    // Parameters:
    //   (1) pin for the software sda
    //   (2) pin for the software scl
    //   (3) use internal pullup resistors. Default true. Set to false to disable them.
    //   (4) allow the Slave to stretch the clock pulse. Default true. Set to false for faster code.
    //
    // Using pin 2 (software sda) and 3 (software scl) in this example.

    SoftwareWire myWire( 2, 3);
    Адреса у них останутся постоянными. Как связать? На пинах понятно, что тот или иной датчик сидит на соответствующих пинах. Я так понимаю, что шина I2C "перескакивает" на другие пины (простите за формулировки мои)... Как понять (считать) именно с того датчика...?
     
  10. Artclonic

    Artclonic Гик

    К примеру как я вижу алгоритм..
    Функцией определяем, что I2C на пинах A4, A5
    Код (C++):
    SoftwareWire myWire(4, 5);
    Далее есть код который считывает значение с датчика, к примеру переменную "X"
    Следующий шаг
    Функцией определяем, что I2C на пинах A6, A7
    Код (C++):
    SoftwareWire myWire(6, 7);
    далее, повторяем абсолютно такой же код, стем же адресом но меняем переменную "X" на "Y"
    (программа считает все тоже самое, только мы как бы ее "обманем"....)
    Потом выводим "X" и "Y" в сериал

    ....это так работает?
     
  11. mcureenab

    mcureenab Гуру

    Wire будет читать с датчика на пинах A4, A5. myWire будет читать с датчика на пинах 2, 3. Адрес 0x0D один и тот же.
    Это как в городе. Номер дома (датчика) 0x0D, но на разных улицах (шинах I2C).
     
  12. Artclonic

    Artclonic Гик

    Я подробно чуть выше описал (через один пост) - верно я мыслю?
     
  13. mcureenab

    mcureenab Гуру

    Как бы да.

    Только строка

    SoftwareWire myWire(....

    это не функция, а объявление переменной myWire. Но наверное никто не мешает для каждого запроса к датчику создавать новый объект myWire привязанный к соответствующим пинам и удалять его после завершения запроса.
     
  14. mcureenab

    mcureenab Гуру

    Или для каждой шины статически создать отдельный объект:

    SoftwareWire myWire1(4, 5);
    SoftwareWire myWire2(6, 7);

    или даже массив.

    SoftwareWire myWire[2] = {SoftwareWire(4,5), SoftwareWire(6,7)};
     
  15. Artclonic

    Artclonic Гик

    Вот... вроде своял.... (только не пойму, когда надо удалить myWire... и надо ли вообще?)
    Код (C++):
    #include <SoftwareWire.h>
    #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(0x0B); // Tell the HMC5883 to Continuously Measure
      Wire.write(0x01); // Set the Register
      Wire.endTransmission();
      Wire.beginTransmission(addr); //start talking
      Wire.write(0x09); // Tell the HMC5883 to Continuously Measure
      Wire.write(0x1D); // Set the Register
      Wire.endTransmission();
    }

    void loop() {
      //Начало первого блока кода для чтения 1 датчика
    SoftwareWire myWire1(4, 5);

      int x1, y1, z1; //triple axis data

      //Tell the HMC what regist to begin writing data into


      Wire.beginTransmission(addr);
      Wire.write(0x00); //start with register 3.
      Wire.endTransmission();

      //Read the data.. 2 bytes for each axis.. 6 total bytes
      Wire.requestFrom(addr, 6);
      if (6 <= Wire.available()) {
        x1 = Wire.read(); //MSB  x
        x1 |= Wire.read() << 8; //LSB  x
        z1 = Wire.read(); //MSB  z
        z1 |= Wire.read() << 8; //LSB z
        y1 = Wire.read(); //MSB y
        y1 |= Wire.read() << 8; //LSB y
      }


    //Начало второго блока кода для чтения 2 датчика
    SoftwareWire myWire1(6, 7);

      int x2, y2, z2; //triple axis data

      //Tell the HMC what regist to begin writing data into

      Wire.beginTransmission(addr);
      Wire.write(0x00); //start with register 3.
      Wire.endTransmission();

      //Read the data.. 2 bytes for each axis.. 6 total bytes
      Wire.requestFrom(addr, 6);
      if (6 <= Wire.available()) {
        x2 = Wire.read(); //MSB  x
        x2 |= Wire.read() << 8; //LSB  x
        z2 = Wire.read(); //MSB  z
        z2 |= Wire.read() << 8; //LSB z
        y2 = Wire.read(); //MSB y
        y2 |= Wire.read() << 8; //LSB y
      }
      }


      // Show Values
       //Serial.print("X Value: ");
    Serial.print("E");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y1);
    Serial.print(",");
    Serial.print(z1);
    Serial.print(x2);
    Serial.print(",");
    Serial.print(y2);
    Serial.print(",");
    Serial.print(z2);
     Serial.print("\n");

      delay(100);
    }
     
  16. mcureenab

    mcureenab Гуру

    Раз создал

    SoftwareWire myWire1(4, 5);

    так и работай с myWire1. Объект Wire это аппаратный I2C и с myWire1 никак не связан.

    Объявить myWire1 в одном блоке дважды нельзя.

    SoftwareWire myWire1(4, 5);

    //Начало второго блока кода для чтения 2 датчика
    SoftwareWire myWire1(6, 7); // Ошибка. Или сделай новый блок { } или назови myWire2.
     
  17. Artclonic

    Artclonic Гик

    Понял!!!! Иными словами все "Wire" надо заменить на "myWire1" в первом блоке.
    А во втором создать SoftwareWire myWire2(6, 7); и соответственно заменить все "Wire" на "myWire2"
    Теперь понятно, для чего надо будет удалять "myWire..." - потому как надо будет создавать новую!
    Все верно?
    Как записать удаление?
     
  18. mcureenab

    mcureenab Гуру

    У тебя еще есть инициализация датчика в функции setup. Будет проще объявить глобальные myWire1 и myWire2 и использовать их как в setup так и в loop. Если памяти хватает, то лучше так сделать.

    Автоматические переменные (в отличии от статических) удаляются автоматически. Ничего писать не надо.
     
  19. Artclonic

    Artclonic Гик

    Вот так?
    Код (C++):
    void setup() {

      Serial.begin(9600);
      myWire1.begin();
      myWire2.begin();

    //Проверить изменение показаний можно магнитом

      myWire1.beginTransmission(addr); //start talking
      myWire1.write(0x0B); // Tell the HMC5883 to Continuously Measure
      myWire1.write(0x01); // Set the Register
      myWire1.endTransmission();
      myWire1.beginTransmission(addr); //start talking
      myWire1.write(0x09); // Tell the HMC5883 to Continuously Measure
      myWire1.write(0x1D); // Set the Register
      myWire1.endTransmission();
      myWire2.beginTransmission(addr); //start talking
      myWire2.write(0x0B); // Tell the HMC5883 to Continuously Measure
      myWire2.write(0x01); // Set the Register
      myWire2.endTransmission();
      myWire2.beginTransmission(addr); //start talking
      myWire2.write(0x09); // Tell the HMC5883 to Continuously Measure
      myWire2.write(0x1D); // Set the Register
      myWire2.endTransmission();


    }

    void loop() {
      //Начало первого блока кода для чтения 1 датчика
    SoftwareWire myWire1(4, 5);

      int x1, y1, z1; //triple axis data

      //Tell the HMC what regist to begin writing data into


      myWire1.beginTransmission(addr);
      myWire1.write(0x00); //start with register 3.
      myWire1.endTransmission();

      //Read the data.. 2 bytes for each axis.. 6 total bytes
      myWire1.requestFrom(addr, 6);
      if (6 <= Wire.available()) {
        x1 = Wire.read(); //MSB  x
        x1 |= Wire.read() << 8; //LSB  x
        z1 = Wire.read(); //MSB  z
        z1 |= Wire.read() << 8; //LSB z
        y1 = Wire.read(); //MSB y
        y1 |= Wire.read() << 8; //LSB y
      }


    //Начало второго блока кода для чтения 2 датчика
    SoftwareWire myWire2(6, 7);

      int x2, y2, z2; //triple axis data

      //Tell the HMC what regist to begin writing data into

      myWire2.beginTransmission(addr);
      myWire2.write(0x00); //start with register 3.
      myWire2.endTransmission();

      //Read the data.. 2 bytes for each axis.. 6 total bytes
      myWire2.requestFrom(addr, 6);
      if (6 <= Wire.available()) {
        x2 = Wire.read(); //MSB  x
        x2 |= Wire.read() << 8; //LSB  x
        z2 = Wire.read(); //MSB  z
        z2 |= Wire.read() << 8; //LSB z
        y2 = Wire.read(); //MSB y
        y2 |= Wire.read() << 8; //LSB y
      }
      }


      // Show Values
       //Serial.print("X Value: ");
    Serial.print("E");
    Serial.print(x1);
    Serial.print(",");
    Serial.print(y1);
    Serial.print(",");
    Serial.print(z1);
    Serial.print(x2);
    Serial.print(",");
    Serial.print(y2);
    Serial.print(",");
    Serial.print(z2);
    Serial.print("\n");

      delay(100);
    }
     
     
  20. mcureenab

    mcureenab Гуру

    Так

    SoftwareWire myWire1(4, 5);
    SoftwareWire myWire2(6, 7);

    должны быть глобальными, а не локальными в функции loop.

    И в функции loop используется Wire вместо myWire1, myWire2...