Olá a todos! Bom, sou iniciante em programação e pretendo desenvolver um programa onde, com um botão eu possa controlar vários (+ ou - 10) Leds independentemente. seria assim:

aciono um botão e um led se acende por 1min., aciono novamente o botão, outro led se acende por 1 min. também, não interferindo no tempo do led anterior e quando chegasse no último led começaria tudo novamente. Só que tem um detalhe, se o próximo led estiver aceso soma-se mais 1 min. no tempo restante. Já pesquisei muito na net, tentei combinar uns códigos mas sempre dá erro. Alguém pode me ajudar? Desde já agradeço!

Exibições: 3241

As respostas para este tópico estão encerradas.

Respostas a este tópico

Mauricio, boa tarde.

perguntas sobre sua lógica:

1.  Aperto o botão. o 1o LED acende ,  ou quer LED acende por um minuto?

2.  Ex: apertei o botão 1 LED acendeu.  30 seg depois apertei novamente e outro LED vai acender.

    O primeir ficaria +30 seg e o segundo 1minuto. neste caso soma-se +1 minuto em cada um? ou só no segundo?

Rui

Lendo esse problema imaginei um codigo que usasse um IF para ligar led e salvar o instante (usando millis) em que ele foi ligado em uma array e depois um for para comparar todos os valores e desligar os que forem necessarios, algo mais ou menos como no codigo abaixo (não pude testar)

