0

Neopixels on a Marlin/Sprinter-based 3D Printer
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Fri Nov 28, 2014 10:44 am

I wanted to offer up a quick tutorial on how I got neopixels working with my 3D printer. My goal was to get a neopixel to change from blue to red as the extruder was heating up to target temp. I wanted the same for the bed. Also I wanted to reverse the process during cool-down and go back to blue.

Hardware

Neopixels require 5vDC and a digital pin to talk to. I couldn't find a reliable 5v source on the Ramps board so I decided to use this to convert 12v to suit my 5v needs. https://www.adafruit.com/product/1385. I wired it directly to my power supply. I used both D42 and D44 located in 'Aux2' as my digital pins. Image I'm using two because the physical wiring was going off in two different directions (extruder & bed). I decided to add a second neopixel to the extruder and set it to white so I had a little part light while printing.

Software

First, you'll need to import your neopixel library files into your firmware's sketchbook.

I found something interesting in the firmware code namely TEMP_STAT_LEDS. It's defined in configuration.h and there's some code for it in Marlin_main.cpp. It's not what we want but it gave me a good idea where to insert neopixel code.

At the top of Marlin_main.cpp in the includes section: (*This is here because it was this way in the neopixel sample code)

Code: Select all | TOGGLE FULL SIZE
#ifdef NEOPIXEL_LEDS
  #include "Adafruit_NeoPixel.h"
  Adafruit_NeoPixel ext_neopixel = Adafruit_NeoPixel(2, 42, NEO_GRB + NEO_KHZ800);
  Adafruit_NeoPixel bed_neopixel = Adafruit_NeoPixel(1, 44, NEO_GRB + NEO_KHZ800);
#endif



In Marlin_main.cpp void setup() Loop (*This is here because it was this way in the neopixel sample code)
Code: Select all | TOGGLE FULL SIZE
  bed_neopixel.begin();
  bed_neopixel.show();
  ext_neopixel.begin();
  ext_neopixel.show();
  uint32_t w = ext_neopixel.Color(255, 250, 250);
  ext_neopixel.setPixelColor(1, w);
  ext_neopixel.show();



In Marlin_main.cpp void loop() Loop (I put it next to the TEMP_STAT_LEDS code)

Code: Select all | TOGGLE FULL SIZE
#ifdef NEOPIXEL_LEDS
static uint32_t stat_update = 0;
static uint16_t neo_r = 0;
static uint16_t neo_g = 0;
static uint16_t neo_b = 255;
static uint16_t c_diff = 0;
static uint32_t bed_c;
static uint32_t ext_c;
static uint32_t last_bed_c;
static uint32_t last_ext_c;
float curr_ext_temp = 0.0;
float target_ext_temp = 0.0;
float curr_bed_temp = 0;
float target_bed_temp = 0;

void handle_neopixels(void) {
  if(millis() > stat_update) {
    stat_update += 500;
 //  SET Bed LED
    if(degBed() > 0) {
      if(degBed() > degTargetBed() && degTargetBed() > 0) {
        curr_bed_temp = degTargetBed();
      } else {
        curr_bed_temp = degBed();
      }
    }
    target_bed_temp = degTargetBed();

    if(curr_bed_temp >= 30.0) {
      if(target_bed_temp > 0) {   //Heating Up
        c_diff = (curr_bed_temp - 30)*255/(target_bed_temp-30);
        if(c_diff>255) {c_diff = 255;}
      } else {  //Cooling Down
        c_diff = (curr_bed_temp-30)*6;
        if(c_diff>255) {c_diff = 255;}
      }
      neo_r = c_diff;
      neo_b = 255 - c_diff;
    } else {  //Temp is less than 30.0
      neo_r = 0;
      neo_b = 255;
    }
    last_bed_c = bed_c;
    bed_c = bed_neopixel.Color(neo_r, neo_g, neo_b);
    if(bed_c != last_bed_c) {  //only update if there's a change
      bed_neopixel.setPixelColor(0, bed_c);
      bed_neopixel.show();
    }

  //  SET Extruder LED   
    if(degHotend(0) > 0) {
      if(degHotend(0) > degTargetHotend(0) && degTargetHotend(0) > 0) {
        curr_ext_temp = degTargetHotend(0);
      } else {
        curr_ext_temp = degHotend(0);
      }
    }
    target_ext_temp = degTargetHotend(0);
    if(curr_ext_temp > 30.0) {
      if(target_ext_temp > 0) {
        c_diff = (curr_ext_temp - 30)*255/(target_ext_temp-30);
        if(c_diff>255) {c_diff = 255;}
      } else {
        c_diff = (curr_ext_temp-30)*2;
        if(c_diff>255) {c_diff = 255;}
      }
      neo_r = c_diff;
      neo_b = 255 - c_diff;
    } else {
      neo_r = 0;
      neo_b = 255;
    }
    last_ext_c = ext_c;
    ext_c = ext_neopixel.Color(neo_r, neo_g, neo_b);
    if(ext_c != last_ext_c) {
      ext_neopixel.setPixelColor(0, ext_c);
      ext_neopixel.show();
    }
  }
}
#endif     
 
