#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
// CONFIGURAZIONE
const byte P_LED = 9;
const byte P_SET = 6;
const byte P_RESET = 7;
const byte P_RELE_APRE = 10; //relè x sbloccare porta
const byte P_RELE_BLOCCA = 11; //rele x bloccare porta
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); //identifiacativo magnetometro
LiquidCrystal_I2C lcd(0x27, 16, 2); //display lcd x la visualizzazione dell orario
RTC_DS3231 rtc;
DateTime now;
char str[3];
int stato1 = 0;
int val = 0;
int val0 = 0;
// Buffer per la composizione delle stringhe da inviare via seriale
char outBuf[20];
int headingDegrees;
void setup() {
Wire.begin();
Serial.begin(9600);
lcd.backlight();
lcd.init();
//pulsanti set e reset
pinMode(P_SET, INPUT);
pinMode(P_RESET, INPUT);
pinMode(P_LED, OUTPUT);
pinMode(P_RELE_APRE, OUTPUT);
pinMode(P_RELE_BLOCCA, OUTPUT);
digitalWrite(P_RELE_APRE, HIGH);
digitalWrite(P_RELE_BLOCCA, HIGH);
if (!rtc.begin()) { //inizializzo l rtc
Serial.println("Couldn't find RTC");
while (true)
;
}
if (!rtc.lostPower()) {
//Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (!mag.begin()) //inizializzo il magnetometro
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while (1)
;
}
}
void loop() {
MostraOra();
//char outBussola[8];
bussola(); // richiama la routine che legge i gradi
if (Serial.available()) {
// Gestione comandi da VB
// Per ora leggo solo un singolo carattere per volta
char comando = Serial.read();
switch (comando) {
case 'A':
digitalWrite(P_RELE_APRE, LOW);
delay(100); // attivo o disattivo i rele in base al comando ricevuto da visual basic
digitalWrite(P_RELE_APRE, HIGH);
break;
case 'O':
digitalWrite(P_RELE_BLOCCA, LOW);
delay(100);
digitalWrite(P_RELE_BLOCCA, HIGH);
break;
default:
// Ignoro qualsiasi altro carattere
break;
}
}
int val = 0;
// Somma tre letture consecutive
for (int i = 0; i < 3; ++i)
val += analogRead(A0);
// Calcola la media
val = val / 3;
// Riporta il valore tra 0 e 100
val = map(val, 0, 1023, 0, 100); // visualbasic cosi regolerà il volume del player
sprintf(outBuf, "%d;%d", headingDegrees, val); // concatena i due valori separati da puntovirgola
Serial.println(outBuf); // invii alla seriale
delay(300); // aggiustare valore per migliori prestazioni tra 50 e 500
}
void bussola() { //evento bussola per indicare i gradi del magnetometro,
sensors_event_t event;
mag.getEvent(&event);
float heading = atan2(event.magnetic.y, event.magnetic.x);
float declinationAngle = 0.06;
heading += declinationAngle;
if (heading < 0) {
heading += 2 * PI;
}
if (heading > 2 * PI) {
heading -= 2 * PI;
}
headingDegrees = heading * 180 / M_PI;
}
void MostraOra() {
switch (stato1) {
case 0:
displayTime();
break;
case 1:
setHour();
break;
case 2:
setMinute();
break;
case 3:
setSecond();
break;
case 4:
setyear();
break;
case 5:
setmonth();
break;
case 6:
setday();
break;
}
}
unsigned long t1, dt1;
bool FIRST = true;
void displayTime() {
if (FIRST) {
lcd.clear();
t1 = millis();
FIRST = false;
}
dt1 = millis() - t1;
if (dt1 > 1000) {
now = rtc.now();
lcd.setCursor(4, 1);
sprintf(str, "%02d", now.hour());
lcd.print(str);
lcd.print(':');
sprintf(str, "%02d", now.minute());
lcd.print(str);
lcd.print(':');
sprintf(str, "%02d", now.second());
lcd.print(str);
lcd.setCursor(3, 0);
sprintf(str, "%02d", now.day());
lcd.print(str);
lcd.print('/');
sprintf(str, "%02d", now.month());
lcd.print(str);
lcd.print('/');
sprintf(str, "%02d", now.year());
lcd.print(str);
t1 = millis();
}
if (digitalRead(P_SET)) {
//imposta ora
stato1 = 1;
delay(300);
FIRST = true;
}
}
int seth = 0;
void setHour() {
if (FIRST) {
lcd.clear();
now = rtc.now();
seth = now.hour();
lcd.setCursor(0, 0);
lcd.print("Imposta ora");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", seth);
lcd.print(str);
if (digitalRead(P_RESET)) {
seth++;
if (seth >= 24) seth = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva ora scelta e passa ai minuti
rtc.adjust(DateTime(now.year(), now.month(), now.day(), seth, now.minute(), now.second()));
stato1 = 2;
FIRST = true;
delay(200);
}
}
int setm;
void setMinute() {
if (FIRST) {
lcd.clear();
now = rtc.now();
setm = now.minute();
lcd.setCursor(0, 0);
lcd.print("Imposta minuti");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", setm);
lcd.print(str);
if (digitalRead(P_RESET)) {
setm++;
if (setm >= 60) setm = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva min scelta e passa ai sec
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), setm, now.second()));
stato1 = 3;
delay(200);
FIRST = true;
}
}
int sets = 0;
void setSecond() {
if (FIRST) {
lcd.clear();
now = rtc.now();
sets = now.second();
lcd.setCursor(0, 0);
lcd.print("Imposta sec.");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", sets);
lcd.print(str);
if (digitalRead(P_RESET)) {
sets++;
if (sets >= 60) sets = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva sec scelta e passa ai minuti
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sets));
stato1 = 4;
delay(200);
FIRST = true;
}
}
int sety = 0;
void setyear() {
if (FIRST) {
lcd.clear();
now = rtc.now();
sety = now.year();
lcd.setCursor(0, 0);
lcd.print("Imposta anno");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", sety);
lcd.print(str);
if (digitalRead(P_RESET)) {
sety++;
if (sety >= 9999) sety = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva sec scelta e passa ai minuti
rtc.adjust(DateTime(sety, now.month(), now.day(), now.hour(), now.minute(), now.second()));
stato1 = 5;
delay(200);
FIRST = true;
}
}
int setmo = 0;
void setmonth() {
if (FIRST) {
lcd.clear();
now = rtc.now();
setmo = now.month();
lcd.setCursor(0, 0);
lcd.print("Imposta mese");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", setmo);
lcd.print(str);
if (digitalRead(P_RESET)) {
setmo++;
if (setmo >= 12) setmo = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva sec scelta e passa ai minuti
rtc.adjust(DateTime(now.year(), setmo, now.day(), now.hour(), now.minute(), now.second()));
stato1 = 6;
delay(200);
FIRST = true;
}
}
int setd = 0;
void setday() {
if (FIRST) {
lcd.clear();
now = rtc.now();
setd = now.day();
lcd.setCursor(0, 0);
lcd.print("Imposta giorno");
FIRST = false;
}
lcd.setCursor(0, 1);
sprintf(str, "%02d", setd);
lcd.print(str);
if (digitalRead(P_RESET)) {
setd++;
if (setd >= 32) setd = 0;
delay(200);
}
if (digitalRead(P_SET)) {
//salva sec scelta e passa ai minuti
rtc.adjust(DateTime(now.year(), now.month(), setd, now.hour(), now.minute(), now.second()));
stato1 = 0;
delay(200);
FIRST = true;
}
}