intervalador duplo ajustavel

boa noite . eu sou novo aqui no forum e novo com a plataforma arduino.
era-me bastante util se alguem me pudesse dar umas dicas
o que eu quero e o seguinte,
quero dois temporizadores , ajustaveis com 3s 5s 7s e 10segundos em estado on e 5 segundos de estado off entre eles.
nao quero utilizar display. apenas quero acionar relês.

a minha ideia inicial era fazer isto em pcb mas com o arduino fica muito mais simples e em conta. :wink:

PS. a seleção dos tempos dera feita com um switch de varias saidas

Parece-me uma ideia interessante.
A questão seguinte seria: O que já tem feito?
Se está mesmo no início e ainda não fez nada, o meu conselho seria que começasse por dar uma vista de olhos ao exemplo Blink Withou Delay . É o exemplo básico para fazer programas que não parem e fiquem sempre "atentos" aos estímulos externos.
Eu diria que uma boa ideia também seria adicionar LED's para indicar o estado de funcionamento, por exemplo um por saída.

EDIT: Não percebi muito bem o que que dizer com "entre eles" quando diz:

pedromsm94:
boa noite . eu sou novo aqui no forum e novo com a plataforma arduino.
(...)
quero dois temporizadores , ajustaveis com 3s 5s 7s e 10segundos em estado on e 5 segundos de estado off entre eles.
(...)

se fosse um projeto em pcb e eu tivesse que construir o cirquito eu estava porreiro. agora com a programaçao estou completamente a nora .
tenho um arduino uno encostado ha bastante tempo por isso mesmo :C

podes-me indicar algum link onde explique a programaçao de uma forma detalhada, quero aprender!!!!

nao sei se entendi bem o programa (Blink Without Delay)
mas o que eu quero com o meu programa é mais ao menos isto

if pin 1 is high ; pin 5 is high for 3 segundos

pin 5=5 segundos low

if pin 2 is high ; pin 5 is high for 5 segundos

pin 5=5 segundos low

if pin 3 is high ; pin 5 is high for 7 segundos

pin 5=5 segundos low

if pin 4 is high ; pin 5 is high for 10 segundos

if pin13 is high ; pin 5 always on

segundo temporizador

if pin 7 is high ; pin 7 is high for 3 segundos

pin 6=5 segundos low

if pin 8 is high ; pin 8 is high for 5 segundos

pin 6=5 segundos low

if pin 9 is high ; pin 9 is high for 7 segundos

pin 6=5 segundos low

if pin 10 is high ; pin 10 is high for 10 segundos

if pin 12 is high ; pin 10 always on

para este tipo de programa apenas posso ussar as saidas digitais certo ?

No link que forneci anteriormente está o código do exemplo, que pode ser aplicado a este caso. A diferença é que no exemplo, o tempo ligado é igual ao tempo desligado. Aqui, o tempo ligado vai variar, conforme a entrada que está activa.

Em relação à questão das saídas digitais: Sim, para isto as saídas digitais são o indicado. Mas atenção que no Arduino todas as entradas/saídas são digitais, mas há algumas delas que também podem ser analógicas.

ja olhei e reolhei para o codigo e nao estou a comprender como posso adaptalo para a minha necessidade :sweat_smile: :sweat_smile: :sweat_smile:

Não me estranha. Possivelmente é um dos exemplos mais difíceis de perceber para quem está a começar. Eliminando os comentários o programa fica da seguinte forma:

const int ledPin =  13;
int ledState = LOW;             
long previousMillis = 0;        

long interval = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  

    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    digitalWrite(ledPin, ledState);
  }
}

A função millis() devolve o tempo em milissegundos desde que o Arduino começou a trabalhar. Vai sendo sempre incrementada e não há possibilidade de parar ou reiniciar a contagem.

No inicio do ciclo (loop), é lido o valor actual de milissegundos. Se a diferença entre o valor actual e um valor anteriormente guardado for maior que um determinado intervalo de tempo (interval), então o estado (neste caso de um LED) é trocado. Aqui o valor de milissegundos é guardado para que se possa contar o tempo que o LED está neste estado.

No seu caso, O tempo (interval) que o LED (ou o relé no seu caso) está ON tem que ser diferente do tempo que o LED está OFF. Para além disso, o tempo ON depende da entrada que está activa. Portanto, logo após a leitura do tempo, deve ler o estado das entradas para ver qual é o valor do tempo ON que vai aplicar. No if:

   if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

Se o LED está LOW (apagado), para além de passar a ter o estado HIGH (ligado) atribui o valor correspondente à variável interval.

Uma forma de fazer com que o programa tenha tempos diferentes, entre o estado ON e o estado OFF, pode ser a seguinte:

const long INTERVAL_ON  = 100;
const long INTERVAL_OFF = 900;

const int ledPin =  13;

int ledState;
long previousMillis;
long interval;

void setup() {
  pinMode(ledPin, OUTPUT);
  
  ledState = LOW;
  previousMillis = 0;        
  interval = INTERVAL_OFF;
}

void loop()
{
  unsigned long currentMillis = millis();
 
  
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  

    if (ledState == LOW) {
      ledState = HIGH;
      interval = INTERVAL_ON;
    }
    else {
      ledState = LOW;
      interval = INTERVAL_OFF;
    }
    digitalWrite(ledPin, ledState);
  }
}

Neste caso, os tempos ON e OFF são constantes e não podem ser alterados externamente.

Uma vez que é necessário, para além dos tempos diferentes entre o estado ON e OFF, um programa que permita escolher tempos ON diferentes, fiz este exemplo que pode servir como base para isso:

#define LENGHT 4

// Tempo desligado
const long INTERVAL_OFF = 5000;

// Diferentes tempos no estado ligado
const long INTERVAL_ON[LENGHT]  =  {3000, 5000, 7000, 10000};
// Pinos associados aos diferentes estados ligado
const int INPUT_PIN[LENGHT] =  {7, 6, 5, 4};

// Saida (neste caso na saida existe um LED)
const int ledPin =  13;

int ledState;        //estado do LED (LIGADO/DESLIGADO)
long previousMillis; // tempo da ultima vez que foi alterado o estado do LED
long interval;       // intervalo de tempo para mudar o estado do LED
long interval_on;    // intervalo de tempo do LED ligado

int state;          // temporizador escolhido (3s, 5s, 7s ou 10s - 0 = desligado)
int last_state;     // para verificar se o estado foi alterado


void setup() {
  // activa pino de saida
  pinMode(ledPin, OUTPUT);

  // condiçoes iniciais
  ledState = LOW;
  previousMillis = 0;        
  interval = INTERVAL_OFF;

  // inicializaçao dos pinos de entrada
  for (int i=0; i<LENGHT; i++) {
    pinMode(INPUT_PIN[i], INPUT);
    // Liga os pull-up's internos
    digitalWrite(INPUT_PIN[i], HIGH);
  }
}

void loop()
{
  // "mede" tempo actual
  unsigned long currentMillis = millis();
  
  last_state = state;
  state = 0; // se no for lido nenhum estado quer dizer que esta desligado
  
  // Leitura do estado das entradas
  for (int i=0; i<LENGHT; i++) {
    // efectua leitura dos pinos um a um
    if (digitalRead(INPUT_PIN[i]) == LOW) { // se o pino estiver no estado BAIXO ele esta activo
      state = i+1; // serve para que o estado ZERO seja guardado para o caso especial (DESLIGADO)
      break; // se encontra um pino activo, nao continua e ver os restantes
    }
  }
  
  // Se o estado mudo, reinicia
  if (state != last_state && state != 0) {
    interval = 0;   // troca o estado imediatamente
    ledState = LOW; //recomeça com o LED ligado
    interval_on = INTERVAL_ON[state-1]; // guarda o tempo_ON actual
  }
  
  // bloco principal
  if (state != 0) { // So executa se uma das opçoes estiver seleccionada
    
    // verifica se o tempo passou
    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis // guarda o tempo actual

      // troca o estado do LED
      if (ledState == LOW) {
        ledState = HIGH;
        interval = interval_on;
      }
      else {
        ledState = LOW;
        interval = INTERVAL_OFF;
      }
      digitalWrite(ledPin, ledState);
    }
  }
  else {
    // Se esta inactivo, mantem-o assim, e proto a recomeçar
    interval = INTERVAL_OFF;
    ledState = LOW;
    digitalWrite(ledPin, ledState);
    previousMillis = currentMillis;  
  }
}