#ifdef TEMP_STAT_LEDS
static bool blue_led = false;
static bool red_led = false;
static uint32_t stat_update = 0;

void handle_status_leds(void) {
  float max_temp = 0.0;
  if(millis() > stat_update) {
    stat_update += 500; // Update every 0.5s
    for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
       max_temp = max(max_temp, degHotend(cur_extruder));
       max_temp = max(max_temp, degTargetHotend(cur_extruder));
    }
    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
      max_temp = max(max_temp, degTargetBed());
      max_temp = max(max_temp, degBed());
    #endif
    if((max_temp > 55.0) && (red_led == false)) {
      digitalWrite(STAT_LED_RED, 1);
      digitalWrite(STAT_LED_BLUE, 0);
      red_led = true;
      blue_led = false;
    }
    if((max_temp < 54.0) && (blue_led == false)) {
      digitalWrite(STAT_LED_RED, 0);
      digitalWrite(STAT_LED_BLUE, 1);
      red_led = false;
      blue_led = true;
    }
  }
}
#endif


and this bit too...

Code: Select all | TOGGLE FULL SIZE
  #ifdef TEMP_STAT_LEDS
      handle_status_leds();
  #endif

  #ifdef NEOPIXEL_LEDS
    handle_neopixels();
  #endif


Finally, in configuration.h

Code: Select all | TOGGLE FULL SIZE
// 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_LEDS
#define NEOPIXEL_LEDS
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by adafruit_support_bill on Fri Nov 28, 2014 11:03 am

Nice work! Thanks for posting.

adafruit_support_bill
 
Posts: 74907
Joined: Sat Feb 07, 2009 10:11 am

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by myo900 on Mon May 11, 2015 4:37 pm

Thanks for the good work, I would use this code for my printer, but with a difference, use 2 neopixel in series, how can I change the code to do this?

myo900
 
Posts: 1
Joined: Mon May 11, 2015 4:37 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Mon May 11, 2015 5:22 pm

It's kinda hard to see but I actually have two neopixels running off the variable ext_neopixel. By their nature, they run in series. The first neopixel is basically white to light the part as it's being printed and I turn it on with this...
Code: Select all | TOGGLE FULL SIZE
uint32_t w = ext_neopixel.Color(255, 250, 250);
  ext_neopixel.setPixelColor(1, w);
  ext_neopixel.show();


then, further down, you'll find the code that is somewhere between blue and red depending on my extruder's temp. So this bit: ext_neopixel.setPixelColor(1,w); the 1 defines the 2nd neopixel in the chain. ext_neopixel.setPixelColor(0,w) would alter the first one in the chain. Hope this helps.
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by echapman on Mon Oct 26, 2015 10:02 pm

Nice work,
I'm in the process of adapting this to my 2Up qu-bd printer. I'm making a slight change though to mine though. I'm using one of the NeoPixels Rings (12). I hope to mount it around the extruder. The goal is to light the print nozzle so its easier to watch it do its thing. I like the aspect of being able to set the pixels dependent on extruder temp(very clever). I was able to get the temperature working which wasn't to difficult.

Any thoughts on if there is a flag that says the printer is actively printing? I would like to use the flag in order to tell the Ring to go all white in order to see whats going on. Once the print is complete the ring would return to extruder temperature mode. It should be pretty easy to code just need that flag.

I did run into a small issue which I'm hoping to resolve tonight, Currently i have to address all 12 NeoPixels which seems to play haveck on the extruder temp. It goes completely erratic even when the extruder is supposed to be off. I'm not sure why yet but its only a matter of time. I suspect its a timing issue.

echapman
 
Posts: 2
Joined: Mon Oct 26, 2015 9:48 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Tue Oct 27, 2015 11:40 am

