0% found this document useful (0 votes)
61 views

LAB7

1) The document discusses using infrared (IR) signals for remote control purposes and includes code examples for receiving and decoding IR signals from a remote control using an Arduino. 2) It explains how to set up an IR receiver circuit and use a library to detect button presses and translate them into button codes or numeric values. 3) Additional examples are provided to modify the code to blink an LED a number of times corresponding to the numeric button value received.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views

LAB7

1) The document discusses using infrared (IR) signals for remote control purposes and includes code examples for receiving and decoding IR signals from a remote control using an Arduino. 2) It explains how to set up an IR receiver circuit and use a library to detect button presses and translate them into button codes or numeric values. 3) Additional examples are provided to modify the code to blink an LED a number of times corresponding to the numeric button value received.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 40

Universidad Nacional Mayor de San Marcos

Facultad de Ingeniería de Sistemas e Informática

Arquitectura de Computadoras

Laboratorio 7 – Control Remoto, I2C

I. Control Remoto
Infra-Red Light

Infra-Red actually is normal light with a


particular colour. We humans can't see
this colour because its wave length of
950nm is below the visible spectrum.
That's one of the reasons why IR is
chosen for remote control purposes, we
want to use it but we're not interested in
seeing it. Another reason is because IR
LEDs are quite easy to make, and
therefore can be very cheap.

Although we humans can't see the Infra-Red light emitted from a remote control
doesn't mean we can't make it visible. 

A video camera or digital photo camera can "see" the Infra-Red light as you can see
in this picture. Even the cheapest cell phones have built in cameras these days.
Simply point your remote to such a camera, press any button and you'll see the LED
flicker.

Unfortunately for us there are many more sources of Infra-Red light. The sun is the
brightest source of all, but there are many others, like: light bulbs, candles, central
heating system, and even our body radiates Infra-Red light. In fact everything that
radiates heat, also radiates Infra-Red light. Therefore we have to take some
precautions to guarantee that our IR message gets across to the receiver without
errors. 

Circuito Emisor/ Receptor Infrarrojo y Arduino


Aqui el circuito del transmisor receptor infrarrojo y la entrada al Arduino:
Para el proyecto use los sensores: 
If you use the IRrecvDemo Sketch (above) and count the 21 buttons from left to right and
top to bottom, the codes received are these: (NOTE: Receiving "FFFFFFFF" means "repeat"
if you hold the button down.)
1 FFA25D

2 FF629D

3 FFE21D

4 FF22DD

5 FF02FD

6 FFC23D

7 FFE01F

8 FFA857

9 FF906F

1 FF6897
0

1 FF9867
1

1 FFB04F
2

1 FF30CF
3

1 FF18E7
4

1 FF7A85
5

1 FF10EF
6

1 FF38C7
7

1 FF5AA5
8

1 FF42BD
9

2 FF4AB5
0

2 FF52AD
1

// Pequeño programa para detectar si hay un obstáculo entre el transmisor y receptor


infrarrojo.

// set pin numbers:

const int buttonPin = 12; // Pin de entrada

const int ledPin = 13; // the number of the LED pin


// variables will change:

int buttonState = 0; // variable for reading the pushbutton status

