Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Neopixels as progress bar #8915

Closed
WojciechBednarski opened this issue Dec 27, 2017 · 31 comments
Closed

[FR] Neopixels as progress bar #8915

WojciechBednarski opened this issue Dec 27, 2017 · 31 comments
Labels
T: Feature Request Features requested by users.

Comments

@WojciechBednarski
Copy link

WojciechBednarski commented Dec 27, 2017

Feature Request

Hello,

I was a little bit away with latest firmwares for my printer (when it works I don't touch:) ), but I have some time and wanted something new.

Currently I have a neopixel LED strip in front of my printer shining through milky white plexi to indicate the progress of the print. For that purpuse I use additional arduino. I implemented I2C data transfer from main board to secondary board, which is running apart from other stuff thing like that:

  if (progress>0){
  int resolution=100/PixelCount;
  for (uint16_t pixel = 1; pixel <= PixelCount; pixel++)
    {
        if (progress>=(pixel*resolution)) {
            strip.SetPixelColor(pixel-1, RgbColor(0,250,0)); 
            }
        else if ((progress<(pixel*resolution)) and (progress>((pixel-1)*resolution))){
            int fade=(250*(progress%resolution))/resolution;
            strip.SetPixelColor(pixel-1, RgbColor(0,fade,0));
            break; 
        }
        else {
          strip.SetPixelColor(pixel-1, RgbColor(0,0,0));
          break;
        }
        
   }
   strip.Show();
   }  

Now, as I browse through latest 2.0 branches I found that the Neopixels are nicely implemented, and that my main board could display LEDs. However by default marlin is turning all LEDs to white when printing to act as a case lightning.

Now I get to the point - how can I modify existing code to implement a kind of a progress bar instead of case lightning using neopixels and 2.0 branch? I need some hints where to start and if it works then I'll share:)

Thanks!

BR
Garreth

//EDIT: That's how it looks now:
image

@WojciechBednarski
Copy link
Author

I tracked down few things inside the code.

  1. We can't set particular single LED in a strip from the code. There is no function prepared for that. Even with "NEOPIXEL_IS_SEQUENTIAL" set, if we want to set last LED we need to go through the whole strip setting each LED one by one.
  2. Sequential setting of LEDs during heatup has empty code, is that on purpuse or just needs work?
           #if ENABLED(NEOPIXEL_IS_SEQUENTIAL)
              , true
            #endif`

I'm going to play with this code a little bit:)

@Tannoo
Copy link
Contributor

Tannoo commented Dec 29, 2017

It works. If NEOPIXEL_IS_SEQUENTIAL is set, the heatup portion changes colors pixel by pixel.

@WojciechBednarski
Copy link
Author

@Tannoo
Either I'm doing something wrong, or my understanding about that functionality is not very good, can you elaborate?
When I use unmodified code with NEOPIXEL_IS_SEQUENTIAL I get result as in the video:
https://www.youtube.com/watch?v=LLvHxqHNqfM

As you can see there, when heatbed heats up the LEDs are turned on pixel by pixel as you said, but they roll up, instead of creating a kind of a progress bar. Ok, that works, the effect is not very nice in my setup, but I could live with it. It's also not very smooth, sometimes few LEDs are turned on at once.
However when the hotend started to heat up all LEDs got to red and stayed like that.

Also there is a bigger problem, with neopixels turned on, the steppers are not working:) I guess that neopixel library is taking over interupts, and doesn't want to give them back for the steppers. Even if we manage to overcome this, I think we will be stuck with constant strip colour during printing, or else the movement would stutter.

I'm working on having secondary arduino just to controll LED strips. So far I've got running arduino mega (later it can be replaced with any smaller arduino, I had this one under my hand) with some simple animations for neopixels, and I2C communications from Arduino Due (running with Marlin) to Mega. I'm now trying to wrap my test code at Due side to a nicer format right now.

@Tannoo
Copy link
Contributor

Tannoo commented Dec 29, 2017

How your video shows, it exactly how it works for me. I don't care for it, so I have that feature turned off.

@WojciechBednarski
Copy link
Author

Well, I've got probably majority of features turned off, but I'm still glad that people develop them and firmware gets better and better:)
I perfectly know that this is nowhere near funtionalities with priorities (as all other cosmetic changes), but I care about it, I have a little time to test it, report how it works, and propose improvements. In current state even if it is intended, it is not "readable" how far with heating are we.

