Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    How to adress Neopixel LEDs individually?

    Scheduled Pinned Locked Moved
    Tuning and tweaking
    6
    9
    1.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • sonderzugundefined
      sonderzug
      last edited by

      Hi everyone,

      maybe I'm just missing it somehow, but I feel the following should be possible but I've not been able to figure it out using the M150 documentation.

      My setup is as follows; I have three single Neopixel LEDs (WS2812B chips) installed in my Voron's printhead, of which the first is sort of a status LED and the two following illuminate the nozzle area (all wired in "series" as they would be on an LED strip).
      In my config.g I have a single M150 X1 to initialise the LEDs, for now all other operations are done in macros and/or the slicer's start/stop gcode.

      I'm now trying, for example, to create macros that allow me to quickly switch the nozzle lights on and off. For this, I'd have to first send a M150 R...U...B... S1 F1 command and then a M150 R255 U255 B255 S3 F0 to set the two nozzle lights to "white". If I leave the first command empty, e.g. M150 S1 F1, it will turn off this LED after entering the second M150 command and lighting up the nozzle lights. Thus I'm concluding that I have to re-send the RGB values that the first LED already has, so that it will stay the way it is when the macro is executed. However I don't know these values since they have been set by another arbitrary macro or print gcode file.

      It seems as if what I'm trying to do is not yet possible with the current set of M150 options. Ideally I'd have a "start" parameter for the M150 command, indicating the first LED in the strip that the command is meant for and skipping the LEDs that come before this one. The S parameter would of course still be used to pass the number of LEDs that should be adressed.

      Any pointers are appreciated.

      Best regards, Niklas

      1 Reply Last reply Reply Quote 0
      • pkosundefined
        pkos
        last edited by

        If I remember correctly, the way communication with neopixels works is that you always have to send the complete string for the whole strip/chain/etc.

        Each of the neopixels grabs only the amount of data it needs for itself, then sends on the remainder of the signal onwards.

        So there's no way to just send data to a single neopixel somewhere down the line.

        One way to do it is to use variables and store what the last selection for that neopixel was.

        In my case (also on a Voron with the SB beta), I just created a set of macros based off klipper suggestion config and trigger them when needed. I only want nozzle leds to be on during printing, they should remain off otherwise, so the macros are simple.

        For example, QGL is:

        M150 S1 R128 U25 B100 W0 P255 F1
        M150 R0 U0 B0 W0
        

        And so on.

        This could be modified so that only the toolhead led gets changed, without touching the other two (just remove the F1 and second line and you're done).

        Voron 2.4 (Duet 3 6HC + 3HC standalone), Voron SW (Duet 3 mini 5+ standalone), Voron Trident (Duet 3 mini 5+ standalone), Voron 0.1

        dc42undefined zaptaundefined 2 Replies Last reply Reply Quote 0
        • dc42undefined
          dc42 administrators @pkos
          last edited by

          @pkos correct, all the Neopixels need to be sent data at the same time. Your suggestion of using variables should be a good solution for @sonderzug because he is using a string of just 3 pixels.

          Duet WiFi hardware designer and firmware engineer
          Please do not ask me for Duet support via PM or email, use the forum
          http://www.escher3d.com, https://miscsolutions.wordpress.com

          1 Reply Last reply Reply Quote 1
          • zaptaundefined
            zapta @pkos
            last edited by

            @pkos said in How to adress Neopixel LEDs individually?:

            I just created a set of macros

            You can also have a single macro file that accepts a pattern selection parameter.

            I update the neopixels in daemon.g using conditional code that looks at various object model variables.

            sonderzugundefined 1 Reply Last reply Reply Quote 0
            • sonderzugundefined
              sonderzug @zapta
              last edited by

              @zapta yes I think that is also what I should be doing, since it is mostly what I'm trying to achieve anyways.

              thank you to all for commenting.

              zaptaundefined 1 Reply Last reply Reply Quote 0
              • zaptaundefined
                zapta @sonderzug
                last edited by

                @sonderzug , this is the led control logic in my daemon.g. Daemon.g runs every 10 secs so sometime I also call it directly for faster response, e.g. when starting a print.

                ; LED control
                if {state.status} == "paused"
                  M150 R255 B255 P255 S20  ; purple
                  M300 S4000 P50 G4 P300 M300 S4000 P50 ; double beep
                elif {state.status} == "processing" || {state.status} == "busy"
                  M150 R255 U255 B255 P255 S20  ; white
                elif {heat.heaters[0].current} > 50 || {heat.heaters[1].current} > 70
                  M150 R255 U0 B0 P255 S20  ; red
                elif {state.status} == "idle"
                  M150 R0 U255 B0 P255 S20  ; green
                else
                  M150 R150 U0 B150 P255 S20 ; purple
                
                rickgomez2003undefined 1 Reply Last reply Reply Quote 1
                • gallaghersartundefined
                  gallaghersart
                  last edited by

                  I was just thinking of this today, then went to search and found this! Sorry to hijack, different uses but same requirement.

                  I wanted to used the LEDS as a status lights that I could just attach to front of printers to see how all printers are doing at that moment.

                  But mounted in a fixed adapter so each color is in its own location. Like those CNC Signal Light towers. But just a strip of a few LEDs.

                  What I was thinking,,
                  RED = Error
                  ALL off = power short/other major alarm
                  RED Blinking = out of filament
                  Solid GREEN = Done
                  GREEN slow blink = printing , GREEN faster blinking near finish OR
                  Groups of green = printing and how much done (1 green led just started, 5 out of 6 all most done)
                  Same Green Light But blue for start /warm up times. %50 blue once bed is heated, then remainder light up blue until hotend is at temp then turns to green for printing.
                  Orange/ blue network connectivity
                  ALL white blink = find printer location
                  Yellow= on, no job
                  Custom Color for groups of printers doing same job

                  IF not can I Have 3 separate Neopixel LEDs strips, and just control those 3 separately from each other rather than just having a single strip?

                  `mike

                  1 Reply Last reply Reply Quote 0
                  • sonderzugundefined
                    sonderzug
                    last edited by

                    @gallaghersart from what I understand now, it can be handled in daemon.g, maybe in a submacro for better structure.

                    You'd have to make extensive use of variables. The macro could be something like this (mockup):

                    • determine RGB values for each individual "light" (=group of LEDs), much like @zapta 's example, according to your specification. Store in variables (e.g. "R_group1, U_group1, B_group1, R_group2 ...")

                    • send M150 string at the end of the macro:

                    M150 R{R_group1} U{B_group1} B{B_group1} S{[number of LEDs in first group]} P{P_group1} F1
                    M150 R{R_group2} U{B_group2} B{B_group2} S{[number of LEDs in second group]} P{P_group2} F1
                    M150 R{R_group3} U{B_group3} B{B_group3} S{[number of LEDs in third group]} P{P_group3} F0
                    

                    this way, all RGB values for the whole strip would be send at once, which was what my initial confusion was about.

                    If this macro is called regularly in daemon.g, it should all be quite smooth.

                    another thing is "blinking"; this would be more difficult. It could be done with a variable for brightness that is changed in each iteration of daemon.g, e.g.

                    P_group1 = 255 (initialised once at start, e.g. in config.g)
                    P_group2 ... 
                    P_sign = 1
                    

                    then in daemon.g:

                    if {P_group1} == 0 || {P_group1} == 255
                      P_sign = -P_sign
                    if {P_group1} < 255 && {P_group1} > 0
                      P_group1 = P_group1 + (P_sign*5)
                    

                    this way in each iteration of daemon.g, the brightness value is changed. the speed of blinking is dependent on how often daemon.g is called (I understand that this can be adjusted) and the value added in the last operation (e.g. 5)

                    note: not tested, just what I imagine could work.
                    I think there has been a request for a more elaborate way of handling LED colours before. Until then, we'd have to work like this.

                    best, Niklas

                    1 Reply Last reply Reply Quote 0
                    • rickgomez2003undefined
                      rickgomez2003 @zapta
                      last edited by

                      This post is deleted!
                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post
                      Unless otherwise noted, all forum content is licensed under CC-BY-SA