Accendere e spegnere arduino con un pulsante

Ciao a tutti e grazie dell’aiuto, spero, non sono esperto, cerco un circuito e relativo sketch per accendere e spegnere arduino tramite un pulsante e un mosfet, arduino deve anche spegnere se la batteria di alimentazione scende sotto un certo valore, avete qualche cosa, grazie

Come partenza si potrebbe considerare qualcosa del genere. Premendo il pulsante si accende il p-mos dando alimentazione. Nel setup bisogna portare alta l'uscita OUT per attivare il transistor di ritenuta. Nel loop bisogna rilevare il primo rilascio del pulsante (letto attraverso l'ingresso pull-up) e settare una variabile "rilasciato". Quando si rileva di nuovo il pulsante premuto, e la variabile "rilasciato" risulta settata, si disattiva l'uscita di ritenuta, e quindi appena si rilascia di nuovo il pulsante si spenge tutto. Il led sulla base del transistor indica visivamente la presenza della ritenuta dell'alimentazione.

698256526

2 Likes

bisogna fare un autoritegno praticamente e come si fa ??

Come descritto:

Nel setup bisogna portare alta l’uscita OUT

pinMode(PIN_RITENUTA, OUTPUT);
digitalWrite(PIN_RITENUTA, 1);

rilevare il primo rilascio del pulsante (letto attraverso l’ingresso pull-up) e settare una variabile “rilasciato”

if (digitalRead(PIN_PULS) == 1) rilasciato = 1;

Quando si rileva di nuovo il pulsante premuto, e la variabile “rilasciato” risulta settata, si disattiva l’uscita di ritenuta

if ((digitalRead(PIN_PULS) == 0)  && rilasciato) digitalWrite(PIN_RITENUTA, 0);
1 Like

Grazie dell'aiuto

ho provato ma mi da errori in caricamento manca
'rilasciato' was not declared in this scope e altro

Ma la variabile "rilasciato" l'hai dichiarata prima di usarla ?

Guglielmo

Sì ok avevo dimenticato, ma non mi funziona, si accende fin qui tutto ok ma dopo non si spegne

ho fatto così ditemi per favore dove sbaglio, adesso premo il pulsante si accende, ma poi non riesco a spegnere
grazie

#define PIN_RITENUTA 7
#define PIN_PULS 10
int rilasciato = 0;

void setup() {
pinMode(PIN_RITENUTA, OUTPUT);
digitalWrite(PIN_RITENUTA, 1);

}

void loop() {
if (digitalRead(PIN_PULS) == 1) rilasciato = 1;
if ((digitalRead(PIN_PULS) == 0)  && rilasciato) digitalWrite(PIN_RITENUTA, 0);

}```

Manca la chiamata a pinMode per impostare il pin di ingresso per il pulsante.

Non ho mica capito il pulsante è sul pin10

Nel setup() ... manca il pinMode() per il pin del pulsante !

Guglielmo

Fatto adesso funziona grazie

#define PIN_RITENUTA 7
#define PIN_PULS 10
int rilasciato = 0;

void setup() {
pinMode(PIN_PULS, INPUT_PULLUP);
pinMode(PIN_RITENUTA, OUTPUT);
delay(500);
digitalWrite(PIN_RITENUTA, 1);

}

void loop() {
if (digitalRead(PIN_PULS) == 1) rilasciato = 1;
if ((digitalRead(PIN_PULS) == 0)  && rilasciato) digitalWrite(PIN_RITENUTA, 0);

}```

ho fatto così e funziona ho aggiunto un ritardo in accensione, come faccio ad aggiungere anche un ritardo in spegnimento, grazie

Modifichi la logica attuale che è questa:
678575678

trasformandola in questa:
6788567234

Scusate cosa sbaglio? si accende ma non si spegne

#define PIN_RITENUTA 7
#define PIN_PULS 10
int rilasciato = 0;
int t = 0;

void setup() {
pinMode(PIN_PULS, INPUT_PULLUP);
pinMode(PIN_RITENUTA, OUTPUT);

digitalWrite(PIN_RITENUTA, 1);

}

void loop() {
if (digitalRead(PIN_PULS) == 1) rilasciato = 1;
if ((digitalRead(PIN_PULS) == 0)  && rilasciato) 
{
  if(millis - t > 500) {digitalWrite(PIN_RITENUTA, 0);}
}else{
  t = millis;
}

}

