Go Down

Topic: Ajuda com exercicio livro Arduino Basico (Read 7972 times) previous topic - next topic

giovannimundim


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
  • , 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
  • ,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.

bubulindo

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. ;)
This... is a hobby.

Filantropic

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


giovannimundim

#3
Sep 04, 2012, 11:37 pm Last Edit: Sep 04, 2012, 11:39 pm by giovannimundim Reason: 1
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.

Mortis

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!

Mortis

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
  • , OUTPUT);
      }
      changetime = millis();
    }

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

    void changeLED(){
      for (int x=0; x < 6; x++){
        digitalWrite(ledPin
  • , 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é +

giovannimundim

#6
Sep 10, 2012, 02:32 am Last Edit: Sep 10, 2012, 05:01 pm by giovannimundim Reason: 1
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'.

Filantropic

Quote

if (direction == 1)


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

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


Quote

 else //direction == -1

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

{
   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.

giovannimundim

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

bubulindo

Ligaste os LEDS nos portos correctos?
This... is a hobby.

giovannimundim

Sim, o leds estao ligados corretamente.

bubulindo

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

Code: [Select]

#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.

This... is a hobby.

Mortis

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 ;)

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 ^^

bubulindo


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 ;)


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... :P
This... is a hobby.

Mortis



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


Esse termo é mais simples kkk

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

o/

Go Up