Go Down

Topic: simulando disparos (Read 915 times) previous topic - next topic

krilos

Hola, qué tal?.
Hace unas semanas me ayudásteis mucho con un temilla que tenía entre manos para los pwm y debo decir que desde entonces he ido haciendo más montajes y practicando con el kit de iniciación y ahí vamos progresando  XD .
Quería volver a preguntaros sobre lo que serían enlazar varios pwm sin que haya terminado el anterior.
El proyecto es hacer que varios led's simulen ser disparos de cañones, así que lo que he hecho es que se encienda uno muy rápido pero luego se vaya apagando despacio. Pero como hay varios cañones, antes de que el primero se haya apagado del todo, se deben "disparar" otro u otros cañones más y se deben ir apagando cada uno a su ritmo.
Le llevo dando vueltas bastante tiempo pero no encuentro la manera de que quede medianamente bien porque siempre es necesario que termine un bucle para meterse en el siguiente. O lo saco del bucle en el que está para que encienda el siguiente led y luego vuelva al anterior para terminarlo.
No sé, la verdad es que en un principio pensé que sería más fácil, pero parece que no lo va a ser tanto.
Podéis darme una idea de cómo podría hacerlo de una forma que no quedara tan parecida al "coche fantástico" ?

Muchas gracias por adelantado.


Cheyenne

Mira el ejemplo del IDE blink whithout delay y aplícalo independientemente a cada led con los parámetros que quieras.

krilos

Muchas gracias por contestar Cheyenne.
La verdad es que me ha sorprendido el funcionamiento que se describe para el blink sin delay. Porque en el fondo es una forma de hacer un delay, verdad?.
Bueno, el caso es que he estado probando formas de implementar como me dices el blink sin delay a los leds para el pwm pero no hay manera. No sale nada, se quedan los leds apagados.
También te quería preguntar otra cosa. Como te dije en el primer post, lo que quiero es una especie de simulación de disparos, es decir, que habrá momentos en los que haya varios pwm desvaneciéndose a la vez mientras que otros se están encendiendo (disparando). Pero yo creo que con el ejemplo que tu me dices, lo que hago es que vaya pasando de un pwm a otro sin delay, pero una vez que está dentro de las lineas que hacen el desvanecimiento del pwm, hasta que no termine de desvanecerlo del todo no pasará al siguiente, no?.
Este es el código al que he llegado después de estar toda la tarde poniendo y quitando líneas. Aunque he declarado dos salidas de pwm solo he estado intentando que funcione al menos una, pero no ha habido forma.
Si me pudiérais dar una mano o incluso si me pudiérais poner un ejemplo con al menos 3 pwm que funcionen como os digo os lo agradezco porque el montaje que quiero hacer deberá tener más de 30 salidas de estas y quiero entender bien como funciona este circuito para intentarlo luego mediante matrices o algo parecido.
Saludos.

/* Blink without Delay

Turns on and off a light emitting diode(LED) connected to a digital 
pin, without using the delay() function.  This means that other code
can run at the same time without being interrupted by the LED code.

The circuit:
* LED attached from pin 13 to ground.
* Note: on most Arduinos, there is already an LED on the board
that's attached to pin 13, so no hardware is needed for this example.


created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen

This example code is in the public domain.


http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/



const int salipwm1 =  10;      // the number of the LED pin
const int salipwm2 =  11;


int fadeAmount = 1;
int brightness = 250 ;


long previousMillis = 0;        // will store last time LED was updated


long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode( salipwm1, OUTPUT); 
  pinMode( salipwm2, OUTPUT); 
}

void loop()
{

  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
   
    previousMillis = currentMillis;   

   
    if (salipwm1 == LOW) {
    digitalWrite( salipwm1, HIGH);
        fade1();
    }
  }

}


void fade1(){
 

  do{

  analogWrite(salipwm1, brightness);
    fadeAmount = - fadeAmount ;
    brightness = brightness - fadeAmount;

    if (brightness == 1 )
    {
      digitalWrite (salipwm1, LOW);
     }     
   
    delay(5);
  }while(1 !=brightness);
 

    digitalWrite(salipwm1, LOW);
   
    }
   






nkl_ale

#3
Nov 28, 2012, 12:34 am Last Edit: Nov 28, 2012, 06:59 pm by nkl_ale Reason: 1
Hola Cheyene

Creo que lo que quieres hacer se puede hacer de esta forma, espero que no sea demasiado complicado....

Code: [Select]

int salidapwm[]={10,11};
int valorpwm[]={0,0};
//por ejemplo
    //puedes decidir cuando se disparan...
long disparoled[]={10000,12000};
const int numsalidas = 2;


int fadeAmount = 5;
int brightness = 250 ;


long previousMillis = 0;        // will store last time LED was updated


long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  //EDIT se me había olvidado :P
  //pinMode( salipwm1, OUTPUT);
  //pinMode( salipwm2, OUTPUT);
  int ix;
  for (ix = 0; ix < numsalidas ; ix++)
  {
      pinMode( salidapwm[ix], OUTPUT);
  }
}

void loop()
{

  unsigned long currentMillis = millis();
  int ix;

  //hace un paso cada interval milisegundos
  if(currentMillis - previousMillis > interval) {
   
    previousMillis = currentMillis;

    //recorremos las salidas para actualizarlas
    for (ix = 0; ix < numsalidas; ix++)
    {
      //es hora del disparo?
      if (currentMillis > disparoled[ix])
      {
        //al entrar en fade se va a encender a este valor
        valorpwm[ix] = 255;
        //puedes poner 255 + fadeAmount , ya que se va a descontar al entrar en fade
        //programa el próximo disparo de este led
        disparoled[ix] = currentMillis + (long)(300000 / fadeAmount);
      }
      //como loop se ejecuta continuamente, la próxima vez que entre en el for seguirá reduciendo valorpwm en la salida
      //actualiza el estado de esta salida un paso cada vez que pasa por aqui
      fade(ix);
    }
  }

}

//reduce el brillo del pin numero ix
void fade(int ix)
{
  if (valorpwm[ix] > 0)
  {
    valorpwm[ix] = valorpwm[ix] - fadeAmount;
    //añade seguridad para no pasarse por accidente
    if (valorpwm[ix] < 0)
    {
      valorpwm[ix] = 0;
    }
    analogWrite(salidapwm[ix],valorpwm[ix]);
    //se ha reducido un paso, la próxima vez se reduce mas... si aun no es 0
  }
}


espero que sirva de ayuda

krilos

#4
Nov 28, 2012, 05:20 pm Last Edit: Nov 28, 2012, 05:23 pm by krilos Reason: 1
Hola!.  Muchas gracias por contestar.
No he tenido de probarlo aún porque he estado fuera, pero a ver si esta noche tengo un rato y lo pruebo para ver si funciona.
Madre mía que cosas más raras hacéis los que sabéis del tema.
Si te digo que entiendo el código a la perfección te estaría engañando, jajaja.
Así que probaré a ver cómo funciona y así lo termino entendiendo.

Por cierto, que si para un micro con 6 pwm hay que montar este follón, no sé cómo se pondrá el tema cuando intente hacer algo con el TLC5940 que me lo compré porque tenía 16pwm :smiley-yell:

Muchas gracias otra vez.
Ya os diré algo a los dos entre esta noche y mañana.

Go Up