FluidNC icon indicating copy to clipboard operation
FluidNC copied to clipboard

I2SO_STREAM bug?

Open snakescb opened this issue 3 years ago • 19 comments

Hi,

on v3.3.0 (but also on the previous version), my motor on a TMC5160 driver runs fine using the I2S_STATIC engine. I setup the config to 32 microstepping, 6400 steps per mm, 50mm per minute. When I jog 1 mm, the motor turns exactly 1 revolution as expected, all fine.

When I change nothing but the stepper engine to I2S_stream, jogging 1mm gives a bit more than 2.5 revolutions. I first assumed my controller board is broken, but I think it is more related to the software. Is this issue known? Is there a general recommendation, in which situation to use I2S_STATIC, and when I2S_STREAM?

Regards Christian

snakescb avatar Jan 13 '22 22:01 snakescb

I'll look into that tomorrow. If there is an issue it is likely setup or firmware.

The hardware is used the same way in either mode.

bdring avatar Jan 13 '22 23:01 bdring

I tested I2SO_Stream and I2SO_Static on my machine. They both behave the same as far as motion and resolution go.

Can you post the config file you used? Only post the one that works. I will change the I2S type myself.

https://github.com/bdring/FluidNC/wiki/Requesting-Help

bdring avatar Jan 14 '22 14:01 bdring

Sure, here my config.yaml. Currently on my bench the motor is installed on the x axis. All drivers configured are installed on the board and initialize ok.

board: NCMate
name: CNC Maettenwil

start:
  must_home: false
  
stepping:
  engine: I2S_STATIC
  idle_ms: 255
  pulse_us: 10
  dir_delay_us: 1
  disable_delay_us: 0

axes:
  shared_stepper_disable_pin: NO_PIN
  
  x:
    steps_per_mm: 6400.000
    max_rate_mm_per_min: 350.000
    acceleration_mm_per_sec2: 50.00
    max_travel_mm: 400.000
    soft_limits: false
    
    homing:
      cycle: 2
      positive_direction: false
      mpos_mm: 150.000
      feed_mm_per_min: 100.000
      seek_mm_per_min: 200.000
      settle_ms: 500
      seek_scaler: 1.100
      feed_scaler: 1.100

    motor0:
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: false
      pulloff_mm: 1.000

      tmc_5160:
        cs_pin: i2so.7
        step_pin: i2so.6
        direction_pin: i2so.5
        disable_pin: i2so.4
        r_sense_ohms: 0.075
        run_amps: 0.8
        hold_amps: 0.4
        microsteps: 32
        stallguard: 0
        stallguard_debug: false
        toff_disable: 0
        toff_stealthchop: 5
        toff_coolstep: 3
        run_mode: StealthChop
        homing_mode: StealthChop
        use_enable: false

  y:
    steps_per_mm: 640.000
    max_rate_mm_per_min: 1500
    acceleration_mm_per_sec2: 1000
    max_travel_mm: 600.000
    soft_limits: false
    
    homing:
      cycle: 2
      positive_direction: false
      mpos_mm: 150.000
      feed_mm_per_min: 100.000
      seek_mm_per_min: 200.000
      settle_ms: 500
      seek_scaler: 1.100
      feed_scaler: 1.100

    motor0:
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: false
      pulloff_mm: 1.000

      tmc_5160:
        cs_pin: i2so.3
        step_pin: i2so.2
        direction_pin: i2so.1
        disable_pin: i2so.0
        r_sense_ohms: 0.075
        run_amps: 2.00
        hold_amps: 1.50
        microsteps: 16
        stallguard: 0
        stallguard_debug: false
        toff_disable: 0
        toff_stealthchop: 5
        toff_coolstep: 3
        run_mode: StealthChop
        homing_mode: StealthChop
        use_enable: false

    motor1:
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: false
      pulloff_mm: 1.000
      
      tmc_5160:
        cs_pin: i2so.11
        step_pin: i2so.10
        direction_pin: i2so.9
        disable_pin: i2so.8
        r_sense_ohms: 0.075
        run_amps: 2.00
        hold_amps: 1.50
        microsteps: 16
        stallguard: 0
        stallguard_debug: false
        toff_disable: 0
        toff_stealthchop: 5
        toff_coolstep: 3
        run_mode: StealthChop
        homing_mode: StealthChop
        use_enable: false

  z:
    steps_per_mm: 640
    max_rate_mm_per_min: 1500
    acceleration_mm_per_sec2: 1000
    max_travel_mm: 200
    soft_limits: false

    homing:
      cycle: 1
      mpos_mm: 100
      positive_direction: true

    motor0:
      limit_neg_pin: NO_PIN
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: false
      pulloff_mm: 1.000

      tmc_5160:
        cs_pin: i2so.15
        step_pin: i2so.14
        direction_pin: i2so.13
        disable_pin: i2so.12
        r_sense_ohms: 0.075
        run_amps: 2.00
        hold_amps: 1.50
        microsteps: 16
        stallguard: 0
        stallguard_debug: false
        toff_disable: 0
        toff_stealthchop: 5
        toff_coolstep: 3
        run_mode: StealthChop
        homing_mode: StealthChop
        use_enable: false
        
