Navigation

    Duet3D Logo

    Duet3D

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • Documentation
    • Order
    1. Home
    2. tfjield
    • Profile
    • Following 0
    • Followers 0
    • Topics 11
    • Posts 79
    • Best 15
    • Groups 0

    tfjield

    @tfjield

    19
    Reputation
    4
    Profile views
    79
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Website fjieldcnc.com Location California

    tfjield Unfollow Follow

    Best posts made by tfjield

    • Scale Layer Chart by Shown Data, Only

      Currently, the layer chart scales the Y axis by all the layer times:

      27f04b1f-5a58-4690-91d0-ed264073cd05-image.png

      But when showing only the last 30 layers, the Y axis stays the same:

      52f37d32-b61b-4852-b587-5da1aee06257-image.png

      When subsequent layers are much faster than the layers before, the graph loses it's value, since all the points are clustered near the bottom.

      My request is to adjust the Y axis based on the shown data, only.

      posted in Duet Web Control wishlist
      tfjield
      tfjield
    • RE: Event notifications not dismissing on multiple clients

      @chrishamm
      Even though the messages aren't dismissed with M292, once the message either times out or close is pressed somewhere, why is the event message shown again, ever? Especially if it has a timeout, it must not be that important to keep coming back.

      How do we get rid of it and keeping it from showing up over and over?

      posted in Duet Web Control
      tfjield
      tfjield
    • RE: Intermittent WiFi Connection at Startup

      @oliof @Phaedrux
      I may have found something. On a hunch, I decided to replace the SD card with a faster one, thinking that there might be some kind of race condition occurring during startup.

      The card that came with it is a SanDisk Edge 8 GB class 4. Here's a stock image of the card:
      43983426-2011-4549-a057-036e0fd23447-image.png

      I replaced it with a SanDisk Ultra.

      With the original card it would boot and connect to WiFi no more than half the time. After replacing the card, it's connected 5 out of 5 reboots. I'll continue testing, but it seems much better!

      EDIT: This is on the same AP; I've only changed the card.

      posted in General Discussion
      tfjield
      tfjield
    • RE: Mesh Bed Compensation Capabilities

      @3dreamer

      I ended up getting my problems all sorted out. But I had to do several things:

      • Increase the supports for my bed so that it was closer to level to start with. My bed is a bit over 600 mm x 600 mm and wasn't sufficiently supported, so there was a significant sag in the middle. Now I still have some sag, but my maximum variance across the surface is 0.387 mm.
      • Fix the twist in my gantry. There was a couple degree twist along my y-axis, and due to the location of my BL Touch relative to my nozzle, just a degree resulted in a very significant height error. One degree of twist was over 0.4 mm of height error.
      • I picked a common point on one corner for my z-axis datum, my probe z offset, my bed tilt probing points, and my bed mesh compensation.
      • Performed a high resolution map (21 x 21) at temperature.
      • Modified my macros so that for every print it will do the following:
        o Verify that the axes have been homed. If not, home them.
        o Verify that the bed has been adjusted for tilt. If not, adjust it, and home z again.
        o Turn on bed mesh compensation.

      I do not like the commonly accepted approach of using the center of the bed for my z datum. I work in a field where I'm very conscious of how things fail, and I don't want my datum at what is most likely the lowest point on my bed. If, for some reason, I don't turn on bed mesh compensation and I'm zeroed at that point, them I'm likely to run into my bed as I move away from the center and screw up my print head and PEI sheet. So I want my datum at one of the highest points.

      Also, I want the corners of my bed tilt and bed mesh to be identical to my datum point, and use the same exact point for measuring the probe's z offset. In this way, it's easy for me to verify that everything is working right. My bed mesh should show zero compensation at that corner, and because I've already corrected the tilt, all four corners of the bed mesh should show almost zero compensation.

      It's been a few weeks and several km of filament since I last took a bed mesh map, and my prints are rock-solid every time, now.

      posted in General Discussion
      tfjield
      tfjield
    • RE: G-Code Meta commands: Option unset (all) globals

      @fcwilt 🤣

      posted in Firmware wishlist
      tfjield
      tfjield
    • RE: Error in Docs for M591

      @comediantf2
      This is what I put in filament-error.g so that it would work with both 3.3 and 3.4+:

      M25				; first, pause the print as pre-RRF 3.3 did
       
      if {param.D == 0}		; now call the right pre-RRF 3.4 subroutines.
      	M98 P"filament-error0.g"
      elif {param.D == 1}
      	M98 P"filament-error1.g"
      
      posted in Filament Monitor
      tfjield
      tfjield
    • RE: Extruders Not Obeying G1 Feed Rate

      @phaedrux Nope, just set to 100%. My long print is almost done, and I'm going to try to duplicate the problem and gather more info.

      posted in General Discussion
      tfjield
      tfjield
    • Cura gcode Save to Disk with Thumbnails

      @resam
      Per the conversation in the other thread, I was looking for a an option in Cura to save a gcode file to disk with QOI thumbnails. I took your thumbnail code from github and incorporated it into this post-processing script:

      import os
      import base64
      import traceback
      from io import StringIO
      
      from PyQt6 import QtCore
      from PyQt6.QtCore import QCoreApplication, QBuffer
      from PyQt6.QtGui import QImage
      
      from UM.Application import Application
      from UM.Logger import Logger
      from UM.Math.Matrix import Matrix
      
      from cura.Snapshot import Snapshot
      from cura.PreviewPass import PreviewPass
      
      from ..Script import Script
      from qoi import QOIEncoder
      
      
      class CreateQOIThumbnail(Script):
          def __init__(self):
              super().__init__()
              
          def render_scene(self):
              scene = Application.getInstance().getController().getScene()
              active_camera = scene.getActiveCamera()
              render_width, render_height = active_camera.getWindowSize()
              render_width = int(render_width)
              render_height = int(render_height)
              Logger.log("d", f"Found active camera with {render_width=} {render_height=}")
      
              QCoreApplication.processEvents()
      
              preview_pass = PreviewPass(render_width, render_height)
              fovy = 30
              satisfied = False
              zooms = 0
              while not satisfied and zooms < 5:
                  preview_pass.render()
                  pixel_output = preview_pass.getOutput().convertToFormat(QImage.Format.Format_ARGB32)
                  # pixel_output.save(os.path.expanduser(f"~/Downloads/foo-a-zoom-{zooms}.png"), "PNG")
      
                  min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output)
                  size = max((max_x - min_x) / render_width, (max_y - min_y) / render_height)
                  if size > 0.5 or satisfied:
                      satisfied = True
                  else:
                      # make it big and allow for some empty space around
                      zooms += 1
                      fovy *= 0.75
                      projection_matrix = Matrix()
                      projection_matrix.setPerspective(fovy, render_width / render_height, 1, 500)
                      active_camera.setProjectionMatrix(projection_matrix)
      
                  Logger.log("d", f"Rendered thumbnail: {zooms=}, {size=}, {min_x=}, {max_x=}, {min_y=}, {max_y=}, {fovy=}")
      
              # crop to content
              pixel_output = pixel_output.copy(min_x, min_y, max_x - min_x, max_y - min_y)
              Logger.log("d", f"Cropped thumbnail to {min_x}, {min_y}, {max_x - min_x}, {max_y - min_y}.")
              # pixel_output.save(os.path.expanduser("~/Downloads/foo-b-cropped.png"), "PNG")
      
              Logger.log("d", "Successfully rendered scene.")
              return pixel_output
      
      
          def render_thumbnail(self, pixel_output, width, height):
              # scale to desired width and height
              pixel_output = pixel_output.scaled(
                  width, height,
                  aspectRatioMode=QtCore.Qt.AspectRatioMode.KeepAspectRatio,
                  transformMode=QtCore.Qt.TransformationMode.SmoothTransformation
              )
              Logger.log("d", f"Scaled thumbnail to {width=}, {height=}.")
              # pixel_output.save(os.path.expanduser("~/Downloads/foo-c-scaled.png"), "PNG")
      
              # center image within desired width and height if one dimension is too small
              if pixel_output.width() < width:
                  d = int((width - pixel_output.width()) / 2. + 0.5)
                  pixel_output = pixel_output.copy(-d, 0, width, pixel_output.height())
                  Logger.log("d", f"Centered thumbnail horizontally {d=}.")
              if pixel_output.height() < height:
                  d = int((height - pixel_output.height()) / 2. + 0.5)
                  pixel_output = pixel_output.copy(0, -d, pixel_output.width(), height)
                  Logger.log("d", f"Centered thumbnail vertically {d=}.")
              # pixel_output.save(os.path.expanduser("~/Downloads/foo-d-aspect-fixed.png"), "PNG")
      
              Logger.log("d", f"Successfully rendered {width}x{height} thumbnail.")
              return pixel_output
      
          def encode_as_qoi(self, thumbnail):
              # https://qoiformat.org/qoi-specification.pdf
              pixels = [thumbnail.pixel(x, y) for y in range(thumbnail.height()) for x in range(thumbnail.width())]
              pixels = [(unsigned_p ^ (1 << 31)) - (1 << 31) for unsigned_p in pixels]
              encoder = QOIEncoder()
              r = encoder.encode(
                  width=thumbnail.width(),
                  height=thumbnail.height(),
                  pixels=pixels,
                  alpha=thumbnail.hasAlphaChannel(),
                  linear_colorspace=False
              )
              if not r:
                  raise ValueError("image size unsupported")
              Logger.log("d", f"Successfully encoded {thumbnail.width()}x{thumbnail.height()} thumbnail in QOI format.")
      
              size = encoder.get_encoded_size()
              return encoder.get_encoded()[:size]
      
          def encode_as_png(self, thumbnail):
              buffer = QBuffer()
              buffer.open(QBuffer.ReadWrite)
              thumbnail.save(buffer, "PNG")
              buffer.close()
              return buffer.data()
      
          def generate_thumbnail(self):
              thumbnail_stream = StringIO()
              Logger.log("d", "Rendering thumbnail image...")
              try:
                  scene = self.render_scene()
      
                  # PanelDue: 480×272 (4.3" displays) or 800×480 pixels (5" and 7" displays)
                  # ref https://forum.duet3d.com/post/270550 and https://forum.duet3d.com/post/270553
                  thumbnail_sizes = [
                      (48, 48),
                      (128, 128),
                      (160, 160),
                      (256, 256),
                  ]
                  for width, height in thumbnail_sizes:
                      thumbnail = self.render_thumbnail(scene, width, height)
                      qoi_data = self.encode_as_qoi(thumbnail)
                      b64_data = base64.b64encode(qoi_data).decode('ascii')
                      b64_encoded_size = len(b64_data)
      
                      thumbnail_stream.write(f"; thumbnail_QOI begin {width}x{height} {b64_encoded_size}\n")
                      max_row_length = 78
                      for i in range(0, b64_encoded_size, max_row_length):
                          s = b64_data[i:i+max_row_length]
                          thumbnail_stream.write(f"; {s}\n")
                      thumbnail_stream.write(f"; thumbnail_QOI end\n")
      
                  Logger.log("d", "Successfully encoded thumbnails as base64 into gcode comments.")
      
                  return thumbnail_stream
              except Exception as e:
                  Logger.log("e", "failed to create snapshot: " + str(e))
                  Logger.log("e", traceback.format_stack())
                  # continue without the QOI snapshot
                  return StringIO()
                  
          def getSettingDataString(self):
              return """{
                  "name": "Create QOI Thumbnail",
                  "key": "CreateQOIThumbnail",
                  "metadata": {},
                  "version": 2,
                  "settings":
                  {
                      "enabled":
                      {
                          "label": "Enabled",
                          "description": "Enable to generate thumbnails.",
                          "type": "bool",
                          "default_value": true
                      }
                  }
              }"""
              
          def execute(self, data):
              if not self.getSettingValueByKey("enabled"):
                  return data;
          
              snapshot = self.generate_thumbnail()
              if snapshot:
      
                  for layer in data:
                      layer_index = data.index(layer)
                      lines = data[layer_index].split("\n")
                      for line in lines:
                          if line.startswith(";Generated with Cura"):
                              Logger.log("d", "Found appropriate place in gcode file.")
                              line_index = lines.index(line)
                              insert_index = line_index + 1
                              lines[insert_index:insert_index] = snapshot.getvalue()[:-1].split("\n")
                              break
      
                      final_lines = "\n".join(lines)
                      data[layer_index] = final_lines
      
              return data
      

      This is just your code, slightly edited to work as a script, and it works well for me. I should have done this up on github, but I've never created a repository there and it would take me more time to figure it out than I wanted to spend today! lol. Besides, I'm just a hack, so if you wanted to take this (or do it better) please do!

      Thanks for doing the heavy lifting!

      posted in General Discussion
      tfjield
      tfjield
    • RE: Extruders Not Obeying G1 Feed Rate

      @fcwilt @Phaedrux
      Just an update, I've found that the issue isn't just when there's a filament error. If I just home the machine, turn on the hot end, and then try to retract to change the filament, I often have the same issue: the extruder races to try to extract. Hitting retract again and it usually runs at the normal rate.

      When this print is done, I'll see if this happens from a cold start so it can be duplicated.

      posted in General Discussion
      tfjield
      tfjield
    • RE: Mesh Outside of Limits

      @fcwilt Maybe! lol. What I mean is that with G30, I can probe wherever I want. The axes limits are not obeyed. Meaning if I set a location for the probe that will move the printhead beyond the limits, it will just do it. (This behavior is warned about in the documentation.) With G29, if such a move would require the printhead to move out of limits, it gives an error. (And trying to avoid the error by using M564 S0 doesn't work. ) And like I said, it surprises me that exceeding the limits is explicitly allowed by G30, but not by G29.

      posted in General Discussion
      tfjield
      tfjield

    Latest posts made by tfjield

    • RE: Mesh Bed Compensation Capabilities

      @3dreamer

      I ended up getting my problems all sorted out. But I had to do several things:

      • Increase the supports for my bed so that it was closer to level to start with. My bed is a bit over 600 mm x 600 mm and wasn't sufficiently supported, so there was a significant sag in the middle. Now I still have some sag, but my maximum variance across the surface is 0.387 mm.
      • Fix the twist in my gantry. There was a couple degree twist along my y-axis, and due to the location of my BL Touch relative to my nozzle, just a degree resulted in a very significant height error. One degree of twist was over 0.4 mm of height error.
      • I picked a common point on one corner for my z-axis datum, my probe z offset, my bed tilt probing points, and my bed mesh compensation.
      • Performed a high resolution map (21 x 21) at temperature.
      • Modified my macros so that for every print it will do the following:
        o Verify that the axes have been homed. If not, home them.
        o Verify that the bed has been adjusted for tilt. If not, adjust it, and home z again.
        o Turn on bed mesh compensation.

      I do not like the commonly accepted approach of using the center of the bed for my z datum. I work in a field where I'm very conscious of how things fail, and I don't want my datum at what is most likely the lowest point on my bed. If, for some reason, I don't turn on bed mesh compensation and I'm zeroed at that point, them I'm likely to run into my bed as I move away from the center and screw up my print head and PEI sheet. So I want my datum at one of the highest points.

      Also, I want the corners of my bed tilt and bed mesh to be identical to my datum point, and use the same exact point for measuring the probe's z offset. In this way, it's easy for me to verify that everything is working right. My bed mesh should show zero compensation at that corner, and because I've already corrected the tilt, all four corners of the bed mesh should show almost zero compensation.

      It's been a few weeks and several km of filament since I last took a bed mesh map, and my prints are rock-solid every time, now.

      posted in General Discussion
      tfjield
      tfjield
    • RE: New Input Shaping plugin v3.4.1-b1

      @oliof As I had posted in another thread, I measured my frequencies and applied a shaper and measured again and it looked good. (I haven't posted my results, yet.) But when I printed a test part, the ringing was noticeably worse.

      What would this be an indication of? Damping factor too high?

      posted in Plugins for DWC and DSF
      tfjield
      tfjield
    • RE: Intermittent WiFi Connection at Startup

      @phaedrux Here are some better pictures. I tried to image near the pads on the bottom.

      d0513ec0-a96d-4d60-ba40-692b4a4e6a61-image.png
      7c30bcab-50f7-45b0-a687-0dec6e741e8b-image.png
      43854fcc-afd2-461a-9987-0d9c2fcc1aa8-image.png
      5824e79f-dc7c-45c4-a3f0-ffd53c6c8e74-image.png

      That's about the best I can do.

      posted in General Discussion
      tfjield
      tfjield
    • RE: Intermittent WiFi Connection at Startup

      @phaedrux Sure, I can get better photos. Anything in particular I should try to capture? Are you looking for a cold solder joint? Perhaps it would be better if I viewed it from a 45° angle...

      posted in General Discussion
      tfjield
      tfjield
    • RE: Intermittent WiFi Connection at Startup

      @phaedrux
      These aren't great... Is there something specific you're looking for? If so, I can try to highlight it better. And these were with a cell phone camera... If these aren't good enough, I can pull out the USB microscope.

      3e9385d7-c377-4099-97c2-7cc2206bc1ff-image.png
      3a1fa8ce-e5b0-48bb-9b83-9f24cf0dc074-image.png

      posted in General Discussion
      tfjield
      tfjield
    • RE: Intermittent WiFi Connection at Startup

      Well, it turns out that this was not the fix. As time went on, the number of times it would fail vs. the number of times that it would succeed has increased a lot. We're back to 50/50 or greater failure rate.

      To this day, once the WiFi is connected I have never lost connection.

      I suppose this could be a hardware problem, but it sure seems more like some kind of race condition. Is there anything I can do to help determine the root cause for the failure?

      posted in General Discussion
      tfjield
      tfjield
    • RE: Using Input Shaping. Any suggestions or advice??

      @chickenwoman said in Using Input Shaping. Any suggestions or advice??:

      @tfjield this is off topic but what wire did you use on your Modix and what length? I have a Big 60 and have tried several different types of wire and cant get it to work.

      The first time I tried I used an old, unshielded network cable and it wouldn't recognize the accelerometer. Then I went with a USB cable.

      I followed this guide:
      https://forum.duet3d.com/topic/22878/software-package-3-3beta3-released/68?_=1624809172098

      I purchased this USB cable from Amazon:
      https://smile.amazon.com/dp/B014RWATK2

      I left the cable at about 5 feet / 1.5 meters. There are two shields inside wrapped around two different pairs, and a shield around the whole thing. I attached all three shields together, and connected it to one of the ground points on the Duet boards. (I have the DueX5, so I used one of the grounds on one of the 5 endstop connectors.)

      I use a PT100 daughterboard, and the daughterboard moves CS3 and CS4 from pins 7 and 9 to pins 3 and 1, respectively. So my CS connects to pin 1 and INT connects to pin 3.

      EDIT: Here are some pics of my connection. I didn't have a dual inline plug that took crimp connections for the Duet side so I made one with the connectors that I had.

      ee0ab1d7-ee9e-43a5-97dd-b0af4d850763-image.png
      633244bf-8312-4683-bf66-d2669ced8806-image.png
      7d83f86b-879a-4fdc-9c37-005c4229cd63-image.png

      posted in General Discussion
      tfjield
      tfjield
    • RE: Using Input Shaping. Any suggestions or advice??

      @oliof Thank you! Great idea about the wires; I didn't think of that. I'll add some strain relief to minimize any artifact they might be introducing.

      I don't think the x and y being different on this machine means much. In my first photos you can see 4 silver screw heads. Those are the only attachments to the y-axis rail, so that whole head can twist around the y-axis forward and backwards (so the hot end oscillates in the x-direction). There's a bit less play rotating around the x-axis.

      But the belts could be contributing. There is one y-axis belt and two x-axis belts, and I know the y tension is higher than the two x's.

      posted in General Discussion
      tfjield
      tfjield
    • Using Input Shaping. Any suggestions or advice??

      I'm starting to look at input shaping (for the first time!), and I could use some guidance...

      I've attached the accelerometer (LIS3DH from adafruit) to the Duet2 WiFi, and it appears to be working properly. I configured it with M955 P0 C"spi.cs4+spi.cs3" I01 and I mounted it to my hot end with a zip tie (and some tape to avoid shorting the back).

      PXL_20220625_060946316.jpg
      PXL_20220625_060952556.jpg

      I'm able to collect data using the Input Shaping Plugin, v4.3.1-b1:
      7a048a4d-a09e-4313-a779-c4981eabcaf7-image.png

      This is with XY maximum speeds set to 16000 mm/min and acceleration set to 3000 mm/sec^2.

      This is on a Modix Big-60, and the accelerometer is connected to the printhead, so there is no z-motion. But the big printhead bracket has a decent amount of movement around the y-axis, so I would expect to see some significant ringing along x, and I see see one peak around 27 Hz.

      Do these curves look right? (Why all the z-axis data? Is this just a byproduct of the FFT without any strong frequency components?)

      Turning on ZVDD at a 27 Hz center frequency (arbitrary choice, and the white checkmark next to the center frequency entry is fun!) gets me this:
      e4b5ad13-9736-4481-b496-a827b5c2b504-image.png

      So it seems like it's working, right? Any advise or suggestions? I haven't tried printing any ringing tests, yet.

      posted in General Discussion
      tfjield
      tfjield
    • RE: Incorrect extrusion amount on slow and/or small axis moves

      @fcwilt Oh, you're right, I was thinking backwards. I forgot that he wants to limit extrusion to below the max, not retraction.

      posted in General Discussion
      tfjield
      tfjield