Apanhando do if

Olá, estou desenhando um protótipo de temporizador para uma mesa de luz UV para cura de telas de serigrafia. O meu protótipo tem um lcd 16x2, um relé shield, dois pots e dois botões. Os pots são usados para definir os minutos que a tela deve ser exposta à luz UV sendo que um controla as dezenas e o outro as unidades. Os botões servem para iniciar a programação do acendimento das luzes e outro servirá para ligar e desligar os ventiladores do módulo de secagem.

//isso tudo está dentro do void loop()
int buttonState = digitalRead(pushButton);
  int pot; //os pots já foram criados anteriormente no setup, criei aqui de novo porque eu usei o map abaixo
  int rele1 = 7;
  int pot1;
  unsigned long timerEffect;
  
  pot = map(analogRead(sensorValue), 0,1023, -1,10); // mapeei os pots para ter uma leitura que coubesse na função delay()
  pot1 = map(analogRead(sensorValue2), 0,1023, -1,101);// mas depois entendi que o delay() não é o mais adequado
  
  //Serial.println(pot1); <==
  
 if (digitalRead(pushButton) == 0)
  { 
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   delay(1000);
   lcd.setCursor(0,1);
   lcd.print("...3            ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("    ...2        ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("        ...1    ");
   delay(1000);
   lcd.clear(); 
   timer = millis();
   timerEffect = timer;  
} 
//até aqui tudo funciona
// eu quero que essa condição aconteça antes do que vem a seguir para que o display mostre que o input (button down) //funcionou e que o código dê segmento
  
 //meu problema é daqui pra baixo o código compila sem erros, mas eu não entendo por que ele simplesmente ignora essa //passagem e volta ao topo do loop, eu tentei com do while mas também não funcionou direito, eu tenho quase certeza de que o //problema reside na parte  da matemática com as variáveis

 if (timerEffect >= (pot + pot1)*60000)
  { 
   digitalWrite(rele1, HIGH);
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando ");
   lcd.setCursor(0,1);
   lcd.print(" favor aguardar ");
   //delay ((pot+pot1)* 6000);
  }
  else if (timerEffect <= (pot + pot1)*60000)
  {
    digitalWrite(rele1, LOW); 

  }
}

espero que alguém possa lançar uma luz nesse problema que eu estou enfrentando, eu pesquisei bastante mas acho que meu caso é um pouco específico por conta das circunstâncias.

obrigado desde já

o código completo para melhor referência:

// include the library code:
#include <LiquidCrystal.h>
#define Rele1 7 // Define pino de saida para rele 1
#define Rele2 8 // Define pino de saida para rele 2
int pushButton = A4; //define botão1 no pino analogico 4
int pushButton2 = 10; //define botao2 no pino digital 10
int inputPin = A5; //define potencimetro no pino analogico 5
int inputPin2 = A3; //define potencimetro no pino analogico 5
int v1[]  = {0, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
int v2[] = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
unsigned long timer;


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

  Serial.begin (9600);

  pinMode(Rele1,OUTPUT); //rele1 como saida
  pinMode(Rele2,OUTPUT); // rele2 como saida
  pinMode(inputPin, INPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2); //diz ao arduino o tamanho do lcd

  lcd.setCursor(0,0); //coloca o cursor do lcd na coluna 0 linha 0
  lcd.print("Ola, bem vindo"); // printa mensagem no lcd
  delay(3000); // 3segs de espera
  lcd.clear(); // limpa o display
  lcd.print("Selecione tempo");
  lcd.setCursor(0,1);
  lcd.print("de exposicao");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" aperte o botao ");
  lcd.setCursor(0,1);
  lcd.print(" > para iniciar ");
  delay(3000);
  lcd.clear();
    lcd.setCursor(0,0);
  lcd.print(" a gravacao da  ");
    lcd.setCursor(0,1);
    lcd.print("     matriz     ");
  delay(3000);
  lcd.clear();
  } 




void loop() {
  
 // int rele1 = 7;
  //int rele2 = 8;
//  int releValue1 = 0;
  
  digitalWrite(pushButton, HIGH);
  //digitalWrite(pushButton2, HIGH);

  int inputPin = A5;
  int sensorValue = 0;
  sensorValue = analogRead (inputPin);
  
  int inputPin2 = A3;
  int sensorValue2 = 0;
  sensorValue2 = analogRead (inputPin2);

lcd.setCursor (0,2); 
lcd.print ("  de exposicao  ");



  //==============parte 1 ==================

  if((sensorValue >= 0)&&(sensorValue <=100))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[1]);


  }
 else if ((sensorValue >= 101)&&(sensorValue <=200))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[2]);

  }
  else if ((sensorValue >= 201)&&(sensorValue <=300))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[3]);
 
  }
   else if ((sensorValue >= 301)&&(sensorValue <=400))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[4]);

  }
  else if ((sensorValue >= 401)&&(sensorValue <=500))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[5]);
 
  }
  else if ((sensorValue >= 501)&&(sensorValue <=600))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[6]);
 
  }
  else if ((sensorValue >= 601)&&(sensorValue <=700))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[7]);
 
  }
  else if ((sensorValue >= 701)&&(sensorValue <=800))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[8]);
 
  }
  else if ((sensorValue >= 801)&&(sensorValue <=900))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[9]);
 
  }
  else if ((sensorValue >= 901)&&(sensorValue <=1023))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[0]);
 
  }

