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

M150 during G29

Scheduled Pinned Locked Moved
General Discussion
3
17
323
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.
  • undefined
    DonStauffer
    last edited by DonStauffer 21 Mar 2024, 02:16

    Is there something about the G29 command that would cause an M150 statement to hang? I've been trying to do a progress meter with daemon.g, and whenever it hits an M150 F0 it hard hangs, and the daemon doesn't run again. I think it "thinks" it's still in it, so it doesn't do it again. M150 F1 doesn't have this effect. So I tried the M150 F0 line in the console while G29 was still running. It doesn't work. Restarted, pasted in the same line, and it works. So it seems like something about having a G29 running makes this command freeze.

    M150 R128 U255 B0 P32 S1 F0 E0

    undefined 5 Replies Last reply 21 Mar 2024, 02:33 Reply Quote 0
    • undefined
      DonStauffer @DonStauffer
      last edited by 21 Mar 2024, 02:33

      @DonStauffer mesh.g

      var LEDCount = 10
      var StripNum = 0
      var MeshXPointCount = 1 + (move.compensation.probeGrid.maxs[0] - move.compensation.probeGrid.mins[0]) / move.compensation.probeGrid.spacings[0]
      var MeshYPointCount = 1 + (move.compensation.probeGrid.maxs[1] - move.compensation.probeGrid.mins[1]) / move.compensation.probeGrid.spacings[1]
      set global.MeshPointCount = var.MeshXPointCount * var.MeshYPointCount
      M150 P0 S{var.LEDCount} F0 E{var.StripNum} ; Turn NeoPixel strip off
      set global.ProgressLEDCount = 0
      if exists(param.K)
      G29 S0 K{param.K}
      else
      G29 S0
      set global.MeshPointCount = 0
      M150 P0 S{var.LEDCount} F0 E{var.StripNum} ; Turn NeoPixel strip off
      1 Reply Last reply Reply Quote 0
      • undefined
        DonStauffer @DonStauffer
        last edited by 21 Mar 2024, 02:35

        @DonStauffer daemon.g

        echo "DAEMON!"
        if global.MeshPointCount > 0
        var X = move.axes[0].machinePosition
        var Y = move.axes[1].machinePosition + sensors.probes[0].offsets[1]
        var XMin = move.compensation.probeGrid.mins[0]
        var YMin = move.compensation.probeGrid.mins[1]
        var XMax = move.compensation.probeGrid.maxs[0]
        var XSpacing = move.compensation.probeGrid.spacings[0]
        var YSpacing = move.compensation.probeGrid.spacings[1]
        var PriorRowCount = (var.Y - var.YMin) / var.YSpacing
        var PointsPerRow = 1 + (var.XMax - var.XMin) / var.XSpacing
        var PriorRowPointCount = var.PriorRowCount * var.PointsPerRow
        var CurrRowPointCount = (var.X - var.XMin) / var.XSpacing
        if mod(var.PriorRowCount, 2) > 0.5
        set var.CurrRowPointCount = (var.XMax - var.X) / var.XSpacing
        var PointCount = var.PriorRowPointCount + var.CurrRowPointCount + 0.5
        echo "X=", {var.X}, " Y=", {var.Y}, " XMin=", {var.XMin}, " YMin=", {var.YMin}, " XMax=", {var.XMax}
        echo "XSpacing=", {var.XSpacing}, " YSpacing=", {var.YSpacing}, " PriorRowCount=", {var.PriorRowCount}
        echo "PointsPerRow=", {var.PointsPerRow}, " PriorRowPointCount=", {var.PriorRowPointCount}, " CurrRowPointCount=", {var.CurrRowPointCount}
        echo "daemon: ", {var.PointCount}, ", ", {var.PointCount / global.MeshPointCount}
        M98 P"/Macros/Lights/NeoPixel/Progress" R255 U255 B0 I32 C10 E0 F{var.PointCount / global.MeshPointCount}
        ;M99
        else
        if global.JobStatus = "Printing"
        M98 P"/Macros/Lights/NeoPixel/Progress" R0 U255 B0 I32 C10 E0 F{job.rawExtrusion / global.JobFilament}
        ;M99
        if global.JobStatus = "HeatingBed"
        var Fraction = (heat.heaters[0].current - global.JobTempBedStart) / (heat.heaters[0].active - global.JobTempBedStart)
        M98 P"/Macros/Lights/NeoPixel/Progress" R255 U0 B0 I32 C10 E0 F{var.Fraction}
        ;M99
        ; Job Statuses defined so far:
        ; if global.JobStatus = "None"
        ; if global.JobStatus = "Starting"
        ; if global.JobStatus = "HeatingBed"
        ; if global.JobStatus = "Printing"
        1 Reply Last reply Reply Quote 0
        • undefined
          DonStauffer @DonStauffer
          last edited by 21 Mar 2024, 02:37

          @DonStauffer Progress

          (This is full of echo commands to see what's happening)

          ; Manage parameters and defaults
          var Red = 255
          var Green = 255
          var Blue = 255
          var Intensity = 32
          var LEDCount = 10
          var StripNum = 0
          var LEDNum = 0
          var ProgressLEDCount = 0
          if exists(param.R)
          set var.Red = param.R
          if exists(param.U)
          set var.Green = param.U
          if exists(param.B)
          set var.Blue = param.B
          if exists(param.I)
          set var.Intensity = param.I
          if exists(param.C)
          set var.LEDCount = param.C
          if exists(param.E)
          set var.StripNum = param.E
          if exists(param.F)
          echo "param.F='", {param.F},"'"
          set var.ProgressLEDCount = floor(param.F * var.LEDCount + 0.5)
          if global.ProgressLEDCount != var.ProgressLEDCount
          echo "A"
          set global.ProgressLEDCount = var.ProgressLEDCount
          echo "B"
          ; Set correct number of lit LEDs
          if var.ProgressLEDCount == var.LEDCount
          echo "C"
          M150 R{var.Red} U{var.Green} B{var.Blue} P{var.Intensity} S{var.ProgressLEDCount} F0 E{var.StripNum}
          echo "D"
          else
          echo "E"
          M150 R{var.Red} U{var.Green} B{var.Blue} P{var.Intensity} S{var.ProgressLEDCount} F1 E{var.StripNum}
          echo "F:", {var.LEDCount - var.ProgressLEDCount}, ", ", {var.StripNum}
          var DarkLEDCount = var.LEDCount - var.ProgressLEDCount
          echo "G"
          M150 P0 S{var.DarkLEDCount} F0 E{var.StripNum}
          echo "H"
          1 Reply Last reply Reply Quote 0
          • undefined
            DonStauffer @DonStauffer
            last edited by 21 Mar 2024, 02:39

            @DonStauffer Known timing issue with this, which I haven't fixed yet since it's a work in progress. If you happen to run G29 when the daemon is about to run, it will catch the carriage on the way to the first point, and erroneously conclude it's something like 59% done. I'm not too concerned with this since I know why it happens. It's the hanging on M150 F0 I can't figure out.

            1 Reply Last reply Reply Quote 0
            • undefined
              DonStauffer @DonStauffer
              last edited by 21 Mar 2024, 05:42

              @DonStauffer RepRapFirmware for Duet 2 WiFi/Ethernet version 3.4.6 (2023-07-21 14:08:28) running on Duet WiFi 1.02 or later + DueX5

              undefined undefined 2 Replies Last reply 21 Mar 2024, 10:06 Reply Quote 0
              • undefined
                dc42 administrators @DonStauffer
                last edited by dc42 21 Mar 2024, 10:06

                @DonStauffer unless the port used by the M150 command supports direct DMA (e.g. the dedicated LED ports on the Duet 3 series main boards), M150 F1 has to disable interrupts while sending the LED data, in order to get the precise timing needed by Neopixel LEDs. This would mess up any movement commands; therefore if the port doesn't support direct DMA then M150 waits for motion to stop before executing. In your case, the M150 command will complete when the G29 command has finished.

                I have updated the documentation for M150.

                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

                undefined 3 Replies Last reply 21 Mar 2024, 15:45 Reply Quote 1
                • undefined
                  droftarts administrators @DonStauffer
                  last edited by 21 Mar 2024, 11:48

                  @DonStauffer I've added a note to the Connections > Dedicated LED connector > Duet 2 WiFi/Ethernet tab here: https://docs.duet3d.com/en/User_manual/Connecting_hardware/IO_Neopixel_DotStar#connections

                  Note that movement will be suspended any time M150 is used to update LEDs. So OK at the start/end of a print, or the end of heating up, but not a good idea during a print. This is because the CONN_LCD port doesn't have hardware DMA support for LEDs, the CPU has to stop all other activity including step pulse generation in order to generate the correct pulses to set the LEDs.

                  Ian

                  Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

                  1 Reply Last reply Reply Quote 0
                  • undefined
                    DonStauffer @dc42
                    last edited by 21 Mar 2024, 15:45

                    @dc42 I thought the CONN_LCD pin 5 on the Duet 2 WiFi did support NeoPixels - are you saying it doesn't?

                    1 Reply Last reply Reply Quote 0
                    • undefined
                      DonStauffer @dc42
                      last edited by DonStauffer 21 Mar 2024, 15:51

                      @dc42 "Note that movement will be suspended any time M150 is used to update LEDs. So OK at the start/end of a print, or the end of heating up, but not a good idea during a print. This is because the CONN_LCD port doesn't have hardware DMA support for LEDs, the CPU has to stop all other activity including step pulse generation in order to generate the correct pulses to set the LEDs."

                      Had that been stated when I started this project 4 months ago I would not have attempted it. It makes NeoPixels useless not to be able to use them during a print, since the whole point is for them to be indicators of progress. I've invested dozens of hours on this project. I designed and printed a board with buffers, a 5V power supply, and connectors to install in the electronics box of my Railcore, a printed mount for the NeoPixels with an integrated connector backshell, ordered numerous parts, etc. This is a major disappointment if there's no way to make it work.

                      I did check at the beginning and read all the materials. It sounded like the Duet 2 WiFi CONN_LCD port was made for NeoPixels and the like. I considered that question carefully and read that part repeatedly and carefully.

                      1 Reply Last reply Reply Quote 0
                      • undefined
                        DonStauffer @dc42
                        last edited by DonStauffer 21 Mar 2024, 16:09

                        @dc42 Is there some sort of driver available I could add to the Duet 2 or Duex 5 for it to hand off the task of providing the timing for the NeoPixels?

                        For instance, is there a way to use this driver, which can receive data via I2C?

                        https://learn.adafruit.com/adafruit-neodriver-i2c-to-neopixel-driver/overview

                        undefined 1 Reply Last reply 21 Mar 2024, 16:38 Reply Quote 0
                        • undefined
                          droftarts administrators @DonStauffer
                          last edited by 21 Mar 2024, 16:38

                          @DonStauffer You could connect an Arduino over a serial port, and have that control the LEDs. That's what people did in the olden days, before LEDs were supported in RRF.

                          The CONN_LCD port was originally for supporting LCDs, not LEDs, and for a long time Duet 2 didn't support LEDs directly (introduced in RRF 3.3) due to hardware limitations that @dc42 was eventually able to skirt around, but always with the caveat that motion stops (it's in the release notes for 3.3 under new features, but perhaps not well documented). As far as I'm aware, there are no available DMA pins on Duet 2. Another reason to move to Duet 3.

                          I don't know how to send messages over I2C, sorry. If there's a way, @dc42 would know!

                          Ian

                          Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

                          undefined 1 Reply Last reply 21 Mar 2024, 16:42 Reply Quote 0
                          • undefined
                            DonStauffer @droftarts
                            last edited by DonStauffer 21 Mar 2024, 16:42

                            @droftarts I do notice the Duex5 has a 10-pin "GPI & I2C Header", and the M260 command appears to be designed to use that. Arduino would be a new thing for me - I think I have one somewhere. But this Adafruit seesaw is only $7.50 and seems pretty capable (it also apparently handles the 5V pullup too). If it's just a matter of connecting the right pins from the Duex to the seesaw, that would be the easiest. The seesaw specifically is advertised for controlling NeoPixels (among other things). It's the connection to the Duex or Duet I'm uncertain about. Adafruit documentation:

                            SCL - I2C clock pin, connect to your microcontroller I2C clock line. There's a 10K pullup on this pin.
                            SDA - I2C data pin, connect to your microcontroller I2C data line. There's a 10K pullup on this pin.

                            At a guess, maybe the Duex GPIO & I2C header "TWD" pin connects to the seesaw I2C clock pin, and "TWC" connects to the seesaw data pin, and I assume a ground wire would be needed too. Then the 5V supply and NeoPixels have obvious seesaw screw terminal connections.

                            Also I don't know anything about this; from Adafruit:

                            "We recommend using 100KHz I2C, but speeds of up to 400KHz are supported. You may want to decrease the SDA/SCL pullups to 2.2K from 10K in that case." I don't know Duex capabilities in this regard. I can handle adding resistors and the like.

                            Similarly, they make the comment:
                            "Now, to be fair - it's not super fast because we have to write each pixel over I2C, but with an 800KHz or 1MHz I2C clock and as long as you're not writing the whole strip at once, it's not so bad!"
                            I'm not sure what the Duex capabilities are in that regard either.

                            The Seesaw default I2C address is 0x60, and M260 has the A parameter to specify that, and I'd just have to figure out what bytes to send, which seems to be documented by Adafruit. Apparently you start with the "standard I2C write header" (is that sent automatically by the M260?), then 2 register bytes (module base register address, which should be 0x60 I think for the seesaw, then module function register address, which seems to be 0x0E for the seesaw NeoPixels module), then just send the data bytes. Doesn't seem too hard.

                            Is there any obvious way this would not work? Not asking for a promise it WILL work, just 1. Does it seem reasonable, and 2. Is there any obvious pitfall? (in particular, any danger to the Duex board?)

                            It seems to me this is an inexpensive solution that should work. The driver supplies the signals the NeoPixels need, and the duet just basically uses I2C to "poke" values into the buffer of the seesaw chip in the driver. Assuming there are no limitations of the M260 like there are with M150, that should solve it.

                            undefined 1 Reply Last reply 21 Mar 2024, 19:35 Reply Quote 0
                            • undefined
                              DonStauffer @DonStauffer
                              last edited by DonStauffer 21 Mar 2024, 19:35

                              @DonStauffer It seems to me the NeoPixels could then be controlled like this. I think setting the buffer size would probably only need to be done once.

                              ; Function 0x03, set the buffer size, 3 bytes per LED, 10 LED strip
                              M260 A0x60 B{0x0E, 0x03, 0, 0x1E} ; 0, 0x1E is little-endian for 30
                              ; Function 0x04, set the 2nd and 3rd LED blue:
                              M260 A0x60 B{0x0E, 0x04, 0, 0x03, 0, 0, 0x20, 0, 0, 0x20} ; Start at byte offset 3
                              M260 A0x60 B{0x0E, 0x05} ; Function 0x05, Show
                              undefined 1 Reply Last reply 21 Mar 2024, 19:39 Reply Quote 0
                              • undefined
                                dc42 administrators @DonStauffer
                                last edited by 21 Mar 2024, 19:39

                                @DonStauffer correct, on Duet 2 you can use I2C to send/receive data to/from a device. Keep the I2C and the associated ground wires between the Duet and the I2C device short. Make sure that the I2C device either includes no pullup resistors and can handle 3.3V I2C signals, or has pullup resistors to 3.3V. If it doesn't satisfy this constraint, use a I2C level shifter.

                                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

                                undefined 1 Reply Last reply 21 Mar 2024, 19:50 Reply Quote 0
                                • undefined
                                  DonStauffer @dc42
                                  last edited by DonStauffer 21 Mar 2024, 19:50

                                  @dc42 Would the same TTL buffer I got to run the NeoPixels off CONN_LCD pin 5 work to pull up I2C signals? It's an MC74VHCT50A hex buffer / CMOS Logic Level Shifter chip, with LSTTL-compatible inputs. It says "tPD = 3.5 ns (Typ) at Vcc=5V".

                                  But I suspect the Adafruit device can do what's necessary. Their documentation says:

                                  SCL - I2C clock pin, connect to your microcontroller I2C clock line. There's a 10K pullup on this pin.
                                  SDA - I2C data pin, connect to your microcontroller I2C data line. There's a 10K pullup on this pin.

                                  I'm not sure what resistance is for what voltage. But also:

                                  "To power the board, give it the same power as the logic level of your microcontroller - e.g. for a 3V microcontroller like a Feather RP2040 or most Single Board Computers, use 3V, or for a 5V microcontroller like Arduino, use 5V."

                                  This Vin is independent of the 5V input used to output the neopixel control signal, so I guess I can take it from the Duet or Duex somewhere. Maybe the +3.3V pin from the Duex GPIO/I2C connector?

                                  undefined 1 Reply Last reply 21 Mar 2024, 20:38 Reply Quote 0
                                  • undefined
                                    dc42 administrators @DonStauffer
                                    last edited by 21 Mar 2024, 20:38

                                    @DonStauffer that buffer won't work for I2C because it is unidirectional; but the Adafruit board sounds OK to connect directly.

                                    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 0
                                    5 out of 17
                                    • First post
                                      5/17
                                      Last post
                                    Unless otherwise noted, all forum content is licensed under CC-BY-SA