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
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...
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...
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.
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...
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?
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
É 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
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.
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 ^^
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
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
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;}
}