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!
Tags:
As respostas para este tópico estão encerradas.
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
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por