"execultando bloco de comando por quantidade de pulso

Amigos esse e o meu primeiro post e ja estou querendo ajuda!! eu tenho um certo conhecimento em eletronica mais em programação em arduino so estou me iniciando.
Eu preciso fazer um projetinho aqui e precisava que o arduino funciona-se da seguinte forma. O arduino executaria um determina bloco de comando dependendo da quantidade de pulsos dados em um de seus terminais. Tipo assim se eu der 2 pulsos consecutivos no pino 1 ele executaria um determinado bloco de comando, mais se eu der 3 pulsos no mesmo pino ele executaria outro bloco de comando. Espero ter mim feito entender e desde ja muito obrigado!!!

Ola bem vindo.
O que queres é simples.Ha no entanto uma questão.Como marcas o inicio da tua escolha?
Podias fazer quando o botão for pressionado começa a contar ate 5 segundos e entre esses 5 segundos tu introduzes os impulsos que queres.Passado esses 5 segundos mediante o numero de impulsos passados faz uma ação.
Pode ser assim?

crie uma interrupção..
Ao acionar a interrupção vá para uma função que incremente uma variável, depois vá para um Switch case e determine qual função executar de acordo com a variável anterior... :slight_smile:

joaomenez:
crie uma interrupção..
Ao acionar a interrupção vá para uma função que incremente uma variável, depois vá para um Switch case e determine qual função executar de acordo com a variável anterior... :slight_smile:

E como é que faz reset dos pulsos?

Eu já tive de fazer algo assim, com pulsos de tamanhos diferentes e um problema horrível com que me deparei, foi o bounce dos botões. Já pensaste nisso?

Outro problema é, como disse, o reset dos pulsos, ou seja, tens de dar os teus pulsos dentro de um determinado tempo, senão o sistema guarda um pulso e depois ao dares dois, ele assume três.