//=============parte2=============

 if((sensorValue2 >= 1)&&(sensorValue2 <=100))
  {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[0]);
  }
  else if ((sensorValue2 >= 101)&&(sensorValue2 <=200))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[1]);
  }
    else if ((sensorValue2 >= 201)&&(sensorValue2 <=300))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[2]);
  }
  
  else if ((sensorValue2 >= 301)&&(sensorValue2 <=400))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[3]);
  }
  
    else if ((sensorValue2 >= 401)&&(sensorValue2 <=500))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[4]);
  }
    else if ((sensorValue2 >= 501)&&(sensorValue2 <=600))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[5]);
  }
  
    else if ((sensorValue2 >= 601)&&(sensorValue2 <=700))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[6]);
  }
  
    else if ((sensorValue2 >= 701)&&(sensorValue2 <=800))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[7]);
  }
  
    else if ((sensorValue2 >= 801)&&(sensorValue2 <=900))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[8]);
  }
  
    else if ((sensorValue2 >= 901)&&(sensorValue2 <=1023))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[9]);
  }
  
 if ((sensorValue <=101)&&(sensorValue2 <=101)) 
    { 
  lcd.setCursor(6,0);
  lcd.print (" minuto   ");
    }
   else
   {  
  lcd.setCursor(6,0);
  lcd.print (" minutos");
  
}

  int buttonState = digitalRead(pushButton);
  int pot;
  int rele1 = 7;
 // int rele2 = 8;
  int pot1;
  unsigned long timerEffect;
  
  pot = map(analogRead(sensorValue), 0,1023, -1,10);
  pot1 = map(analogRead(sensorValue2), 0,1023, -1,101);
  
  Serial.println(pot1);
  
 if (digitalRead(pushButton) == 0)
  { 
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   delay(1000);
   lcd.setCursor(0,1);
   lcd.print("...3            ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("    ...2        ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("        ...1    ");
   delay(1000);
   lcd.clear(); 
   timer = millis();
   timerEffect = timer;  
}
   if (timerEffect >= (pot + pot1)*60000)
  { 
   digitalWrite(rele1, HIGH);
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando ");
   lcd.setCursor(0,1);
   lcd.print(" favor aguardar ");
   //delay ((pot+pot1)* 6000);
  }
  else if (timerEffect <= (pot + pot1)*60000)
  {
    digitalWrite(rele1, LOW); 

  }
}


//delay (timer * sensorValue + timer * sensorValue2);
  /*
  
  int buttonState = digitalRead(pushButton);
 if (digitalRead(pushButton) == 0)
  { 
    lcd.setCursor(3,0);
   lcd.print("desligado    ");
   digitalWrite(rele1, LOW);



  
  
  lcd.setCursor(0, 0);

  
  //lcd.print(buttonState);
 // lcd.setCursor(0, 1);
  int buttonState2 = digitalRead(pushButton2);
  //lcd.print(buttonState2);

  int rele1 = 7;
  int rele2 = 8;
  
  if (digitalRead(pushButton) == 0)
  { 
    lcd.setCursor(3,0);
   lcd.print("desligado    ");
   digitalWrite(rele1, LOW);
  }else{
    
    lcd.setCursor(3,0);
    lcd.print("ligado       ");
    digitalWrite(rele1, HIGH);
  }
  if (digitalRead(pushButton2) == 1)
    { 
      lcd.setCursor (3,1);
    lcd.print("desligado    ");
    digitalWrite(rele2, LOW);
    }else{
      
      lcd.setCursor(3,1);
      lcd.print("ligado       ");
      digitalWrite(rele2, HIGH);
  }
          
}
  
*/

Visto que o código compila com êxito qual é a falha ou o que é que nao faz e devia fazer? Tenho a bola de cristal avariada e foi pra reparação :grin: :grin:

