Ajuda com exercicio livro Arduino Basico

O exercício pede para fazer com LED's um efeito de uma bola quicando.

byte ledPin[7] = {8, 9, 10, 11, 12, 13};
int currentLED = 0;
int ledDelay (100);
int direction = 1;
unsigned long changetime;

void setup(){
for(int x=0; x<6;x++){
pinMode(ledPin[x], OUTPUT);
}
changetime = millis();
}

void loop(){

if ((millis()-changetime) > ledDelay){

changeLED();
changetime = millis();
}
}
void changeLED(){
int y;
for (int x=0; x<6; x++){
digitalWrite(ledPin[x],LOW);

}
int currentLED2 = 5-y;

digitalWrite(ledPin[currentLED],HIGH);
currentLED += direction;
if (currentLED == currentLED2){direction = -1;}
if (currentLED == 0) {direction = 1;}
y++;
}

Esse é o código que eu consegui criar, eu pensei em fazer um numero inteiro 'y' aumentar a cada volta do LED, so que não funcionou.

E o uqe é que o teu código não faz?

Eu, e julgo outros participantes, não estamos aqui para fazer o teu TPC. Se disseres o que o teu código faz e o que pretendes fazer, talvez consigas alguma ajuda. :wink:

Olá amigo, infelizmente estou no trabalho e não poderei te ajudar muito.

Mas olhando rápido para seu programa, posso apontar alguns erros na função changeLED();

Você declarou as variáveis "y" e "currentLED2" dentro dela, mas quando você sai desta função, esses valores se perdem. Você precisará declara-las globalmente, ou seja, no início do programa, para que elas armazenem os valores fora da função também.

Verifique também se toda vez que chamar a função será necessário mesmo fazer "currentLED2 = 5-y" e "y++". Talvez será necessário fazer isso apenas quando currentLED == currentLED2. Eu disse TALVEZ> Não analisei seu programa a fundo.

Você tinha delcarado inicialmente "int y" e depois mandou fazer o cálculo "int currentLED2 = 5-y", mas qual o valor de y? Não sei se por padrão o arduino considera como "0", mas seria melhor declarar já atribuindo um valor para evitar surpresas.

Faça seu algoritmo passo a passo no papel para ver o resultado.

Abraços

O obejtivo do programa é com led em sequencias dessem um efeito de uma bola quicando no chao e perdendo velocidade a cada volta( ou seja a cada volta menos um led ira acender).

Eu vou por um valor no y, mas como eu faço para que cada vez que a iluminaçao do led va e volte aumente o valor do y em 1. Pois aumentando o ultimo currentled iria diminuir a cada passada.

giovannimundim,

Gostei da brincadeira, amanhã vejo com calma teu código (estou no tabalho agora), mas como nosso amigo Filantropic comentou, você precisa armazenar em uma variável global o número de leds da próxima rodada (olhando o código Y será sempre zero e currentLED2 será sempre 5, afinal 5 - 0 = 5).

Com a variável global, a cada loop você terá a referência de quantos leds você quer acender e poderá reduzir o número para a próxima "rodada".

Boa sorte ai!

fala ai giovannimundim!

Como prometi, parei para dar uma olhada no teu código ^^

Pelo que entendi você quer o efeito de uma bola quicando, então a direção inicial seria -1 e o led seria o cinco.

  1. Então a bola cai:
    a direção caindo (direction = -1)
    de cima para baixo (currentLED = 5)
    a referencia da altura é a que a bola foi solta (y = 5)
    a cada loop adicionamos - 1 (currentLED += direction)
    gerando o efeito led 5, led 4, led 3, led 2, led 1, led 0

  2. A bola chega ao chão (led 0):
    neste momento podemos determinar a ação da gravidade, ou seja, a bola só chegará até a altura 4 (y = y -1, ou y--)
    a bola quica, mudamos a direção (direction = -1)
    a cada loop adicionamos +1 (currentLED += direction)
    gerando o efeito led 0, led 1, led 2, led 3, led 4
    então a bola perde a força e cai (e o loop continua de 4 até 0, 0 até 3, 3 até 0, 0 até 2, 2 até 0, zero até 1 e começa novamente)

Veja como ficou o código com a lógica acima:

