Ecco lo Sketch, per chi conosce questo linguaggio è abbastanza semplice.
Partiamo dal presupposto che con il pilot.. non debbo attraversare l'Atlantico quindi una cosa molto semplice, tra l'altro parliamo di una scheda Arduino uno da 15 euro. Attualmente il problema maggiore è durante la navigazione con angolo di rotta intorno a 0 gradi.
#include <LiquidCrystal.h>
#include <Wire.h> //i2c library for the Digital Compass
LiquidCrystal lcd( 12, 11, 7, 8, 9, 10 );
const int hmc5883Address = 0x1E; //0011110b, I2C 7bit address for compass
const byte hmc5883ModeRegister = 0x02;
const byte hmcContinuousMode = 0x00;
const byte hmcDataOutputXMSBAddress = 0x03;
int rotta=0;
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.clear(); //make sure screen is clear.
lcd.print("pepilene is Go");
delay(4000);
Wire.begin(); // Start the i2c communication
Wire.beginTransmission(hmc5883Address); //Begin communication with compass
Wire.write(hmc5883ModeRegister); //select the mode register
Wire.write(hmcContinuousMode); //continuous measurement mode
Wire.endTransmission();
pinMode(2, OUTPUT);//LED FUTURO RELAIS MOTORE A SINISTRA
pinMode(3, OUTPUT);//LED IN FUTURO RELAIS MOTORE A DRITTA
pinMode(4, OUTPUT);//LED PILOTA ON /OFF
pinMode(1, INPUT);//INTERRUTTORE ON OFF PILOTA
pinMode(5, INPUT);//PULSANTE MEMORIZZA ROTTA NUOVA DALL'ANGOLO ATTUALE
pinMode(13, INPUT);//PULSANTE + DIECI GRADI A DRITTA
pinMode(6, INPUT);//PULSANTE - DIECI GRADI A SINISTRA
}
void loop()
{
int x,y,z;
Wire.beginTransmission(hmc5883Address);
Wire.write(hmcDataOutputXMSBAddress); //Select register 3, X MSB register
Wire.endTransmission();
Wire.requestFrom(hmc5883Address,6);
if(6<=Wire.available())
{
x = Wire.read()<<8; //X msb
x |= Wire.read(); //X lsb
z = Wire.read()<<8; //Z msb
z |= Wire.read(); //Z lsb
y = Wire.read()<<8; //Y msb
y |= Wire.read(); //Y lsb
}
int angle = atan2(-y,x)/M_PI*180; // setta angolo SEMPRE POSITIVO
if (angle < 0) // 360 gradi
{
angle = angle +360; // 360 gradi
}
//IL DISPLAY VISUALIZZA STATO ON OPPURE OFF E POI ROTTA E ANGOLO , NON PIù X,Y,Z CHE MI PARE SERVANO A POCO
lcd.clear(); //make sure screen is clear again.
lcd.setCursor(0,0);
if (digitalRead(1) == HIGH) {lcd.print("ON:");} else {lcd.print("OFF:");}
lcd.setCursor(4,0);
lcd.print("rotta:");
lcd.setCursor(0,1);
lcd.print("gradi:");
lcd.setCursor(11,0);
lcd.print(rotta);
lcd.setCursor(11,1);
lcd.print(angle);
delay(500);
//PRIMA VA IMPOSTATA LA ROTA PREMENDO IL BOTTONE 5
if (digitalRead(5) == HIGH) {rotta = angle;}
//POI VA AVVIATO IL PILOTA CON L'INTERRUTTORE 1
if (digitalRead(1) == HIGH) {digitalWrite(4, HIGH);
//PILOTA ADESSO AVVIATO FUNZIONANO I TASTI PER CAMBIARE ROTTA
:smiley30:if (digitalRead(6) == HIGH) {rotta = rotta + 10;}
:smiley30:if (digitalRead(13) == HIGH) {rotta = rotta - 10;}
if (rotta < angle){digitalWrite(3, HIGH); delay(100);digitalWrite(3, LOW); delay(100);}
else {digitalWrite(2, HIGH);delay(100);digitalWrite(2, LOW);delay(100);}
}
else
{digitalWrite(3, LOW);}
}