tens razão, ficou meio confuso do jeito que eu escrevi.

 if (digitalRead(pushButton) == 0)
  { 
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   delay(1000);
   lcd.setCursor(0,1);
   lcd.print("...3            ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("    ...2        ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("        ...1    ");
   delay(1000);
   lcd.clear(); 

// Serial.print(pot1);

// Serial.println(pot);
  
  
   while (timer <= (pot + pot1)*60000)
  { 
    
   timer = millis();
   digitalWrite(rele1, HIGH); 
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando ");
   lcd.setCursor(0,1);
   lcd.print(" favor aguardar ");  
   Serial.println(timer);
 
   
  }
  while (timer >= (pot + pot1)*60000)
  {
 
   digitalWrite(rele1, LOW); 
   Serial.println("desligou");

  }

essa é a parte sensível do código, o problema que eu tenho enfrentado é com essas condicionais, quando eu aperto o botão, ele para no lcd.clear() do primeiro if e não processa o resto, e o curioso é que eu fiz essa parte processar antes e descobri que meu problema anterior era mesmo com a matemática do código, consegui ajustar e quando voltei para essa parte ela parou de funcionar.

me diga se ainda não consegui ser claro
grato,
Fernando

Nao faco ideia do que esta dentro da variavel timer… Importas-te de mostrar?

Os teus timers sao absolutos…
Isto:

while (timer <= (pot + pot1)*60000)
  { 
    
   timer = millis();
   digitalWrite(rele1, HIGH); 
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando ");
   lcd.setCursor(0,1);
   lcd.print(" favor aguardar ");  
   Serial.println(timer);
  }

Corre durante… (pot + pot1) * 60 segundos. Passado esse limite, este codigo nunca mais corre ate fazeres reset ao Arduino.

Usar >= e <= na mesma condicao nao costuma resultar muito bem…

Alem disso, o segundo while corre sempre apos o momento no tempo (pot + pot1)*60 segundos.

Tempo negativo nao existe… Que pretendes atingir com isto:

  pot = map(analogRead(sensorValue), 0,1023, -1,10);
  pot1 = map(analogRead(sensorValue2), 0,1023, -1,101);

Estas a complicar imenso o teu codigo para o que pretendes fazer.

Comeca por criar uma temporizacao fixa… olhando para o teu codigo diria que nunca atingiste este passo.
Depois de teres uma temporizacao fixa, adiciona a variavel com UM potenciometro para variar o tempo.
Adiciona o LCD para ficar bonito no final.

Olhando para o teu codigo, comecaste pelo LCD e so agora estas a olhar para a parte importante do sistema.

bubulindo:
Nao faco ideia do que esta dentro da variavel timer… Importas-te de mostrar?

Os teus timers sao absolutos…
Isto:

while (timer <= (pot + pot1)*60000)

{
   
   timer = millis(); //<===========aqui está o timer==============
   digitalWrite(rele1, HIGH);
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando “);
   lcd.setCursor(0,1);
   lcd.print(” favor aguardar "); 
   Serial.println(timer);
  }



Corre durante.... (pot + pot1) * 60 segundos. Passado esse limite, este codigo nunca mais corre ate fazeres reset ao Arduino. 


Usar >= e <= na mesma condicao nao costuma resultar muito bem... usar apenas > e < seria mais seguro?

Alem disso, o segundo while corre sempre apos o momento no tempo (pot + pot1)*60 segundos. 
sim, pois o tempo vai para frente sempre não?

Tempo negativo nao existe.... Que pretendes atingir com isto: 


pot = map(analogRead(sensorValue), 0,1023, -1,10);
  pot1 = map(analogRead(sensorValue2), 0,1023, -1,101);


essa parte já foi substituida por não ser precisa (de precisão), lembre que eu estou usando um potenciometro que são dispositivos mecânicos, ele não estava chegando nem em 0 e nem em 100 isso foi uma medida paliativa e que gerou inconsistências

Estas a complicar imenso o teu codigo para o que pretendes fazer. 
tens razão, ainda estou aprendendo e fazendo ao mesmo tempo, pretendo polir o código, isso ainda não passa de um protótipo :blush:

Comeca por criar uma temporizacao fixa.... olhando para o teu codigo diria que nunca atingiste este passo. 
Depois de teres uma temporizacao fixa, adiciona a variavel com UM potenciometro para variar o tempo. 
Adiciona o LCD para ficar bonito no final. 

sim, eu tive problemas para entender o conceito dos millis e abandonar um pouco o delay() que realmente não é uma boa opção, de todo modo, eu não entendi o conceito da temporização fixa, seria tirar ela de dentro da condicional? o problema disso para mim seria como saber o estado do tempo atual se eu quero predeterminá-lo entendes? por exemplo, se eu começo com millis no começo do código, ele estará correndo há um bom tempo quando eu quiser calcular algo com ele, ou eu entendi errado?
me passou pela cabeça usar apenas um potenciômetro para o tempo, isso economizaria toneladas de código, mas eu ainda não atingi um terço do espaço disponível, fazer a seleção do tempo com botões poderia ser mais interessante, mas o potenciometro por ser mecânico pode guardar posições mais facilmente

Olhando para o teu codigo, comecaste pelo LCD e so agora estas a olhar para a parte importante do sistema. 
sim, tens toda a razão, é algo que fez sentido pra mim no começo, não imaginei que calcular com tempo era algo mais complicado

usar >= e < ou > e <= e a forma correta. O igual so pode estar numa das condicoes.

Sim… o tempo vai sempre para a frente… mas tu queres contar o tempo entre dois momentos. Nao o tempo total que passou desde que ligaste o Arduino.

Quanto aos potenciometros… como podemos saber onde esta o erro se nao estamos a ver a ultima versao do codigo?

Ok, o millis e um relogio que conta milisegundos desde que o arduino foi ligado ou resetado. Se tu quiseres saber ha quanto tempo o Arduino foi ligado, fazes assim:

unsigned long tempo = millis() /1000;

// tempo em segundos.

No entanto o que tu queres e um intervalo… logo tens de determinar quando esse intervalo comeca e fazer as contas com o millis().

Ou seja…

unsigned long inicio = 0; // inicio do intervalo. 
int tempo = 0; //flag para travar o botao.

//imagina que queres que o intervalo comece quando carregares num botao. 
if (digitalRead(botao) && tempo = 0) { //primeira vez que carregas no botao e a temporizacao nao esta a correr
   inicio == millis();   // guarda o momento no tempo em que o millis comecou...
   tempo = 1;   // mostra que a temporizacao esta activa.... 
   digitalWrite(Rele1, HIGH);
}

if (millis() - inicio >= 60000) {  // se o tempo agora e 60000 milisegundos maior do que era quando comecou....
   tempo = 0;    // a temporizacao terminou. 
   digitalWrite(Rele1, LOW);
}

No fundo isto e o mesmo que tu fazes quando contas um intervalo. Se queres contar o tempo que te demora ir de casa ao supermercado, olhas para o relogio, fixas a hora actual, vais ao supermercado e quando chegas la olhas de novo para o relogio e fazes as contas.

Portanto, adapta este codigo para ligares a lampada durante um minuto. Depois coloca o potenciometro… fazer um menu com o LCD, apesar de possivel e dificil. Logo preocupa-te com a funcionalidade que queres mesmo mesmo ter… e depois disso realizado, comeca a desenvolver o interface com os botoes e LCD.
Nao estou a dizer que nao possas usar o LCD com o potenciometro… apenas que fazer a parte dos botoes e potenciometro e bem mais complexa.

Fantástico, sim agora está mais claro!
Antes mesmo de você escrever essa resposta, o que já tinhas me escrito no post anterior foi suficiente para eu ir adiante e continuar pesquisando e entendendo o que se passava de errado com o código.
Antes de postar o código, surgiu uma dúvida a respeito do que me disse, quando eu iniciar millis() ao pressionar o botão ele vai partir daquele input, mas toda vez que o botão for pressionado ele guarda o novo estado do millis? Ou seja, posso reutilizar essa passagem?

segue o código que está funcionando para as minhas necessidas, agora é polimento.

// include the library code:
#include <LiquidCrystal.h>
#define Rele1 7 // Define pino de saida para rele 1
//#define Rele2 8 // Define pino de saida para rele 2
int pushButton = A4; //define botão1 no pino analogico 4
//int pushButton2 = 10; //define botao2 no pino digital 10
int inputPin = A5; //define potencimetro no pino analogico 5
int inputPin2 = A3; //define potencimetro no pino analogico 5
int v1[]  = {0, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
int v2[] = {0, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
unsigned long timer;


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {

  Serial.begin (9600);

  pinMode(Rele1,OUTPUT); //rele1 como saida
  pinMode(Rele2,OUTPUT); // rele2 como saida
  pinMode(inputPin, INPUT);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2); //diz ao arduino o tamanho do lcd

  lcd.setCursor(0,0); //coloca o cursor do lcd na coluna 0 linha 0
  lcd.print("Ola, bem vindo"); // printa mensagem no lcd
  delay(3000); // 3segs de espera
  lcd.clear(); // limpa o display
  lcd.print("Selecione tempo");
  lcd.setCursor(0,1);
  lcd.print("de exposicao");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" aperte o botao ");
  lcd.setCursor(0,1);
  lcd.print(" > para iniciar ");
  delay(3000);
  lcd.clear();
    lcd.setCursor(0,0);
  lcd.print(" a gravacao da  ");
    lcd.setCursor(0,1);
    lcd.print("     matriz     ");
  delay(3000);
  lcd.clear();
  } 




void loop() {
 
  
  digitalWrite(pushButton, HIGH);
  //digitalWrite(pushButton2, HIGH);

  int inputPin = A5;
  int sensorValue = 0;
  sensorValue = analogRead (inputPin);
  
  int inputPin2 = A3;
  int sensorValue2 = 0;
  sensorValue2 = analogRead (inputPin2);
  int pot;
int pot1;

pot = sensorValue;
pot1 = sensorValue2;

lcd.setCursor (0,2); 
lcd.print ("  de exposicao  ");




  if((sensorValue >= 51)&&(sensorValue <=100))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[1]);
  pot = 1;

  }
 else if ((sensorValue >= 101)&&(sensorValue <=200))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[2]);
  pot = 2;
  }
  else if ((sensorValue >= 201)&&(sensorValue <=300))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[3]);
  pot = 3;
  }
   else if ((sensorValue >= 301)&&(sensorValue <=400))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[4]);
  pot = 4;
  }
  else if ((sensorValue >= 401)&&(sensorValue <=500))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[5]);
  pot = 5;
  }
  else if ((sensorValue >= 501)&&(sensorValue <=600))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[6]);
  pot = 6;
  }
  else if ((sensorValue >= 601)&&(sensorValue <=700))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[7]);
  pot = 7;
  }
  else if ((sensorValue >= 701)&&(sensorValue <=800))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[8]);
  pot = 8;
  }
  else if ((sensorValue >= 801)&&(sensorValue <=1023))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[9]);
  pot = 9;
  }
  else if ((sensorValue >= 0)&&(sensorValue <=50))
  {
  lcd.setCursor (3,0);
 delay(100);
  lcd.print (v1[0]);
  pot = 0;
  }



 if((sensorValue2 >= 0)&&(sensorValue2 <=50))
  {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[0]);
    pot1 = 0;
  }
  else if ((sensorValue2 >= 51)&&(sensorValue2 <=200))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[1]);
  pot1 = 1;
  }
    else if ((sensorValue2 >= 201)&&(sensorValue2 <=300))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[2]);
  pot1 = 2;
  }
  
  else if ((sensorValue2 >= 301)&&(sensorValue2 <=400))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[3]);
  pot1 = 3;
  }
  
    else if ((sensorValue2 >= 401)&&(sensorValue2 <=500))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[4]);
  pot1 = 4;
  }
    else if ((sensorValue2 >= 501)&&(sensorValue2 <=600))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[5]);
  pot1 = 5;
  }
  
    else if ((sensorValue2 >= 601)&&(sensorValue2 <=700))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[6]);
  pot1 = 6;
  }
  
    else if ((sensorValue2 >= 701)&&(sensorValue2 <=800))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[7]);
  pot1 = 7;
  }
  
    else if ((sensorValue2 >= 801)&&(sensorValue2 <=900))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[8]);
  pot1 = 8;
  }
  
    else if ((sensorValue2 >= 901)&&(sensorValue2 <=1023))
    {
  lcd.setCursor (2,0);
 delay(100);
  lcd.print (v2[9]);
  pot1 = 9;
  }
  
 if ((sensorValue <=101)&&(sensorValue2 <=101)) 
    { 
  lcd.setCursor(6,0);
  lcd.print (" minuto   ");
    }
   else
   {  
  lcd.setCursor(6,0);
  lcd.print (" minutos");
  
}

  int buttonState = digitalRead(pushButton);

  int rele1 = 7;