i2so:
  bck_pin: gpio.22
  data_pin: gpio.21
  ws_pin: gpio.17

spi:
  miso_pin: gpio.19
  mosi_pin: gpio.23
  sck_pin: gpio.18

sdcard:
  card_detect_pin: NO_PIN
  cs_pin: gpio.5

control:
  safety_door_pin: NO_PIN
  reset_pin: NO_PIN
  feed_hold_pin: NO_PIN
  cycle_start_pin: NO_PIN
  macro0_pin: NO_PIN
  macro1_pin: NO_PIN
  macro2_pin: NO_PIN
  macro3_pin: NO_PIN

coolant:
  flood_pin: i2so.23
  mist_pin: i2so.20
  delay_ms: 0

probe:
  pin: gpio.4:low
  check_mode_start: true

macros:
  startup_line0:
  startup_line1:
  macro0:
  macro1:
  macro2:
  macro3:

10V:
  forward_pin: i2so.16
  reverse_pin: i2so.17
  pwm_hz: 5000
  output_pin: gpio.16
  enable_pin: NO_PIN
  direction_pin: NO_PIN
  disable_with_s0: false
  s0_with_disable: true
  spinup_ms: 0
  spindown_ms: 0
  tool_num: 0
  speed_map: 0=0.000% 10000=100.000%

snakescb avatar Jan 14 '22 16:01 snakescb

What is the controller board?

MitchBradley avatar Jan 14 '22 16:01 MitchBradley

It is going to take me a little while to setup a real test with all your settings.

Observation: The acceleration looks a little fast for all your other settings. With 1mm/rev you are asking a lot of that motor.

I was able to put both on a logic analyzer and they both look good for step generation. There is about 4us of jitter on the signal, but it would be negligible at your 50mm/min feed rate.

bdring avatar Jan 14 '22 19:01 bdring

Hi, there is no rush, I can work well with I2S_STATIC. I lowered the acceleration, same result. Two videos attached, only difference is the stepper engine. Really super weird. I am running it on my own custom controller, I can send one over to you if you wish (but I just cannot imagine it is HW related). Btw, the motor also sound much harsher with I2S_STREAM

https://user-images.githubusercontent.com/10495848/149575199-c42715e4-cca3-4057-9153-9189c35509b8.mov https://user-images.githubusercontent.com/10495848/149575210-78e3868b-6504-4e10-a082-7308a5c269d9.mov

snakescb avatar Jan 14 '22 19:01 snakescb

Quick update, attached my (cheapo) logic analyzer to the pulse signal on the driver, here what I get: With STATIC, I get evenly distributed pulses at constant speed, with STREAM I get missing pulses, sometimes pulses remaing high, and some pulses are triggering doubled. I see the same on several boards, it can we a hardware issue, but I cannot imagine where it could come from. I2S_STREAM I2S_STATIC

snakescb avatar Jan 17 '22 13:01 snakescb

What have you done to ensure signal integrity on the I2S bus? I am guessing that you have not observed the waveforms with a scope. You did not provide a photo of your controller so we have no way to gauge the quality of your design and wiring practices.

MitchBradley avatar Jan 17 '22 15:01 MitchBradley

That is unlike anything I have ever seen. Even when the I2S had problems in testing, the long step pulse was never seen.

At first I was assuming there could be a firmware problem, but I think the hardware is more likely now.

bdring avatar Jan 17 '22 16:01 bdring

If you have bad signal quality on a clocked signal, ringing or edge timing discrepancies can cause all manner of false triggering. Static mode can have a different timing relationship between clock and data that could hide such problems.

MitchBradley avatar Jan 17 '22 17:01 MitchBradley

Thank you for your input. I am fine assuming the issue is hardware related and will check further. I have not taken any sophisticated measures to ensure integrity. Bit Clock and Data line are around 50mm long, 0.254mm wide. Word and BCK have a via at each chip . BCK has a 10k pulldown. Is there any difference in clock period between the two modes?

