Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Hoe maak je een kompas met Arduino en Processing IDE?

In dit Arduino-project zullen we zien hoe we dit coole kompas kunnen maken met behulp van een Arduino, een MEMS-magnetometer en de Processing IDE. Hier is een demonstratievideo van het kompas:

Overzicht

Alles wat we nodig hebben voor dit project is een MEMS-magnetometer, voor het meten van het aardmagneetveld, een Arduino-bord en enkele jumperdraden. Als voorbeeld zal ik de HMC5883L gebruiken, een 3-assige magnetometer geïntegreerd in het GY-80 breakout-bord.

Hoe het kompas werkt

Arduino-onderdeel

Eerst moeten we de gegevens van de sensor krijgen met behulp van het Arduino-bord via het I2C-protocol. Vervolgens gebruiken we de X-as- en Y-as-waarden van de sensor om de koers te berekenen en de waarde via de seriële poort naar de verwerkings-IDE te sturen. De volgende code doet dat werk:

/*   Arduino Compass 
 *      
 *  by Dejan Nedelkovski, 
 *  www.HowToMechatronics.com
 *  
 */

#include <Wire.h> //I2C Arduino Library

#define Magnetometer_mX0 0x03  
#define Magnetometer_mX1 0x04  
#define Magnetometer_mZ0 0x05  
#define Magnetometer_mZ1 0x06  
#define Magnetometer_mY0 0x07  
#define Magnetometer_mY1 0x08  


int mX0, mX1, mX_out;
int mY0, mY1, mY_out;
int mZ0, mZ1, mZ_out;

float heading, headingDegrees, headingFiltered, declination;

float Xm,Ym,Zm;


#define Magnetometer 0x1E //I2C 7bit address of HMC5883

void setup(){
  //Initialize Serial and I2C communications
  Serial.begin(115200);
  Wire.begin();
  delay(100);
  
  Wire.beginTransmission(Magnetometer); 
  Wire.write(0x02); // Select mode register
  Wire.write(0x00); // Continuous measurement mode
  Wire.endTransmission();
}

void loop(){
 
  //---- X-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mX0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mX0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mX1 = Wire.read();
  }

  //---- Y-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mY0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mY0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mY1 = Wire.read();
  }
  
  //---- Z-Axis
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ1);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mZ0 = Wire.read();
  }
  Wire.beginTransmission(Magnetometer); // transmit to device
  Wire.write(Magnetometer_mZ0);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer,1); 
  if(Wire.available()<=1)   
  {
    mZ1 = Wire.read();
  }
  
  //---- X-Axis
  mX1=mX1<<8;
  mX_out =mX0+mX1; // Raw data
  // From the datasheet: 0.92 mG/digit
  Xm = mX_out*0.00092; // Gauss unit
  //* Earth magnetic field ranges from 0.25 to 0.65 Gauss, so these are the values that we need to get approximately.

  //---- Y-Axis
  mY1=mY1<<8;
  mY_out =mY0+mY1;
  Ym = mY_out*0.00092;

  //---- Z-Axis
  mZ1=mZ1<<8;
  mZ_out =mZ0+mZ1;
  Zm = mZ_out*0.00092;
  // ==============================
  //Calculating Heading
  heading = atan2(Ym, Xm);
 
  // Correcting the heading with the declination angle depending on your location
  // You can find your declination angle at: https://www.ngdc.noaa.gov/geomag-web/
  // At my location it's 4.2 degrees => 0.073 rad
  declination = 0.073; 
  heading += declination;
  
  // Correcting when signs are reveresed
  if(heading <0) heading += 2*PI;

  // Correcting due to the addition of the declination angle
  if(heading > 2*PI)heading -= 2*PI;

  headingDegrees = heading * 180/PI; // The heading in Degrees unit

  // Smoothing the output angle / Low pass filter 
  headingFiltered = headingFiltered*0.85 + headingDegrees*0.15;

  //Sending the heading value through the Serial Port to Processing IDE
  Serial.println(headingFiltered);

  
  delay(50);
}Code language: Arduino (arduino)

Als je meer details nodig hebt over hoe de MEMS-magnetometer werkt en hoe je de gegevens eruit kunt halen, kun je mijn MEMS Sensors-zelfstudie raadplegen.

IDE-gedeelte verwerken

Hier moeten we eerst de koerswaarden ontvangen die van de seriële poort komen. Voor meer informatie over hoe u dit doet, kunt u mijn Arduino- en verwerkingshandleiding raadplegen.

Het kompas is eigenlijk een afbeelding, of beter gezegd, het is samengesteld uit meerdere transparante afbeeldingen die in Processing IDE zijn geladen. De afbeeldingen moeten in de werkmap van de schets staan. Na het definiëren van de afbeeldingsobjecten in de sectie draw() met behulp van de functie image() laden we de achtergrondafbeelding (die optioneel is, je kunt gewoon een eenvoudige kleur voor de achtergrond gebruiken). Vervolgens wordt de kompasafbeelding geladen die met behulp van de functie roterenZ() wordt geroteerd met de waarden van de kop. Bovenaan wordt de afbeelding van de kompaspijl geladen.

Hier is de verwerkings-IDE-code:

/*   Arduino Compass 
 *      
 *  by Dejan Nedelkovski, 
 *  www.HowToMechatronics.com
 *  
 */
 
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;

Serial myPort;
PImage imgCompass;
PImage imgCompassArrow;
PImage background;

String data="";
float heading;

void setup() {
  size (1920, 1080, P3D);
  smooth();
  imgCompass = loadImage("Compass.png");
  imgCompassArrow = loadImage("CompassArrow.png");
  background = loadImage("Background.png");
  
  myPort = new Serial(this, "COM4", 115200); // starts the serial communication
  myPort.bufferUntil('\n');
}

void draw() {
  
  image(background,0, 0); // Loads the Background image
    
  pushMatrix();
  translate(width/2, height/2, 0); // Translates the coordinate system into the center of the screen, so that the rotation happen right in the center
  rotateZ(radians(-heading)); // Rotates the Compass around Z - Axis 
  image(imgCompass, -960, -540); // Loads the Compass image and as the coordinate system is relocated we need need to set the image at -960x, -540y (half the screen size)
  popMatrix(); // Brings coordinate system is back to the original position 0,0,0
  
  image(imgCompassArrow,0, 0); // Loads the CompassArrow image which is not affected by the rotateZ() function because of the popMatrix() function
  textSize(30);
  text("Heading: " + heading,40,40); // Prints the value of the heading on the screen

  delay(40);
  
}

// starts reading data from the Serial Port
 void serialEvent (Serial myPort) { 
  
   data = myPort.readStringUntil('\n');// reads the data from the Serial Port and puts it into the String variable "data".
  
  heading = float(data); // Convering the the String value into Float value
}
Code language: Arduino (arduino)

Hier kun je de bestanden van het project, de afbeeldingen en de broncodes downloaden:


Productieproces

  1. Maak Monitor Ambilight met Arduino
  2. ULTRASONE LEVITATION-machine die ARDUINO gebruikt
  3. Universele afstandsbediening met Arduino, 1Sheeld en Android
  4. DIY voltmeter met Arduino en smartphone
  5. Frequentie- en werkcyclusmeting met Arduino
  6. Een aanpasbare ponsbare toetsenbordknop maken
  7. Sonar met arduino en weergave op verwerkings-IDE
  8. Autoteller met Arduino + Processing + PHP
  9. LED-helderheid regelen met Bolt en Arduino
  10. Eenvoudige en slimme robotarm met Arduino
  11. Een website maken die Arduino communiceert met PHP