unsigned long timer;
unsigned long timerEffect;

  
 if (digitalRead(pushButton) == 0)
  { 
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   delay(1000);
   lcd.setCursor(0,1);
   lcd.print("...3            ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("    ...2        ");
   delay(1000);
   lcd.clear(); 
   lcd.setCursor(0,0);
   lcd.print("iniciando em... ");
   lcd.setCursor(0,1);
   lcd.print("        ...1    ");
   delay(1000);
   lcd.clear(); 

 Serial.print(pot1);
 Serial.println(pot);
    

   do {
   timer = millis(); 
   digitalWrite(rele1, HIGH); 
   lcd.setCursor(0,0);
   lcd.print(" sensibilizando ");
   lcd.setCursor(0,1);
   lcd.print(" favor aguardar ");  
   Serial.println(timer);
   }
   
   while (timer <= (pot + pot1)*60000);
   do { 

    digitalWrite(rele1, LOW); 
   Serial.println("desligou");
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("      tela      ");
   lcd.setCursor(0,1);
   lcd.print("  sensibilizada ");
   delay(200);
   lcd.clear();
   delay(200);
   lcd.setCursor(0,0);
   lcd.print("      tela      ");
   lcd.setCursor(0,1);
   lcd.print("  sensibilizada ");
   delay(200);
   lcd.clear();
   delay(200);
   lcd.setCursor(0,0);
   lcd.print("      tela      ");
   lcd.setCursor(0,1);
   lcd.print("  sensibilizada ");
   delay(200);
   lcd.clear();
   delay(200);
   lcd.setCursor(0,0);
   lcd.print("    aperte X    ");
   lcd.setCursor(0,1);
   lcd.print("  para resetar  ");
   
   
  }
  while (timer >= (pot + pot1)*60000);
  
   
}
   
 }

a única coisa que me incomoda ainda são os potenciômetros, quando o dial está entre um número e outro ele traz inconsistências, algumas vezes não consigo chegar ao zero. isso é da natureza do potenciometro imagino.
e muito obrigado pela ajuda

Que pretendes atingir com isto??

digitalWrite(pushButton, HIGH);

Como recomecas isso o processo de iluminar? Fazes reset?

Porque fazes toda aquela logica para definir o numero de minutos (suponho) que queres que o sistema funcione?

Porque nao algo assim:

setup() {
unsigned char timer_on = 0;
}

