Ajuda com exercicio livro Arduino Basico

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?

Oi pessoal,

Acabei de me registrar aqui no forum só pra dizer que, eu estava com o mesmo problema do giovannimundim, mesmo livro, mesmo exercício, e o código que o Mortis passou funcionou direitinho, e, acredito que eu entendi a lógica de funcionamento dele (talvez não conseguisse fazer de novo sozinha... mas, por enquanto tá bom!). Na verdade eu usei só a parte final da função changeLED.

Vou colocar aqui como ficou, talvez ajude alguém:

byte ledPin[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // cria um array  para os pinos LEDs
int ledDelay; //intervalo entre as alterações
int direction = 1;
int currentLED = 0;
int LEDquique = 9;
unsigned long changeTime;
int potPin = 2; // seleciona o pino de entrada para o potenciômetro

void setup(){
  for (int x=0; x<10; x++) { // define todos os pinos como saída
    pinMode(ledPin[x], OUTPUT);}
  changeTime = millis();
}

void loop(){
  ledDelay = analogRead(potPin); // lê o valor do potenciômetro
  if ((millis() - changeTime) > ledDelay){ // verifica se ja transcorreram ledDelay ms desde a última alteração
    changeLED();
    changeTime = millis();
  }
}

void changeLED() {
  for (int x=0; x<10; x++) { // apaga todos os LEDs
    digitalWrite(ledPin[x], LOW);
  }
  digitalWrite(ledPin[currentLED], HIGH); // acende o LED atual
  currentLED += direction; // incrementa de acordo com o valor direction

  if (direction == 1)
  {
    if (currentLED == LEDquique){direction = -1;}
  }
  else //direction == -1
  {
    if (currentLED == 0){
      direction = 1;
      LEDquique--;
        if (LEDquique == 0){LEDquique = 9;}
    }
  } 
}

obs: no meu caso estou usando os 10 pinos digitais para os leds, e a variável y do Mortis aqui é LEDquique

Nao sei porque, testei agora o codigo do mortis e funcionou;

Muito obrigado

Também testei o programa do bubulindo, mas na hora de compilar esta dando um erro.

Olá Erica, sou novo por aqui também rs

É muito legal compartilhar, valeu pelo código, certamente ajudará outras pessoas.

ericamattos:
talvez não conseguisse fazer de novo sozinha...

Consegue sim! Mesmo que não seja na primeira, quando persistimos conseguimos! Tudo é difícil enquanto nós não sabemos como funciona, depois fica fácil :wink:

giovannimundim:
Nao sei porque, testei agora o codigo do mortis e funcionou;

Muito obrigado

Também testei o programa do bubulindo, mas na hora de compilar esta dando um erro.

giovannimundim, Obrigado pela confirmação, eu estava sem saber como te ajudar.

o código do bubulindo precisa de uma pequena revisão, se der no final de semana eu testo e posto o revisado.

Eu uso pouco as variáveis estáticas, pois, até o momento, minha variáveis globais são usadas em mais de um bloco (método/função), mas é sempre bom sabermos o maior número de recursos.

Sou novato também, mas estamos aqui =)

giovannimundim:
Também testei o programa do bubulindo, mas na hora de compilar esta dando um erro.

É bom saber que sou humano de vez em quando. :slight_smile:

#define UP       0
#define DOWN  1

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

void loop() {
  LEDChange(); 
  delay(1000); //Nao e bonito... mas e 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;
      }
  }
}

Estee tinha um pequeno erro... vê se funciona. :slight_smile: Agora estou curioso.

bubulindo coloquei seu codigo e quando fui compilar apareceu esse erro "expected `}' at end of input"

#define UP       0
#define DOWN  1

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

void setup() {

//fazer setup dos pinos. 
for (int i = 0; i<6; i++) {
  pinMode(ledPin[i], OUTPUT);
}
};

void loop() {
  LEDChange(); 
  delay(1000); //Nao e bonito... mas e 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;
      }
  }
}
}

Já está.

bubulindo acabei de testar seu codigo, nao funcionou, os seis primeiros LED's ficam acesos, e nao muda mais.

bubulindo:
static unsigned char sentido = DOWN;
static unsigned char LED = 5;
static unsigned char MaxH = 5;

existe um problema nas variáveis declaradas, pois unsigned char é o mesmo que bit, ou seja de 0 a 255, por isso a variável LED e Max H jamais serão menores que zero ^^

Edit: o ideal seria static int LED = 5;

Olá!

Agora a pouco precisei sair ^^

tentei explicar cada passo das alterações, mas estava meio confuso.

Bom, com as alterações abaixo funcionou, mas creio que esteja meio parretado rs

#define UP       0
#define DOWN  1

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

void setup() {

//fazer setup dos pinos. 
for (int i = 0; i<6; i++) {
  pinMode(ledPin[i], OUTPUT);
}
};