But more worrying is that steppers are not running with #define NEOPIXEL_LED` enabled...

@Tannoo
Copy link
Contributor

Tannoo commented Dec 29, 2017

If the NEOPIXEL_IS_SEQUENTIAL is disabled, all of the pixels will change color at the same time. From blue to purple (for the bed) and purple to red (for the hotend).

@Tannoo
Copy link
Contributor

Tannoo commented Jan 4, 2018

But more worrying is that steppers are not running with #define NEOPIXEL_LED enabled...

How do you mean?

@WojciechBednarski
Copy link
Author

@Tannoo Try it for yourself at 2.0.x even without neopixels attached to the board (if you don't have them), just enable NEOPIXEL_LED and try to move motors. For me they didn't move. They are all enabled correctly but homing or jogging didn't work for me.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

I have. Homing and leveling work fine.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

Btw, I am running bugfix-2.0.x.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

I have both an RGB strip and a Neopixel RGBW strip attached to my printer (mainly for LED code testing). Only one can be enabled at a time (due to the sanity checking).

All works fine for me. I have even changed the startup script to a smooth color wheel test.

If you are referring to moving the steppers while the printer is heating up? Well, if M109 or M190 were used, the steppers will not move because just about everything is put on hold until the temps are met (by design).
Otherwise, all works just fine.

@WojciechBednarski
Copy link
Author

That's quite interesting, as I was using pure build from the repo without any modifications, just config.... Which board are you using? 32 bits or 8 bits?
Abot wait for heatup I know, no problems with that.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

8-bit. Lemme test a clean build. Mine is updated with all the latest commits. I rebase almost daily.

@WojciechBednarski
Copy link
Author

That may be the reason, as I tested on Due, and we all know how many new problems 32bits introduce. I'll try that on 8 bits as well but I have to reanimate one of old boards, so can't promise when I'll have time for that.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

I have a Due somewhere, but no sheild for it. Never had Marlin on it.
I have a dead Re-Arm... I think I have new one somewhere.

@WojciechBednarski
Copy link
Author

WojciechBednarski commented Jan 5, 2018

I will also try that without hooking up everything to the printer, maybe I'll just take a bare Arduino Mega, load firmware with dummy temperature sensors in config and endstops bypassed, then I'll put LED with resistor to the Step pin for one of the motors. If hopefuly led blinks it means that everything is fine.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

I don't have time to find the other boards, atm.

@Tannoo
Copy link
Contributor

Tannoo commented Jan 5, 2018

Is it possible you have NEOPIXEL_PIN assigned to a conflicting pin?

@gordo3di
Copy link

gordo3di commented Feb 9, 2018

@GarrethX @Tannoo

Used your code to make this.

I still have to add a conditional to not show the progress bar during heating but it works well anyway.

I'm also going to use this code to change the heating process too. Instead of changing the color of the full bar from red to blue slowly, I want it to all start blue and transition to red just like the progress bar. This is much more useful when looking from far away to see how far the printer has until its up to temp since you will see it creep along. Thanks!

In ultralcd.cpp

void lcd_status_screen() {

  #if ENABLED(ULTIPANEL)
    ENCODER_DIRECTION_NORMAL();
    ENCODER_RATE_MULTIPLY(false);
  #endif



  //gCreate add RGBLED progress bar with neopixel
  // https://github.com/MarlinFirmware/Marlin/issues/8915

if (IS_SD_PRINTING && ENABLED(PRINTER_EVENT_LEDS)) {
int progress = card.percentDone();

if (progress > 0) {
int resolution = 100/pixels.numPixels();
int pixel = pixels.numPixels();
int PixelCount = pixels.numPixels();

for (uint16_t pixel = 1; pixel <= PixelCount; pixel++)
        if (progress>=(pixel*resolution)) {
            pixels.setPixelColor(pixel-1, pixels.Color(0, 255, 0, 0)); 
            }
        else if ((progress<(pixel*resolution)) and (progress>((pixel-1)*resolution))){
            int fade=(250*(progress%resolution))/resolution;
            if (fade < 10) {
              fade = 10;
            } 
            pixels.setPixelColor(pixel-1, pixels.Color(0, fade, 0, 0));
            break; 
        }
        else {
          pixels.setPixelColor(pixel-1, pixels.Color(0, 0, 0, 0));
          break;
        }
  pixels.show();
}

}

@WojciechBednarski
Copy link
Author

@gordo3di Hi! Did you take the code form my repo (https://github.com/GarrethX/NeopixelMarlinSlave)? Because it looks familiar:)
From my last commit there I use this system without big problems. There's just one small issue - when the gcode is very large, the progress is rounded to 0% for a long time after start, so it stays red after heat-up, Not a big deal for me, but anyway I have a few projects pending and not much time to work on the cosmetics, but I'll get back to it for sure:)

@thinkyhead thinkyhead added the T: Feature Request Features requested by users. label Feb 18, 2018
@thinkyhead
Copy link
Member

thinkyhead commented Feb 18, 2018

Try it for yourself at 2.0.x even without neopixels attached to the board (if you don't have them), just enable NEOPIXEL_LED and try to move motors. For me they didn't move. They are all enabled correctly but homing or jogging didn't work for me.

I've heard a rumor that if you turn off NEOPIXEL_STARTUP_TEST or replace the safe_delay calls in setup_neopixel with delay it might fix the issue.

@WojciechBednarski
Copy link
Author

WojciechBednarski commented Feb 18, 2018

Hmm.. I'll give it a shot tomorrow, however for me personally it's not the functionality I'm looking for about neopixels:)

As a side note, I'm working on a a functionality I need here, the code is far from perfect, but since publishing the code I'm using it and it works without surprises. I'm going to update this code soon, as I have a few more ideas for animations, but maybe if you will like it we could work out implementation of this in Marlin.
https://github.com/GarrethX/NeopixelMarlinSlave , I even have a video there (I need to record new one btw, but it gives a general idea:) ).

Thing is that I don't know if it is possible to have neopixel animations together with step generation. Neopixels have strict timings, and arduino based boards are not allowing for DMA control.

@gordo3di
Copy link

gordo3di commented Feb 18, 2018

@GarrethX Sorry. I haven't tried your code yet other than the code from the top of this post which i modified. I just worked on mine and it ended up working pretty well. One weird "issue" is during heat up as the pixels transition from blue to red, if you perform any moves (like prepare > move...) the motors sound like they are missing steps even though they aren't. It's almost as if the arduino cant process both the led loop and step generation. It's not a huge issue since you generally aren't moving during heat up anyway. Maybe something in this code could be useful for your implementation.

Here's the final code for the progress bar and the blue/red progress bar during heat up. The only "problem" is if your print is short, the green progress bar fights with the heat up so sometimes the first pixel blinks green as its trying to turn red. I spent forever trying to turn off the green progress bar during heat up but could never figure it out.

Some videos:
https://www.instagram.com/p/BfJ888vlkfk/?taken-by=gtlmakes
https://www.instagram.com/p/Be_tpuNlO5y/?taken-by=gtlmakes

Marlin_main.cpp (around line #7789)

  #if ENABLED(PRINTER_EVENT_LEDS)
    const float start_temp = thermalManager.degHotend(target_extruder);
    uint8_t old_blue = 0;
    uint8_t old_red = 255;
    //Start with full strip blue. gCreate added
    leds.set_color(MakeLEDColor(0, 0, 255, 0, pixels.getBrightness()));
  #endif

Marlin_main.cpp (around line #7826 after const float temp = thermalManager.degHotend(target_extruder);)

//gCreate neopixel rgb heat from blue to red in progressbar style
#if ENABLED(PRINTER_EVENT_LEDS)
if (!wants_to_cool) {
  
int heatprogress = temp/target_temp*100;
int resolution = 100/pixels.numPixels();
int pixel = pixels.numPixels();
int PixelCount = pixels.numPixels();

for (uint16_t pixel = 1; pixel <= PixelCount; pixel++) 
        if (heatprogress>=(pixel*resolution)) {
            pixels.setPixelColor(pixel-1, pixels.Color(255, 0, 0, 0)); 
            }
        else if((heatprogress<(pixel*resolution)) and (heatprogress>((pixel-1)*resolution))){
         //Fade from blue to red for active pixel
         int red = (250*(heatprogress%resolution)/resolution);
         int blue =  250-red;
         pixels.setPixelColor(pixel-1, pixels.Color(red, 0, blue, 0));
            break; 
        }
        else {
          pixels.setPixelColor(pixel-1, pixels.Color(0, 0, 255, 0));
          break;
        }
        pixels.show();
        
}

#endif

Here's the green progress bar during print code

ultralcd.cpp (around line #618 right after void lcd_status_screen()

//gCreate add RGBLED progress bar with neopixel.
//Start white and progress to the right with green as print finishes. Active pixel is gradient.
// https://github.com/MarlinFirmware/Marlin/issues/8915

#if (ENABLED(PRINTER_EVENT_LEDS)) 
if (IS_SD_PRINTING) {

int progress = card.percentDone();

if (progress > 0) {
int resolution = 100/pixels.numPixels();
int pixel = pixels.numPixels();
int PixelCount = pixels.numPixels();

for (uint16_t pixel = 1; pixel <= PixelCount; pixel++)
        if (progress>=(pixel*resolution)) {
            pixels.setPixelColor(pixel-1, pixels.Color(0, 255, 0, pixels.getBrightness())); 
            }
        else if ((progress<(pixel*resolution)) and (progress>((pixel-1)*resolution))){
            int fade=((240*(progress%resolution))/resolution)+10;
              pixels.setPixelColor(pixel-1, pixels.Color(0, fade, 0, pixels.getBrightness()));
            break; 
        }
        else {
          pixels.setPixelColor(pixel-1, pixels.Color(0, 10, 0, pixels.getBrightness()));
          break;
        }
  pixels.show();
}
}
#endif

@WojciechBednarski
Copy link
Author

@gordo3di Sorry, too many things on me head right now and many things are happening. I honestly forgot that I pasted this code in the first post, when I was answering you last time:)

But getting into the thing, it seems that my concern about stepping generations were correct unfortunately. Maybe we can get some support from @thinkyhead about that, but I'm afraid that it's just the way the neopixels are made and we can't jump over it. Also priority is printing, not LEDs.

About the green progress bar, please take a look in my repo I posted above, maybe this will give you an idea. I used a bool variable "leds.progress_lock": https://github.com/GarrethX/NeopixelMarlinSlave/search?utf8=✓&q=progress_lock&type=
It works quite well, however I still have an issue when the progress is rounded to 0, because then I see heat-up progress bar for some time during long prints. I need to bite a little bit more into marlin to change that:)

@thinkyhead
Copy link
Member

thinkyhead commented Feb 19, 2018

I presume you only need to apply change to the neopixels when there is something to change, and they aren't just being updated constantly. If you are running a loop to update several at once, modify it so that it is reentrant, and only changes one LED color per-call.

@AnHardt
Copy link
Contributor

AnHardt commented Feb 19, 2018

About the 'green status bar'. Some of these stripes/arrays are are organized 'RGB' others 'GRB'. Is

  #define NEOPIXEL_TYPE   NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)

set to your needs?

About setting single pixels.
This little things have only one input and one output pin. In between there is a shift register. If you have more LEDs, they are chained. To reach the last LED in the chain you have to shift the information through all the others. That means, all other LEDs are updated to. The time critical part is not setting the color in the buffer, but transferring the buffer to the LEDs.

@piotrekmonko
Copy link

@GarrethX have you found a solution for not working steppers? Got bit by the same issue, on a Due.

@WojciechBednarski
Copy link
Author

@GarrethX have you found a solution for not working steppers? Got bit by the same issue, on a Due.

@piotrekmonko not in a marlin way unfortunately. Standard adafruit library disables interrupts, non-standard library uses DMA which DUE lacks of. I used second microcontroller for LEDs and communicated DUE over i2c, but for some time now I'm playing with other 3d printer firmware and so I didn't update my code for quite a long time, sorry:(

@piotrekmonko
Copy link

piotrekmonko commented Nov 12, 2018 via email

@ellensp
Copy link
Contributor

ellensp commented Jul 28, 2020

M150 was extended to have a [I<index>] options, so you can individually turn on/off neopixels.

Egs
Set Neopixel 0 to red brightness 100
M150 R100 I0

Set Neopixel 1 to green brightness 45
M150 U45 I1

NB PRINTER_EVENT_LEDS will overwrite them

So all you need it to sprinkle M150's throughout your gcode to turn more and more on..

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Oct 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
T: Feature Request Features requested by users.
Projects
None yet
Development

No branches or pull requests

7 participants