A saída é a mesma que é usada no programa original (LED ligado à saída 13). O programa oferece 4 possibilidades para escolha do tempo ALTO (pino 7=3s, 6=5s, 5=7s e 4=10s). Caso nenhuma opção esteja seleccionada, o “temporizador” está desligado.

Este programa já é um pouco mais complexo que o original, mas já está muito perto daquilo que pedia originalmente.

Espero que ajude.

Como disse no post anterior, aquele exemplo estava muito próximo da resposta final. Com pouco trabalho, consegue-se acrescentar uma nova saída que faz exactamente o mesmo que a anterior:

#define LENGHT 4
#define OUT_NUMBER 2

const long INTERVAL_OFF = 5000;

const long INTERVAL_ON[LENGHT]  =  { 3000, 5000, 7000, 10000 };
const int INPUT_PIN[OUT_NUMBER][LENGHT] =  { {7, 6, 5, 4  }, {3, 2, 1, 0} };

const int ledPin[OUT_NUMBER] =  { 12, 11 };

int ledState[OUT_NUMBER];        
long previousMillis[OUT_NUMBER]; 
long interval[OUT_NUMBER];      
long interval_on[OUT_NUMBER];   

int state[OUT_NUMBER];         
int last_state[OUT_NUMBER];     


void setup() {
  for (int j=0; j<OUT_NUMBER; j++) {
    pinMode(ledPin[j], OUTPUT);
    ledState[j] = LOW;
    previousMillis[j] = 0;        
    interval[j] = INTERVAL_OFF;
    for (int i=0; i<LENGHT; i++) {
      pinMode(INPUT_PIN[j][i], INPUT);
      digitalWrite(INPUT_PIN[j][i], HIGH);
    }
  }
}

void loop()
{
  unsigned long currentMillis = millis();

  for (int j=0; j<OUT_NUMBER; j++) {
    last_state[j] = state[j];
    state[j] = 0; 

    for (int i=0; i<LENGHT; i++) {
      if (digitalRead(INPUT_PIN[j][i]) == LOW) { 
        state[j] = i+1; 
        break; 
      }
    }

    if (state[j] != last_state[j] && state[j] != 0) {
      interval[j] = 0;   
      ledState[j] = LOW; 
      interval_on[j] = INTERVAL_ON[state[j]-1];
    }

    if (state[j] != 0) { 

      if(currentMillis - previousMillis[j] > interval[j]) {
        previousMillis[j] = currentMillis; 

        if (ledState[j] == LOW) {
          ledState[j] = HIGH;
          interval[j] = interval_on[j];
        }
        else {
          ledState[j] = LOW;
          interval[j] = INTERVAL_OFF;
        }
        digitalWrite(ledPin[j], ledState[j]);
      }
    }
    else {
      interval[j] = INTERVAL_OFF;
      ledState[j] = LOW;
      digitalWrite(ledPin[j], ledState[j]);
      previousMillis[j] = currentMillis;  
    }
  }
}

As saídas são os pinos 12 e 11.
As entradas são as mesmas que no exemplo anterior para a saída 12 e os pinos 3, 2, 1, 0 para a saída 11 (pela mesma ordem que no exemplo anterior (ou seja, pino 3=3s, 2=5s, 1=7s e 0=10s).