void setup() {

// initialize the LED pin as an output:

pinMode(ledPin, OUTPUT);

// initialize the pushbutton pin as an input:

pinMode(buttonPin, INPUT);

void loop(){

// read the state of the pushbutton value:

buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed.

// if it is, the buttonState is HIGH:

if (buttonState == HIGH) {

// led se prende cuando hay un obstaculo entre el transmisor y receptor

digitalWrite(ledPin, HIGH);

else {

// led se apaga cuando no se obstruye el paso entre el transmisor y el receptor

digitalWrite(ledPin, LOW);
}

Usando el mismo circuito le agregamos la librería IRremote, que nos servirá para detectar
las teclas que se están presionando. He aquí el código.

/* Example Software Sketch

IR Remote Kit Test

Unzip folder into Libraries. RENAME folder IRremote

[email protected] */

/*-----( Import needed libraries )-----*/

#include "IRremote.h"

/*-----( Declare Constants )-----*/

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 12

/*-----( Declare objects )-----*/

IRrecv irrecv(receiver); // create instance of 'irrecv'

decode_results results; // create instance of 'decode_results'

/*-----( Declare Variables )-----*/

void setup() /*----( SETUP: RUNS ONCE )----*/

Serial.begin(9600);
Serial.println("IR Receiver Raw Data + Button Decode Test");

irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/

if (irrecv.decode(&results)) // have we received an IR signal?

// Serial.println(results.value, HEX); UN Comment to see raw values

translateIR();

irrecv.resume(); // receive the next value

}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/

void translateIR() // takes action based on IR code received

// describing Car MP3 IR codes

switch(results.value)

{
case 0xFFA25D:

Serial.println(" CH- ");

break;

case 0xFF629D:

Serial.println(" CH ");

break;

case 0xFFE21D:

Serial.println(" CH+ ");

break;

case 0xFF22DD:

Serial.println(" PREV ");

break;

case 0xFF02FD:

Serial.println(" NEXT ");

break;

case 0xFFC23D:

Serial.println(" PLAY/PAUSE ");

break;

case 0xFFE01F:

Serial.println(" VOL- ");

break;

case 0xFFA857:

Serial.println(" VOL+ ");

break;
case 0xFF906F:

Serial.println(" EQ ");

break;

case 0xFF6897:

Serial.println(" 0 ");

break;

case 0xFF9867:

Serial.println(" 100+ ");

break;

case 0xFFB04F:

Serial.println(" 200+ ");

break;

case 0xFF30CF:

Serial.println(" 1 ");

break;

case 0xFF18E7:

Serial.println(" 2 ");

break;

case 0xFF7A85:

Serial.println(" 3 ");

break;

case 0xFF10EF:

Serial.println(" 4 ");
break;

case 0xFF38C7:

Serial.println(" 5 ");

break;

case 0xFF5AA5:

Serial.println(" 6 ");

break;

case 0xFF42BD:

Serial.println(" 7 ");

break;

case 0xFF4AB5:

Serial.println(" 8 ");

break;

case 0xFF52AD:

Serial.println(" 9 ");

break;

default:

Serial.println(" other button ");

delay(500);

} //END translateIR

Otra implementación del mismo código, convierte la tecla presionada en un número


determinado, aquí el código:
/*

IR Remote Kit Test: Returns numeric value for button pressed

*/

/*-----( Import needed libraries )-----*/

#include "IRremote.h"

/*-----( Declare Constants )-----*/

#define REPEAT_DELAY 500 // Delay before checking for another button / repeat

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 12

// NOTE: Other pins can be used, except pin 3 and 13

/*-----( Declare objects )-----*/

IRrecv irrecv(receiver); // create instance of 'irrecv'

decode_results results; // create instance of 'decode_results'

/*-----( Declare Variables )-----*/

int ButtonValue; // 0..9,100,200, top 9 buttons encoded 10..18, -1 Bad Code

void setup() /*----( SETUP: RUNS ONCE )----*/

Serial.begin(9600);

Serial.println("YourDuino.com IR Infrared Remote Control Kit V2");

Serial.println("IR Receiver Raw Data + Button Decode Test");

irrecv.enableIRIn(); // Start the receiver


}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/

if (irrecv.decode(&results)) // have we received an IR signal?

// Serial.println(results.value, HEX); // UN Comment to see raw values

ButtonValue = translateIR();

Serial.println(ButtonValue, DEC);

delay(REPEAT_DELAY); // Adjust for repeat / lockout time

irrecv.resume(); // receive the next value

}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/

int translateIR() // returns value of "Car MP3 remote IR code received

switch(results.value)