loop(){

pot = analogRead(pot_pin); // le o que esta no pino do potenciometro. 
Serial.println (pot); // este passo e importante para testar...  coloca o potenciometro no minimo e ve que numero te aparece aqui. Coloca no maximo e ve o que aparece. 

//Imagina que o teu potmeter varia entre  200 e 1000
int exposure = map(pot, 300, 900, 0, 100); // de zero a 100 minutos. como o teu range e maior que o intervalo que queres mapear, vais ter valores menores que zero e maiores que 100. Dai usares as proximas duas linhas de codigo... 

if (exposure < 0) exposure = 0; // 0 e sempre o minimo.
if (exposure > 100) exposure = 100; // 100 e o maximo. Isto podes acertar em conjunto com o map depois. 

unsigned long intervalo = exposure * 60000; // exposure esta em minutos
unsgined long inicio = 0;

if (digitalRead(start_button) && timer_on == 0) {
    timer_on = 1;
    inicio = millsi();
    // lcd stuff... 
    digitalWrite(rele1, HIGH); 
    //more LCD stuff...
  }

if (timer_on == 1 ) { 
    if (millis() - inicio > intervalo) {
        digitalWrite(rele1, LOW);
        timer_on = 0;
        //LCD stuff....
    }
}
// podes fazer algo giro no LCD...escolhes um sitio para escrever no LCD...
lcd.goto()... //vai para a linha escolhida. 

int time = (millis() - inicio)/60000;
lcd.print(time);

Nota que nao deves estar sempre a escrever no LCD. E preferivel teres uma funcao que escreve no LCD e e chamada sempre que algo mudou no LCD ou de segundo a segundo, por exemplo. Senao o que vais reparar e que o LCD parece estar a piscar.

bubulindo:
Que pretendes atingir com isto?? estou usando um pushbutton de dois pinos, segui a recomendação desse post:
http://forum.arduino.cc/index.php/topic,72276.0.html

digitalWrite(pushButton, HIGH);

Como recomecas isso o processo de iluminar? Fazes reset? exato, é um método precário mesmo

Porque fazes toda aquela logica para definir o numero de minutos (suponho) que queres que o sistema funcione?

Porque eu não estava conseguindo usar a função map da maneira correta e eu precisava que o pot gerasse, ao mesmo tempo, valores para exibir no lcd e no cálculo do tempo.

Porque nao algo assim:

setup() {

unsigned char timer_on = 0;
}

loop(){

pot = analogRead(pot_pin); // le o que esta no pino do potenciometro.
Serial.println (pot); // este passo e importante para testar…  coloca o potenciometro no minimo e ve que numero te aparece aqui. Coloca no maximo e ve o que aparece.

//Imagina que o teu potmeter varia entre  200 e 1000
int exposure = map(pot, 300, 900, 0, 100); // de zero a 100 minutos. como o teu range e maior que o intervalo que queres mapear, vais ter valores menores que zero e maiores que 100. Dai usares as proximas duas linhas de codigo…

if (exposure < 0) exposure = 0; // 0 e sempre o minimo.
if (exposure > 100) exposure = 100; // 100 e o maximo. Isto podes acertar em conjunto com o map depois.

unsigned long intervalo = exposure * 60000; // exposure esta em minutos
unsgined long inicio = 0;

if (digitalRead(start_button) && timer_on == 0) {
    timer_on = 1;
    inicio = millsi();
    // lcd stuff…
    digitalWrite(rele1, HIGH);
    //more LCD stuff…
  }

if (timer_on == 1 ) {
    if (millis() - inicio > intervalo) {
        digitalWrite(rele1, LOW);
        timer_on = 0;
        //LCD stuff…
    }
}
// podes fazer algo giro no LCD…escolhes um sitio para escrever no LCD…
lcd.goto()… //vai para a linha escolhida.

int time = (millis() - inicio)/60000;
lcd.print(time);




Nota que nao deves estar sempre a escrever no LCD. E preferivel teres uma funcao que escreve no LCD e e chamada sempre que algo mudou no LCD ou de segundo a segundo, por exemplo. Senao o que vais reparar e que o LCD parece estar a piscar.

gostei muito do método de calibragem do potenciômetro, é muito inteligente, vou aplicar estes testes que indicou, e realmente o código fica muito mais organizado e sintético, além de ser muito mais fácil de debugar, MUITO obrigado pelas ajudas e apontamentos!

Grato, Fernando

olá de novo, acho que estou me entendendo com os millis(),

<reclamação não relacionada ao tópico> // leia por sua conta e risco :slight_smile:
outra coisa, começo a entender quais são os verdadeiros nemesis dentro da comunidade do arduino. um deles foi recomendada pelo colega bubulindo (o qual é extremamente prestativo), o que eu teria usado muito facilmente não fosse a verdadeira selvageria em relação à função, que no caso é o ‘goto’.

eu fico muito entristecido por essas bandas em ver que as pessoas simplesmente esquecem que as dúvidas algumas são realmente inocentes e as pessoas querem apenas ver uma aplicação funcionar, ou dar um passo adiante no entendimento, mas parece que a pureza do código é extremamente mais importante, esquecem que por trás de um balbuciante coder pode ter um inovador, alguém que pense fora da caixa e consegue criar algo novo e distinto, aparentemente o mesmo acontece com o delay(), é quase um pecado usar o delay.
</reclamação não relacionada ao tópico>

voltando ao assunto principal, eu continuei com o código e segui basicamente o que o bubulindo recomendou e parei no goto por falta de referência, não que o que está postado na referência do arduino não seja boa, mas eu gosto de ver o código sendo usado na natureza, digamos assim, em outros habitats e ver o que as pessoas fazem com ele, mas é meio difícil, os harcoders do fórum não deixam.

segue o meu código no ponto que está me parece funcionar bem:
tirando a parte que ele executa a função do timer apenas uma vez

#include <LiquidCrystal.h>
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);


int Luz = 7;
int Vento = 8;


int Botao1 = 10;
int Botao2 = 9;


int potPin1 = A5;
int potPin2 = A4;

int estado = HIGH;
int anterior = LOW;
int leitura;

long tempo = 0;
long debounce = 200;


void setup(){

lcd.begin(16, 2);
  
Serial.begin(9600);

pinMode (Luz, OUTPUT);
pinMode (Vento, OUTPUT);

pinMode (Botao1, INPUT);
pinMode (Botao2, INPUT);

pinMode (potPin1, INPUT);
pinMode (potPin2, INPUT);

}

void loop(){

  leitura = digitalRead(Botao2);
  if (leitura == HIGH && anterior == LOW && millis() - tempo > debounce){
    if (estado == HIGH)
    estado = LOW;
    else 
    estado = HIGH;
  tempo = millis();
  }
  digitalWrite(Vento, estado);
  anterior = leitura;
//int potPin1;

int potValue = analogRead(potPin1);
int exposure = map(potValue, 0, 1023, 1, 10); 

if (exposure < 0) exposure = 0; 
if (exposure > 10) exposure = 10;  


unsigned long intervalo = exposure * 60000; 
unsigned long timerSample ;
unsigned long timerInicial = 0;


digitalWrite(Botao1, HIGH);
digitalWrite(Botao2, HIGH);


if (digitalRead(Botao1) == 0 ){
  timerInicial = 1;
  timerSample = millis ();
  lcd.setCursor(0,0);
  lcd.print ("     ligou      ");
  digitalWrite(Luz, HIGH);

}
if (timerSample == 1) {
if(millis() - timerSample > intervalo)
{

lcd.setCursor(0,0);
lcd.print("    desligou    ");
digitalWrite (Luz, LOW);
//goto: alguma coisa
}
}
}

então no final eu colocaria essa parte do goto: e depois mais lá pra cima do código eu coloco a outra parte da flag, é isso? eu andei lendo que a melhor forma é fazer com uma função, isso me ajudaria de alguma forma ou devo seguir com o goto e receber as pedradas?

fernandossala:
<reclamação não relacionada ao tópico> // leia por sua conta e risco :slight_smile:
outra coisa, começo a entender quais são os verdadeiros nemesis dentro da comunidade do arduino. um deles foi recomendada pelo colega bubulindo (o qual é extremamente prestativo), o que eu teria usado muito facilmente não fosse a verdadeira selvageria em relação à função, que no caso é o ‘goto’.

eu fico muito entristecido por essas bandas em ver que as pessoas simplesmente esquecem que as dúvidas algumas são realmente inocentes e as pessoas querem apenas ver uma aplicação funcionar, ou dar um passo adiante no entendimento, mas parece que a pureza do código é extremamente mais importante, esquecem que por trás de um balbuciante coder pode ter um inovador, alguém que pense fora da caixa e consegue criar algo novo e distinto, aparentemente o mesmo acontece com o delay(), é quase um pecado usar o delay.
</reclamação não relacionada ao tópico>

Eu tinha já falado do goto?? Provavelmente noutro post.
Eu não tenho problemas em ver goto usado num programa… mas para o considerar correcto a pessoa que o usou tem de me mostrar que:

  • Não há outra opção melhor.
  • Havendo outra opção melhor, o uso de goto torna o programa mais eficaz/rápido, etc…
  • Mesmo usando o goto, ele tem de ser usado dentro de certos limites e não esporadicamente.

Se procurares na net, certamente que encontrarás alguns dos mais conceituados programadores mundiais a defender o uso do goto. A diferença entre eles e grande parte das pessoas que acham que se deve usar o goto é que eles conseguem explicar porque é que o goto é usado ali e quais os perigos (se ainda existentes) de o fazer. A maioria das pessoas não o consegue fazer.

Os professores (tipo os meus da faculdade) são é preguiçosos e não querem falar disto. Após um ano de programação C, uma pessoa deve ter saber suficiente para entender os perigos do goto e nada que uma aula aberta de uma ou duas horas não esclarecessem isto com os alunos e os deixassem melhor formados sobre isto. Para que fique notado a única coisa que aprendi sobre o goto em 5 anos de universidade foi “Não podem usar o goto.”

Dito isto, nota que ainda hoje não vejo o uso de goto em programas meus… mas nunca vi necessidade de o usar.

Acho que o teu segundo parágrafo não é indicativo do fórum. Eu sou muito provavelmente das pessoas mais criticas que contribui para o fórum e tu podes fazer as perguntas mais idiotas que pensares desde que suportes o que pretendes fazer, fizeste e onde procuraste sem achar uma resposta, e certamente que não serás criticado por isso. O que eu critico é quando as pessoas chegam aqui, dizem que querem fazer um robot e esperam que a malta faça tudo para elas.

Quanto à pureza do código… “ensina um homem a pescar e não tens de lhe dar de comer”. Se focamos, talvez em demasia, certos aspectos do código como o uso do delay ou goto é precisamente para garantir que isso não deita a perder trabalho já feito.

Se baseares uma funcionalidade num código feito com delay, mais tarde poderás ter de tirar o delay dali e o código deixa de funcionar. Havendo uma maneira mais correcta de fazer as coisas, essa maneira deve ser adoptada. Não fazemos isso para travar as pessoas nos seus projectos, mas apenas para transmitir alguma da experiência e conhecimento.
Nota também que em 99,9% dos casos que critico o delay, ninguém respondeu a explicar porque é que o delay ali estava e se era temporário ou não.

Para teres uma ideia… olha aqui um excerto dum programa que estou a fazer…

int randomTime(int span) {
  return ((rand()%span) - (span/2));
}

....
  bool ok = radio.write( toSend, MSG_LEN );

  // Try again 1s later //not cool... try sleeping.
  delay(3000 + randomTime(1000)); // try to make this be random within reason. 
}

