Buonasera,
mi chiamo Emanuele e nella programmazione sono alle prime armi.
Mi servirebbe un po' di aiuto...sono 3 giorni che cerco una soluzione consultando forum,manuali e youtube ma non ne vengo a capo
Ho scritto uno sketch (Arduino Uno) che dopo mille intoppi finalmente funziona correttamente, il problema è che faccio un massiccio impiego del delay per entrambe le condizioni "if" e questo mi preclude la possibilità di eseguire altre istruzioni necessarie alla realizzazione del progetto.
L'esecuzione parte da in interruttore che se aperto o chiuso avvia una condizione o l'altra e che a loro volta pilotano un servo e un relè con l'uno o l'altro "comportamento".
La cosa assolutamente imperativa è che una volta completato il ciclo relativo non deve assolutamente essere ripetuto fino al prossimo cambio di stato dell'interruttore.
byte mela;
const int Aancora = 13;
#include <Servo.h>
Servo portelli;
int chiuso = 150;
int aperto = 50;
const int relepompa = 4;
void setup () {
if ( digitalRead (2)==HIGH) mela=1;
if ( digitalRead (2)==LOW) mela=0;
pinMode(Aancora, OUTPUT);
portelli.attach(6);
portelli.write(chiuso);
pinMode(relepompa, OUTPUT);
digitalWrite(relepompa, LOW);
Serial.begin(9600);
}
void loop(){
if ( digitalRead (2)==HIGH && mela==1) {
mela=0, Serial.println(" stato di immersione");
digitalWrite(Aancora, LOW);
digitalWrite(relepompa, LOW);
portelli.write(aperto);
delay(10000);
portelli.write(chiuso);
}
if ( digitalRead (2)== LOW && mela==0) {
mela=1, Serial.println(" stato di sollevamento");
portelli.write(chiuso);
digitalWrite(relepompa, HIGH);
delay(8000);
digitalWrite(relepompa, LOW);
digitalWrite(Aancora, HIGH);
delay(10000);
digitalWrite(relepompa, HIGH);
delay(2000);
digitalWrite(relepompa, LOW);
}
delay (20);
}
Buonasera,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentartiIN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.
Guglielmo
P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda: - serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections - pinout delle varie schede by xxxPighi: Pinout - link generali utili: Link Utili
Ok ho fatto la presentazione dove indicato e grazie per i link sempre utili ed interessanti.
Come dicevo sono giorni che ci sbatto la testa e non sono capace di trovare una soluzione, il fatto che il codice venga eseguito una sola volta con le mie attuali limitate conoscenze non mi permette di usare il millis...
Emanueleb:
... con le mie attuali limitate conoscenze non mi permette di usare il millis...
Guarda che non è nulla di trascendentale (è solo un contatore che avanza sempre al passare del tempo) e richiede solo di applicarsi un momento a studiare come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ...
... vedrai che dopo molte cose ti saranno più chiare.
Ti dico come faccio io di solito:
Prima mi scrivo (con l'esperienza puoi anche non scrivere più) la cose da fare, nella giusta sequenza
Poi lo rileggo, "giocando a farle" nella mia testa, un po' come quando ero all'asilo, non sto scherzando, tento sempre di stare a basso livello
Quando il "gioco" gira bene comincio a buttare giù righe di codice
Fino a che non gira bene, non so per esempio se mi accorgo che non ho spento una pompa, correggo e ricomincio a "giocare"
Prova a scrivermi cosa devi fare
a parte il discorso sui millis() che diventa semplice dopo averci studiato giusto un pochino.
Nel tuo sketch mancano alcuni commenti che aiuterebbero a capire cosa vuoi fare...
Ad esempio da quello che ho capito si tratta si un sottomarino o simili per acquario
a questo punto cosa significa la variabile "mela"?
nel setup se il contatto 2 (che non si sa cosa sia) diventa alto cambi lo stato di mela e poi nel loop ricontrolli ancora il contatto 2 e anche mela ( ma mela è intimamente legata al contatto 2, cioè non ci sarà mai la situazione contatto2 =low e mela=1 per cui...) e Aancora che è? in questo caso il led
byte mela; // mela = nome di fantasia
const int Aancora = 13; //abilita/disabilita l'uso dell'ancora su altro controller esterno,
#include <Servo.h> //almeno fino a quando non riesco ad integrare iil millis per
Servo portelli; //eliminare l'altro controller ed integrare qui tutto il codice...
int chiuso = 150;
int aperto = 50;
const int relepompa = 4;
void setup () {
if ( digitalRead (2)==HIGH) mela=1;
if ( digitalRead (2)==LOW) mela=0;
pinMode(Aancora, OUTPUT);
portelli.attach(6);
portelli.write(chiuso);
pinMode(relepompa, OUTPUT);
digitalWrite(relepompa, LOW);
Serial.begin(9600);
}
void loop(){
if ( digitalRead (2)==HIGH && mela==1) {
mela=0, Serial.println(" stato di immersione"); //verfica se il pulsante è in on:
digitalWrite(Aancora, LOW); //ancora disabilitata
digitalWrite(relepompa, LOW); //pompa spenta
portelli.write(aperto); //portelli aperti
delay(10000); //atesa allagamento comparti
portelli.write(chiuso); //portelli chiusi
}
if ( digitalRead (2)== LOW && mela==0) {
mela=1, Serial.println(" stato di sollevamento"); //verfica se il pulsante è in off:
portelli.write(chiuso); //portelli chiusi
digitalWrite(relepompa, HIGH); //pompa attiva
delay(8000); //tempo necessario allo svuotamento dei comparti
digitalWrite(relepompa, LOW); //pompa spenta
digitalWrite(Aancora, HIGH); //ancora abilitata
delay(10000); //pausa per convogliare l'ultimo deflusso in zona pompa
digitalWrite(relepompa, HIGH); //attivazione pompa
delay(2000); //tempo necessario per eliminare l'ultimo deflusso raccolto
digitalWrite(relepompa, LOW); //pompa spenta
}
delay (20);
}
>Emanueleb: .. perdona la franchezza , ma ... da tuo codice si capisce che tu di Arduino NON sai quasi nulla e che scrivi istruzioni in un oridine che difficilmente potrà portare a qualche cosa che funzioni.
Ora, noi qui aiutiamo a correggere, ma le BASI uno se le deve fare studiando ...
... se uno mi inizia una setup() con una digitalRead() senza neanche aver definito se il pin che usa è di INPUT o di OUTPUT significa appunto che di Arduino NON ha studiato NULLA.
Quindi ... prima di andare avanti ... tocca che almeno ti studiQUESTO prosegui con con QUESTO (che sono veramente le BASI) e acquisti qualche buon libro (es. QUESTO) ... dopo di che ti riavvicini al tuo programma sapendo cosa stai facendo.
Guglielmo
P.S.: ... youtube è pieno di tutorial sbagliati (almeno il 90%) quindi te lo sconsiglio come base di partenza ... prima studia la teoria, poi puoi guardare qualche tutorial riconoscendo chi racconta frescacce da chi dice cose serie.
Non è mica quello che ti avevo chiesto
Comunque taca banda
credo di aver capito
Schiaccio bottone e si apre un portello
Mollo il bottone e si chiude il portello e una serie di accendi spegni
Così va bene? (la parte della mela non è farina del mio sacco...)
byte mela; // mela = nome di fantasia
const int Aancora = 13; //abilita/disabilita l'uso dell'ancora su altro controller esterno,
#include <Servo.h> //almeno fino a quando non riesco ad integrare iil millis per eliminare
Servo portelli; //l'altro controller ed integrare qui tutto il codice...
int chiuso = 150;
int aperto = 50;
const int relepompa = 4;
void setup () {
pinMode(2, INPUT);
if ( digitalRead (2)==HIGH) mela=1;
if ( digitalRead (2)==LOW) mela=0;
pinMode(Aancora, OUTPUT);
portelli.attach(6);
portelli.write(chiuso);
pinMode(relepompa, OUTPUT);
digitalWrite(relepompa, LOW);
Serial.begin(9600);
}
void loop(){
if ( digitalRead (2)==HIGH && mela==1) {
mela=0, Serial.println(" stato di immersione"); //verfica se il pulsante è in on:
digitalWrite(Aancora, LOW); //ancora disabilitata
digitalWrite(relepompa, LOW); //pompa spenta
portelli.write(aperto); //portelli aperti
delay(10000); //atesa allagamento comparti
portelli.write(chiuso); //portelli chiusi
}
if ( digitalRead (2)== LOW && mela==0) {
mela=1, Serial.println(" stato di sollevamento"); //verfica se il pulsante è in off:
portelli.write(chiuso); //portelli chiusi
digitalWrite(relepompa, HIGH); //pompa attiva
delay(8000); //tempo necessario allo svuotamento dei comparti
digitalWrite(relepompa, LOW); //pompa spenta
digitalWrite(Aancora, HIGH); //ancora abilitata
delay(10000); //pausa per convogliare l'ultimo deflusso in zona pompa
digitalWrite(relepompa, HIGH); //attivazione pompa
delay(2000); //tempo necessario per eliminare l'ultimo deflusso raccolto
digitalWrite(relepompa, LOW); //pompa spenta
}
delay (20);
}
Ma l'esecuzione va modificata da sequenziale (faccio tutti i singoli passi uno dopo l'altro) a ciclica (verifico se è il momento di fare qualcosa altrimenti proseguo senza mai fermarmi), come descritto qui e qui...
...e di cui si sta discutendo qui (se riesci a trasformare il tuo codice sequenziale in "situazioni" sei a cavallo).
byte mela; // mela = nome di fantasia
Ecco, questo è un esempio di commento che non aggiunge alcuna informazione utile alla comprensione. Quello che serve sapere è cos'è e cosa fa 'mela', ad esempio:
byte mela; // variabile di stato per rilevare fronti
// di commutazione del pulsante
E infatti dopo nel programma parli correttamente di 'stato' (immersione/sollevamento).
Molto corretto invece commentare le varie digitalWrite, infatti leggere solo HIGH o LOW non da immediatamente idea di quale operazione viene svolta (accenderà? spegnerà?), il commento lo specifica bene.
Volendo è possibile ottenere la stessa chiarezza anche senza l'uso di commenti creando apposite "etichette" all'inizio del programma:
#define POMPA_ACCESA HIGH
#define POMPA_SPENTA LOW
digitalWrite(relepompa, POMPA_ACCESA);
Grazie,
ottimo consiglio!
Adesso mi applico e vediamo se riesco a trasformarlo in ciclico...(dopo essermi ben documentato con tutti i link che ho ricevuto )
Per farla ancora più semplice pensa a quando sei nato(in quel momento è partito il tuo millis()), poi ad ogni età corrisponde un cronometro(unsigned long) ...fatto questo non ti resta che far partire il cronometro,e fare quello che devi quando raggiunge oppure entro il tempo impostato,....poi quando hai fatto tutto, azzeri il cronometro(dichiarando che è = al tempo trascorso da quando 6 nato(millis()).