case 0xFFA25D:

return 10; // CH-

break;
case 0xFF629D:

return 11; // CH

break;

case 0xFFE21D:

return 12; // CH+

break;

case 0xFF22DD:

return 13; // PREV

break;

case 0xFF02FD:

return 14; // NEXT

break;

case 0xFFC23D:

return 15; // PLAY/PAUSE

break;

case 0xFFE01F:

return 16; // VOL-

break;
case 0xFFA857:

return 17; // VOL+

break;

case 0xFF906F:

return 18; // EQ

break;

case 0xFF6897:

return 0; // ZERO

break;

case 0xFF9867:

return 100; // 100+

break;

case 0xFFB04F:

return 200; // 200+

break;

case 0xFF30CF:

return 1; // 1 etc.. to 9

break;
case 0xFF18E7:

return 2;

break;

case 0xFF7A85:

return 3;

break;

case 0xFF10EF:

return 4;

break;

case 0xFF38C7:

return 5;

break;

case 0xFF5AA5:

return 6;

break;

case 0xFF42BD:

return 7;

break;
case 0xFF4AB5:

return 8;

break;

case 0xFF52AD:

return 9; // 9

break;

case 0xFFFFFFFF:

return -2; // REPEAT: Button Held down longer than

break;

default:

return -1; // Other Button / Bad Code

} //END case

} //END translateIR

El ejemplo producido puede modificarse, pero esta vez manejando un led conectado al pin
13, que parpadeara n veces (de acuerdo al número devuelto por el código de la tecla).

/*
IR Remote Kit Test: Blinks Pin 13 when numeric buttons pressed
http://arduino-direct.com/sunshop/index.php?l=product_detail&p=153
based on code by Ken Shirriff - http://arcfn.com
[email protected] */

/*-----( Import needed libraries )-----*/


#include "IRremote.h"
#include "IRremoteInt.h"

/*-----( Declare Constants )-----*/


#define REPEAT_DELAY 500 // Delay before checking for another button / repeat
int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 11
// NOTE: Other pins can be used, except pin 3 and 13

/*-----( Declare objects )-----*/


IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'

/*-----( Declare Variables )-----*/


int ButtonValue; // 0..9,100,200, top 9 buttons encoded 10..18, -1 Bad Code

void setup() /*----( SETUP: RUNS ONCE )----*/


{
Serial.begin(9600);
Serial.println("IR Receiver Raw Data + Button Decode Test");
irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/


{
if (irrecv.decode(&results)) // have we received an IR signal?

{
// Serial.println(results.value, HEX); // UN Comment to see raw values
ButtonValue = translateIR();
Serial.println(ButtonValue, DEC);
BlinkNum(ButtonValue); // Blink Pin 13 LED
delay(REPEAT_DELAY); // Adjust for repeat / lockout time
irrecv.resume(); // receive the next value
}
}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/


int translateIR() // returns value of "Car MP3 remote IR code received
{

switch(results.value)

case 0xFFA25D:
return 10; // CH-
break;
case 0xFF629D:
return 11; // CH
break;
case 0xFFE21D:
return 12; // CH+
break;
case 0xFF22DD:
return 13; // PREV
break;
case 0xFF02FD:
return 14; // NEXT
break;
case 0xFFC23D:
return 15; // PLAY/PAUSE
break;
case 0xFFE01F:
return 16; // VOL-
break;
case 0xFFA857:
return 17; // VOL+
break;
case 0xFF906F:
return 18; // EQ
break;

case 0xFF6897:
return 0; // ZERO
break;
case 0xFF9867:
return 100; // 100+
break;
case 0xFFB04F:
return 200; // 200+
break;
case 0xFF30CF:
return 1; // 1 etc.. to 9
break;
case 0xFF18E7:
return 2;
break;
case 0xFF7A85:
return 3;
break;
case 0xFF10EF:
return 4;
break;
case 0xFF38C7:
return 5;
break;
case 0xFF5AA5:
return 6;
break;
case 0xFF42BD:
return 7;
break;
case 0xFF4AB5:
return 8;
break;
case 0xFF52AD:
return 9; // 9
break;
case 0xFFFFFFFF:
return -2; // REPEAT: Button Held down longer than
break;
default:
return -1; // Other Button / Bad Code

} //END case

} //END translateIR