Lá está um delay de 2500 a 3500 milisegundos. Algo que eu digo abertamente que não deve ser feito.
No entanto, neste caso o delay está aqui para bloquear o programa que vai enviar dados de X em X tempo. O Arduino vai estar ligado a um carregador de telemóveis e os dados do rádio são apenas enviados do Arduino para um hub central. Não tem comunicação série e como não é alimentado a bateria, não estou a ter grandes preocupações com o consumo.
O meu objectivo com este projecto é recolher dados da minha casa. Não ter um sistema robusto de controlo, logo o delay nesta aplicação não é muito descabido.

Por outro lado, um dos nós deste sistema vai estar na garagem… alimentado a pilhas. Esse vai ser bastante diferente no que toca a delays no código para aproveitar ao máximo a bateria.

Entendes agora que as coisas não são todas intrinsecamente más… a utilização desinformada delas é que o é. E é isso que eu tento transmitir. Se tu usares um delay e o justificares, eu não tenho problema com isso… mas quando dizes que é assim porque não vi outro método, então há algo a melhorar, né?

Eu alterei um pouco o teu código… creio que é isto que pretendes.

#include <LiquidCrystal.h>
LiquidCrystal lcd (12, 11, 5, 4, 3, 2);

const char Luz = 7;
const char Vento = 8;