snakescb avatar Jan 17 '22 23:01 snakescb

For fast edge signals a ground return path needs to be physically close to the signal path for the entire length of the trace. Otherwise the impedance of the signal/return pair will vary, perhaps wildly, along the path, resulting in reflections that can cause false triggering, sometimes differently on different shift register chips.

I2S STREAM uses hardware to generate edges automatically. I2S_STATIC uses software for a lot of functions that are done with a hardware engine in STREAM mode.

Bart and I went to a lot of effort to design and validate the layout and the signal integrity of the boards that Bart sells, calling on decades of EE experience. The many hobbyist electronics tutorials on the internet make digital design seem easier than it actually is, especially when fast edges are involved.

MitchBradley avatar Jan 18 '22 00:01 MitchBradley

Thank you. Will take this into account in my next version I am working on.

snakescb avatar Jan 18 '22 08:01 snakescb

This might or might not help: I have a DLC32 and I2S_STATIC works 100% reliable, while I2S_STREAM does not: it uses less steps per mm (30% less), and moving forward in 4 moves and then moving back in one move yields a difference in position. So I2S_STREAM is not reliable. I cannot say if this is hardware related or something else is wrong, but I can confirm this behavior exists.

haraldkubota avatar Apr 29 '22 12:04 haraldkubota

I noticed this issue, read through it, and figured I should chime in some data points. My 6-pack v1p5 exhibits similar issues when using stream, yet works fine with static. I haven't modified the board at all.

name: TrugMPCNC
board: 6-pack

# MPCNC Primo J w/ dual endstops, z-max, & 1-start z screw
# 6-pack v1p5 controller
# 4@ drv8255 (XXYY), 1@ 16 microstep hacked drv8255 (z)
# 2@ quad input, 1@ RS485, 1@ 5V output, 1@ fet 12V output,
# Huanyang rs485 VFD+1.5kW spindle & PWM laser
# Pause and Start buttons

kinematics:
  Cartesian:

stepping:
  engine: I2S_static
  idle_ms: 255
  dir_delay_us: 0
  pulse_us: 4
  disable_delay_us: 0

axes:
  x:
    steps_per_mm: 200.000
    max_rate_mm_per_min: 7500.000
    acceleration_mm_per_sec2: 127.000
    max_travel_mm: 562.000
    soft_limits: true
    homing:
      cycle: 2
      mpos_mm: -562.000
      positive_direction: false
      settle_ms: 250.000
      seek_mm_per_min: 2000.000
      feed_mm_per_min: 300.000
      seek_scaler: 1.100
      feed_scaler: 5.000
    motor0:
      limit_neg_pin: gpio.33
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: true
      stepstick:
        direction_pin: i2so.1
        step_pin: i2so.2
        disable_pin: i2so.0
        ms3_pin: i2so.3
    motor1:
      limit_neg_pin: gpio.32
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: true
      stepstick:
        direction_pin: i2so.12
        step_pin: i2so.13
        disable_pin: i2so.15
        ms3_pin: i2so.14
  y:
    steps_per_mm: 200.000
    max_rate_mm_per_min: 7500.000
    acceleration_mm_per_sec2: 127.000
    max_travel_mm: 562.000
    soft_limits: true
    homing:
      cycle: 2
      mpos_mm: -562.000
      positive_direction: false
      settle_ms: 250.000
      seek_mm_per_min: 2000.000
      feed_mm_per_min: 300.000
      seek_scaler: 1.100
      feed_scaler: 5.000
    motor0:
      limit_neg_pin: gpio.35
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: true
      stepstick:
        direction_pin: i2so.4
        step_pin: i2so.5
        disable_pin: i2so.7
        ms3_pin: i2so.6
    motor1:
      limit_neg_pin: gpio.34
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: true
      stepstick:
        direction_pin: i2so.17
        step_pin: i2so.18
        disable_pin: i2so.16
        ms3_pin: i2so.19
  z:
    steps_per_mm: 1600.000
    max_rate_mm_per_min: 700.000
    acceleration_mm_per_sec2: 80.000
    max_travel_mm: 150.000
    soft_limits: true
    homing:
      cycle: 1
      mpos_mm: 0.000
      positive_direction: true
      settle_ms: 250.000
      seek_mm_per_min: 700.000
      feed_mm_per_min: 300.000
      seek_scaler: 1.100
      feed_scaler: 5.000
    motor0:
      limit_neg_pin: gpio.25
      limit_pos_pin: NO_PIN
      limit_all_pin: NO_PIN
      hard_limits: true
      stepstick:
        direction_pin: i2so.9
        step_pin: i2so.10
        disable_pin: i2so.8
        ms3_pin: i2so.11
    motor1:
      null_motor:

i2so:
  bck_pin: gpio.22
  data_pin: gpio.21
  ws_pin: gpio.17

spi:
  miso_pin: gpio.19
  mosi_pin: gpio.23
  sck_pin: gpio.18

sdcard:
  cs_pin: gpio.5

control:
  feed_hold_pin: gpio.36:pu
  cycle_start_pin: gpio.2:pu
  
Huanyang:
  uart:
    txd_pin: gpio.26
    rxd_pin: gpio.16
    rts_pin: gpio.4
    baud: 9600
    mode: 8N1
  modbus_id: 1
  tool_num: 0
  speed_map: 0=0% 0=25% 6000=25% 24000=100%
  
coolant:
  flood_pin: i2so.24
  mist_pin: gpio.15
  delay_ms: 1000.000

probe:
  pin: gpio.39
  check_mode_start: false

macros:
  startup_line0: 
  startup_line1: 
  macro0: 
  macro1: 
  macro2: 
  macro3: 

start:
  must_home: true
  check_limits: true
  deactivate_parking: false

user_outputs:
  digital0_pin: i2so.25

laser:
  spinup_ms: 0
  spindown_ms: 0
  tool_num: 1
  speeds: 0=0.0% 1000=100.0%
  output_pin: gpio.13
  enable_pin: gpio.14
  disable_with_s0: false
  s0_with_disable: false
  pwm_hz: 5000
arc_tolerance_mm: 0.002
junction_deviation_mm: 0.010
verbose_errors: false
report_inches: false
enable_parking_override_control: false
use_line_numbers: false 

Let me know if there's any other data I can provide.

truglodite avatar Jun 10 '22 20:06 truglodite

@truglodite When using I2S_STREAM and you move a motor to e.g. 100mm, 200mm, 300mm and 400mm and then move back to 0mm, you get an offset? In my case it stays at approx. 10mm. When using I2S_STATIC, it's 100% accurate and back to the original 0mm position/ Also when using I2S_STREAM I have to use about 30% more steps/mm compared to I2S_STATIC. If this is the case and since you use a very different board, it makes a good case about the hardware (outside of the ESP32) is not the issue.

haraldkubota avatar Jun 11 '22 11:06 haraldkubota

I can't say it was consistently offsetting Xmm in my case, but it was definitely not following the intended time/position plan. This happened this February, when I switched from GRBL_ESP32 to fluidnc, the translator changed my config from static to stream. I had a laser etch job at that time, and it resulted in a fuzzy double image due to the spindle firing at incorrect positions. In the end the result likely would be the same as yours with normal non-raster moves. I didn't feel like researching the problem, so I have used static since. Static works flawlessly for both cutting on the router and burning laser raster images.

It's been a while, but I vaguely recall mentioning this in an issue on github... but can't seem to find it. I'm with you that it's not a hardware issue... or if it is then even Bart's boards are affected. Then again, in my case maybe it was just the spindle commands were not synced but it was otherwise tracking position correctly? Either way, that seems a bit sketch to me.

Let me know if any further testing may help here. I do have an oscope if needed.

truglodite avatar Jun 11 '22 18:06 truglodite

I2S_STREAM does not work well with lasers because there is a queueing delay between the time that the laser power is modulated and the time that the steps arrive at the motors. This is pretty difficult to fix so it is unlikely that we will change it anytime soon.

MitchBradley avatar Jun 11 '22 19:06 MitchBradley

This happened this February, when I switched from GRBL_ESP32 to fluidnc, the translator changed my config from static to stream.

I think I found your translation - was it issue 1078 ? It was somewhat hard to find because you did not replace YOUR NAME in the title. There is a reason why we ask people to do that. Anything that saves us time is more time that we can spend actually fixing bugs and adding features.

Anyway, from that issue, I see this in the .h file:

// I2S (steppers & other output-only pins)
#define USE_I2S_OUT
#define USE_I2S_STEPS
//#define DEFAULT_STEPPER ST_I2S_STATIC

So I don't think the translator got the I2S_Stream thing wrong, as I2S_STATIC is commented out in the .h file.

MitchBradley avatar Jun 11 '22 19:06 MitchBradley

Closed as stale. Not much more to do or say.

MitchBradley avatar Oct 03 '22 18:10 MitchBradley