void BlinkNum(int NumBlinks)


{
int n;

for (n = 0; n < NumBlinks; n++)


{
digitalWrite(13, HIGH);
delay(50);
digitalWrite(13,LOW);
delay(250);
}
} // END BlinkNum

Finalmente un ultimo ejemplo de uso de las teclas del control remoto:

/*

Brick Starter Set IR Remote Kit Test

*/

/*-----( Import needed libraries )-----*/

#include "IRremote.h"

/*-----( Declare Constants )-----*/

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 11

/*-----( Declare objects )-----*/

IRrecv irrecv(receiver); // create instance of 'irrecv'

decode_results results; // create instance of 'decode_results'

/*-----( Declare Variables )-----*/

void setup() /*----( SETUP: RUNS ONCE )----*/


{

Serial.begin(9600);

Serial.println("IR Receiver Button Decode Test");

irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/

void loop() /*----( LOOP: RUNS CONSTANTLY )----*/

if (irrecv.decode(&results)) // have we received an IR signal?

// Serial.println(results.value, HEX); UN Comment to see raw values

translateIR();

irrecv.resume(); // receive the next value

}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/

void translateIR() // takes action based on IR code received

// describing KEYES Remote IR codes


{

switch(results.value)

case 0xFF629D: Serial.println(" FORWARD"); break;

case 0xFF22DD: Serial.println(" LEFT"); break;

case 0xFF02FD: Serial.println(" -OK-"); break;

case 0xFFC23D: Serial.println(" RIGHT"); break;

case 0xFFA857: Serial.println(" REVERSE"); break;

case 0xFF6897: Serial.println(" 1"); break;

case 0xFF9867: Serial.println(" 2"); break;

case 0xFFB04F: Serial.println(" 3"); break;

case 0xFF30CF: Serial.println(" 4"); break;

case 0xFF18E7: Serial.println(" 5"); break;

case 0xFF7A85: Serial.println(" 6"); break;

case 0xFF10EF: Serial.println(" 7"); break;

case 0xFF38C7: Serial.println(" 8"); break;

case 0xFF5AA5: Serial.println(" 9"); break;

case 0xFF42BD: Serial.println(" *"); break;

case 0xFF4AB5: Serial.println(" 0"); break;

case 0xFF52AD: Serial.println(" #"); break;

case 0xFFFFFFFF: Serial.println(" REPEAT");break;

default:
Serial.println(" other button ");

}// End Case

delay(500); // Do not get immediate repeat

} //END translateIR

II. I2C

GY-80 10 DOF IMU MODULE WITH L3G4200D ADXL345 HMC5883L BMP085

 Chips included on the board


o 1 L3G4200D: girocompás de 3 ejes
o 1 ADXL345: acelerómetro de 3 ejes 
o 1BMP085: sensor de la presión atmosférica
o 1 compás digital del eje de HMC5883L 3 
o LLC a bordo (trabajos en 3 y 5 voltios).
 Built in regulator and logic converter to support  3.3V/5.0V
microcontrollers
 I2C Digital Interface
 Module Size: 25.8 x 16.8mm mounting hole 3mm
 Immersion Gold PCB process
 Standard 2.54mm pin interface, plug straight into breadboards
 Both Straight and Right-Angle headers included

Figuras del IMU GY-80


Acelerometro

Los acelerómetros son dispositivos electromecánicos que detectan las


