Skip to main content

Ilumina tu impresora 3D

Recientemente he estado haciendo pruebas de cómo iluminar mi impresora 3D con leds RGB y controlarlos vía software para poder cambiar los colores. Como me parece algo bastante chulo, y estoy contento con el resultado, dejo un tutorial con el fin de facilitar las cosas a quien quiera implementarlo en su máquina.

Aclaraciones previas

  • Esta forma de iluminar la impresora es una de muchas otras.
  • La electrónica que he utilizado es la que tengo en mi impresora, una Arduino Mega + RAMPS 1.4. Voy a utilizar algunos de los pines que están pensados para los servos (lo pone en la serigrafía), por lo que si utilizas otra electrónica diferente simplemente tendrás que buscar 3 pines digitales que soporten PWM.
  • El firmware que he modificado es el Marlin.
  • Este tutorial no pretende valer únicamente para impresoras 3D.

Materiales

Antes de seguir explicando cómo poner esto en marcha, te dejo aquí una lista de los materiales que he utilizado para realizar este pequeño circuito.

  • Tira leds RGB, de las que aparecen al realizar una búsqueda en google. La que tengo yo no sé exactamente cuál es ya que me la regalaron. Puedo deciros que es ánodo común y se alimenta a 12V. La tira se puede dividir en trozos, y yo, para este proyecto, únicamente usaré un trozo (3 leds) y lo pegaré con algo de termofusible al soporte del ventilador del hotend para que se ilumine. (La pieza del ventilador la tengo impresa en plástico transparente de forma que queda translúcido y cuando no hay mucha luz se logra un efecto bastante chulo.
  • 3 transistores npn, en concreto, los bc547B, (dejo el datasheet por aquí que nos hará falta luego). Eran los transistores que tenía a mano, y echando un ojo al datasheet nos pueden valer.
  • 3 resistencias de 8k2 ohmios.
  • Pines macho, pines hembra y algo de cablecillo.
  • Lo típico para soldar. Abajo dejaré un ejemplo de fritzing por si quieres soldarlo en placa de topos y los ficheros necesarios para hacer el circuito mediante una cnc o incluso en una pcb.

Esquemático

ledramps_sch

Vamos a explicar un poco el circuito.

La idea es que cuando tengamos alguna de las salidas digitales (D4, D5, D6) a 0V, el transistor correspondiente esté en corte, funcionando como un circuito abierto entre colector y emisor. No circulará corriente y el led correspondiente estará apagado. En el datasheet podemos ver que el transistor aguanta los 12V sin problema en el colector. Cuando pongamos el pin digital a 5V, el transistor entrará en saturación, funcionando como un cortocircuito entre colector y emisor. Por tanto, habrá 0V en la patilla del led correspondiente y se iluminará.

Aclaro que antes de hacer este tutorial, he tenido la tira de leds conectada a la fuente directamente durante un par de meses, con los cátodos directamente conectados a tierra para iluminarla con luz blanca. Estas tiras están pensadas para eso, las resistencias que acompañan a los leds van en la propia tira.

La resistencia de la base la hemos seleccionado para limitar la corriente. Si nos fijamos en el datasheet podemos ver lo siguiente.

vbesat

Es decir, si caen 0,7V en base-emisor, nos quedan 4,3V para llegar a los 5V del pin. Estos caerán en la resistencia. Si limitamos la corriente a 0,5mA en la base (según la tabla), aplicando la ley de Ohm obtenemos que el valor de la resistencia es de 8k6. Tenemos resistencias de 8k2 a mano así que usaremos esas. Con este valor la corriente estimada de la base será de 0,524mA.

Lo que aparece a la derecha de 12V y GND es simplemente que pondré un conector hembra para enchufarlo una salida de 12V que hay en la RAMPS que os comentaré más adelante. Además mi tira de leds tiene un conector hembra por lo que en este circuito para eso empleare pines macho. El resto de pines que utilizaré serán de tipo hembra.

Por último, remarcar que D4, D5 y D6 no es obligatorio que correspondan con esos colores, eso lo podéis poner como mejor os venga, luego definiremos los pines como corresponda en Marlin. Yo los tengo puestos así porque es el orden que me aparecía en la tira de colores.

Montando el circuito

Pre-Nota: Independientemente de qué método utilices, asegúrate de proteger el circuito de tal forma de que no haya cortos por algún mal contacto entre cosas que no deberían.

En primer lugar, lo monté en una protoboard para ver que funcionaba de forma correcta. Una vez hecho esto me lancé a soldarlo en una placa de topos. Mi idea era que ocupara lo menos posible, así que doble las patas de los transistores para intentar limitar al máximo el espacio.

¡Que no se me olvide! Hay que tener en cuenta a qué pata corresponde cada cosa. Mirando de nuevo el datasheet.

patas

Os dejo un circuito de ejemplo por si queréis tomarlo como referencia.

fritzing

No se aprecia muy bien, pero los transistores tendrían la pata correspondiente al emisor doblada hasta la línea negra de tierra. Los pines hembra de la izquierda se conectarían directamente a las salidas digitales de la RAMPS, los dos pines macho de arriba (12V cable amarillo y GND cable negro) se conectarían directamente a los 12V de la RAMPS también, y los 4 pines macho de la derecha se conectarían directamente a la tira de leds. Como no se ve muy bien en el dibujo, os dejo otra imagen sin los transistores por si queréis usarla como guía a la hora de soldar.

fritz_sinnpn

No es trivial, pero la imagen está vista desde arriba, si queréis que os quede tal cual, no os olvidéis de espejarla para soldar por la cara de abajo.

Os dejo un par de fotos de cómo me ha quedado a mi.

20160909_091632

20160909_091651

Nota: los colores de los cables no se corresponden con lo que deberían representar, pero eran los que tenía a mano y eran bastante cómodos ya que no tenía que soldar los conectores a los cables.

Haciendo una PCB con la Cyclone

Ahora la idea es hacer una pcb con la cyclone, así que he generado los ficheros correspondientes. Aún sólo los tengo en el ordenador, pero cuando los haga físicamente y compruebe que funcionan perfectamente los publicaré, de tal forma que los podáis usar, ya sea mandando fabricar la pcb o fresando el circuito con una cnc. Tras comprobar que funcionan los he publicado en mi GitHub. Los podéis ver aquí. De esta forma, el aspecto será más profesional. El circuito completo está en una única cara.

ledramps_pcb

Las dimensiones de este son de 20mm x 20mm y todos los componentes que he usado en el diseño son through-hole.

toplayer

bottomlayer

Para realizar los gcodes he usado el programa FlatCAM. A la hora de realizar los drills he escalado el .txt por un factor 0.01 ya que lo sobredimensiona por algún error al exportar. Para controlar la Cyclone he usado el programa CNC Gcode Controller. Hay que tener en cuenta que como he diseñado el circuito en la bottom layer, por lo que hay que hacer un mirror del eje x antes de empezar el job.

Conectando el circuito a la RAMPS

ramps

Te dejo en la imagen dónde se encuentran los pines digitales D4, D5 y D6. Además, he resaltado también de dónde puedes sacar los 12V por si no quieres sacarlos directamente de la fuente. Es posible que esos dos pines no estén soldados, en ese caso, simplemente coge un par de pines macho y suéldalos.

El conector que nos faltaría por conectar en nuestra plaquita sería el que iría directamente a la tira de leds.

Imprimiendo una carcasa

Para dejar el circuito bien protegido y visualmente con un mejor acabado, he impreso una pequeña carcasa en 3D. Es una única pieza, y por cómo está diseñada, no se saldrá en ningún momento ni necesita sujeción extra. Está diseñada en Sketchup. Se puede descargar tanto el .skp como el .stl de github. Os dejo unas fotos de cómo queda el montaje final.

20161012_112030

20161012_112115

Y a continuación ya incorporada en la electrónica de la impresora.

20161012_112335

Como se puede apreciar en la siguiente imagen, no incordia para nada en la carcasa de la electrónica que ya teníamos hecha de antes.

20161012_112425

Modificando el código

Tenemos que modificar 3 cosas en Marlin para poder activar, configurar y programar los leds a nuestro gusto. Para ello abrimos Marlin.ino con Arduino, y pasamos a realizar los siguientes pasos.

    1.  Abrimos el fichero Configuration.h y descomentamos la línea que hace referencia a los leds de temperatura. Nos quedará de la siguiente forma.
      // Temperature status LEDs that display the hotend and bet temperature.
      // If all hotends and bed temperature and temperature setpoint are < 54C then the BLUE led is on.
      // Otherwise the RED led is on. There is 1C hysteresis.
      #define TEMP_STAT_LED
      
    2. Abrimos el fichero pins.h y añadimos los pines digitales que hemos utilizado.
      #ifdef TEMP_STAT_LEDS
        #if MOTHERBOARD == 33
          #define STAT_LED_GREEN  4
          #define STAT_LED_RED    5
          #define STAT_LED_BLUE   6
        #endif
      #endif

      Según la electrónica que utilices tú, puede que cambie el valor de MOTHERBOARD, eso compruébalo en boards.h. Además, depende de en qué pin conectes cada led, podrás dejarlo igual que en el ejemplo, o tendrás que cambiarlo.

    3. Ahora pasamos a la parte de programar como tal. Vamos a trabajar en el fichero Marlin_main.cpp
      1. En primer lugar localizamos
        #ifdef TEMP_STAT_LEDS
         /* código que puedes borrar o dejar
            yo lo voy a personalizar y te dejo mis ejemplos
            por si te gustan
          */
        #endif
      2. Lo que haría ahora sería activar cada pin en orden (rojo – verde – azul) respecto a la nomenclatura para comprobar que he definido bien los pines. Una vez hecho esto, cargaría el programa, de tal forma que si se ilumina rojo – azul – verde (por poner un ejemplo), sé que tengo al revés los pines azul y verde, y no tardaría nada en ponerlo bien.
      3. Una vez hecho esto borraría eso y programaría a mi gusto.

Qué he programado, ejemplos.

A continuación te dejo el código que he utilizado, he comentado las distintas partes para que sea fácil localizarlas y facilitar la comprensión del código. Quizás se podría optimizar mejor, pero lo he escrito un poco rápido. Resumo un poco las características.

  • Coge el valor del extrusor 0, por lo que vale en caso de tener uno o más termistores. Como digo,si tenemos más de un hotend solo hará uso del primero con el ejemplo que se propone a continuación. Para usar otro habría que cambiar la línea de degHotend(0) y degTargetHotend(0) por otro número.
  • Mientras la impresora está en espera, hace fundidos de distintos colores (de forma pseudoaleatoria) encendiendo y apagando los leds. Siempre habrá algún color, no hay opción de off.
  • Mientras se calienta irá haciendo un fundido de azul a rojo representando la temperatura.
  • Mientras se enfría irá haciendo un fundido de rojo a azul representando la temperatura. Además irá alternando en intervalos de un segundo con el color verde con el fin de indicar que la impresión ha terminado.
  • Mientras imprime una pieza estará iluminada de blanco para poder ver bien la impresión.
//ILUMINACION PRINTRBOT
#ifdef TEMP_STAT_LEDS
  static uint32_t stat_update = 0;
  static uint32_t end_update = 0;
  
  #define LEDmax 255

  //Variables
  byte Rval = 0;
  byte Gval = 0;
  byte Bval = 0;
  int ExtTemp = 0;
  int ExtTarg = 0;
  byte flag = 0;
  boolean flag2=true;

  //funciones de colores básicos para que las tengas a mano
  void off(){    Rval = 0;      Gval = 0;      Bval = 0;}
  void white(){  Rval = LEDmax; Gval = LEDmax; Bval = LEDmax;}
  void red(){    Rval = LEDmax; Gval = 0;      Bval = 0;}
  void green(){  Rval = 0;      Gval = LEDmax; Bval = 0;}
  void blue(){   Rval = 0;      Gval = 0;      Bval = LEDmax;}
  void yellow(){ Rval = LEDmax; Gval = LEDmax; Bval = 0;}
  void cyan(){   Rval = 0;      Gval = LEDmax; Bval = LEDmax;}
  void magenta(){Rval = LEDmax; Gval = 0;      Bval = LEDmax;}


  void handle_status_leds()
  {
    if(millis() > stat_update)
    {
      stat_update += 50; // actualización cada 50ms
      //Cogemos el valor del extrusor 0
      ExtTemp = degHotend(0); //en versiones nuevas thermalManager.degHotend(0);
      ExtTarg = degTargetHotend(0); //en versiones nuevas thermalManager.degTargetHotend(0);
      //Blanco mientras imprime para ver la pieza bien
      if(ExtTarg >= ExtTemp-TEMP_HYSTERESIS && ExtTarg <= ExtTemp+TEMP_HYSTERESIS)
      {
        white();
      }
      /*Colores aleatorios
        fading de colores aleatorios encendiendo y apagando. No hay opción de off
      */
      else if(ExtTarg == 0 && ExtTemp <= 30)
      {
        if (flag == 0)
        {
          Rval = random(2);
          Gval = random(2);
          Bval = random(2);
          if(Rval == 1 || Gval == 1 || Bval == 1)
            flag = 1;
        }
        else if (flag == 1)
        {
          if(Rval > 0) Rval+=4;
          if(Gval > 0) Gval+=4;
          if(Bval > 0) Bval+=4;
          if(Rval > 251 || Gval > 251 || Bval > 251)
            flag = 2;  
        }
        else
        {
          if(Rval > 0) Rval-=4;
          if(Gval > 0) Gval-=4;
          if(Bval > 0) Bval-=4;
          if(Rval <= 1 && Gval <= 1 && Bval <= 1)
            flag = 0;
        }
      }
      //Cuando el hotend empieza a calentar pero aún está frío se pone azul
      else if(ExtTarg!=0 && ExtTemp <=30)
      {
        blue();
      }
      //Cuando el hotend casi alcanza la temperatura de calentamiento que sea rojo
      else if(ExtTarg!=0 && ExtTemp >= ExtTarg-10)
      {
        red();
      }
      /* Calentamiento hotend
         fading de azul a rojo en función de la temperatura
      */
      else if(ExtTarg != 0)
      {
        Rval = map(ExtTemp,30,ExtTarg-10,0,LEDmax);
        Bval = LEDmax - Rval;
        Gval=0;
      }
      /*Proceso de enfriamiento:
        fading de rojo a azul en función de temperatura
        con alternancia color verde indicando fin
      */
      else
      {
        if(millis() > end_update) {
          end_update += 1000; // Update every second
        if(flag2)
        {
          green();
          flag2 = false;
        }
        else
        {
          Rval = map(ExtTemp,30,240,0,LEDmax);
          Bval = LEDmax - Rval;
          Gval = 0;
          flag2 = true;
        }
      }
    }

    //Encendemos los leds
    analogWrite(STAT_LED_RED, Rval);
    analogWrite(STAT_LED_GREEN, Gval);
    analogWrite(STAT_LED_BLUE, Bval);
    }
  }
#endif

Un par de vídeos

Este es un vídeo que publiqué el otro día en youtube demostrando qué ocurre cuando calentamos el hotend. (He modificado el código y ahora se ve todavía mejor.)

Este otro es un vídeo de los fundidos de colores aleatorios mientras la impresora se encuentra «en espera».

Eneko Montero

Estudiando teleco e imprimiendo en 3D. A veces hago robotillos. Cuando tengo tiempo escribo algún artículo.

4 comentarios en “Ilumina tu impresora 3D”

  1. Hola, buen manual!, una pregunta. El código que escribes, se hace en algún fichero de Marlin ya existente o se crea uno nuevo llamado (por ejemplo) led_temp, y se hace un include en el configuration o algún fichero que se cargue con Marlin? :S

Deja un comentario