• Welcome to LusoRobótica - Robótica em Português.
 

Alternar leds fazendo um fade entre eles

Started by joaobernardino, 27 de October de 2010, 21:08

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

joaobernardino

Boa noite, estou agora a iniciar-me no mundo arduino. O meu projecto é o seguinte Kaoss Pad Touch Screen Midi Controller .
O led RGB tem dois programas, um loop que está sempre a executar e outro que activa quando toco no touchpad e que depois altera a cor consoante o movimento.
Agora de inicio como ainda não chegou o touchpad estou a trabalhar no led RGB quando está solto, o loop, mas sem sucesso.
Eu queria fazer o seguinte :

motion de 0 para 255 a voltar a 0 com o vermelho
motion de 0 para 255 a voltar a 0 com o verde
motion de 0 para 255 a voltar a 0 com o azul
motion de 0 para 255 com vermelho juntamente com motion de 0 para 255 com azul para dar roxo

etc...

Alguém me consegue ajudar ??

joaobernardino

Como se fosse este exemplo:
Mas com um fade entre cada cor e não pode ser tão demorado porque vou estar a enviar sinal midi em simultâneo.



/*
* Codigo para testar led RGB
* Ativa as cores principais dos leds em sua intensidade maxima e as misturas entre elas
* Baseado no exemplo constante no site do Arduino
* Jeronimo Avelar Filho <jeronimo@blogdoje.com.br>
*/

// Saida
int greenPin = 6; // conectado ao led verde no pino 09
int bluePin = 9; // conectado ao led azul no pino 10
int redPin = 5; // conectado ao led vermelho no pino

// Variaveis do Programa

int wait = 500; // 500 ms menor valor = transicoes rapidas
int i ;

void setup()
{

pinMode(redPin, OUTPUT); // configura os pinos como saida
pinMode(greenPin, OUTPUT); // não é necessario no Arduino007
pinMode(bluePin, OUTPUT);
i = 1 ;

}

// Main program
void loop()
{

switch (i) { //

case 1: // Vermelho
ativaRgb(255,0,0) ;
break;

case 2: // Verde
ativaRgb(0,255,0) ;
break;

case 3: // Azul
ativaRgb(0,0,255) ;
break;

case 4: // Amarelo
ativaRgb(255,255,0);
break;

case 5: // Cyano
ativaRgb(0,255,255) ;
break;

case 6: // Magenta
ativaRgb(255,0,255) ;
break;

case 7: // Branco ( todos os leds acessos)
ativaRgb(255,255,255);
break;

}
delay(wait) ;
i=i+1 ;
if( i > 7) i= 1 ;

}

void ativaRgb(int redVal,int greenVal, int blueVal) {

analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho
analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde
analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul

}

microbyte

Não precisas de fazer assim.
Nem precisas de delay para fazer o fade. Usas o millis() para fazer o fade como queres, e o delay para controlares o fluxo de dados de MIDI.

Dá uma olhada: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Só tens de ter uma variável que guarda o valor para cada um dos LEDs (0-255) e mais uma para o estado (8 estados para o que queres fazer - 4 para fazer subir os valores e outros 4 para descer), depois a de cada vez que queres actualizar os LEDs, lês primeiro o estado e depois actuas consoante esse estado.

joaobernardino

Obrigado pela rápida resposta. Não consegues dar um exemplo mais concreto?
Porque eu tenho 3 saídas e não uma e não estou a ver como fazer o fade..

Desculpa a minha ignorância no assunto!

microbyte

Ok... Vamos lá então.  :)

Defines 8 estados: (exemplo apenas)
1- aumentar vermelho até 255
2- diminuir vermelho até 0
3- aumentar verde até 255
...
7- aumentar vermelho+azul até 255
8- diminuir vermelho+azul até 0

Para saberes em que estado estás, defines uma nova variável inteira:
int state = 1;

depois para cada um dos LEDs defines os valores:
int redVal = 0;
int greenVal = 0;
int blueVal = 0;


A função millis() retorna-te o nº de milisegundos que passaram desde que o código começou a correr (tipo unsigned long).
Logo tens de ter mais duas variáveis:
unsigned long previousMillis = millis();
unsigned long currentMillis;


currentMillis = millis();

