Hola.
Después de dias de búsqueda, al final he encontrado un sketch que me reconoce el sensor con el cuál estoy dando palos de ciego, el HMC 6352. Lo he compilado y no me ha dado error. Lo he introducido en el arduino y funciona, ohhh que emoción!! pues veo la lectura en grados en el "Monitor Serial" que aparece en la pantalla de mi ordenador mi ordenador y responde a los movimentos que le doy.
Ahora viene lo malo, le he añadido dos leds al sketch (para que se iluminen en rumbos a babor y estribor) y también me ha permitido la compilación. Pero cuando le he intentado escribir lo que queria hacer con los dos leds, (que se iluminara uno u otro segun los grados de lectura del sensor) entonces me ha dado un mesaje de error. Aquí he puesto en rojo las lineas que he añadido al final del sketch y el mensaje de error que aparece:
Gracias
Hola.
¿Has probado a sustituir los or de las comparaciones por el or estándar C ||?
if (headingDegrees > 0 || headingDegrees < 180)
Lo curioso es que no pensé que el compilador lo aceptara, pero en el mío no me da error (tal vez porque es una versión más moderna y tal vez lleve algún define que haga la sustitución.
Dicho sea de paso, creo que más que un or las comparaciones deberían llevar un and (&&).
Solo para que lo veas con mayor detenimiento pero ya esta bien explicado.
Examples
if (a >= 10 && a <= 20){} // true if a is between 10 and 20
Muchas gracias. Hoy lo probaré y comentaré el resultado.
Hola. Acabo de probar poniendo || y también && y me sigue dando el mismo error que aparece en la imagen que puse antes. Tambien he probado borrando "headingDegrees" y ponendo solo degrees en minúscula (entonces el color de esta palabra cambia de negro a sepia), pero al intentar compilar sigue con el mismo error.
Lo que intento es que esta lectura:
Serial.println(" degrees");
(la que precede a la orden final -delay (500) } -de las lineas que si estan bien compiladas) sea utilizada en las ordenes siguientes para encender un led verde (giro a estribor) si la lectura Serial.println(" degrees"); está comprendida entre 0 y 180. Por el contrario si la lectura es entre 180 y 360 se encienda un led rojo (giro a babor).
Las ordenes que he puesto estan copiadas de un sketch público aunque el sensor no era el mismo.
Gracias.
Bueno recomienza posteando tu código usando el icono correspondiente.
Entonces podemos probarlo y te diremos.
Que versión ide usas?
Gracias por vuestra paciencia.
La versión de ide es 1.0.6
El código que he modificado
#include <Wire.h>
int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin1 = 13;
//añado estos dos leds para rojo y verde
int ledPin2 = 10;
int ledPin3 = 9;
boolean ledState = false;
byte headingData[2];
int i, headingValue;
void setup()
{
// Shift the device's documented slave address (0x42) 1 bit right
// This compensates for how the TWI library only wants the
// 7 most significant bits (with the high bit padded with 0)
slaveAddress = HMC6352Address >> 1; // This results in 0x21 as the address to pass to TWI
Serial.begin(9600);
pinMode(ledPin1, OUTPUT); // Set the LED pin as output
//inicialitzar pines añadidos como salida
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
Wire.begin();
}
void loop()
{
// Flash the LED on pin 13 just to show that something is happening
// Also serves as an indication that we're not "stuck" waiting for TWI data
ledState = !ledState;
if (ledState) {
digitalWrite(ledPin1,HIGH);
}
else
{
digitalWrite(ledPin1,LOW);
}
// Send a "A" command to the HMC6352
// This requests the current heading data
Wire.beginTransmission(slaveAddress);
Wire.write("A"); // The "Get Data" command
Wire.endTransmission();
delay(10); // The HMC6352 needs at least a 70us (microsecond) delay
// after this command. Using 10ms just makes it safe
// Read the 2 heading bytes, MSB first
// The resulting 16bit word is the compass heading in 10th's of a degree
// For example: a heading of 1345 would be 134.5 degrees
Wire.requestFrom(slaveAddress, 2); // Request the 2 byte heading (MSB comes first)
i = 0;
while(Wire.available() && i < 2)
{
headingData[i] = Wire.read();
i++;
}
headingValue = headingData[0]*256 + headingData[1]; // Put the MSB and LSB together
Serial.print("Current heading: ");
Serial.print(int (headingValue / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (headingValue % 10)); // The fractional part of the heading
Serial.println(" degrees");
delay(500);
}
if(headingDegrees > 0 or headingDegrees < 180)
{
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 180 or headingDegrees < 360)
{
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
Aquí pongo lo que he añadido en color rojo, porque en la ventana del código no me dejaba:
En la introducción:
int ledPin1 = 13;
//añado estos dos leds para rojo y verde
int ledPin2 = 10;
int ledPin3 = 9;
En el setup:
pinMode(ledPin1, OUTPUT); // Set the LED pin as output
//inicialitzar pines añadidos como salida
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
en el void:
digitalWrite(ledPin1,HIGH);
}
else
{
digitalWrite(ledPin1,LOW);
(y las últimas lineas del void, que son las que dan el error):
if(headingDegrees > 0 or headingDegrees < 180)
{
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 180 or headingDegrees < 360)
{
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
Acá esta tu error
headingValue = headingData[0]*256 + headingData[1]; // Put the MSB and LSB together
Serial.print("Current heading: ");
Serial.print(int (headingValue / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (headingValue % 10)); // The fractional part of the heading
Serial.println(" degrees");
delay(500);
} /// <=== ERROR ESTE } no tiene { buscalo
Otro error
error: 'headingDegrees' was not declared in this scope
Declaralo como gloabl supongo.
El programa ahora compila.
adjunto sketch a continuación
sensor_HMC6532.ino (2.33 KB)
Gracias. He corrido a cargarlo al Arduino. Me sigue leyendo los grados (lo veo en el monitor del PC) muevo el sensor y escribe diferentes grados. Pero los dos leds 9 y 10 Ohhhh desilusión, no se iluminan.
Trabaja un poco, te resolví el 99% del problema jajaja
Bueno ahora mi fijo.
Te animas a capturar una pantalla, con lo que ves en tu serial monitor y mostrarla acá?
Será de gran ayuda.
subelo usando algun sitio de los que almacen imagenes como imageshack, tinypic.com etc
Pués pensé que lo mejor era un video. Y ya lo estaba poniendo cuando he leido tu respuesta. Lo que pasa es que no entendí lo de "declaralo como global". No es que no quiera trabajar, jejeje, llevo dias probando. Desmonté un disco duro externo, para aprovechar su led bicolor de tres patillas (se ve en el primer video al lado de la placa, junto a unos leds de un viejo radiocasete) no era por tacañeria que no fuí a comprarlos, estoy de baja por una operación y aprovecho para aprender algo de electrónica (no tengo casí ni idea) Horas de pruebas, de cambiar resistencias, calcular valores, colores, y descubrí casi por casualidad que el p. led era de ánodo común y dos cátodos. Renuncié al bicolor y al final me funcionó la primera "lección del Arduino", pero con dos leds, para ir probando:
primer video, los dos leds funcionan:
segundo video el sensor funciona (de hace una hora):
Gracias por tu paciencia. Estas invitado a una vueltecita en mi velerito.
bueno, primero me alegro que estes bien, y que uses este período de recuperación para aprender. Estarás motivado. Me da gusto.
Segundo, los enlaces ponlos por favor usando esto

como verás tanto lo digo que con el tiempo no se va a salvar nadie y todos lo haremos correctamente.
Mira como quedan.
segundo video el sensor funciona (de hace una hora):
Gracias por tu paciencia. Estas invitado a una vueltecita en mi velerito.
Jaja, dime donde vives y me pego una vuelta. Ahora me sales con Canarias y voy muerto.
Bueno jordi, yo subí el sketch definiendo a headingdegree como entero (int) y veo que tu lo defines como float.
Si defines como float, las comparaciones deben hacer asi
if(headingDegrees > 0.0 && headingDegrees < 180.0) {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 180.0 && headingDegrees < 360.0){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
Es sutil el cambio pero es lo que garantiza que lo haga bien.
Hola de nuevo. No se que he definido como float, pero ahora he sustituido estas nuevas lineas (solo veo la diferencia del puntito del decimal) y siguen sin iluminarse. Buscando ejemplos, "trabajando" para poder aportar algo de mi parte, he pensado que quizás seria que no tienen tiempo de iluminarse. He añadido mas valor al delay existente (y ahora muestra la lectura de grados más lenta. También he añadido un nuevo delay en las ordenes finales, pero siguen sin encenderse.
Bueno te puse el if de ese modo porque si no definiste como float a distance no veo la manera de que tu monitor serie arroje valores con decimales.
Estas usando el código que yo dejé para ser descargado?
Voy a simular porque ahora no veo el error.
POR DIOS!!!!!!!!!!! Ahora veo que tu código separa parte entera y parte fraccionaria.
Disculpa.
Veo que ocurre. Esta bien como originalmente subí el código.
Ahora veo que ocurre y porque no funciona.
Tal vez el problema sea que arrastran los valores multiplicados por algo y se salen de rango de comparación.
Bueno acá esta,
Serial.print(int (headingValue / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (headingValue % 10)); // The fractional part of the heading
Tus valores estan multiplicados por 10. En lugar de 90 grados son 900 y en lugar de 180 son 1800.
Asi que ajustemos las cosas.
La solucion es esta
if(headingDegrees > 0 && headingDegrees < 1800) {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 1800 && headingDegrees < 3600){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
sensor_HMC6532.ino (2.33 KB)
Hola.
Espero no hay prisa.
Tengo el velero en Torredembarra (Tarragona). Cuando esté de alta de la operación ya te invitaré de nuevo.
Vuelvo a poner el sketch (lo copié y pegué de otro hilo del Arduino, en el que la libreria Libcompass no funcionaba, modificando numero y cantidad de leds) añadí al final con lo que tu me corrijiste y a mi me compila pero no se iluminan. En principio debia cargar dos librerias wire.h y compass.h, pero con el código que copié ya no parece que sean necesarias. El código lo copié de aquí en concreto de la entrada # (nik Tablet).
#include <Wire.h>
int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin1 = 13;
//añado estos dos leds para rojo y verde
int ledPin2 = 10;
int ledPin3 = 9;
boolean ledState = false;
byte headingData[2];
int i, headingValue;
int headingDegrees;
void setup() {
// Shift the device's documented slave address (0x42) 1 bit right
// This compensates for how the TWI library only wants the
// 7 most significant bits (with the high bit padded with 0)
slaveAddress = HMC6352Address >> 1; // This results in 0x21 as the address to pass to TWI
Serial.begin(9600);
pinMode(ledPin1, OUTPUT); // Set the LED pin as output
//inicialitzar pines añadidos como salida
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
Wire.begin();
}
void loop() {
// Flash the LED on pin 13 just to show that something is happening
// Also serves as an indication that we're not "stuck" waiting for TWI data
ledState = !ledState;
if (ledState) {
digitalWrite(ledPin1,HIGH);
}
else
digitalWrite(ledPin1,LOW);
// Send a "A" command to the HMC6352
// This requests the current heading data
Wire.beginTransmission(slaveAddress);
Wire.write("A"); // The "Get Data" command
Wire.endTransmission();
delay(10); // The HMC6352 needs at least a 70us (microsecond) delay
// after this command. Using 10ms just makes it safe
// Read the 2 heading bytes, MSB first
// The resulting 16bit word is the compass heading in 10th's of a degree
// For example: a heading of 1345 would be 134.5 degrees
Wire.requestFrom(slaveAddress, 2); // Request the 2 byte heading (MSB comes first)
i = 0;
while(Wire.available() && i < 2) {
headingData[i] = Wire.read();
i++;
}
headingValue = headingData[0]*256 + headingData[1]; // Put the MSB and LSB together
Serial.print("Current heading: ");
Serial.print(int (headingValue / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (headingValue % 10)); // The fractional part of the heading
Serial.println(" degrees");
delay(500);
if(headingDegrees > 0.0 && headingDegrees < 180.0) {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 180.0 && headingDegrees < 360.0){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
}
Hola de nuevo.
Si prefieres podemos descansar el domingo. Porque sigue sin encenderse. Pensando en como lee "degrees" y veo los datos en monitor: serial.println(degrees") en cambio arriba se ha definido int headingDegrees; en mayúscula,....no sé por pensar algo.
esto es lo que debes usar.
if(headingDegrees > 0 && headingDegrees < 1800) {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 1800 && headingDegrees < 3600){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
Hola.
Voy haciendo pruebas. Lo último no funcionó. Pero a partir de mi imaginación, he dado un "palo de ciego" y casi que me "sonó la flauta por casualidad".
No entendia que si en el monitor serial aparecian los valores de lectura del sensor en grados, para encender el led se usara otra expresión,entonces..., pues he copiado la misma expresión, y después de unos errores de compilación por los parentesis, me ha compilado. Lo he probado y ohhhh??? solo se enciende el pin 10 (verde), y no se apaga nunca, decepción de nuevo. He abierto el monitor serial a ver si leia los grados, y sorpresa, lee pero escribe tres veces degrees, entre cada lectura. Aquí está lo que he modificado(donde antes ponia headingDegrees he puesto Serial.println(" degrees"):
if( Serial.println(" degrees") > 0 && Serial.println(" degrees") < 1800){
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if( Serial.println(" degrees") > 1800 && Serial.println(" degrees") < 3600){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);

Lo ultimo que posteas es una barbarídad. No sirve.
No puede no funcionar!!! Algo estas poniendo mal.
if(headingDegrees > 0 && headingDegrees < 1800) {
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if(headingDegrees > 1800 && headingDegrees < 3600){
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
Esto es lo que debería funcionar.