const char Botao1 = 10;
const char Botao2 = 9;

const char potPin1 = A5;
const char potPin2 = A4;

unsigned char estado = HIGH;
unsigned char anterior = LOW;
unsigned char leitura;

unsigned long intervalo = exposure * 60000; 
unsigned long timerInicial = 0;

void setup(){

lcd.begin(16, 2);
  
Serial.begin(9600);

pinMode (Luz, OUTPUT);
pinMode (Vento, OUTPUT);

pinMode (Botao1, INPUT_PULLUP); 
pinMode (Botao2, INPUT_PULLUP); 

}

void loop(){

  //Verifica qual o tempo de exposiçao. 
  int potValue = analogRead(potPin1);
  int exposure = map(potValue, 0, 1023, 1, 10); 

  if (exposure < 0) exposure = 0; 
  if (exposure > 10) exposure = 10;  

  unsigned char button1 = digitalRead(Botao1); 
  unsigned char progress = 0; 
  unsigned char butStart = HIGH; 
  
  if (button1 == LOW) { //se carregaste no botao... 
     while (button1 = digitalRead(Botao1) == LOW); //prende-te aqui ate o botao ser solto. 
     butStart = LOW; //quando o butao for solto, da inicio a temporizacao. 
  }else{
     butStart = HIGH; //se nao for carregado, nao facas nada. 
  }
  
  if (butStart == LOW && progress == 0) { //alguem carregou no botao e o temporizador nao esta a andar. 
    timerInicial = millis(); //tempo inicial. 
    progress = 1; //a funçao esta em progresso. 
    lcd.setCursor(0,0);
    lcd.print ("     ligou      ");
    digitalWrite(Luz, HIGH);
  }
  
  if ((millis() - timerInicial >= intervalo) && (progress == 1)) { //a funcao ainda esta a correr e o tempo acabou... 
    progress = 0; //a funçao nao esta em progresso. 
    lcd.setCursor(0,0);
    lcd.print("    desligou    ");
    digitalWrite (Luz, LOW);
  }
  
if (butStart == LOW && progress == 1) { //carregaste no botao e a funcao esta a correr...
  progress = 0; //a funçao nao esta em progresso. 
  lcd.setCursor(0,0);
  lcd.print("    desligou    ");
  digitalWrite (Luz, LOW);
  }
}

Isto basicamente começa a temporização quando soltares o dedo do botão1. E se voltares a carregar, ele para tudo.
Quando carregares de novo, o ciclo começa de novo. Não foi usado um único goto…

Eu reparei que tinhas um código para debounce, não sei se tens problemas de debounce ou não, mas a parte inicial que prende o programa quando o utilizador carrega no botão pode ser substituída por um código de debouce mais sofisticado.
Depois para começar a sequência apenas tens de colocar a variável butStart a LOW.

A propósito do delay...

http://forum.arduino.cc/index.php?topic=228748.0

bubulindo: Eu tinha já falado do goto?? Provavelmente noutro post. Eu não tenho problemas em ver goto usado num programa... mas para o considerar correcto a pessoa que o usou tem de me mostrar que:

  • Não há outra opção melhor.
  • Havendo outra opção melhor, o uso de goto torna o programa mais eficaz/rápido, etc...
  • Mesmo usando o goto, ele tem de ser usado dentro de certos limites e não esporadicamente.

Se procurares na net, certamente que encontrarás alguns dos mais conceituados programadores mundiais a defender o uso do goto. A diferença entre eles e grande parte das pessoas que acham que se deve usar o goto é que eles conseguem explicar porque é que o goto é usado ali e quais os perigos (se ainda existentes) de o fazer. A maioria das pessoas não o consegue fazer.

Os professores (tipo os meus da faculdade) são é preguiçosos e não querem falar disto. Após um ano de programação C, uma pessoa deve ter saber suficiente para entender os perigos do goto e nada que uma aula aberta de uma ou duas horas não esclarecessem isto com os alunos e os deixassem melhor formados sobre isto. Para que fique notado a única coisa que aprendi sobre o goto em 5 anos de universidade foi "Não podem usar o goto."

algumas das coisas que li sobre o goto assinalam exatamente o que você apontou, o que vi foi uma pergunta de um rapaz na parte inglesa do fórum e muitas pessoas fazendo chacota do guri por usar goto, inclusive um moderador global, o que me deixou bastante confuso e definitivamente me desencorajou em seguir nessa direção. e é lamentável saber que isso é uma prática acadêmica, saber dos perigos do uso, como evitá-lo e em que casos especiais deve ser usado deveria ser uma prática mesmo, mas enfim, mais uma vez obrigado pelo esclarecimento.

bubulindo: Dito isto, nota que ainda hoje não vejo o uso de goto em programas meus... mas nunca vi necessidade de o usar.

Acho que o teu segundo parágrafo não é indicativo do fórum. Eu sou muito provavelmente das pessoas mais criticas que contribui para o fórum e tu podes fazer as perguntas mais idiotas que pensares desde que suportes o que pretendes fazer, fizeste e onde procuraste sem achar uma resposta, e certamente que não serás criticado por isso. O que eu critico é quando as pessoas chegam aqui, dizem que querem fazer um robot e esperam que a malta faça tudo para elas.

totalmente de acordo, ainda mais porque existem já projetos prontos a torto e a direito de como fazer esse ou aquele robô, eu tenho um pouco de experiência com fóruns, já moderei um fórum de counter-strike LOL quando era mais jovem e de fato, as pessoas vão com sede ao pote e esquecem que todo a ajuda é voluntária, mas eu sempre acreditei que as pessoas não fazem isso por serem folgadas, mas por acharem que existe uma resposta pronta, como em matemática, talvez não saibam direito que uma linguagem de programação é exatamente isso, uma linguagem, é preciso aprender a falar, entender e ler essa nova linguagem para poder escrever.

