Телефонуйте » (+38) 096 227 41 41

Ми розглянули використання цифрового компаса HMC5883L з Arduino для вимірювання магнітного поля Землі. Спробуємо зробити 3D-моделювання отиманих даних з допомогою Processing. Скористаємося кодами для Arduino і Processing, знайденими в Інтернеті, але додамо більше коментарів, щоб легше було зрозуміти їх роботу. Бібліотеку для HMC5883L завантажимо звідси, хоча спочатку можете спробувати і бібліоте з попереднього уроку.

Код для Arduino

// Підключення бібліотеки I2C
#include <Wire.h>
// Підключення бібліотеки компасу HMC5883L
#include <HMC5883L.h>

// Збереження нашого compass як змінної.
HMC5883L compass;
// Запис будь-яких помилок, які можуть виникнути в компасі.
int error = 0;

//кут повороту
int RoundDegreeInt;
int PreviousDegree = 0;

// З функцією setup() ми налаштовуємо мікроконтролер і компас.
void setup()
{
  Serial.begin(9600); // Ініціалізація послідовного порта
  Wire.begin(); // Запуск інтерфейсу I2C.
  compass = HMC5883L(); // Створення нового компасу HMC5883.

  error = compass.SetScale(1.3); // Встановлення максимальної шкали компасу.
  if(error != 0) // Якщо помилка, то виводимо на екран.
    Serial.println(compass.GetErrorText(error));
error = compass.SetMeasurementMode(Measurement_Continuous); // Встановлення режиму безперервного вимірювання
  if(error != 0) // Якщо помилка, то виводимо на екран.
    Serial.println(compass.GetErrorText(error));
}

// Основний цикл програми.
void loop()
{
  // Отримання первинних значень з компасу (без маштабування).
  MagnetometerRaw raw = compass.ReadRawAxis();
  // Отримання маштабованих значень з компасу (маштабування згідно виставленої шкали).
  MagnetometerScaled scaled = compass.ReadScaledAxis();

  // Значення доступні подібно цьому:
  int MilliGauss_OnThe_XAxis = scaled.XAxis; // (або YAxis, або ZAxis)

  // Розрахунок напрямку, коли є рівень магнітометра, то знак осі правильний.
  float heading = atan2(scaled.YAxis, scaled.XAxis);

  // Оскільки маємо напрямок, то повинні додати свій кут зміщення, який є «помилкою» магнітного поля для вашої місцевості.
  // Знаходимо його, як і в попередньому уроці, тут: http://www.magnetic-declination.com/
  // Для Києва ми знайшли +7° 19′, або (що нам необхідно) 0.1277 радіана.
  // Якщо не можете знайти відхилення, то закоментуйте нижні два рядки, але компас буде дещо неточним.
   float declinationAngle = 0.1277;
   heading += declinationAngle;

  // Коригування, коли змінюються знаки.
  if(heading < 0)
    heading += 2*PI;
  // Перевірка повертання із-за додавання магнітного зміщення.
   if(heading > 2*PI)
    heading -= 2*PI;
  // Перетворення для зручності радіанів в градуси.
  float headingDegrees = heading * 180/M_PI;
  //корекція значення кута
  if (headingDegrees >= 1 && headingDegrees < 240)
  {
    headingDegrees = map(headingDegrees,0,239,0,179);
  }
  else if (headingDegrees >= 240)
  {
    headingDegrees =  map(headingDegrees,240,360,180,360);
  }

  //кут повертання
  RoundDegreeInt =round(headingDegrees);

  //згладжування значення
  if( RoundDegreeInt < (PreviousDegree + 3) && RoundDegreeInt > (PreviousDegree - 3) )
{
    RoundDegreeInt = PreviousDegree;
  }

  Output(RoundDegreeInt);
   PreviousDegree = RoundDegreeInt;

  // Зазвичай робимо затримку додатка 66 мс при циклу
  // для запуску на 15 Гц (полоса за замовчуванням для HMC5883L).
  // Однак, оскільки ми маємо велику затримку на послідовному порту (104 мс при 9600),
  // то дозволимо йому працювати з природною швидкістю.
  // delay(66);
}

// Виведення даних через послідовний порт.
void Output(int RoundDegreeInt)
{
   //Serial.println();
   Serial.println(RoundDegreeInt);
   delay(150);
}