byte ledPin[] = {8, 9, 10, 11, 12, 13};
int currentLED = 5;
int y = 5;
int ledDelay = 100;
int direction = -1;
unsigned long changetime;

void setup(){
for(int x=0; x < 6;x++){
pinMode(ledPin[x], OUTPUT);
}
changetime = millis();
}

void loop(){
if ((millis() - changetime) > ledDelay){
changeLED();
changetime = millis();
}
}

void changeLED(){
for (int x=0; x < 6; x++){
digitalWrite(ledPin[x], LOW);
}

currentLED += direction;
digitalWrite(ledPin[currentLED], HIGH);

if (direction == 1)
{
if (currentLED == y){direction = -1;}
}
else //direction == -1
{
if (currentLED == 0){
direction = 1;
y--;
if (y == 0)
y = 5;
}
}
}

Repare que o que faltava no teu código era:

  1. colocar o y como variável global
  2. considerar que o y só muda quando a bola bate no chão (direction -1 e currentLED = 0) e não cada vez que ocorre o loop()

com as duas considerações acima foi só acertar o código.

Eu to com preguiça, então rodei o código em um emulador (Virtual Breadboard), se não funcionar no arduíno você me fala rs

Até +

Eu testei o código no Arduíno só que não funcionou.

os LEDs não tem uma sequencia ficam acendendo aleatoriamente.

e outra duvida, como eu estou começando com programação agora eu não entendo muito e essa parte
if (direction == 1)
{
if (currentLED == y){direction = -1;}
}
else //direction == -1
{
if (currentLED == 0){
direction = 1;
y--;
if (y == 0)
y = 5;
}
}
}

você poderia me explicar o 'else'.

if (direction == 1)

Esta parte de cima significa: Se direction for igual a 1, faça isso:

{
if (currentLED == y){direction = -1;}
}

else //direction == -1

Esta parte de cima significa: caso não for então faça isso:

