Come collegare e controllare l'interruttore di un aerosol ad arduino

Ciao a tutti, mi chiamo Maddalena e avrei bisogno del vostro aiuto.
Per il mio progetto di tesi mi è stato chiesto di comandare l'accensione e lo spegnimento di un interruttore di un aerosol, interruttore a pulsante, per mezzo di arduino.
L'obiettivo sarebbe quello nella fase iniziale di mantenerlo spento per 2 minuti, e poi andare ad intervallare una fase di accensione della durata di 10 secondi a una di spegnimento per 30 secondi, ripetendo queste 2 fasi per 10 volte, infine deve tornare nello stato spento per 2 minuti.
Se qualcuno di voi fosse disponibile per fornirmi qualche dritta, ne sarei molto grata!
Grazie per il tempo didicatomi.

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato.
Grazie.

Ciao. Lato software non dovrebbe essere difficile. Lato hardware come pensavi di fare?

Per la realizzazione pratica puoi benissimo usare una scheda Arduino nano (UNO). Nell'attesa che arrivi il materiale puoi iniziare con il simulatore online wokwi (gratuito).

Qui un esempio che puoi modificare:

Ciao.

1 Like

A livello hardware, consiglio di usare un piccolo rele' con il contatto NA in parallelo al pulsante, non conoscendo il resto del circuito a cui tale pulsante e' collegato, l'uso di un contatto "pulito" potrebbe essere migliore di transistor, mosfet o altri componenti simili.

1 Like

Grazie a tutti per le risposte ed i suggerimenti forniti.
La mia idea era quella di smontare la custodia dell'Aerosol e far sì che il l'elettronica del pulsante venga messo a contatto con un relè, il quale a sua volta venga collegato ad una scheda Arduino nano (UNO). Così che poi, controllando via software il relè, questo mi faccia da vero e proprio interruttore dell'aerosol.
La tipologia di codice da implementare per programmare il circuito pensavo a questo:

#define BUTTON_PIN 2  
#define RELAY_PIN 3    

void setup() {
  pinMode(BUTTON_PIN, OUTPUT);
  digitalWrite(BUTTON_PIN, LOW);  
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);   
}

void loop() {
  for (int i = 0; i < 10; i++) {
    digitalWrite(RELAY_PIN, LOW); 
    delay(2 * 60 * 1000);       
    
  
    digitalWrite(RELAY_PIN, HIGH); 
    delay(10 * 1000);               
   
    digitalWrite(RELAY_PIN, LOW);  
    delay(30 * 1000);               
  }
}

Se qualcuno poi ha un'idea migliore mi faccia sapere!
Grazie ancora, qualsiasi suggerimento è prezioso, purtoppo non sono esperta come vedete di elettronica e programmazione!

Per quanto riguarda il codice avendo messo l'attesa di due minuti nel for avrai che per 10 volte attendi due minuti con relé spento, poi acceso per dieci secondi, spento per trenta secondi.
Alla fine dei dieci cicli essendo l'unico codice nel loop si ripeterà la sequenza indicata.
Non fa quello che hai dichiarato, per ovviare dovresti spostare il primo digitalWrite e delay fuori dal for

1 Like

In tal modo dovrebbe essere corretto?

#define BUTTON_PIN 2  
#define RELAY_PIN 3    

void setup() {
  pinMode(BUTTON_PIN, OUTPUT);
  digitalWrite(BUTTON_PIN, LOW);  
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);   
}

void loop() {
 digitalWrite(RELAY_PIN, LOW); 
    delay(2 * 60 * 1000);   
  for (int i = 0; i < 10; i++) {
    digitalWrite(RELAY_PIN, HIGH); 
    delay(10 * 1000);               
   
    digitalWrite(RELAY_PIN, LOW);  
    delay(30 * 1000);               
  }
}

A me interessa che nella fase iniziale di 2 minuti stia spento e poi inizi quel ciclo for di 10 ripetizioni in cui stimola per 10 secondi e sta spento per 30 secondi.

Così fa quel che desideri. Occorre tenere presente che usando i delay, specie così lunghi, tra un attesa e l'altra non sarà possibile fare nulla (il programma è fermo al delay) quindi anche operazioni tipo ferma il programma, cambia qualche modo operativo ecc. non saranno possibili.
Se non deve esserci possibilità d'intervento dall'esterno e quindi il programma deve agire sempre in modo perpetuo facendo due minuti d'attesa, 10 secondi acceso e 30 spento per dieci volte allora ok, altrimenti occorre ripensare il programma in modo da evitare i delay usando, ad esempio, la funzione millis() per determinare le tempistiche e una macchina a stati finiti per gestire le varie fasi del programma

1 Like

Grazie del suggerimento, si purtroppo dovendo collegare l'Aerosol con l'arduino ad un EEG per sincronizzare i tempi di stimolazione e garantire un trigger, ho bisogno che anche nei periodi di rest iniziale sia sintonizzato a aspetti 2 minuti.
Utilizzando quindi la funzione millis() dice sia meglio?
Le riporto un esempio:

#define BUTTON_PIN 2  // Pin collegato all'interruttore a pulsante
#define SWITCH_PIN 3  // Pin collegato all'interruttore da controllare

unsigned long previousMillis = 0;
const long intervalOn = 10000;   // Intervallo di accensione (10 secondi)
const long intervalOff = 30000;  // Intervallo di pausa (30 secondi)
const long initialDelay = 120000; // Ritardo iniziale (2 minuti)
const int repetitions = 10;  // Numero di ripetizioni

int currentState = LOW;  // Stato attuale dell'interruttore
int previousState = LOW;  // Stato precedente dell'interruttore
int repetitionsCount = 0;  // Contatore delle ripetizioni

void setup() {
  pinMode(BUTTON_PIN, INPUT);   // Imposta il pin dell'interruttore come input
  pinMode(SWITCH_PIN, OUTPUT);  // Imposta il pin dell'interruttore da controllare come output
  digitalWrite(SWITCH_PIN, currentState);  // Inizialmente, l'interruttore è spento
}

void loop() {
  unsigned long currentMillis = millis();  // Ottieni il tempo corrente

  // Controllo dell'interruttore
  int buttonState = digitalRead(BUTTON_PIN);

  if (buttonState != previousState) {
    // Se lo stato del pulsante cambia, azzera il contatore delle ripetizioni
    repetitionsCount = 0;
  }

  previousState = buttonState;

  // Se sono trascorsi 2 minuti dall'avvio, inizia il ciclo di accensione e pausa
  if (currentMillis - previousMillis >= initialDelay) {
    // Se il contatore delle ripetizioni è minore del numero desiderato
    if (repetitionsCount < repetitions) {
      // Accendi l'interruttore per 10 secondi
      if (currentState == LOW) {
        digitalWrite(SWITCH_PIN, HIGH);
        currentState = HIGH;
        delay(intervalOn);
      }
      // Spegni l'interruttore per 30 secondi
      else {
        digitalWrite(SWITCH_PIN, LOW);
        currentState = LOW;
        delay(intervalOff);
        repetitionsCount++;  // Incrementa il contatore delle ripetizioni
      }
    } else {
      // Se le ripetizioni sono state completate, spegni l'interruttore
      digitalWrite(SWITCH_PIN, LOW);
      currentState = LOW;
      // Rimani spento per altri 2 minuti
      if (currentMillis - previousMillis >= initialDelay + intervalOff) {
        repetitionsCount = 0;  // Azzera il contatore delle ripetizioni
        previousMillis = currentMillis;  // Azzera il tempo precedente
      }
    }
  } else {
    // Se sono trascorsi meno di 2 minuti dall'avvio, mantieni l'interruttore spento
    digitalWrite(SWITCH_PIN, LOW);
    currentState = LOW;
  }
}