bubulindo: Quanto à pureza do código... "ensina um homem a pescar e não tens de lhe dar de comer". Se focamos, talvez em demasia, certos aspectos do código como o uso do delay ou goto é precisamente para garantir que isso não deita a perder trabalho já feito.

concordo muito com essa filosofia

bubulindo: Se baseares uma funcionalidade num código feito com delay, mais tarde poderás ter de tirar o delay dali e o código deixa de funcionar. Havendo uma maneira mais correcta de fazer as coisas, essa maneira deve ser adoptada. Não fazemos isso para travar as pessoas nos seus projectos, mas apenas para transmitir alguma da experiência e conhecimento. Nota também que em 99,9% dos casos que critico o delay, ninguém respondeu a explicar porque é que o delay ali estava e se era temporário ou não.

Para teres uma ideia... olha aqui um excerto dum programa que estou a fazer...

int randomTime(int span) {
  return ((rand()%span) - (span/2));
}

....   bool ok = radio.write( toSend, MSG_LEN );

  // Try again 1s later //not cool... try sleeping.   delay(3000 + randomTime(1000)); // try to make this be random within reason. }




Lá está um delay de 2500 a 3500 milisegundos. Algo que eu digo abertamente que não deve ser feito. 
No entanto, neste caso o delay está aqui para bloquear o programa que vai enviar dados de X em X tempo. O Arduino vai estar ligado a um carregador de telemóveis e os dados do rádio são apenas enviados do Arduino para um hub central. Não tem comunicação série e como não é alimentado a bateria, não estou a ter grandes preocupações com o consumo. 
O meu objectivo com este projecto é recolher dados da minha casa. Não ter um sistema robusto de controlo, logo o delay nesta aplicação não é muito descabido. 

Por outro lado, um dos nós deste sistema vai estar na garagem... alimentado a pilhas. Esse vai ser bastante diferente no que toca a delays no código para aproveitar ao máximo a bateria. 

Entendes agora que as coisas não são todas intrinsecamente más... a utilização desinformada delas é que o é. E é isso que eu tento transmitir. Se tu usares um delay e o justificares, eu não tenho problema com isso... mas quando dizes que é assim porque não vi outro método, então há algo a melhorar, né?

Entendo, vejo agora a importância do correto emprego do código, minha oposição em relação ao tema é tratar a coisa como um tabu e não tratar como deve ser tratado, uma ferramenta que foi usada e abusada por poder ser um atalho, no final das contas, todo principiante escolhe o atalho, evidentemente, não vai trilhar um caminho que possivelmente vai aumentar a carga de complexidade do código, e nessa direção, fica sem saber o perigo do código espaguete, que é realmente um conceito simples de ser explicado, algo que poderia constar na referência do arduino, aliás, você sabe dizer por que a referência não é um wiki?

bubulindo:
Eu alterei um pouco o teu código… creio que é isto que pretendes.

#include <LiquidCrystal.h>

LiquidCrystal lcd (12, 11, 5, 4, 3, 2);

const char Luz = 7;
const char Vento = 8;

const char Botao1 = 10;
const char Botao2 = 9;

const char potPin1 = A5;
const char potPin2 = A4;

unsigned char estado = HIGH;
unsigned char anterior = LOW;
unsigned char leitura;

unsigned long intervalo = exposure * 60000;
unsigned long timerInicial = 0;

void setup(){

lcd.begin(16, 2);
 
Serial.begin(9600);

pinMode (Luz, OUTPUT);
pinMode (Vento, OUTPUT);

pinMode (Botao1, INPUT_PULLUP);
pinMode (Botao2, INPUT_PULLUP);

}

void loop(){

//Verifica qual o tempo de exposiçao.
  int potValue = analogRead(potPin1);
  int exposure = map(potValue, 0, 1023, 1, 10);

if (exposure < 0) exposure = 0;
  if (exposure > 10) exposure = 10;

unsigned char button1 = digitalRead(Botao1);
  unsigned char progress = 0;
  unsigned char butStart = HIGH;
 
  if (button1 == LOW) { //se carregaste no botao…
     while (button1 = digitalRead(Botao1) == LOW); //prende-te aqui ate o botao ser solto.
     butStart = LOW; //quando o butao for solto, da inicio a temporizacao.
  }else{
     butStart = HIGH; //se nao for carregado, nao facas nada.
  }
 
  if (butStart == LOW && progress == 0) { //alguem carregou no botao e o temporizador nao esta a andar.
    timerInicial = millis(); //tempo inicial.
    progress = 1; //a funçao esta em progresso.
    lcd.setCursor(0,0);
    lcd.print ("     ligou      “);
    digitalWrite(Luz, HIGH);
  }
 
  if ((millis() - timerInicial >= intervalo) && (progress == 1)) { //a funcao ainda esta a correr e o tempo acabou…
    progress = 0; //a funçao nao esta em progresso.
    lcd.setCursor(0,0);
    lcd.print(”    desligou    “);
    digitalWrite (Luz, LOW);
  }
 
if (butStart == LOW && progress == 1) { //carregaste no botao e a funcao esta a correr…
  progress = 0; //a funçao nao esta em progresso.
  lcd.setCursor(0,0);
  lcd.print(”    desligou    ");
  digitalWrite (Luz, LOW);
  }
}




Isto basicamente começa a temporização quando soltares o dedo do botão1. E se voltares a carregar, ele para tudo. 
Quando carregares de novo, o ciclo começa de novo. Não foi usado um único goto... 

Eu reparei que tinhas um código para debounce, não sei se tens problemas de debounce ou não, mas a parte inicial que prende o programa quando o utilizador carrega no botão pode ser substituída por um código de debouce mais sofisticado. 
Depois para começar a sequência apenas tens de colocar a variável butStart a LOW.

muito obrigado pela ajuda, vou estudar as suas alterações, acredito que volto a postar códigos novamente quando tiver a versão mais próxima do final.

bubulindo: A propósito do delay...

http://forum.arduino.cc/index.php?topic=228748.0

muito interessante, vejo exatamente o modo de pensar dessa pessoa, eu ainda penso dessa maneira, a maneira de escrever e aprender ao mesmo tempo é copiando, engraçado ver ele ir pelo mesmo caminho que eu.