HMC5883L как использовать полученную величину?

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Glitch, 23 окт 2015.

  1. Glitch

    Glitch Нуб

    Добрый день!
    Подключил компас с помощью библиотеки и решил провести эксперимент. Человек в вопросах программирования я вообще не сведущий, поэтому делал как мог и, к сожалению, к ожидаемому результату не пришел.
    Вопрос вот в чём: "Как использовать градусную величину в коде дальше? Какой у неё формат и можно ли её сравнивать с другими величинами?"
    Спасибо.

    Код (C++):
    #include "Wire.h"
    #include "HMC5883L.h"

    HMC5883L compass;
    int led = 5;
    int head2 = 0;
    void setup()
    {
      Serial.begin(9600);
      Wire.begin();
     
      compass = HMC5883L();  // создаем экземпляр HMC5883L библиотеки
      setupHMC5883L();       // инициализация HMC5883L
      turnBattery();
    }

    void loop(){
      float heading = getHeading();
      head2 = heading;
      Serial.println(head2);
      delay(250);
    }

    void setupHMC5883L()
    {
      // инициализация HMC5883L, и проверка наличия ошибок
      int error;
      error = compass.SetScale(0.88); // чувствительность датчика из диапазона: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1
      if(error != 0) Serial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее

      error = compass.SetMeasurementMode(Measurement_Continuous); // установка режима измерений как Continuous (продолжительный)
      if(error != 0) Serial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
    }

    float getHeading()
    {
      // считываем данные с HMC5883L и рассчитываем  направление
      MagnetometerScaled scaled = compass.ReadScaledAxis(); // получаем масштабированные элементы с датчика
      float heading = atan2(scaled.YAxis, scaled.XAxis);    // высчитываем направление

      // корректируем значения с учетом знаков
      if(heading < 0) heading += 2*PI;
      if(heading > 2*PI) heading -= 2*PI;

      return heading * RAD_TO_DEG; // переводим радианы в градусы
    }

    int turnBattery()
    {
      if(head2 < 100)
      (led, HIGH);
      else
      (led, LOW); // сравниваем значение head2 с 100
    }
     
     
  2. А какие значения показываются в логе? Возможно это угол относительно направления на север (или юг) от 0 до 360.

    Может данная ссылка поможет https://www.sparkfun.com/products/10530 (там есть и быстрый старт и пример для Ардуино)

    И что вы хотите получить? Если хотите мигать светодиодом относительно направления (то что в функции turnBattery) то вызываейте turnBattery в методе loop перед вызовом delay

    Код (C++):
    void loop(){
      float heading = getHeading();
      head2 = heading;
      Serial.println(head2);
      turnBattery();
      delay(250);
    }
     
    Glitch нравится это.
  3. Glitch

    Glitch Нуб

    В лог показываются значения угла относительно севера (0/360).
    Вместо светодиода в дальнейшем будет подключен через драйвер ШД, который будет ориентировать солнечную панель по градусам относительно времени.

    Если не использовать turnBattery, а напрямую сравнивать величину, то тоже ничего не выходит. Не понимаю почему.

    Код (C++):
    void loop()
    {
      float heading = getHeading();
      head2 = heading;
      Serial.println('Znachenie = ', head2);  //  выводим значение head2 на экран;
      if(head2 > 100) (led,HIGH);
      delay(250);
    }
     
  4. Забыли вызов функции.
    Код (C++):
    void loop()
    {
      float heading = getHeading();
      head2 = heading;
      Serial.println('Znachenie = ', head2);  //  выводим значение head2 на экран;
      if(head2 > 100) {
         // забыли вызов функции
          digitalWrite(led,HIGH);
      } else { // а это чтобы его погасить если угол меньше 100
          digitalWrite(led,LOW);
      }
      delay(250);
    }
     
    Glitch нравится это.
  5. Glitch

    Glitch Нуб

    Огромное спасибо! Если всё получится, обязательно отпишусь.

    Смогу ли я после поменять значение "100" на переменную типа integer, которая будет изменяться во времени?

    Код (C++):
     if(head2 > 100) {
          digitalWrite(led,HIGH);
      } else {
          digitalWrite(led,LOW);
      }
     
  6. Вы можете привести (cast) переменную к типу int, например так: int(head2) но при этом лишитесь дробной части, если она была.
    А что значит, изменяться во времени? Ваш heading (и с ним head2) изменяются от перемещения датчика, соответсвенно они не обращают внимание на время. Но если вы имеете ввиду что будет другой датчик который будет например смотреть на уровень освещенности то да, его можно подставлять в функции loop и поведение программы будет меняться в зависимости от уровня освещения (как например в этом уроке http://wiki.amperka.ru/конспект-arduino:ночной-светильник )

    Возможный совет:
    Вообще если вы хотите позиционировать батарею по солнцу (если мы говорим о стационарном размещении панелей, как на доме, а не на машине), то вам нужно только один раз узнать где север и, в соответствии от времени суток поворачивать сервомотор который крутит батарею, так как положение солнца не меняется относительно сторон света.
     
    Glitch нравится это.
  7. Glitch

    Glitch Нуб

    Вместо значения "100" планировалось использовать формулу приращения относительно времени. Т.е. каждый час он прибавлял по 10' (градусов) до определенного предела (запад). Достигнув этого предела, батарея вернётся в исходное состояние (восток) и пробудет в нем указанное время (до восхода солнца), после чего цикл будет повторяться.

    Это изначальная задумка от которой, скорее всего, придётся отойти.