problema lampeggio led con millis e while

Buona sera a tutti,ho un problema con questa parte di codice.

Il codice dovrebbe comportarsi cosi':

pulsante non premuto:

il led lampeggia
nel display lcd il testo"HS Multi Loader" fisso e il testo "Ready!" di sotto lampeggiante

pulsante premuto (quindi dovrebbe uscire dal while):

led spento
display lcd senza testo

Lo sketch quando gira funziona,ma quando premo il pulsante il led non si spegne come non uscirebbe dal while...

Ringrazio per qualsiasi consiglio dato.

#include <LiquidCrystal.h> // include la libreria del display lcd

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // dichiara i pin assegnati al display lcd 

int switchstate = 0;

int a;

// ----------------------------------LED-----------------------------------------

const int ledPin =  6;      

int ledState = LOW;           

unsigned long previousMillis = 0;        

const long interval = 200;          

// ------------------------------------------------------------------------------
// ----------------------------------LCD-----------------------------------------

int lcdState = LOW;          

unsigned long previousMillisLcd = 0;        

const long intervalLcd = 1500;         

// ------------------------------------------------------------------------------

void setup() {
lcd.begin(16, 2); // imposta il numero di colonne e righe del display lcd

pinMode(9, OUTPUT); // dichiara il pin 9 come uscita per la retroilluminazione

digitalWrite(9, HIGH);
  
pinMode(ledPin, OUTPUT);

 pinMode(8, INPUT); // dichiara il pin 8 come ingresso per il pulsante
}

void loop()
{  

while(a == 0) { 

switchstate = digitalRead(8); 
if (switchstate == HIGH) {
  a = 1;
  }
  else {
  a = 0;
  }
// ---------------------------------LED----------------------------------------
unsigned long currentMillis = millis();

if(currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;   

  if (ledState == LOW)
    ledState = HIGH;
    else
      ledState = LOW;
      digitalWrite(ledPin, ledState);
}
// ---------------------------------LCD----------------------------------------
unsigned long currentMillisLcd = millis();

if(currentMillisLcd - previousMillisLcd >= intervalLcd) {
  previousMillisLcd = currentMillisLcd;   

  if (lcdState == LOW) {
    lcdState = HIGH;
    lcd.setCursor(0, 0); 
    lcd.write("HS Multi  Loader"); 
    lcd.setCursor(5, 1);
    lcd.write("Ready!         "); 
}   
    else {
      lcdState = LOW;
      lcd.setCursor(5, 1);
      lcd.write("                ");     
}
}
// ----------------------------------------------------------------------------
}   
 lcd.clear();
 lcd.write("STOP");
 delay(1000);
 a = 0;
 digitalWrite(6, LOW); 
}

E' il classico problema della lettura dei pulsanti, se lo leggi in un ciclo e lo tieni premuto anche pochi istanti, il programma lo "vede" più volte quindi non sembra mai funzionare bene.

Prova questo sketch, l'ho riscritto da zero e fa quello che chiedi. Non ho collegato l'LCD quindi troverai solo il codice per il led, comunque ti sarà facile aggiungerlo. Ma soprattutto contiene alcuni consigli che ti vorrei dare, come usare i "#define" per la configurazione dei pin (non consumano memoria), i timer per gli eventi ciclici come far lampeggiare qualcosa (ti basta la libreria SimpleTimer che vedi referenziata all'inizio), così come fare funzioni specifiche per varie operazioni (invece di annegare logica nel codice principale), e indentare sempre per bene per leggere più comodamente un listato (questo è un programma piccolo, immagina centinaia di righe...).

Eccolo:

#include <SimpleTimer.h> 

#define LED 13
#define BUTTON 8

SimpleTimer timer;

int switchstate = LOW;
int prevstate = LOW;

boolean blink = true;
int interval = 200;
int tmrBlink = -1;

void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT); // dichiara il pin 8 come ingresso per il pulsante
  // Inizializzo il primo stato, led lampeggiante
  tmrBlink = timer.setInterval(interval, BlinkLed);
}

void loop()
{
  switchstate = digitalRead(BUTTON); 
  if (switchstate == HIGH && prevstate == LOW) {
    Serial.println("Switch");
    blink = !blink;
    delay(100); // evita i rimbalzi
    if (blink)
      tmrBlink = timer.setInterval(interval, BlinkLed);
    else
      LedOff();
  }
  prevstate = switchstate;
  timer.run();
}

void BlinkLed() {
  // Inverte lo stato del led
  digitalWrite(LED, !digitalRead(LED));
}

void LedOff() {
  // Spegne il led e disattiva il timer
  digitalWrite(LED, LOW);
  if ( tmrBlink != -1 ) {
    timer.deleteTimer(tmrBlink);
    tmrBlink = -1;
  }
}

Grazie per la risposta!!
Ho provato a compilare sul ide il tuo sketch ma non me lo compila e mi da il seguente errore:


Arduino:1.6.4 (Windows Vista), Scheda:"Arduino Uno"

sketch_jun25a.ino:1:26: fatal error: SimpleTimer.h: No such file or directory
compilation terminated.
Errore durante la compilazione

Questo report potrebbe essere più ricco
di informazioni con
"Mostra un output dettagliato durante la compilazione"
abilitato in "File > Impostazioni"


io sto usando una arduino uno,forse è quello il motivo??
comunque è molto interessante il tuo,quello che non capisco sono i void di sotto fuori dal loop,perche'sono separati?
In ogni caso ti ringrazio,proverò comunque il tuo codice su un'altra arduino adesso che la prendero'.

No, è che devi installare la libreria "SimpleTimer".
Trovi tutto qui:
http://playground.arduino.cc/Code/SimpleTimer
In "get the code" puoi trovare il codice, oppure puoi scaricare direttamente lo ZIP da qui e installarlo tramite l'IDE di Arduino (Sketch, Include Library, Add zip library):
SimpeTimer-master.zip

questo

if (switchstate == HIGH) {
  a = 1;
  }
  else {
  a = 0;
  }

cambialo cosi:

if (switchstate == HIGH) break;

ok non mi resta che provare!un grazie di cuore a tutti e due.