{
if (currentLED == 0){
direction = 1;
y--;
if (y == 0)
y = 5;
}

Algumas observações:
O else significa-> se o que está no if for falso, então faz o que eu estou falando. No caso acima, se directions for diferente de 1, ele vai fazer o "else".

É importante observar que existem dois "if" seguidos. O else é referente apenas ao primeiro if, pois ele está imediatamente após ao fechamento da chave que pertence ao primeiro "if".
Por consequencia disso, se o primeiro "if' for satisfeito mas o segundo "if" não, ele não executará o "else", pois este "else" é referente ao primeiro "if".

No else existe o termo //direction == -1. Este termo é apenas um comentário, que não influencia no programa.

Espero que tenha entendido.

Muito obrigado pela explicaçao, só que o programa ainda nao funcionou. Os LEDs nao tem sequencias, ficam acendendo aleatoriamente.

Ligaste os LEDS nos portos correctos?

Sim, o leds estao ligados corretamente.

Eu nem sequer compilei... mas deve ser isto que pretendes, não?

#define UP    0
#define DOWN  1

byte ledPin[] = {8, 9, 10, 11, 12, 13}; 

void loop() {
  
  LEDChange(); 
  delay(1000); //N~o ´ bonito... mas ´ para demonstrar. 
  
}


void LEDChange() {
  
  static unsigned char sentido = DOWN;
  static unsigned char LED = 5; 
  static unsigned char MaxH = 5; 
  if (sentido == UP) {
    digitalWrite(ledPin[LED] LOW); //desliga o que estava. 
    digitalWrite(ledPin[LED++]; HIGH); //liga o próximo.
    if (LED > MaxH) { //se atingimos a altura máxima... 
      sentido = DOWN; //vamos para baixo. 
      LED = MaxH;  //mas começamos de MaxH
    }  
  } else { //sentido = DOWN
    digitalWrite(ledPin[LED], LOW);   //desliga o anterior
    digitalWrite(ledPin[LED--], HIGH);  //liga o próximo
    if (LED < 0) {  //se chegamos ao chão
      LED = 0;   // não vamos abaixo
      sentido = UP;  //vamos para cima
      MaxH--;   // mas não chegamos tão alto quanto antes. 
      if (MaxH < 0) { // Se atingimos repouso
        MaxH = 5;  // VOLTAMOS AO InÍCIO.
        LED = 5; 
        sentido = DOWN;
      }
  }
}

Vê se funciona. A melhor maneira de fazer troubleshoot disto é colocar um Serial.print com os valores das variáveis para perceberes que bocado de código está a falhar.

Filantropic:
Valeu pelos comentários, muito bem explicado rs

bubulindo:
Teu código ficou bem simples, só acho difícil explicar para novatos a variável do tipo static dentro de um método.
Eu tentei não fugir do código original, apenas adequá-lo, nem me atentei ao loop desnecessário :wink:

giovannimundim: Os leds estavam ligados na sequencia correta (led1 na porta 8, led2 na porta 9, etc)?

Se não funcionar me avisa e eu tento tirar o arduino da gaveta à noite, agora estou no trabalho ^^

Mortis:
bubulindo:
Teu código ficou bem simples, só acho difícil explicar para novatos a variável do tipo static dentro de um método.
Eu tentei não fugir do código original, apenas adequá-lo, nem me atentei ao loop desnecessário :wink:

Uma variável static e uma variável global, na realidade não têm muita diferenca... mas quando fazes um programa com umas quantas linhas, colocar a variável static dentro da funcão em que vai ser usada em vez de ficar perdida dentro dum ficheiro ajuda imenso na leitura do código e evitar problemas com a variável global.

Para ensinar como funciona, nada como:

  • Explicar porque é que é má política usar variáveis globais.
  • Dar um exercício onde é preciso uma variável global para fazer uma funcão simples.
  • Dizer que se usarem o static, a variável passa a ser global (no sentido em que fica na memória), mas apenas acessível dentro daquela funcão.

podes usar o termo global_local se fizer mais sentido... :stuck_out_tongue:

bubulindo:

Mortis:
bubulindo:
podes usar o termo global_local se fizer mais sentido... :stuck_out_tongue:

Esse termo é mais simples kkk

Muito bem explicado, to até anotando para quando me perguntarem :smiley:

o/

De certeza que arranjas melhores explicações... :wink:

Num dos livros que li sobre C, existia um exemplo para demonstrar isso... assim de repente, deve ter sido no do Vitor Damas. Não me lembra se o static estaria na especificação do Kernigan e Ritchie... mas também pode ter sido nesse.

bubulindo:
De certeza que arranjas melhores explicações... :wink:

Num dos livros que li sobre C, existia um exemplo para demonstrar isso... assim de repente, deve ter sido no do Vitor Damas. Não me lembra se o static estaria na especificação do Kernigan e Ritchie... mas também pode ter sido nesse.

As melhores explicações são as mais simples! As vezes nos preocupamos tanto em como explicar que deixamos os "alunos" ainda mais confusos.

O meu codigo esta baseado ate a parte do exercicio do livro, ou seja eu nao conheço essas funçoes estaticas.

Os leds estao ligados corretamentes.

giovannimundim:
O meu codigo esta baseado ate a parte do exercicio do livro, ou seja eu nao conheço essas funçoes estaticas.

Acabou de aprender xD

giovannimundim:
Os leds estao ligados corretamentes.

Estranho não funcionar ai, acabei de copiar e colar o código que te passei e funcionou direitinho... Para facilitar a visuaização podes alterar o dalay de cem para duzendos (int ledDelay = 200);

Veja lá no post

Mortis:
Como prometi, parei para dar uma olhada no teu código ^^

Fiquei com preguiça de rever o código do bubulindo...

Até

giovannimundim:
O meu codigo esta baseado ate a parte do exercicio do livro, ou seja eu nao conheço essas funçoes estaticas.

O livro chama-se Arduino Básico... embora não pareca são duas palavras redundantes. O objectivo do Arduino não é ensinar C, nem tão pouco ensinar microcontroladores porque cerca de 90% das pessoas que o usam não sabem como configurar uma porta com registos ou sequer usar um timer. E depois, como se não bastasse não ter como objectivo ensinar C, é básico. E variáveis static não são básicas e precisam de prática para entender.

giovannimundim:
Os leds estao ligados corretamentes.

E o exemplo que coloquei, funciona?
Os exemplos restantes funcionam?
Colocaste resistências com os LEDs?
Colocaste Serial.print() com os valores das variáveis para entenderes o que está errado? Ou pelo menos uma mensagem a dizer que o Arduino acabou de executar o setup para perceberes se ele está a fazer reset?