void loop() {
  LEDChange(); 
  delay(300); //Nao e bonito... mas e 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.
    LED++;
    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
    if (LED == 6)
      digitalWrite(ledPin[0], LOW); //depois de MaxH == 0 o LED é 5, então o zero não é apagado
    
    digitalWrite(ledPin[LED], LOW);   //desliga o anterior
    LED--;
    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 = 6; 
        sentido = DOWN;      
      }
    }
  }
}

bubulindo, o que tens a dizer? Marretei demais? rs

Mortis:
existe um problema nas variáveis declaradas, pois unsigned char é o mesmo que bit, ou seja de 0 a 255, por isso a variável LED e Max H jamais serão menores que zero ^^

Edit: o ideal seria static int LED = 5;

My bad. Tens razão. Mas o ideal seria char. -126 a 127.

Segundo o que percebi, alteraste as condicões para nunca testar abaixo de zero e alteraste os decrementos e incrementos para fora da digitalWrite()... algum motivo para isso?

Edit:

Tive um tempinho para brincar com isto no Visual Studio e o meu printout deste código funciona trocando apenas o unsigned char por char.

Se quiserem experimentar num compilador de C para PC:

#define UP       0
#define DOWN  1

unsigned char ledPin[] = {8, 9, 10, 11, 12, 13}; 
//adaptei a digitalWrite do Arduino para PC.... he eh
void digitalWrite(unsigned char* pin, unsigned char state){
    *pin = state;
};

void LEDChange() {
  //alterei estas variáveis....
  static char sentido = DOWN;
  static char LED = 5; 
  static char MaxH = 5; 
//mas o resto ficou igual. 
  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;
      }
  }
}
//adicionei isto para debug na consola. 
  printf("LED = %d\n", (int)LED);
  printf("Sentido = %d\n", (int) sentido);
  printf("MaxH = %d\n", (int) MaxH);
}


int main(char argc, char** argv) {
	int i;
	printf("Hello, world!!\n");
//60 iteracões dá para ver o algoritmo a funcionar... 
	for (i = 0; i <60; i ++) {
		LEDChange();
	}
	getchar();

	return 0; 
}

E tirando a parte final em que a bola regressa ao início, o código funciona. :S

bubulindo:

Mortis:
Segundo o que percebi, alteraste as condicões para nunca testar abaixo de zero e alteraste os decrementos e incrementos para fora da digitalWrite()... algum motivo para isso?

Eu colei o teu código no compilador do arduino e fui alterando o que parecia causar os problemas, com as alterações funcionou. Não testei teu código no VS, mas se tentares rodar usando o software do arduino não irá funcionar. As limitações estariam no compilador do arduino?

O que eu mudei e porque:
Com os encrementos e decrementos dentro da digitalWrite o arduino ligava todos os 6 leds em sequencia (a cada loop) e não os desligava (como citou o giovannimundim). Colocando-os para fora, os leds ligaram e desligaram, mas ainda não corretamente (se rodar neste estágio verás que a cada virada de up para down o led maxH não é desligado).

Para resolver o acima foi usado == no lugar de ><. Porem, quando o MaxH == 0 o led 0 não aparava, então forcei LED = 6 quando MaxH == 0 e tratei isso no inicio do sentido down:

if (LED == 6)
digitalWrite(ledPin[0], LOW); //depois de MaxH == 0 o LED é 5, então o zero não é apagado

apesar de que faltou ai um else ^^ deveria ficar assim:

if (LED == 6)
digitalWrite(ledPin[0], LOW); //depois de MaxH == 0 o LED é 5, então o zero não é apagado
else
digitalWrite(ledPin[LED], LOW); //desliga o anterior

Afinal não existe led na posição 6 do array :wink:

Abraço,

Cara, segue abaixo o meu código completo:

//Bola quicando

byte ledPin[] = {4, 5, 6, 7, 8, 9, 10, 11}; // Cria um array para os pinos dos LEDs
int ledDelay; // intervalo entre as alterações
int direction = 1;
int currentLED = 0;
unsigned long changeTime;
int potPin = 2; // seleciona o pino de entrada para o potenciômetro
int cont=0, max=7;

void setup() {
for (int x=0; x<8; x++) { // define todos os pinos como saída
pinMode(ledPin[x], OUTPUT); }
changeTime = millis();
}
void loop() {
ledDelay = analogRead(potPin); // lê o valor do potenciômetro
if ((millis() - changeTime) > ledDelay) { // verifica se transcorreram ledDelay ms desde a
// última alteração
changeLED();
changeTime = millis();
}
}
void changeLED() {
for (int x=0; x<8; x++) { // apaga todos os LEDs
digitalWrite(ledPin[x], LOW);
}
digitalWrite(ledPin[currentLED], HIGH); // acende o LED atual
currentLED += direction; // incrementa de acordo com o valor de direction
// altera a direção se tivermos atingido o fim
if (currentLED == max-cont){
direction = -1;
}
if (currentLED == 0) {direction = 1; cont++;}
if (cont==6) {cont=0;}
}

Espero ter ajudado, qualquer coisa pode me comunicar através do email vilmar.rodrigs@gmail.com