int n=0, intervalo=60000, botao=2;
int led[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int tempo[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

void setup()
{
for(int i=0; i<=9; i++)
{
pinMode(led[i], OUTPUT);
}
pinMode(botao, INPUT);
}

void loop()
{
if(digitalRead(botao)==1)
{
digitalWrite(led[n], HIGH);
tempo[n]=tempo[n]+millis();
if(n==9)
{
n=0;
}else{
n++;
}
}
for(int i=0; i<=9; i++)
{
if(millis()-tempo[i]>=intervalo)
{
digitalWrite(led[i], LOW);

tempo[i]=0;
}
}
}

A array led[] contem os pinos nos quais os leds estao ligados e a array tempo[] contem o instante de tempo em que determinado led (na mesma posiçao da array) foi ligado, por isso inicialmente possui o valor 0 em todas as posições

O primeiro IF alem de ligar o led e armazenar o instante de tempo ainda consegue adicionar mais um minuto como descrito no problema

Você esta usando um resistor de pulldown no botão?

Se não estiver, muda o pinMode(botao, INPUT); para pinMode(botao, INPUT_PULLUP); e coloca GND no botao, alem disso muda o IF de 1 para 0.

tenta adicionar um pequeno delay dentro do IF, cerca de 300~500, ficando assim

if(digitalRead(botao)==1)
{
digitalWrite(led[n], HIGH);
tempo[n]=tempo[n]+millis();
if(n==9)
{
n=0;
}else{
n++;
}

delay(300);
}

Ou cria uma função para deixar o IF sensivel a borda de subida do sinal do botao, verificando o estado anterior e o atual, se for diferente e o atual for igual a 1, executa o codigo.

Olá pessoal,

Eu conheço mais JAVA do que C, portanto, vou postar apenas a lógica. Se gostarem da idéia, eu posso gastar um tempo para preparar o código pro arduíno:

Eu faria quase o que o Arthur fez porém com a diferença de que eu faria a seguinte lógica:

SETUP:

1-No final de cada loop, teria um delay de 10 milisegundos que seria 1/100 segundo.

2-Calcularia o LED seguinte usando módulo: Seria algo assim: n = (n + 1) % 10

3-Após determinar o LED a se somar 1 segundo, soma-se 100 ao valor anterior do elemento correspondente do array: tempo[n] = tempo[n] + 100

4-Diminuir 1 do valor de cada elemento do tempo se o elemento for diferente de zero

for(int i=0; i<10; i++) {
  if(tempo[i]>0) tempo[i] = tempo[i] - 1;
}

5-Atualizar o estado dos LEDs:

for(int i=0; i<10; i++) {
  if(tempo[i]>0) digitalWrite(led[n + 2], HIGH);

  else digitalWrite(led[n + 2], LOW);
}

Espero ter ajudado.

Boa sorte,

  'Eiju

O segundo erro é porque uma variavel do tipo int tem valor maximo de 32767 o que daria menos de 33 segundos (não me atentei a esse detalhe) então para resolver declare a variavel tempo[] como long ao em vez de int, nesse caso teria valor maximo de 2147483647.

long tempo[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

O primeiro erro acredito que possa ser resolvido alterando o codigo dentro do IF para verificar se tempo[n]>0 e se for verdadeiro soma 1000, ficando assim

if(digitalRead(botao)==1)
{
digitalWrite(led[n], HIGH);

if(tempo[n]>0)

{

tempo[n]=tempo[n]+1000;

}else{

tempo[n]=millis();

}

if(n==9)
{
n=0;
}else{
n++;
}
}

Oi Mauricio, bom dia.

Ontem à noite montei este código, mas estava dando um pequeno erro e fui dormir.

Hoje corrigi e testei no UNO.      http://pastebin.com/x8YNPM0V

Ajuste o tempo  de 1seg.

Rui

on

Mauricio,

reduzi o código.   http://pastebin.com/FrcB8cZc

Cuidado com os ruídos da chave (Bounce), tente usar um capacitor  pra melhorar.

Rui

Olá Rui,

Gostei do seu código.

Desculpe-me por fazer o meu código a partir do seu. Fiz isso porque tenho visto suas contribuições e acho seu código muito bem feito.

Achei bacana ter utilizado interrupção, eu aprendi coisa nova.

O meu código está aqui. Eu não tenho como testar agora. Alguém pode testar?

// Liga led com tempos variados
// para uso educativo
// Esta versão utiliza tecnica multitarefa cuidando de cada detalhe a cada 10 milisegundos
// Não considerei a perda de processamento em cada loop pois considerei despresivel
// Eiju 20/05/2015

int botao = 2; // Botao tem que ser no pino 2
int led[] = {4,5,6,7,8,9,10,11,12,13}; // Array definindo os pinos dos 10 leds
int tempo[] = {0,0,0,0,0,0,0,0,0,0}; // Array com o tempo restante de cada led
// cada unidade de tempo corresponde a 10 milisegundos
int ledAtual = 0; // Led selecionado
int contadorBotaoAcionado = 0; // Contador para eliminar bounce

// ------------------------------- funcao principal Setup -------------------------------
void setup() {
pinMode(botao,INPUT); // botao entrada
digitalWrite(Botao,HIGH); // Pull-up
for (unsigned j = 0; j < 10; j++) { // Repetir para cada led
pinMode(led[j],OUTPUT); // Definir pino dos leds como saida
}
}
// -------------------------------- funcao testaBotao -------------------------------
void testaBotao() { // Funcao de tratamento do botao
{
if(digitalRead(botao) == 1) { // Botao esta acionado
contadorBotaoAcionado++; // Incrementa o contador do botao acionado para evitar bounce
if(contadorBotaoAcionado == 3) { // Faz 30 milisegundos desde que o botao foi acionado e continuou
// acionado pois cada loop tem delay de 10 milisegundos
adicionaSegundo(); // Adiciona 1 segundo no LED seguinte
}
} else { // Botao nao esta acionado
contadorBotaoAcionado = 0; // Mantem o contador zerado
}
}
// -------------------------------- funcao adicionaSegundo -------------------------------
void adicionaSegundo() { // Funcao de adicao de 1 segundo ao proximo led
{
ledAtual++; // Incrementa led a ser tratado
if(ledAtual > 9) ledAtual = 0; // Certifica que o led 0 seja o proximo depois do led 9
tempo[ledAtual]=tempo[ledAtual]+100 // Adiciona 100 * 10 milisegundos ao led atual
}
// -------------------------------- funcao principal loop --------------------------------
void loop() {
testaBotao(); // Tratamento do botao
for(unsigned k = 0; k < 10; k++) { // Repetir para cada led
tempo[k]--; // Decrementa 10 milisegundos do led atual
if(tempo[k] < 0) tempo[k] = 0; // Se ficar negativo, zera
if(tempo[k] > 0) { // Se tiver tempo sobrando
digitalWrite(led[k], HIGH) // Acende o led
} else { // Se o tempo estiver zerado
digitalWrite(led[k], LOW) // Apaga o led
}
}
delay(10); // Espera os 10 milisegundos de cada loop
}

Muito obrigado e boa sorte,

  'Eiju

Oi Eijo, bom dia.

Qto ao uso do codigo que escrevi fique tranquilo, a ideia aqui é esta mesma,

um ir ajudando o ourto e melhorar os códigos. Foi divertido participar deste desafio.

Qto ao aprendizado, fico feliz, pois tenho aprendido muito aqui com todos e é bom  saber

que consegui ensinar também.

Sempre fui um cara de Hardware, mas o software é uma "cachaça" e voce vai ficando viciado.

Comecei com PIC em assembler à alguns anos, depois resolvi aprender um pouco de C,

e recetemente (out 14) fui ajudar a um amigo (quase filho), e me embrenhei nas garras do arduino.

Rui

Somente para satisfação pessoal fiz uma simulação no Proteus do código proposto pelo Rui, e publiquei o vídeo no meu canal do youtube para ilustrar este tópico e incrementar meu canal.

https://www.youtube.com/watch?v=oMKJ8JdLWI4&feature=youtu.be

Devido a limitações de simular em tempo real, os tempos virtuais não são exatamente os do código, mas serve como um exemplo.

Abs.

Mauricio, 

Isto aconteceu devido a forma com ligou os LEDs?

Estão invertidos . qdo voce ve apagado pra mim é acesso.

Eu liguei assim:  O lado  negativo dos LEDs em GND, o positivo em resistores de 470 Ohms,

o outro lado  dos resistores nos pinos de 4 a  13.

Funcionou da forma que voce pediu.

testei aqui no proto e funcionou.

Voce pode inverter tb a logica de acendimento.  Trocar HIGH por LOW  e LOW por HIGH no controle dos LEDs.

Rui

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço