ciao, ho apportato un po di modifiche al mio progetto (che prima funzionava) ma ho il countdown per uscire dallo "stato 2" che anche se impostato a qualsiasi minutaggio (20 60 110) mi va su "tempo scaduto" e torna a "stato 0" dopo 3/4 secondi.
sul display per quei pochi secondi leggo i minuti giusti.
c'ho ragionato tutto il giorno ma non ne vengo a capo, mi potete aiutare? grazie
parte 1:
#include <StepperMotor.h>//libreria motore passopasso
#include <LiquidCrystal_I2C.h> //libreria display
#include <EEPROM.h> //libreria scrittura su memoria assenza rete
//#define DEBUG //decommentare per attivare la scrittura su seriale per PC
#define ledmovimento 2 //modulo lampeggiante (led rosso)
#define ledstato 3 //led giallo di notifica (spento=sitema a riposo) (acceso=sistema attivo) (fadein fadeout statomanuale a tempo) (lampeggiante= anomalia posizione motore)
#define reletermostato 4 //relè contatto termostato
#define startsonoff 5 //comando da remoto (SONOFF)
#define finecorsa 6 //finecorsa per motore passopasso
#define riarmo 7 //pulsante per spegnere il sistema
#define _PIN1 8 //pin motore
#define _PIN2 9 //pin motore
#define _PIN3 10 //pin motore
#define _PIN4 11 //pin motore
#define releoff 13 //contatto per spegnimento sonoff
#define minpiu A0 //pulsante incremento minuti manuale
#define minmeno A1 //pulsante decremento minuti manuale
#define attesamodval 5000 //attesa ultima modifica per scrittura su eeprom
#define offintervallo 60000 //variabile conto alla rovescia
unsigned int minutimanuale; // tempo manuale
unsigned int off; //variabile per manuale
unsigned int tempomanuale; //tempo durata riscaldamento manuale in millisecondi
byte stato; //per funzione relè
byte punto0 = 0; //variabile per reset motore
byte statoprec = 0; //variabile stato precedente
byte flag = 0; //variabile per incremento temperatura
byte flag1 = 0; //variabile per decremento temperatura
byte flag2 = 0; //variabile per scrittura eeprom
byte flag3 = 0; //variabile per pulsante ritardato (riarmo)
byte flag4 = 0; //variabile per comando remoto/locale
byte brightness = 0; // luminosità led a 0 alla partenza fadein
byte fadeAmount = 10; // velocità fadein
bool fadein = false; //definizione stato fade-in
bool blinking = false; //definizione stato per lampeggio
unsigned long modval = 0; //variabile per tempo attesa scrittura eeprom
unsigned long timeout; //tempo di accensione riscaldamento manuale
unsigned long iniziomanuale; //variabile per temporizzatore manuale
unsigned long iniziopulsante; //variabile per ritardo pulsante
unsigned long tempopulsante; //variabile per ritardo pulsante
unsigned long blinkInterval = 110; // millisecondi di lampeggio
unsigned long currentMillis; // variabile per lampeggio
unsigned long previousMillis; //variabile per lampeggio
unsigned long tempoffinterval; //variabile conto alla rovescia
unsigned long offtime; //variabile conto alla rovescia
LiquidCrystal_I2C lcd(0x27, 16, 2); // associazione parametri display
StepperMotor stepper(_PIN1, _PIN2, _PIN3, _PIN4); //assegnazione pin motore
void setup()
{
pinMode(startsonoff, INPUT_PULLUP); //pulsante avvio sistema
pinMode(finecorsa, INPUT_PULLUP); //pulsante lampeggio movimento/reset motore
pinMode(riarmo, INPUT); //pulsante touch riarmo
pinMode(ledstato, OUTPUT); // led stato sistema prenotato
pinMode(reletermostato, OUTPUT); //relè termostato riscaldamento
pinMode(ledmovimento, OUTPUT); //relè led lampeggio movimento
pinMode(minpiu, INPUT); //pulsante incremento temperatura
pinMode(minmeno, INPUT); //pulsante decremento temperatura
pinMode(releoff, OUTPUT); //relè spegnimento sonoff
pinMode(_PIN1, OUTPUT); //pin motore
pinMode(_PIN2, OUTPUT); //pin motore
pinMode(_PIN3, OUTPUT); //pin motore
pinMode(_PIN4, OUTPUT); //pin motore
digitalWrite (reletermostato, HIGH); //stato relè spento ad accensione
digitalWrite (releoff, HIGH); //stato relè spento ad accensione
stato = 0; //per funzione relè
flag = 0; //per funzione minuti +
flag1 = 0; //per funzione minuti -
flag2 = 0; //per funzione scrittura eeprom
flag3 = 0; //per funzione ritardo pulsante
tempopulsante = 1000; //millisecondi ritardo pulsante
minutimanuale = EEPROM.read(0); //lettura memoria eeprom per minuti manuale impostati
delay (50);
tempomanuale = (minutimanuale * 60000); //conversione minuti in millisecondi
off = minutimanuale; //impostato tempo manuale su variabile
stepper.setPeriod(1); //velocità motore passopasso in millisecondi (1 massimo)
lcd.init(); // inizializzo la comunicazione del display
digitalWrite (ledmovimento, LOW); //stato relè lampeggio led rosso spento
#ifdef DEBUG
Serial.begin(9600); // inizializzo la comunicazione seriale
#endif
lcd.backlight(); //accensione retroilluminazione display
lcd.begin(16, 2); //parametri display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AZZERAMENTO");
lcd.setCursor(0, 1);
lcd.print("IN CORSO");
stepper.move (4096); //leggero allontanamento da finecorsa (1 giro)
punto0 = digitalRead(finecorsa); //variabile per reset iniziale
delay (10);
while (punto0 == HIGH) //riposizionamento a punto 0 se il finecorsa non è premuto
{
#ifdef DEBUG
Serial.println(" azzeramento in corso ");
#endif
stepper.move (-200);
delay (1);
punto0 = digitalRead(finecorsa); //controllo stato finecorsa
}
stepper.stop ();
#ifdef DEBUG
Serial.println(" azzeramento eseguito ");
#endif
lcd.clear();
lcd.setCursor(0, 0 );
lcd.print(" SPENTO "); //scrittura testo standard
lcd.noBacklight();
}
void loop()
{
// codice per fade in su stato MANUALE
if (fadein) {
analogWrite(ledstato, brightness); //imposto uscita con funzione analogica
brightness = brightness + fadeAmount; //aumento luminosità
if (brightness == 0 || brightness == 170) { //diminuzione luminosità
fadeAmount = -fadeAmount ;
}
delay(30);
}
if (stato == 2) // condizione funzione manuale attivo
fadein = true; // start lampeggio
else
fadein = false; // stop lampeggio
//fine codice fade in
// codice per lampeggio
if (blinking) {
if (((unsigned long)(currentMillis - previousMillis)) >= (blinkInterval)) { //calcolo tempo per lampeggio anomalia motore
digitalWrite((ledstato), !digitalRead((ledstato))); // led giallo
previousMillis = currentMillis; // sets the time we wait "from"
}
}
int reading = digitalRead(finecorsa); //lettura stato finecorsa
if (reading == HIGH) // condizione a finecorsa non premuto
blinking = true; // start lampeggio
else
blinking = false; // stop lampeggio
//fine codice lampeggio
if ((digitalRead(startsonoff) == LOW) && (stato == 0)) //funzione per effetto relè stato 1
{
#ifdef DEBUG
Serial.println("stato=1"); //stato automatico attivo
#endif
lcd.clear();
lcd.backlight(); //accensione retroilluminazione display
lcd.setCursor(0, 0);
lcd.print(" AUTOMATICO "); //scrittura stato su display
stato = 1;
flag4 = 1;
}
Il codice è piuttosto incasinato (rinuncio a seguire la logica), contiene elementi in esubero (vedi variabili ìiniziomanuale' e 'offtime' con la stessa funzione), commenti errati, coppie di parentesi eccedenti ecc.
Gli stati non sono mutuamente esclusivi tra loro (possibilità di effetti collaterali per logica troppo complessa). Gli eventi riconosciuti all'interno di ogni stato non sono mutuamente esclusivi tra loro (di nuovo possibilità di effetti collaterali per logica troppo complessa). Il codice è un "monoblocco", è troppo lungo e complesso da seguire, sarebbe da suddividere in piccole funzioni semplici con nomi chiari e descrittivi di cosa si sta facendo.
Ma soprattutto in qualche punto la funzione millis è usata in modo sbagliato (le condizioni soffrono del problema dell'overflow), mentre in qualche altro punto è usata correttamente.
Ad esempio il controllo che hai evidenziato andrebbe riscritto così:
if ((offtime - tempoffinterval) >= offintervallo) {
Claudio_FF:
Il codice è piuttosto incasinato (rinuncio a seguire la logica), contiene elementi in esubero (vedi variabili ìiniziomanuale' e 'offtime' con la stessa funzione), commenti errati, coppie di parentesi eccedenti ecc.
Gli stati non sono mutuamente esclusivi tra loro (possibilità di effetti collaterali per logica troppo complessa). Gli eventi riconosciuti all'interno di ogni stato non sono mutuamente esclusivi tra loro (di nuovo possibilità di effetti collaterali per logica troppo complessa). Il codice è un "monoblocco", è troppo lungo e complesso da seguire, sarebbe da suddividere in piccole funzioni semplici con nomi chiari e descrittivi di cosa si sta facendo.
Ma soprattutto in qualche punto la funzione millis è usata in modo sbagliato (le condizioni soffrono del problema dell'overflow), mentre in qualche altro punto è usata correttamente.
Ad esempio il controllo che hai evidenziato andrebbe riscritto così:
if ((offtime - tempoffinterval) >= offintervallo) {
questo codice è frutto di mille prove e modifiche, quindi sicuramente è "sporco" o cercato di pulirlo in base alle mie conoscenze ma sicuramente qualcosa è sfuggito.
ora che mi ci fai pensare invece di fargli fare quel controllo li po trei dirgli semplicemente
if (off==0){
"tempo scaduto" e i successivi comandi
Aggiungo anche che se vuoi postare un codice lungo qui nel forum, invece di metterlo in due post separati mettilo come allegato. E' più semplice per tutti.
ciao, ho apportato la modifica suggerita da @Claudio_FF, ho cercato di ripulire il codice e sistemare i commenti.
ora ho il problema che a volte (circa 4 su 10 prove fatte) quando mi passa dallo stato 2 allo stato 0 (sia che faccia io la commutazione manualmente sia allo scadere del tempo), arduino si resetta e rifà il ciclo SETUP. :o
Magari fosse quello il problema!
Il problema è che, con questo telefono come con il precedente, non riesco ad aprire i file .ino, se non salvandoli e rinominando l'estensione in .txt! Purtroppo non c'è verso, mi sembra, di far aprire i file .ino come se fossero di testo.
ciao...per iniziare ti suggerisco di rivedere il tipo delle variabili minutimanuale e tempomanuale.
sono entrambe unsigned int...solo che la prima la salvi anche nella eeprom con EEPROM.write() che salva 1 byte...quindi o usi una variabile byte oppure usi la EEPROM.put().
per la seconda variabile fai un :
tempomanuale = (minutimanuale * 60000);
se la variabile minutimanuale vale 2 che valore avrà tempomanuale?
Datman:
Il problema è che, con questo telefono come con il precedente, non riesco ad aprire i file .ino, se non salvandoli e rinominando l'estensione in .txt! Purtroppo non c'è verso, mi sembra, di far aprire i file .ino come se fossero di testo.
Se parli di metterlo come allegato, a Chrome (ed al sito) non frega nulla se è ino, txt o altro. tu sfogli, selezioni e salvi.
Se parli di incollare il testo nel messaggio, allora non ho capito: se da un qualsiasi file manager (anche quello predefinito di Android) clicchi su un file .ino a me chiede "Apri come.." e poi la scelta tra Testo, Immagine, Audio, Video. Seleziono Testo e lo apro, quindi faccio copia/incolla in Chrome.
Dico che se lo scarico e cerco di aprirlo, Android 8 (già prima con il 4) si rifiuta. Devo scaricarlo e andare ad aprirlo lì con x-plore. Ho provato anche a installare qualche applicazione, ma non ho risolto il problema. Con windows, invece, se non avessi l'IDE potrei comunque aprirli come file di testo.
Datman, io ho Android 7 (e comunque lo facevo anche prima) e funziona: non devi cercare di aprirlo direttamente dalla notifica ma tu lo scarichi, finisce in Download, quindi con File Manager entri nella cartella e clicchi sul file .ino e a quel punto non conoscendo il tipo di file ti chiede come aprirlo.
ORSO2001:
ciao...per iniziare ti suggerisco di rivedere il tipo delle variabili minutimanuale e tempomanuale.
sono entrambe unsigned int...solo che la prima la salvi anche nella eeprom con EEPROM.write() che salva 1 byte...quindi o usi una variabile byte oppure usi la EEPROM.put().
per la seconda variabile fai un :
tempomanuale = (minutimanuale * 60000);
se la variabile minutimanuale vale 2 che valore avrà tempomanuale?
grazie,allora sia la variabile "minutimanuale" sia "off" le ho messe in byte tanto non avranno mai valore superiore a 255 (quindi risolvo il problema della eeprom
per la tua domanda su "tempomanuale" ti risponderei 120000, ma da come mi hai posto la domanda sento puzza di fregatura
ma rianalizzando il codice, anche il valore "tempomanuale" è diventato inutile dopo le modifiche fatte l'altro giorno ovvero eliminato un altro "conto alla rovescia" sostituendolo con if (off==0).
quindi ho apportato tutte queste modifiche e ricaricato il codice... ora lo torno a testare per un po e vedo se fa ancora scherzi
edit: ma da cosa può essere causato un reset di arduino? tralasciando i collegamenti elettrici che sono giusti?