lettura analogica

Ciao a tutti,
ho trovato questo codice che, attraverso un pulsante, attiva il pin digitale 7 se la variabile "analogvalue" supera una certa soglia. Vorrei pero' conservare questo valore fin quando non viene ripremuto il pulsante, un po' come succede con gli interruttori di casa. E' possibile?

const int analogPin = A0;    // Pin analogico
const int ledPin = 7;       // Pin digitale
const int soglia = 400;   

void setup() {
  
  pinMode(ledPin, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  
  int analogValue = analogRead(analogPin);  //legge il valore dell'ingresso analogico

  // se il valore analogico e abbastanza alto accendi il led:
  if (analogValue > soglia) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin,LOW);
  }


  Serial.println(analogValue);
  delay(100);      
}

Grazie per le numerose risposte :wink:

Prima ti tutto, dichiara la variabile "analogValue" prima della setup() dove hai le varie const.
Logicamente nella loop() non dovrà esserci la parola int.

Come hai fatto tu, la "analogValue" ha "scope" o visibilità/vita locale alla funzione loop(). Ogni volta che viene eseguita la loop() la variabile nasce e alla fine della loop() muore.

Messa prima della setup() (praticamente fuori dalla loop()) allora la variabile diventa globale. Ha visibilità in tutto il programma e vita legata al programma stesso.

Ciao e grazie per la risposta.
Ho fatto come hai detto tu ed ho modificato un po' il codice, ora se premo il pulsante il led si accende e se lo ripremo si spegne. Se lo tengo premuto pero' lampeggia, come mai? C'è un modo per evitare che accada?

const int analogPin = A0;    // Pin analogico
const int ledPin = 7;       // Pin digitale
const int soglia = 400;
int analogValue = 0;
int state = 0;
int val = 0;
int old_val = 0;

void setup() {
  
  pinMode(ledPin, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  
analogValue = analogRead(analogPin);  //legge il valore dell'ingresso analogico

  // se il valore analogico e abbastanza alto accendi il led:
 
 
 
  if (analogValue > soglia) {
     state = 1 - state;
     delay(50);
     
  }
  

  if (state == 1) {  
    digitalWrite(ledPin, HIGH); 
}
  else {
    digitalWrite(ledPin,LOW);
  }


  Serial.println(analogValue);
  delay(100);      
  }

Qui c'è lo schema:

Lampeggia perché se il pulsante è premuto gli cambi lo stato

state = 1 - state;

Quindi se tieni premuto il pulsante a ogni ciclo loop il led passa da accesso a spento e viceversa, ovvero lampeggia.
Per evitarlo devi registrare lo stato del pulsante (non del led) al precedente loop e se è uguale ignorare il comando.

Quoto @paoloP

Però, perchè hai collegato il pulsante all'analogico? Cosi la corrente in ingresso balla nel tuo caso attorno a 400 quando lo premi ma non è fisso. Collegalo a pin digitale. digitalRead(pindigitale) -> 1 oppure 0 (HIGH o LOW) molto più semplice

Potresti comunque avere, quando premi il pulsante, segnali "impuri" ovvero c'e' l'effetto bounce.
In pratica quando premi il pulsante in realtà non è detto che fai contatto e basta, magari fai contatto e per microsecondi ristacchi e poi ripremi.
Prova a cercare nel forum debounce di un pulsante o su internet. Si può risolvere in maniera software o in maniera hardware.

Eppure ci sono molte guide su internet che consigliano di usare gli ingressi analogici per i pulsanti. Non ne comprendo l'utilità se non quando si collegano più pulsanti ad un solo ingresso. Per uno solo meglio (credo) un ingresso digitale.

Ok grazie per le dritte.
Utizillo gli ingressi analogici perche' quelli digitali sono gia' tutti occupati.

Ciao.

Puoi usare gli ingressi analogici come pin digitali nomilandoli semplicemente A0, A1, A2 ecc oppure da 14 a 19.
Esempio

val = digitalRead(A0);

oppure

val = digitalRead(14);

Attento che se hai dichiarato l'analog pin come 0 e non come A0, analogRead e digitalRead leggono da due pin diversi.
digitalRead(0) usa un pin diverso da analogRead(0)
mentre
digitalRead(A0) è sullo stesso pin di analogRead(A0).

ok, questo dovrebbe essere abb.za corretto:

// definisce il pin analogico

#define analog0 A0


// definisce il pin digitale
 
#define led 2


// variabile int che memorizza lo stato (high/low) del led

int stLed0 = 0;

 
void setup()
{
    pinMode( analog0, INPUT ); //imposta il pin analogico come imput  

 
    pinMode( led, OUTPUT ); //imposta il led come output

 
    digitalWrite( led, stLed0 ); //
}
 
void loop()
{
 
  if ( analogRead(analog0) > 1000 )  //se analog0 è maggiore di 1000
  {
    if ( stLed0 == LOW  ) stLed0 = HIGH;  //se la variabile stLed0 è low portala ad high
    else                     stLed0 = LOW;  // altrimenti imposta la variabile stLed0 come low
    digitalWrite( led, stLed0 );
    delay(200);  /*importante! se non ci fosse risulterebbe problematico catturare lo stato acceso o spento alla pressione del pulsante
    in piu' evita di premere il pulstante alla velocita' di 1 millesimo di sec */
    
  }
 
}

Piccolo consiglio, nulla di importante (cerca nel forum, ne abbiamo discusso):

meglio

const byte led=2;

di

#define led 2

ok, grazie.