Amigos vou explicar o que eu preciso fazer. Na verdade eu preciso fazer um maquina de vending machine, esta maquina terá um noteiro ( http://produto.mercadolivre.com.br/MLB-499033163-frente-para-noteiro-bl700-e-p70-apenas-r-2000-cada-_JM ) este aparelho gera pulsos negativos em um de suas saídas de acordo com a nota que vc passar nele,ou seja se vc colocar um nota de 10 reais ele gera 10 pulso sincronizados em sua saída. E sendo assim o arduino terá que ter entrada para os pulsos, e saída para motores de passos que fará a entrega dos produtos. Como eu quero colocar não só um tipo de produto, a entrega do produto ou o inicio de um determinado bloco de comando pode ser iniciado por um push button que tambem determinara qual produto vai entregar. Amigos a parte eletrônica e gabinetes eu garanto mais na parte do programa eu sou muito iniciante nisso preciso muito da ajuda de vc. Obrigado amigos Bubulindo, HugoPT e Joaomenez pelo interesse.

Você pode fazer algo desse tipo:

// Pino que será conectado o contador - supondo que é o 2
#define CONTADOR_PIN 2

// Tempo para contar os pulsos - 1 s = 1000 ms
#define TEMPO_CONTAGEM 1000

// Contador dos pulsos
int contador;

// Tempo inicial da contagem dos pulsos
long tempoPrimeiroPulso;

// Variavel para iniciar a contar os pulsos
bool contarPulsos;

void setup()
{
  // Define pino do contador como input, e ativa do pull-up (deve funcionar dessa forma, mas nao tenho certeza)
  pinMode (CONTADOR_PIN, INPUT_PULLUP);
  
  contador = 0;
  
  contarPulsos = false;
  
  // Inicia o Serial para debug
  Serial.begin(115200);
  
}

void loop()
{
  // Verifica se foi gerado algum pulso - entrada negativa (LOW)
  if (digitalRead(CONTADOR_PIN) == LOW)
  {
    // Verifica se a contagem ainda não foi iniciada
    if (contarPulsos == false)
    {
      tempoPrimeiroPulso = millis(); // Atualiza valor do tempo inicial
      contador = 1;                       // Inicia o contador
      contarPulsos = true;              // Inicia a contagem de pulsos
    }
    else // Se já iniciou a contagem...
    {
      contador++;                     // ... adiciona 1 ao contador
    }
  }

  // Verifica se estava sendo feita a contagem e se o tempo já passou
  if ((contarPulsos == true) && (millis() >= (tempoPrimeiroPulso + TEMPO_CONTAGEM)))
  {
    // Para a contagem
    contarPulsos = false;
    
    // Realiza ação de acordo com a quantidade de pulsos. Por enquanto, só um print do valor para verificar o código
    Serial.println(contador);
    
  }
  
}

O código não foi testado na IDE, então erros inesperador podem ocorrer :P.

Era isso que tinha em mente
Depois no final basta juntar um switch case para fazer as açoes mediante o numero de impulsos obtidos.

  switch (contador) {
    case 1:
      //faz algo se o contador for 1
      break;
    case 2:
       //faz algo se o contador for 2
      break;
    default: 
    Serial.println("Funcao por defeito");
      //caso nao entre em nenhum dos casos faz sempre este default
  }

Amigos já vou testar e lhes reporto os resultados. obrigado!!!

Amigo LegendBR eu testei o programa que vc me passou mais ele não esta contando os pulsos. Eu ligo o noteiro e passo uma nota de dois reais o que geraria 2 pulsos mais depois dos pulsos no serial monitor aparece os seguintes dados;
28373
25729 // Portanto não esta gerando números patrão,e não dá para vincular para chamar
21427 // determinados blocos de programa.
13246 //
20371 //Conto com a ajuda de vcs amigos!!!
-31266

Vamos debugar, então, e tentar entender como funciona esse noteiro. Tenta o seguinte código:

// Pino que será conectado o contador - supondo que é o 2
#define CONTADOR_PIN 2

void setup()
{
  // Define pino do contador como input, e ativa do pull-up (deve funcionar dessa forma, mas nao tenho certeza)
  pinMode (CONTADOR_PIN, INPUT_PULLUP);
  
  // Inicia o Serial para debug
  Serial.begin(115200);
  
}

void loop()
{
  // Verifica se foi gerado algum pulso - entrada negativa (LOW)
  if (digitalRead(CONTADOR_PIN) == LOW)
  {
    // Imprime que o pino está LOW
    Serial.print("Pino LOW no tempo");
    Serial.println(millis());
  }
}

Monitora o serial, passa a nota de 2 reais e diz o resultado. Mas comece a monitorar antes de passar a nota, para termos certeza de que o pino só vai para LOW quando a nota é passada.

De fato há um erro no meu código, eu só deveria contar o pulso quando o pino fosse de LOW para HIGH, mas primeiro vamos ter certeza de que o hardware está funcionando como o esperado.

Amigo legendBR a impressão que tenho e que este programa não esta contando a quantidade de pulsos mais sim o tempo de cada pulso...veja o novo resultado como dois pulsos do noteiro;
Pino LOW no tempo1752
Pino LOW no tempo1752
Pino LOW no tempo1753
Pino LOW no tempo1753
Pino LOW no tempo1975
Pino LOW no tempo1976
Pino LOW no tempo1976
Pino LOW no tempo1977
Pino LOW no tempo1979
Pino LOW no tempo1981
Pino LOW no tempo1983

Amigo tenta com o código que eu dei uma modificada...

#define CONTADOR_PIN 2
unsigned long tempo;
void setup()
{
  pinMode (CONTADOR_PIN, INPUT_PULLUP);
 Serial.begin(115200);
  
}

void loop()
{
while(digitalRead(CONTADOR_PIN)){} //fica aqui enquanto estiver high
tempo=millis(); 
while(!digitalRead(CONTADOR_PIN)){} //esperar até fim do pulso
Serial.print("OFF ");
Serial.println(tempo-millis()); //largura do pulso
}

Uma outra opção seria ligar a interrupção por FALLING nesse pino, na primeira detecção inicia um timer ou variavel com millis e finaliza e faz a ação assim que detectar que tempo passou 100ms alem do possivel novo pulso.

Esse código não te dará o numero de impulsos mas sim a duração deles.
Fiz este pequeno código.
Testa ai e diz o resultado

#define Pino_Entrada_Pulsos 2
#define tempoMaximoDaAnaliseMoedeiro 3000 //3 segundos 

volatile unsigned int contador = 0;
unsigned long startCounting = 0;

void setup()
{
  pinMode(Pino_Entrada_Pulsos, INPUT);
  digitalWrite(Pino_Entrada_Pulsos, 1); //Activa o internal pull-up
  attachInterrupt(0, contaImpulsos, FALLING);
  
}

void loop()
{
   if((millis() - startCounting) >= tempoMaximoDaAnaliseMoedeiro)
   {
    //Significa que o tempo de leitura do moedeiro expirou e podemos recolher o contador
    Serial.println(contador);
    contador = 0;
    startCounting =0;
  }
}

void contaImpulsos()
{
  startCounting = millis();
  contador++;
  
}

vagner:
Amigo legendBR a impressão que tenho e que este programa não esta contando a quantidade de pulsos mais sim o tempo de cada pulso...veja o novo resultado como dois pulsos do noteiro;
Pino LOW no tempo1752
Pino LOW no tempo1752
Pino LOW no tempo1753
Pino LOW no tempo1753
Pino LOW no tempo1975
Pino LOW no tempo1976
Pino LOW no tempo1976
Pino LOW no tempo1977
Pino LOW no tempo1979
Pino LOW no tempo1981
Pino LOW no tempo1983

Sim, a ideia era para verificar se o noteiro está gerando os pulsos, e parece que está sim. O código do HugoPT deve funcionar, eu só faria uma pequena modificação para que ele não fique imprimindo o tempo todo:

#define Pino_Entrada_Pulsos 2
#define tempoMaximoDaAnaliseMoedeiro 3000 //3 segundos 

volatile unsigned int contador = 0;
unsigned long startCounting = 0;

void setup()
{
  pinMode(Pino_Entrada_Pulsos, INPUT);
  digitalWrite(Pino_Entrada_Pulsos, 1); //Activa o internal pull-up
  attachInterrupt(0, contaImpulsos, FALLING);
}

void loop()
{
   if(((millis() - startCounting) >= tempoMaximoDaAnaliseMoedeiro) && (startCounting != 0))
   {
    //Significa que o tempo de leitura do moedeiro expirou e podemos recolher o contador
    Serial.println(contador);
    contador = 0;
    startCounting =0;
  }
}

void contaImpulsos()
{
  startCounting = millis();
  contador++;
  
}

Só um comentário: tempoMaximoDaAnaliseMoedeiro vai ser o tempo que você vai ficar aguardando após o último pulso para a execução do código. Pelos resultados postados por você do outro código que eu coloquei, acho que você pode utilizar 500 (0.5 s) tranquilo.

@HugoPT

Só uma dica para os seus próximos códigos (se é que você já não segue): o Padrão de Codificação recomenda que constantes (#define ou const) sejam declaradas / utilizadas com todas as letras em maiúsculo. Da mesma forma que a indentação, isso facilita a leitura do código ;).

Padrão de Codificação recomenda que constantes (#define ou const) sejam declaradas / utilizadas com todas as letras em maiúsculo. Da mesma forma que a indentação, isso facilita a leitura do código smiley-wink.

Tens toda a razão. Obrigado pela correção.

Estou mesmo sem tempo para verificar isto, mas se o teu sinal vindo dos botões for limpo, ou seja, sem bounce. Podes configurar o Timer1 para ler os pulsos do pino 5 do Arduino e contar os segundos com o timer0 (millis).

Caros amigos me desculpa a demora para responder e que meu trabalho me toma muito tempo,mais vamos lá...Amigo fabiohbm007 usei o seu code e veja os resultados; eu passei uma nota de dois reais por 4 vezes consecutivas o gerou 8 pulsos com os seguintes resultados:
OFF 4294967247
OFF 4294967246
OFF 4294967247
OFF 4294967246 Bom eu ate entendo o porque de vcs quererem medir o tempo dos pulsos mais ate
OFF 4294967247 agora não consegui entender que tipo de dados vai gerar pra chamar o bloco de
OFF 4294967247 programa. Há só como mais referencias,estes noteiro aceita notas de 2,5,10,20,50
OFF 4294967247 reais portanto qualquer pulso que passar de 1 logicamente será 2 e qualquer pulso
OFF 4294967245 que ficar entre 3 e 5 poderá ser considerado como 5 e assim por diante 6 a 10=10
11 a 20=20, 21 a 50 = 50 .

Amigo HugoPT o seu code não imprime nada nada no serial monitor poderia dar mais uma olhada pra ver o que esta acontecendo. Meus agradecimentos a você amigo HugoPT e LegendBR. Conto com Vocês.

Tenta esse para ver no que dá:

#define Pino_Entrada_Pulsos 2
#define tempoMaximoDaAnaliseMoedeiro 3000 //3 segundos 

volatile unsigned int contador = 0;
unsigned long startCounting = 0;

void setup()
{
  pinMode(Pino_Entrada_Pulsos, INPUT);
  digitalWrite(Pino_Entrada_Pulsos, 1); //Activa o internal pull-up
  attachInterrupt(0, contaImpulsos, FALLING);
}

void loop()
{
   if(((millis() - startCounting) >= tempoMaximoDaAnaliseMoedeiro) && (startCounting != 0))
   {
    //Significa que o tempo de leitura do moedeiro expirou e podemos recolher o contador
    Serial.println(contador);
    contador = 0;
    startCounting =0;
  }
}

void contaImpulsos()
{
  startCounting = millis();
  contador++;
  Serial.print("Contando, no tempo ");
  Serial.println(millis());
}

Mas cara, acho que já deu para você ter uma ideia de como as coisas funcionam. Tenta mexer no código você agora, e mostrar aqui o resultado, afinal não vai dar para nós fazermos todo o código, não é? :wink:

Amigo LegendBR esse ultimo code não imprime no serial monitor... Amigo eu já estou entendendo bastante coisas, graças a vocês pois só tem duas semanas que estou tentando aprender programar em arduino prometo me empenhar mais. Amigo LegendBR eu andei mexendo naquele primeiro code que vc fez pra mim, aumentei o tempo para 5 segundos e mudei o pino de entrada para o pino 5 e coloquei um resistor de 220R entre o pino 5 e os 5 volts. Os resultados melhorarão bastante, veja:
9042
9043 Os resultados 904x foram obtido com notas de 2 reais, cada resultado por vez que passei a nota
9043 Os resultados 2260x foram obtidos com notas de 5 reais. Daria para fazer a leitura somente dos
9041 dois primeiros dígitos descartando os demais para fazer o que intenciono?
9043
22605
22607
22605
22607
22607