if(currentMillis - previousMillis > 500) { // Se quiseres fazer o update a cada 500ms
  previousMillis = currentMillis;  // salvas o novo valor de tempo

  // fazes o que queres de acordo com o estado
  switch(state){
    case 1:
    {
      if(redVal < 255) redVal++; // se ainda nao chegámos aos 255, aumenta o valor de redVal
      else state = 2; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 2:
        ................

    case 7:
    {
      if(redVal < 255){
        redVal++;
        blueVal++;
      }else state = 8;
      break;
    }
  }
 
  // Actualizas os valores nos LEDs, independentemente do estado
  analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho
  analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde
  analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul
}


Espero que tenhas percebido o suficiente para conseguires completar o código com o resto das condições, estados, etc...
Não te esqueças que a troca de estado quando estás no último, é para o primeiro...

joaobernardino

Assim?




void setup(){
  int state = 1;
 
case 1: // Vermelho
int redVal = 255;
int greenVal = 0;
int blueVal = 0;
break;

case 2: // Verde
int redVal = 0;
int greenVal = 255;
int blueVal = 0;
break;

case 3: // Azul
int redVal = 0;
int greenVal = 0;
int blueVal = 255;
break;

case 4: // Amarelo
int redVal = 255 ;
int greenVal = 255;
int blueVal = 0;
break;

case 5: // Cyano
int redVal = 0;
int greenVal = 255;
int blueVal = 255;
break;

case 6: // Magenta
int redVal = 255;
int greenVal = 0;
int blueVal = 255;
break;

case 7: // Branco ( todos os leds acessos)
int redVal = 255;
int greenVal = 255;
int blueVal = 255;
break;
}

void loop(){
unsigned long previousMillis = millis();
unsigned long currentMillis;


currentMillis = millis();

if(currentMillis - previousMillis > 500) { // Se quiseres fazer o update a cada 500ms
  previousMillis = currentMillis;  // salvas o novo valor de tempo

  // fazes o que queres de acordo com o estado
  switch(state){
    case 1:
    {
      if(redVal < 255) redVal++; // se ainda nao chegámos aos 255, aumenta o valor de redVal
      else state = 2; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 2:
    {if(greenVal < 255) greenVal++; // se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
       

    case 7:
    {
      if(redVal < 255){
        redVal++;
        blueVal++;
      }else state = 8;
      break;
    }
  }

  // Actualizas os valores nos LEDs, independentemente do estado
  analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho
  analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde
  analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul
}

microbyte

Tens aí vários erros...

Revê o teu código e vê se ele faz sentido...

joaobernardino

Eu não estou a perceber onde é que vou indicar os estados

microbyte

Quote from: joaobernardino on 27 de October de 2010, 22:37
Eu não estou a perceber onde é que vou indicar os estados

Tu não tens de indicar explicitamente os estados. Só tens de programar o que cada um faz... Se o numero do 1º estado é 1 ou 345676543 tanto faz, apenas ordenamos para ser mais fácil.

joaobernardino

Se não for isto não estou mesmo a perceber o que queres dizer  :(



void setup(){
  int state = 1;
 
}

void loop(){
unsigned long previousMillis = millis();
unsigned long currentMillis;


currentMillis = millis();

if(currentMillis - previousMillis > 500) { // Se quiseres fazer o update a cada 500ms
  previousMillis = currentMillis;  // salvas o novo valor de tempo

  // fazes o que queres de acordo com o estado
  switch(state){
    case 1:
    int redVal = 255;
    int greenVal = 0;
    int blueVal = 0;
    {
      if(redVal < 255) redVal++; // se ainda nao chegámos aos 255, aumenta o valor de redVal
      else state = 2; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 2:
    int redVal = 0;
int greenVal = 255;
int blueVal = 0;
    {if(greenVal < 255) greenVal++; // se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 3:
    int redVal = 0;
int greenVal = 0;
int blueVal = 255;
    {if(blueVal < 255) blueVal++; // se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 4:
    int redVal = 255;
int greenVal = 255;
int blueVal = 0;
    {if(greenVal < 255) greenVal++; redVal++;// se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 5:
    int redVal = 0;
int greenVal = 255;
int blueVal = 255;
    {if(greenVal < 255) greenVal++; blueVal++;// se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
    case 6:
    int redVal = 255;
int greenVal = 0;
int blueVal = 255;
    {if(redVal < 255) redVal++; blueVal++;// se ainda nao chegámos aos 255, aumenta o valor de greenVal
      else state = 3; // se atingiste os 255, mudas para o proximo estado, onde vais decrementar o valor do vermelho
      break;
    }
       
  case 7:
  int redVal = 255;
int greenVal = 255;
int blueVal = 255;
    {
      if(redVal < 255){
        redVal++;
        blueVal++;
        greenVal++;
      }else state = 1;
      break;
    }
  }

  // Actualizas os valores nos LEDs, independentemente do estado
  analogWrite(redPin, redVal); // Escreve o valor do PWM do led vermelho
  analogWrite(greenPin, greenVal); // Escreve o valor do PWM do led verde
  analogWrite(bluePin, blueVal); // Escreve o valor do PWM do led azul
}

microbyte

Sim, era isso. Um problema já resolveste.  ;)

Outra dica. Se declarares uma variável dentro de uma função, perdes o seu valor quando a função acaba.

joaobernardino

Passo o int state = 1; Para o inicio de tudo. Mas continua com erros  :(

microbyte

Quote from: joaobernardino on 27 de October de 2010, 23:14
Passo o int state = 1; Para o inicio de tudo. Mas continua com erros  :(
Errado.

Verifica onde é que são declarados os previousMillis e currentMillis no link que te enviei na primeira resposta.

joaobernardino

Fica estranho


unsigned long previousMillis = millis();

void setup(){
int state = 1;
 
}

void loop(){

unsigned long currentMillis;

currentMillis = millis();

if(currentMillis - previousMillis > 500) { // Se quiseres fazer o update a cada 500ms
  previousMillis = currentMillis;  // salvas o novo valor de tempo

microbyte

Não fica estranho, fica bem  ;D

Agora fazes o mesmo para os valores de redVal, greenVal, blueVal, ... etc
Isto para conseguires guardar os valores de cada um, para poderes alterar esse valor em cada iteração.