I think you could just use the target_ext_temp>0 statement to differentiate between printing and not. I commented the target_bed_temp section with //heating up & //cooling down. You could keep the cooling down part as is but switch up the heating up part to go all white.
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by echapman on Tue Oct 27, 2015 10:53 pm

That's deffinately one way of doing it. I was hoping to keep the heating and cooling effect if possible.

There is supposedly a completion variable that might also be usable. Just need to find which variable that is.

echapman
 
Posts: 2
Joined: Mon Oct 26, 2015 9:48 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by Duese73 on Thu Jan 28, 2016 6:22 am

Hi,

First of all thanks for your work.
I implement your code to my Marlin Rc3 running on a Rumba Board.
I use pin 13 and 14 (pin mapped to 30 and 31) from the EXP3 connector and declare them to digital pins.

The first LED (White) is runnig , but not the two others for blue and red .

My Problem is when i paste this part of your code:

#ifdef TEMP_STAT_LEDS
handle_status_leds();
#endif

#ifdef NEOPIXEL_LEDS
handle_neopixels();
#endif

i got an compile error, like :

"C:\Users\kjghzg\AppData\Local\Temp\buildbbfe2d9268a14041f1c7d115cc677896.tmp\sketch\Marlin_main.cpp.o"
Marlin_main.cpp:7011: error: expected constructor, destructor, or type conversion before ';' token

handle_neopixels();

^

Bibliothek LiquidCrystal in Version 1.0.4 im Ordner: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal wird verwendet
Bibliothek Adafruit_NeoPixel-master in Version 1.0.4 im Ordner: C:\Users\geerhh\Documents\Arduino\libraries\Adafruit_NeoPixel-master wird verwendet
exit status 1
expected constructor, destructor, or type conversion before ';' token

I tried to paste it at some other points in the code but always the same error.

I hope you can help me

daniel

Duese73
 
Posts: 5
Joined: Thu Jan 28, 2016 6:00 am

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Thu Jan 28, 2016 9:55 am

It seems like some of the other bits of code may be missing. Did you add #define NEOPIXEL_LEDS to configuration.h?
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by Duese73 on Thu Jan 28, 2016 11:34 am

Hi,

yes i did.

I copy all of the codeparts into my fw .

Where should this part exactly placed?

#ifdef TEMP_STAT_LEDS
handle_status_leds();
#endif

#ifdef NEOPIXEL_LEDS
handle_neopixels();
#endif

directly after the third part ?

thanks
daniel

Duese73
 
Posts: 5
Joined: Thu Jan 28, 2016 6:00 am

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Thu Jan 28, 2016 3:08 pm

This bit is already in marlin_main.cpp

#ifdef TEMP_STAT_LEDS
handle_status_leds();
#endif


You only need to add the neopixel part directly after it.
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by Duese73 on Fri Jan 29, 2016 4:01 am

Hi,

Hm does not work.

Maybe i send you my scetch and you can take a look at the code?

Thats the only way for me to keep marlin otherwise i change to repetier.

Duese73
 
Posts: 5
Joined: Thu Jan 28, 2016 6:00 am

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Fri Jan 29, 2016 9:54 am

First, try starting back at the beginning. There are a few other instances where my neopixel code is placed directly after the TEMP_STAT_LEDS code that was already there.
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by Duese73 on Fri Jan 29, 2016 12:44 pm

Hi,

thanks for your patience.

Now i am a bit confused...the code in your guide is all for what i need or not?

First part:
Marlin_main.cpp in the includes section....

Second part:
Marlin_main.cpp void setup() Loop...

Third part:
Marlin_main.cpp void loop() Loop...

Fourth part:
direct after third.....

Fifth part:
in config.h....

The 1st,2nd and 3th part seems to work because the white led on stripe is enabled.

is there something that i have to delete from TEMP_STAT_LEDS original code? maybe?

The ilumination is the last step of my printer so i will not give up this mess;)

Can you send me your config.h and marlin_main.cpp to inspect?

best regards and thx

Duese73
 
Posts: 5
Joined: Thu Jan 28, 2016 6:00 am

Re: Neopixels on a Marlin/Sprinter-based 3D Printer

by donhuevo on Fri Jan 29, 2016 2:17 pm

You can find them both here... http://www.oddhobs.com/neopixels/.

Just right-click the files and choose 'Save Target As'
donhuevo
 
Posts: 9
Joined: Fri May 09, 2014 12:40 pm

Please be positive and constructive with your questions and comments.