fuerzas de aceleración, ya sea estática o dinámica. Las fuerzas estáticas
incluyen la gravedad, mientras que las fuerzas dinámicas pueden incluir
vibraciones y movimiento.
Los acelerómetros pueden medir la aceleración en uno, dos o tres ejes.  Los
de tres ejes son más comunes  conforme los costos de producción de los
mismos baja.
 Generalmente, los acelerómetros contienen placas capacitivas
internamente. Algunos de estos son fijos, mientras que otros están unidos a
resortes minúsculos que se mueven internamente conforme las  fuerzas de
aceleración actúan sobre el sensor. Como estas placas se mueven en relación
el uno al otro, la capacitancia entre ellos cambia. A partir de estos cambios
en la capacitancia, la aceleración se puede determinar.
Sistema microelectromecánico para la aceleración en 1 eje.

 
Otros acelerómetros se pueden centrar en torno materiales piezoeléctricos.
Generan pequeña carga eléctrica de salida en la estructura cristalinas cuando
se coloca bajo tensión mecánica (por ejemplo aceleración).

Sistema con tensión mecánica.

 
Para la mayoría de los acelerómetros , las conexiones básicas que se
requieren para la operación son el poder y las líneas de comunicación. Como
siempre, leer la hoja de datos para una correcta conexión.
Out of the box, the ADXL345 is an I2C 3-axis accelerometer with user
selectable sensitivity and 10-13 bit resolution (depending on sensitivity).
And… It is pretty decent all around, but were not really going to spend much
time talking about boring stuff today. Today, we are talking about getting the
special features of the ADXL345 up and running. (tap, double tap, free fall,
activity and inactivity)

These special detection features have the ability to trigger 2 interrupt pins,
making the pin go HIGH the moment one of the events is sensed. You can
select what events to watch for, and what interupt pin to trigger when it is
sensed (I had issues with INT2, it would not reset). You can take these
interrupt pins and connect them to your Arduino to trigger an interrupt. An
interrupt, when sensed on the Arduino, pauses the system instantly, even if it
is in the middle of something, and responds to that interrupt how ever you
have it setup before returning to the normal code. Like a police officer
coming down the street with its lights on… Even if you have a green light, you
stop and let them go. But using interrupts is a little beyond the scope of this
article, so we are going to just keep checking for these actions in code and
respond to them when we see them.

Circuito

A4 conectado a SDA y A5 conectado SCL


Código de funcionamiento

#include <Wire.h>

#include <ADXL345.h>

ADXL345 adxl; //variable adxl is an instance of the ADXL345 library

void setup(){

Serial.begin(9600);

Serial.println("Inicio de medicion");

adxl.powerOn();

//set activity/ inactivity thresholds (0-255)

adxl.setActivityThreshold(75); //62.5mg per increment

adxl.setInactivityThreshold(75); //62.5mg per increment

adxl.setTimeInactivity(10); // how many seconds of no activity is inactive?

//look of activity movement on this axes - 1 == on; 0 == off

adxl.setActivityX(1);

adxl.setActivityY(1);

adxl.setActivityZ(1);

//look of inactivity movement on this axes - 1 == on; 0 == off

adxl.setInactivityX(1);
adxl.setInactivityY(1);

adxl.setInactivityZ(1);

//look of tap movement on this axes - 1 == on; 0 == off

adxl.setTapDetectionOnX(0);

adxl.setTapDetectionOnY(0);

adxl.setTapDetectionOnZ(1);

//set values for what is a tap, and what is a double tap (0-255)

adxl.setTapThreshold(50); //62.5mg per increment

adxl.setTapDuration(15); //625μs per increment

adxl.setDoubleTapLatency(80); //1.25ms per increment

adxl.setDoubleTapWindow(200); //1.25ms per increment

//set values for what is considered freefall (0-255)

adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per


increment

adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment

//setting all interupts to take place on int pin 1

//I had issues with int pin 2, was unable to reset it

adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT,
ADXL345_INT1_PIN );
adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT,
ADXL345_INT1_PIN );

adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT,
ADXL345_INT1_PIN );

adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT,
ADXL345_INT1_PIN );

adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT,
ADXL345_INT1_PIN );

//register interupt actions - 1 == on; 0 == off

adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1);

adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1);

adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1);

adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1);

adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1);

void loop(){

//Boring accelerometer stuff

int x,y,z;

adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them
in variables x,y,z
// Output x,y,z values - Commented out

// Serial.print(x);

// Serial.print(y);

// Serial.println(z);

//Fun Stuff!

//read interrupts source and look for triggerd actions

//getInterruptSource clears all triggered actions after returning value

//so do not call again until you need to recheck for triggered actions

byte interrupts = adxl.getInterruptSource();

// freefall

if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){

Serial.println("freefall");

//add code here to do when freefall is sensed

//inactivity

if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){

//Serial.println("inactivo");
Serial.println("Que aburrido, sin hacer nada..");

//add code here to do when inactivity is sensed

//activity

if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){

//Serial.println("actividad");

Serial.println("Me gusta trabajar y hacer algo");

//add code here to do when activity is sensed

//double tap

if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){

//Serial.println("doble golpe");

Serial.println("Ya entendi, me voy a portar bien..");

//add code here to do when a 2X tap is sensed

//tap

if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){

//Serial.println("golpe");

Serial.println("Auu! me dolio!!");
//add code here to do when a tap is sensed

Giroscopio

El L3G4200D es un sensor de velocidad angular de 3 ejes, también conocido


como giroscopio / giroscopio con una escala seleccionable por el usuario de
250, 500 o 2.000 ° / seg.

Los giroscopios miden la velocidad angular, la forma casi algo está girando
sobre el eje. Si se está tratando de controlar la orientación de un objeto en
movimiento en el acelerómetro junio no le dan suficiente información para
saber exactamente cómo se orienta. A diferencia de los acelerómetros
giroscopios no se ven afectadas por la gravedad, por lo que hacen un gran
complemento a unos de otros. Por lo general, usted verá velocidad angular
representado en unidades de revoluciones por minuto (RPM), o grados por
segundo (° / s). Los tres ejes de giro o son referenciados como x, y, z,

Codigo:

#include <Wire.h>

#define CTRL_REG1 0x20

#define CTRL_REG2 0x21

#define CTRL_REG3 0x22

#define CTRL_REG4 0x23

#define CTRL_REG5 0x24

int L3G4200D_Address = 105; //I2C address of the L3G4200D


int x;

int y;

int z;

void setup(){

Wire.begin();

Serial.begin(9600);

Serial.println("iniciando L3G4200D");

setupL3G4200D(2000); // Configure L3G4200 - 250, 500 or 2000 deg/sec

delay(1500); //wait for the sensor to be ready

void loop(){

getGyroValues(); // This will update x, y, and z with new values

Serial.print("X:");

Serial.print(x);
Serial.print(" Y:");

Serial.print(y);

Serial.print(" Z:");

Serial.println(z);

delay(100); //Just here to slow down the serial to make it more readable

void getGyroValues(){

byte xMSB = readRegister(L3G4200D_Address, 0x29);

byte xLSB = readRegister(L3G4200D_Address, 0x28);

x = ((xMSB << 8) | xLSB);

byte yMSB = readRegister(L3G4200D_Address, 0x2B);

byte yLSB = readRegister(L3G4200D_Address, 0x2A);

y = ((yMSB << 8) | yLSB);

byte zMSB = readRegister(L3G4200D_Address, 0x2D);

byte zLSB = readRegister(L3G4200D_Address, 0x2C);

z = ((zMSB << 8) | zLSB);


}

int setupL3G4200D(int scale){

// Enable x, y, z and turn off power down:

writeRegister(L3G4200D_Address, CTRL_REG1, 0b00001111);

// If you'd like to adjust/use the HPF, you can edit the line below to
configure CTRL_REG2:

writeRegister(L3G4200D_Address, CTRL_REG2, 0b00000000);

// Configure CTRL_REG3 to generate data ready interrupt on INT2

// No interrupts used on INT1, if you'd like to configure INT1

// or INT2 otherwise, consult the datasheet:

writeRegister(L3G4200D_Address, CTRL_REG3, 0b00001000);

// CTRL_REG4 controls the full-scale range, among other things:

if(scale == 250){

writeRegister(L3G4200D_Address, CTRL_REG4, 0b00000000);

}else if(scale == 500){

writeRegister(L3G4200D_Address, CTRL_REG4, 0b00010000);


}else{

writeRegister(L3G4200D_Address, CTRL_REG4, 0b00110000);

// CTRL_REG5 controls high-pass filtering of outputs, use it

// if you'd like:

writeRegister(L3G4200D_Address, CTRL_REG5, 0b00000000);

void writeRegister(int deviceAddress, byte address, byte val) {

Wire.beginTransmission(deviceAddress); // start transmission to device

Wire.write(address); // send register address

Wire.write(val); // send value to write

Wire.endTransmission(); // end transmission

int readRegister(int deviceAddress, byte address){

int v;

Wire.beginTransmission(deviceAddress);

Wire.write(address); // register to read

Wire.endTransmission();
Wire.requestFrom(deviceAddress, 1); // read a byte

while(!Wire.available()) {

// waiting

v = Wire.read();

return v;

Compass

Un compás es un instrumento navegacional que muestra direcciones en un


marco de referencia que es relativamente estacionaria con respecto a la
superficie de la Tierra. El marco de referencia define las cuatro direcciones
cardinales (o los puntos) - del norte, al sur, al este y al oeste. Las direcciones
intermedias también son definidas. Por lo general, un diagrama llamado rosa
de los vientos, muestra las direcciones (con sus nombres generalmente
abreviado a las iniciales), está marcado en la brújula. Cuando la brújula está
en uso, la rosa se alinea con las direcciones reales en el marco de referencia,
por lo que, por ejemplo, la marca "N" en la rosa señala realmente al norte.
Con frecuencia, además de la rosa o, a veces en lugar de ello, las marcas de
ángulo en grados se muestran en la brújula. Norte corresponde a los cero
grados, y los ángulos aumentan ampliar las agujas del reloj, por lo que este es
90 grados, el sur es 180, y el oeste es 270 Estos números permiten que el
compás muestre los acimuts o los transportes, que son comúnmente figuran
en esta notación.

Codigo
#include <Wire.h>

#include <HMC5883L.h>

HMC5883L compass;

void setup(){

Serial.begin(9600);

Wire.begin();

compass = HMC5883L(); //new instance of HMC5883L library

setupHMC5883L(); //setup the HMC5883L

// Our main program loop.

void loop(){

float heading = getHeading();

Serial.println(heading);

delay(100); //only here to slow down the serial print

}
void setupHMC5883L(){

//Setup the HMC5883L, and check for errors

int error;

error = compass.SetScale(1.3); //Set the scale of the compass.

if(error != 0) Serial.println(compass.GetErrorText(error)); //check if there is


an error, and print if so

error = compass.SetMeasurementMode(Measurement_Continuous); // Set


the measurement mode to Continuous

if(error != 0) Serial.println(compass.GetErrorText(error)); //check if there is


an error, and print if so

float getHeading(){

//Get the reading from the HMC5883L and calculate the heading

MagnetometerScaled scaled = compass.ReadScaledAxis(); //scaled values


from compass.

float heading = atan2(scaled.YAxis, scaled.XAxis);

// Correct for when signs are reversed.

if(heading < 0) heading += 2*PI;

if(heading > 2*PI) heading -= 2*PI;


return heading * RAD_TO_DEG; //radians to degrees

You might also like