La funzione millis va chiamata (come ogni funzione) aggiungendo le due parentesi di chiamata, e la variabile temporale deve essere di tipo unsigned long.

Ok e funziona perfettamente, vorrei però inserirlo in un progetto già fatto senza aggiungere un pulsante, ma utilizzando i due pulsanti già esistenti, che fanno altro uno naviga nelle pagine uno seleziona, vorrei fare on- off premendoli insieme, secondo voi potrebbe essere possibile, grazie

È possibile, certo.

Però devi modificare il comportamento di ciascuno dei due pulsanti esistenti. Adesso alla pressione di uno dei due pulsanti si ottiene la funzione 'naviga' oppure la funzione 'seleziona'. Devi modificare ciascun pulsante in modo che, quando viene premuto, non vada subito ad eseguire la funzione assegnata 'naviga' oppure 'seleziona', ma per un tempo da te prefissato (100-200 ms) analizzi l'altro pulsante con una funzione non bloccante basata su millis(). Se l'altro pulsante non è già premuto o non viene premuto in quell'intervallo di tempo, il pulsante esplica la sua funzione di 'naviga' oppure 'seleziona', altrimenti viene eseguita la funzione 'spegni'.

Ciao,
P.

Non necessariamente bisogna attendere quei tempi tra azioni sui pulsanti, se ad esempio i comandi normali vengono modificati per essere sensibili al rilascio anziché alla pressione, allora basta riscontrare i due pulsanti premuti assieme e si sa subito che si vuole spegnere.

Occorre certamente una modifica al circuito per gestire in hardware l'and dei pulsanti per l'accensione:


98747684


Ma questa modifica è il meno. Il problema grosso potrebbe essere il resto del software se non è stato scritto in partenza con criteri ben precisi di codice non bloccante e letture ingressi ben disaccoppiate dalla logica esecutiva.

Se invece come vedo di solito tutte le letture degli ingressi sono embeddate dentro le condizioni if della logica, e magari questa è pure scritta in modo bloccante, significa dover riscrivere (e quindi ripensare da capo) un bel po' di roba.

Diciamo che almeno tutti gli ingressi dovrebbero essere letti in un punto solo, producendo delle variabili di comando chiamate magari 'click1' ecc, e nella logica si dovrebbero leggere queste variabili al posto degli ingressi diretti, allora se ne potrebbe uscire.

In quest'ottica la lettura/gestione dei due pulsanti potrebbe diventare la seguente (ammesso che quelli già presenti chiudano verso massa e quindi si possa realizzare il circuito di cui sopra):

#define PIN_RITENUTA ...
#define PIN_PULS1    ...
#define PIN_PULS2    ...

byte rilasciato = 0;
unsigned long t = 0;
byte prem1Prec = 0;
byte prem2Prec = 0;


void setup() 
{
    pinMode(PIN_PULS1, INPUT_PULLUP);
    pinMode(PIN_PULS2, INPUT_PULLUP);
    pinMode(PIN_RITENUTA, OUTPUT);
    digitalWrite(PIN_RITENUTA, 1);
}


void loop() 
{
    delay(40); // debounce barbaro minimo

    // letture ingressi con riconoscimento
    // click su rilascio

    byte prem1 = (digitalRead(PIN_PULS1) == 0);
    byte click1 = !prem1 && prem1Prec;
    prem1Prec = prem1;

    byte prem2 = (digitalRead(PIN_PULS2) == 0);
    byte click2 = !prem2 && prem2Prec;
    prem2Prec = prem2;


    // Gestione autoritenuta

    if (!rilasciato)
    {
        click1 = 0;  // nessun comando finche' non rilasciato
        click2 = 0;
        if (!prem1 && !prem2) { rilasciato = 1; }
    }

    if (rilasciato && prem1 && prem2)
    {
        if (millis()-t > 2000)  // se premuti per due secondi
        {
            digitalWrite(PIN_RITENUTA, 0);
            while (1);        // attesa rilascio
        }
    }
    else
    {
        t = millis(); 
    }


    // Resto della logica circa 25 cicli al secondo

    // ......................

}
1 Like