Grazie ancora, molto gentile davvero!

Ciao, qui ci diamo del tu :slight_smile:
Sarebbe anche un inizio ma non penso funzioni come da richiesta e penso che sia frutto di un bel prompt fornito ad un intelligenza artificiale, sbaglio?

Si, l'altro però l'ho fatto io ma perché era semplice e mi sono basata su un esempio preso da YouTube. Ma la funzione millis() non so come si implementa. Se puoi gentilmente fornirmi qualche suggerimento, purtroppo non sto trovando esempi su come scriverlo. Grazie

Qui c'è uno dei più subdoli problemi aritmetici, il risultato dei quell'espressione è: -11072, perché in assenza di specifiche esplicite i calcoli vengono effettuati a 16 bit con segno (tipo int: valore massimo +32767), e si ottiene un bel overflow.

Basta specificare in modo esplicito il tipo di almeno un operando (che deve essere un unsigned long a 32 bit):

(2 * 60 * 1000UL)

Ancora più comodo si scrive una define a inizio programma:

#define MINUTE 60000UL

e l'espressione si può scrivere:

(2 * MINUTE)

1 Like

E allora come definisci i 10 e 30 secondi? grazie

Certo, per capire le basi con cui si usa millis() Devi studiarti 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 poi ti sarà tutto più chiaro :wink:

1 Like

I 10 e 30 secondi non darebbero problemi perché il risultato è inferiore a 32767. Ma si può usare un'altra define come per i minuti.

Poi deve ricominciare?

I due minuti di attesa iniziali puoi metterli nel setup, con un LED giallo che lampeggia.

Che vuol dire?...

La seconda puoi realizzarla con una cosa simile:

#define SPENTO 0
#define ACCESO 1

setup:
n=1;

loop:
if(n<11 && stato==SPENTO && millis()-t0>=120000UL)
  {
  t0=millis();
  digitalWrite(out, HIGH);
  stato=ACCESO;
  }
else if (n<11 && stato==ACCESO && millis()-t0>=1800000UL)
  {
  t0=millis();
  digitalWrite(out, LOW);
  stato=SPENTO;
  n+=1;
  }
if(n==11) ... // Pausa di 2 minuti
1 Like

Per il millis, devi solo tenere presente che, al contrario di delay, non e' un "comando", ma un "registro".

Con il delay, che e' un comando, tu gli dici quanti millisecondi deve aspettare, e lui aspetta senza fare nulla (e quindi anche senza leggere ingressi, pilotare uscite, eseguire altro) per quei tot millisecondi che gli passi fra parentesi (ed e' quindi un comando "bloccante", perche' per tutto il tempo che passa ad aspettare, il micro non fa assolutamente nient'altro) ... il delay va bene nelle macchine a stati finiti, dove anche se ci sono blocchi, sono intenzionali.

Il registro millis, invece, contiene il numero di millisecondi passati da quando hai alimentato il micro, quindi non lo usi come comando, ma lo leggi e poi usi il valore che ti restituisce per farci delle operazioni o controllare se il tempo che ti serve e' passato, e cosi via (i link che ti ha passato fabpolli spiegano molto piu in dettaglio :wink:) ... millis va meglio dove mentre attendi devi avere la possibilita' di fare anche altro, leggere ingressi, cambiare uscite, eccetera.

1 Like
1 Like

Dovendo sintonizzare l'accensione e lo spegnimento dell'Aerosol con l'acquisizione di un segnale EEG, ho bisogno che questo tenga di conto del protocollo che vado ad utilizzare per l'EEG.
Ovvero anche dei primi due minuti, anche se non lo accendo deve rimanere temporizzatore con l'EEG in modo tale che una volta passati quei due minuti, inizi la fase di accensione (10s) e pausa (30s), ripetendolo per 10 volte. Giusto perchè voglio che sia preciso e coordinato con la macchina EEG.
Il codice che mi ha suggerito tiene conto di quanto le ho riportato? grazie