Код для Processing

import processing.serial.*;

Serial myPort;
PFont b;

int lf = 10;    // Перетворюємо рядки в ASCII
String myString = null;
float angle;

void setup(){
  size(600,400);
  b = loadFont("Arial-BoldMT-48.vlw");
  myPort = new Serial(this, "COM3", 9600);
}

void draw(){

background(255);

while (myPort.available() > 0) {
    myString = myPort.readStringUntil(lf);
    if (myString != null) {
  //print(myString);  // Друкуємо рядок
    angle=float(myString);  // Конвертуємо і друкуємо поплавок
    println(angle);
   }
  }
  translate(160, 50);

  // малюємо фон для компасу
  ellipseMode(CENTER);
  fill(50);
  stroke(10);
  strokeWeight(2);
 ellipse(150,150,300,300);

  // малюємо лінії і точки
  translate(150,150);  // переводимо лінії і точки в середину компасу
  float CompassX = -angle;
  rotate(radians(CompassX));
  noStroke();
  fill(51, 255, 51);

  int radius = 120;

  for( int degC = 5; degC < 360; degC += 10) //Точки компасу
  {
    float angleC = radians(degC);
    float xC = 0 + (cos(angleC)* radius);
    float yC = 0 + (sin(angleC)* radius);
    ellipse(xC,yC, 3, 3);
  }

  for( int degL = 10; degL < 370; degL += 10) //Лінії компасу
  {
    float angleL = radians(degL);
    float x = 0 + (cos(angleL)* 145);
    float y = 0 + (sin(angleL)* 145);
 
    if( degL==90 || degL==180 || degL==270 || degL==360)
    {
     stroke(51, 255, 51);
     strokeWeight(4);
    }
    else
    {
      stroke(234,144,7);
      strokeWeight(2);
    }
    line(0,0, x,y);
  }

  fill(102, 102, 102);
  noStroke();
  ellipseMode(CENTER);
  ellipse(0,0, 228,228); //малюємо заповнений круг, щоб сховати в середині лінії
  b = loadFont("Arial-BoldMT-48.vlw");
  textAlign(CENTER);

  // Малюємо букви
  fill(250);
  textFont(b, 32);
  text("N", 1, -90);
  rotate(radians(90));
  text("E", 0, -90);
  rotate(radians(90));
  text("S", 0, -90);
  rotate(radians(90));
  text("W", 0, -90);
  rotate(radians(90));

  textFont(b,40);
  textAlign(CENTER);
  //text((angle), 20, 20);
  println(angle);

  //draw the needle

  rotate(radians(-CompassX)); //зробити це стаціонарним
  stroke(234,144,7);
  strokeWeight(3);

  triangle(-10, 0, 10, 0, 0, -85);
  fill(234,144,7);
  triangle(-10, 0, 10, 0, 0, 60);
}

На зхакінчення, коротке відео:

(Джерело: arduikyo.blogspot.nl)

Новини

  • SDR в IoT

    iotSDR пропонує платформу розробок для IoT-радіо та мережевих доменів. На платі два передавачі Microchip AT86RF215, для вводу-виводу модему на Xilinx ZYNQ SoC, приймач GNSS MAX2769 для GPS, Galileo, BieDou та Glonass. Плата сумісна з ПЗ GNURadio SDR. Дозволяє розробити протоколи фізичного рівня LoRa, SigFox, WightLess, Bluetooth, BLE, 802.15.4, ZigBee тощо для IoT, або шлюз IoT через TheThingsNetwork, LPWAN або Google Thread. Пам'ять EEPROM: 1x AT24MAC602 , flash-пам'ять: 1x QSPI 128 Мб, RAM: 256 MБ DDR3,слот для Micro SD карти, входи/виходи: 2x 8-бітних інтерфейси PL, інтерфейс 8-бітного PS, Gigabit Ethernet, USB 2.0 (USB3310), USB 2.0 (CP2104), 2x SMA RF-роз'єми для приймача діапазонів IoT, 2x SMA RF-роз'єми для приймача 2,4 ГГц , RF-роз'єм приймач GNSS, FPGA-роз'єм JTAG для програмування. Розміри плати: 76,2 мм x 101,6 мм.

     

    in Новини

Записатися на курс