Shop OBEX P1 Docs P2 Docs Learn Events
New Stepper Driver Object - A Variant Of PulseTheStepPin — Parallax Forums

New Stepper Driver Object - A Variant Of PulseTheStepPin

idbruceidbruce Posts: 6,197
edited 2015-01-27 02:54 in Propeller 1
Here ya go
{{
  StepperDriver Version ?.?
  Copyright 2015. Bruce Drummond.
  Release Date: 01/24/2015

  Usage:
    X.Initialize(17, 18, 19, 0, 1, CLKFREQ / 1000000, CLKFREQ / 20000, CLKFREQ / 1600, CLKFREQ / 3200000, 2000)
    X.EnableStage
    X.IncreaseStagePosition(25)
    X.IncreaseStagePosition(50)
    X.IncreaseStagePosition(75)
    X.IncreaseStagePosition(100)
    X.DecreaseStagePosition(250)
    X.DisableStage

    or the equivalent

    X.Initialize(X_DIRECTION, X_STEP, X_ENABLE_DISABLE, CW, CCW, CLKFREQ / 1000000, CLKFREQ / 20000, CLKFREQ / 1600, CLKFREQ / 3200000, 2000)
    X.EnableStage
    X.MoveStagePosition(0, 25)
    X.MoveStagePosition(0, 50)
    X.MoveStagePosition(0, 75)
    X.MoveStagePosition(0, 100)
    X.MoveStagePosition(1, 250)
    X.DisableStage
}}

VAR

  BYTE bDirectionPin
  BYTE bStepPin
  BYTE bEnableDisablePin
  
  BYTE bIncreaseDirection
  BYTE bDecreaseDirection

  LONG lHighPulseWidth
  LONG lMaxExeMotorSpeed
  LONG lStartStopSpeed
  LONG lRampIncDec
  LONG lStepsPerRev

  LONG lRampingSteps
  LONG lTotalRampingSteps

PUB Initialize(DirectionPin, StepPin, EnableDisablePin, IncreaseDirection, DecreaseDirection, HighPulseWidth, MaxExeMotorSpeed, StartStopSpeed, RampIncDec, StepsPerRev)
{{
  Method Description:
    This method initializes global variables and sets pin parameters which will be used
    by a stepper drive unit.

  Parameters:
    DirectionPin = This parameter is the I/O pin number going from the Propeller
      chip to the stepper drive unit. This pin is an output, which sets the OUTA
      register utilized by the bDirectionPin.  This setting will control the direction
      of rotation for most stepper drives and it should be a value of 0 (LOW) or 1 (HIGH).
      
    StepPin = This parameter is the I/O pin number going from the Propeller
      chip to the stepper drive unit. This pin is an output, which sends pulses to the
      stepper drive unit, which it turn passes it on to the stepper motor, telling it when
      to make a step.

    EnableDisablePin = This parameter is the I/O pin number going from the Propeller
      chip to the stepper drive unit. This pin is an output, which sets the OUTA
      register utilized by the bEnableDisablePin.  This setting will control the enabling
      and disabling of the stepper motor and it should be a value of 0 (LOW) or 1 (HIGH).

    IncreaseDirection = This parameter simply sets the direction of rotation for the
      stepper motor as clockwise or counter-clockwise, whichever increases the stage
      position.  This value should be the opposite of the following DecreaseDirection
      parameter and it should be a value of 0 (LOW) or 1 (HIGH), because it will be used
      to set the OUTA register utilized by the bDirectionPin.

    DecreaseDirection = This parameter simply sets the direction of rotation for the
      stepper motor as clockwise or counter-clockwise, whichever decreases the stage
      position.  This value should be the opposite of the proceeding IncreaseDirection
      parameter and it should be a value of 0 (LOW) or 1 (HIGH), because it will be used
      to set the OUTA register utilized by the bDirectionPin.

    HighPulseWidth = This parameter establishes the pulse width of the OUTA register
      utilized by the bStepPin, as per manufacturers specifications of a stepper drive unit.    
      
    MaxExeMotorSpeed = The primary purpose of this parameter is to set the maximum execution
      speed of the iterations utilized within the MoveStagePosition method, therefore this
      parameter also directly affects the maximum speed of the stepper motor.

    StartStopSpeed = This parameter is a time delay between high and low pulses going out of
      the bStepPin.  During the motor rotation, time will be added to and subtracted from
      the global variable lStartStopSpeed.
      
    RampIncDec = This parameter is the ramp incrementor/decrementor, and it will affect just
      how fast the motor ramps up to top speed and ramps down until the motor stops.  Basically
      this is a setting of 1 - 25, at least for Gecko G251 stepper drives.

    StepsPerRev = This parameter establishes the number of steps per revolution for the stepper
      motor, regardless of full steps, half steps, or microsteps

  Example Usage:
    X.Initialize(17, 18, 19, 0, 1, CLKFREQ / 1000000, CLKFREQ / 20000, CLKFREQ / 1600, CLKFREQ / 3200000, 2000)    

  Expected Results:
    When using a Gecko G251 stepper drive with an Applied Motion HT23-400 motor, the proceeding
    parameters will really make that motor ZING.  However, please keep in mind that all of the
    timing related parameters are pretty much at a maximum level.  Please expect every motor and
    driver to have different timing.  Start out with slow speeds and work your way up.

    *After writing this, I began experimenting with a NEMA 17 with the following initialization and
    that motor was really zinging.  Which just goes to show me that some of my theories are wrong
    about the maximum values stated above.  All I can say is that you will have to experiment.

    X.Initialize(X_AXIS_DIRECTION, X_AXIS_STEP, X_AXIS_DISABLE, 1, 0, 80, 2500, 20000, 200, 2000)

  Additional Notes:
    Besides the mandatory settings as determined by your requirements or specified by
    manufacturer datasheets, the main parameters for affecting motor operation are MaxExeMotorSpeed,
    StartStopSpeed, and the RampIncDec.  By altering the values of these three parameters,
    a wide variety of ramping and operating profiles can be achieved.
}}

  bDirectionPin := DirectionPin
  bStepPin := StepPin
  bEnableDisablePin := EnableDisablePin

  bIncreaseDirection := IncreaseDirection
  bDecreaseDirection := DecreaseDirection
  
  lHighPulseWidth := HighPulseWidth
  lMaxExeMotorSpeed := MaxExeMotorSpeed
  lStartStopSpeed := StartStopSpeed
  lRampIncDec := RampIncDec
  lStepsPerRev := StepsPerRev

  lRampingSteps := (lStartStopSpeed - lMaxExeMotorSpeed) / lRampIncDec
  lTotalRampingSteps := lRampingSteps * 2

  'Set the directions of the direction, step, and disable pins
  'for the stepper driver as outputs.
  DIRA[bStepPin] := 1
  DIRA[bDirectionPin] := 1
  DIRA[bEnableDisablePin] := 1

PUB EnableStage
{{
  Method Description:
    This method enables a stepper drive unit.
    
  Example Usage:
    X.EnableStage
}}

  'Enable the motor.  Depending on the stepper driver utilized, the following value
  'may need to be 0
  OUTA[bEnableDisablePin] := 1
  
PUB DisableStage
{{
  Method Description:
    This method disables a stepper drive unit.
    
  Example Usage:
    X.DisableStage
}}

  'Disable the motor.  Depending on the stepper driver utilized, the following value
  'may need to be 1
  OUTA[bEnableDisablePin] := 0
  
PUB IncreaseStagePosition(TotalSteps)
{{
  Method Description:
    This method passes the direction of motor rotation and the total number of steps to
    the MoveStagePosition method.
    
  Example Usage:
    X.IncreaseStagePosition(5000)
}}

  'Move the stage
  MoveStagePosition(bIncreaseDirection, TotalSteps)
  
PUB DecreaseStagePosition(TotalSteps)
{{
  Method Description:
    This method passes the direction of motor rotation and the total number of steps to
    the MoveStagePosition method.
    
  Example Usage:
    X.DecreaseStagePosition(5000)
}}

  'Move the stage
  MoveStagePosition(bDecreaseDirection, TotalSteps)
  
PUB MoveStagePosition(Direction, TotalSteps) | Counter, RampingSteps, RunningSteps
{{
  Method Description:
    This method will ramp up a stepper motor until the maximum speed
    is obtained and it will maintain that maximum speed for a determined number
    of steps, at which point it will begin a ramp down of the stepper motor
    until it comes to a stop.

  Parameters:
    Direction = This parameter sets the OUTA register utilized for bDirectionPin.
      This setting will control the direction of rotation for stepper drives
      and it should be a value of 0 (LOW) or 1 (HIGH).

    TotalSteps = This is the total amount of steps or microsteps that you want the
      motor to rotate, and this should be equivalent to the number of high pulses
      sent to the stepper driver unit.

  Local Variables:      
    Counter = This variable is used to hold the value of the System Counter for
      timing accuracy of the stepper driver.

    RampingSteps = After computations, this variable will contain the number of pulses
      required to obtain the highest speed possible with the provided parameters.

    RunningSteps = Providing TotalSteps is larger than the value of the global variable
      lTotalRampingSteps, this variable will contain the number of maximum speed steps.
      However, if TotalSteps is smaller than the value of the global variable
      lTotalRampingSteps, the value of this variable will become either 1 or 0.

  Example Usage:
    This method can be called directly as follows:

    X.MoveStagePosition(0, 5000) or X.MoveStagePosition(1, 5000)

    or it can be called through the IncreaseStagePosition and DecreaseStagePosition methods.
}}  

  'If maximum speed can be obtained, determine the actual number of
  'ramping and running steps.
  IF TotalSteps > lTotalRampingSteps

    'Copy the global amount of ramping steps
    RampingSteps := lRampingSteps

    'Determine the number of full speed steps.  
    RunningSteps := TotalSteps - lTotalRampingSteps    

   'Else ramp upto the half-way point and then ramp down.    
  ELSE
  
    RampingSteps := TotalSteps / 2
    RunningSteps := TotalSteps // 2

  'Set the OUTA register to match the desired direction of rotation.
  OUTA[bDirectionPin] := Direction     
  
  'Set up the CTRMODE of Counter A for NCO/PWM single-ended.
  CTRA[30..26] := %00100

  'Set the output pin for Counter A.
  CTRA[5..0] := bStepPin

  'Set the value to be added to PHSA with every clock cycle.
  FRQA := 1

  'Set APIN as an output.
  DIRA[bStepPin] := 1

  'Get the current System Counter value.
  Counter := CNT

  'Ramp up the stepper motor to maximum speed.
  REPEAT RampingSteps
  
    'Send out a high pulse on the step pin for the desired duration.
    PHSA := -lHighPulseWidth

    'Wait for a specified period of time before sending another
    'high pulse to the step pin.
    WAITCNT(Counter += lStartStopSpeed -= lRampIncDec)

  'Maintain maximum speed    
  REPEAT RunningSteps
   
    'Send out a high pulse on the step pin for the desired duration.
    PHSA := -lHighPulseWidth

    'Wait for a specified period of time before sending another
    'high pulse to the step pin.
    WAITCNT(Counter += lStartStopSpeed)

  'Ramp down the stepper motor and come to a stop. 
  REPEAT RampingSteps
  
    'Send out a high pulse on the step pin for the desired duration.
    PHSA := -lHighPulseWidth

    'Wait for a specified period of time before sending another
    'high pulse to the step pin.
    WAITCNT(Counter += lStartStopSpeed += lRampIncDec)

DAT
{{
  ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐
  │                                     TERMS OF USE: MIT License                                       │                                                            
  ├─────────────────────────────────────────────────────────────────────────────────────────────────────┤
  │Copyright(C) 2015.  Bruce Drummond.                                                                  │
  │                                                                                                     │
  │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and    │
  │associated documentation files (the "Software"), to deal in the Software without restriction,        │
  │including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,│
  │and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,│
  │subject to the following conditions:                                                                 │
  │                                                                                                     │                        
  │The above copyright notice and this permission notice shall be included in all copies or substantial │
  │portions of the Software.                                                                            │
  │                                                                                                     │                        
  │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT│
  │LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  │
  │IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         │
  │LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION│
  │WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                      │
  └─────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}   

Comments

  • idbruceidbruce Posts: 6,197
    edited 2015-01-26 18:29
    As mentioned in my previous post, this driver will make a stepper motor rotate rather quickly, and with the three main speed settings, there are a lot of options. However speed is not always the main issue, but should always be considered. In my current situation, I am testing a couple of linear actuators that I constructed for a 3D printer project. Of course speed is an issue, but for 3D printing, I also want a nice and smooth ramp up/down, and when it comes to changing directions, I really don't want to much vibration. To get me in the ballpark, with just some guessing and a little testing, I came up with some values for this driver, that gives me a decent speed, nice ramping, and little vibration when changing directions. I am providing some source code, so that you can get a better idea of how to use the stepper driver. In the source code, you will notice that I base most of my stepper constants on the clock frequency(but I also give the results), because this stepper driver is based upon the clock frequency. Here are the specs for the linear actuators, just to give you a well rounded idea of what is actually happening.

    NEMA 17 Motors: Applied Motion HT17-275
    Linear Travel: 12 IN
    Belt Pitch: 2 MM
    Timing Pulley: 18 Teeth
    Stepper Driver Module: Gecko G251X

    In conjunction with the previously attached stepper driver object, the following code provided 40 feet of linear travel between the two actuators in approximately 55 seconds. 40 feet of travel could have been accomplished with this driver in much less time than 55 seconds, but then I would not have the smooth operation that I am now seeing.
    CON
    
      _CLKMODE            = XTAL1 + PLL16X
      _XINFREQ            = 5_000_000
    
      'Clock Frequency Equation
      CLK_FREQ            = ((_CLKMODE - XTAL1) >> 6) * _XINFREQ
    
      {{
      Propeller Pin Assignment Constants
      }}
      'Z Axis Pin Assignments
      Z_DISABLE           = 0
      Z_STEP              = 1
      Z_DIRECTION         = 2
    
      'ESTOP And Limit Switches Pin Assignments
      ESTOP_AND_LIMIT     = 3
    
      'Serial LCD Display Pin Assignment
      SERIAL_LCD          = 4
    
      'Homing Switch Pin Assignments
      X_HOMING            = 5
      Y_HOMING            = 6
      Z_HOMING            = 7
    
      'Propeller Memory Card Pin Assignments
      DI                  = 8 'IO0 / DI / MOSI / CD Pin
      DO                  = 9 'IO1 / DO / MISO Pin
      WP                  = 10 'IO2 / WP Pin
      HOLD                = 11 'IO3 / HOLD Pin
      SD_CS               = 12 'CS Pin For MicroSD Card Memory
      FLASH_CS            = 13 'CS Pin For Flash Memory
      SRAM_CS             = 14 'CS Pin For SRAM Memory
      CLK                 = 15 'CLK Pin
    
      'Daughterboard Pin Assignments
      PLATFORM_HEATER     = 16
      EXTRUDER_HEATER     = 17
      EXTRUDER_FAN        = 18
    
      'E Axis Pin Assignments  
      E_DIRECTION         = 19
      E_STEP              = 20
      E_DISABLE           = 21
    
      'X Axis Pin Assignments  
      X_DIRECTION         = 22
      X_STEP              = 23
      X_DISABLE           = 24
      
      'Y Axis Pin Assignments
      Y_DISABLE           = 25
      Y_STEP              = 26  
      Y_DIRECTION         = 27
    
      'I2C Pin Assignments
      I2C_SCL             = 28
      I2C_SDA             = 29
    
      'Full Duplex Serial Pin Assignments
      TX                  = 30
      RX                  = 31
    
      {{
      Additional Constants
      }}
      'X Axis Driver Constants
      X_PULSE_WIDTH       = CLK_FREQ / 1_000_000 '= 80
      X_MIN_SPEED         = CLK_FREQ / 5_714 '= 14_000 Rounded
      X_MAX_SPEED         = CLK_FREQ / 16_000 '= 5_000
      X_RAMP_INC_DEC      = CLK_FREQ / 26_666_666 '= 3 Rounded
      X_INC_DIR           = 0 '= Counter-clockwise rotation
      X_DEC_DIR           = 1 '= Clockwise rotation
      X_STEPS_PER_REV     = 2_000 '= 200 Full steps * 10 microsteps
    
      'X Axis Stage Constants
      X_MAX_STEPS         = 16933 '12 inches of linear travel
    
      'Y Axis Driver Constants
      Y_PULSE_WIDTH       = CLK_FREQ / 1_000_000 '= 80
      Y_MIN_SPEED         = CLK_FREQ / 5_714 '= 14_000 Rounded
      Y_MAX_SPEED         = CLK_FREQ / 16_000 '= 5_000
      Y_RAMP_INC_DEC      = CLK_FREQ / 26_666_666 '= 3 Rounded
      Y_INC_DIR           = 0 '= Counter-clockwise rotation
      Y_DEC_DIR           = 1 '= Clockwise rotation
      Y_STEPS_PER_REV     = 2_000 '= 200 Full steps * 10 microsteps
    
      'Y Axis Stage Constants
      Y_MAX_STEPS         = 16933 '12 inches of linear travel
    
      'Full Duplex Serial Driver Constants  
      COMM_MODE           = 0
      COMM_BAUD_RATE      = 115_200
    
      'FAT Engine Assignment for unused pins or RTC. Please refer to the
      'FAT16/FAT32 Full File System Driver Documentation for proper usage
      NEG_ONE             = -1
    
    VAR
    
      'The following variable holds the G-Code file line characters.  It has been
      'established that the G-Code file used as a guide in this code, had a maximum
      'file line character count of 72.  To be on the safe side, the maximum file
      'line size has been increased to 100. 
      BYTE bChBuffer[100]
    
      'The following variables are intended to store G-Code into various fields.
      'For more information about these fields, please refer to RepRap G Code
      'Fields at: http://reprap.org/wiki/G-code .  Additionally, these are the
      'only known fields to be supported by the KISSlicer.  Please note that the
      'maximum character count may change in the future, because I am not exactly
      'sure on bFieldElement_8 maximum character count, but support for 7 characters
      'should be sufficient.  The maximum character count should support a build
      'volume area of 999.99mm(X) X 999.99mm(Y) X 999.99mm(Z).  
      BYTE bFieldElement_0[2] 'G Field
      BYTE bFieldElement_1[3] 'M Field
      BYTE bFieldElement_2[1] 'T Field
      BYTE bFieldElement_3[3] 'S Field
      BYTE bFieldElement_4[7] 'X Field - Floating Point
      BYTE bFieldElement_5[7] 'Y Field - Floating Point
      BYTE bFieldElement_6[7] 'Z Field - Floating Point
      BYTE bFieldElement_7[7] 'F Field - Floating Point
      'BYTE bFieldElement_8[7] 'E Field - Floating Point Temporary comment
      BYTE bFieldElement_8[8] 'E Field - Floating Point
    
      BYTE bValidFields[9]
    
      'The following G-Code commands are currently the only known (by me) commands
      'supported by the KISSlicer, therefore these are the only G-Code commands
      'that I will currently support.
      {
            G1: Controlled Move
                  G Field - bFieldElement_0, X Field - bFieldElement_4,
                  Y Field - bFieldElement_5, Z Field - bFieldElement_6,
                  F Field - bFieldElement_7, and E Field - bFieldElement_8
                  filled during line parse 
      
            G20: Set Measurement Units To Inches
                  G Field - bFieldElement_0 filled during line parse
            
            G21: Set Measurement Units To Millimeters
                  G Field - bFieldElement_0 filled during line parse
            
            G28: Home Axes
                  G Field - bFieldElement_0 filled during line parse
            
            G90: Set Absolute Positioning
                  G Field - bFieldElement_0 filled during line parse
            
            G91: Set Relative Positioning
                  G Field - bFieldElement_0 filled during line parse
            
            M82: Set E Codes Absolute
                  M Field - bFieldElement_1 filled during line parse
            
            M83: Set E Codes Relative
                  M Field - bFieldElement_1 filled during line parse
            
            M104: Set Extruder Temperature With No Wait
                  M Field - bFieldElement_1 and S Field - bFieldElement_3
                  filled during line parse
      
            M106: Fan On
                  M Field - bFieldElement_1 filled during line parse
      
            M109: Set Extruder Temperature And Wait
                  M Field - bFieldElement_1 and S Field - bFieldElement_3
                  filled during line parse
      
            M107: Fan Off
                  M Field - bFieldElement_1 filled during line parse
      
            M140: Set Bed Temperature
                  M Field - bFieldElement_1 and S Field - bFieldElement_3
                  filled during line parse
      
            T0: Select Tool With No Fields
                  T Field - bFieldElement_2 filled during line parse   
      }
    
    OBJ
    
      SDCard:       "SD-MMC_FATEngine.spin"
      Memory:       "SPI Memory Driver"
      Terminal:     "FullDuplexSerial"
      Expander:     "SimpleMCP23008"
      X:            "StepperDriver"
      Y:            "StepperDriver"
    
    PUB Main
    
      'Start FullDuplexSerial
      Terminal.Start(RX, TX, COMM_MODE, COMM_BAUD_RATE)
      WAITCNT(CNT + (1 * CLKFREQ))
    
      'Start FATEngine
      SDCard.fatEngineStart(DO, CLK, DI, SD_CS, NEG_ONE, NEG_ONE, NEG_ONE, NEG_ONE, NEG_ONE)
    
      'Initialize the MCP23008
      Expander.Initialize
    
      'Initialize the stepper driver for the X axis
      X.Initialize(X_DIRECTION, X_STEP, X_DISABLE, X_INC_DIR, X_DEC_DIR, X_PULSE_WIDTH, X_MAX_SPEED, X_MIN_SPEED, X_RAMP_INC_DEC, X_STEPS_PER_REV)
    
      'Initialize the stepper driver for the Y axis
      Y.Initialize(Y_DIRECTION, Y_STEP, Y_DISABLE, Y_INC_DIR, Y_DEC_DIR, Y_PULSE_WIDTH, Y_MAX_SPEED, Y_MIN_SPEED, Y_RAMP_INC_DEC, Y_STEPS_PER_REV)
    
      'Parse the G-Code file MINIMUM.TXT located on SD card
    '  Parse
    
      'Quick test for the MCP23008
    '  Test_MCP23008
    
      'Test X stage for smoothness of operation and speed
      REPEAT 10
    
        Test_X_Stage
    
      'Test Y stage for smoothness of operation and speed
      REPEAT 10
    
        Test_Y_Stage
    
    PUB Test_X_Stage
      
      X.IncreaseStagePosition(X_MAX_STEPS)
      X.DecreaseStagePosition(X_MAX_STEPS)
    
    PUB Test_Y_Stage
      
      Y.IncreaseStagePosition(Y_MAX_STEPS)
      Y.DecreaseStagePosition(Y_MAX_STEPS)
    
    PUB Test_MCP23008 | Value
    
      'GP0 Menu Button
      'GP1 Select Button
      'GP2 Scroll Button
      'GP3 Pause Button
      'GP4 Back Button
      'GP5 Exit Button
      'GP6 Yellow LED
      'GP7 Red LED
        
      Expander.Configure_IODIR_Register(%00111111)  'Configure the IODIR register to 2 outputs and 6 inputs
      Expander.Configure_GPIO_Register(%10000000) '0 is low, GP7, OUTPUT - RED LED
    
      REPEAT
    
        Value := Expander.GetPinStates
    
          IF Value == %10010000
    
            Expander.Configure_GPIO_Register(%11000000)
    
          ELSE
    
            Expander.Configure_GPIO_Register(%10000000) '0 is low, GP7, OUTPUT - RED LED
    
    PUB Parse  
    
      'Mount Partition
      SDCard.mountPartition(0)
    
      'Open G-Code File "MINIMUM.TXT" for reading
      SDCard.openFile(STRING("MINIMUM.TXT"), "R")
    
      REPEAT
    
        'Fill bChBuffer with 0s
        BYTEFILL(@bChBuffer, 0, 100)
    
        'Fill bValidFields with 0s
        BYTEFILL(@bValidFields, 0, 9)
    
        'Grab file lines that are not comments or blank
        GetNextValidFileLine
    
        IF(bChBuffer[0] == 0)
          QUIT
    
        'Fill in the various field elements
        FillFieldElements
        
        Terminal.Str(@bChBuffer)        
    
        'Display the various field seperations
        Terminal.Str(STRING("G="))
    
        IF(bFieldElement_0 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_0)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("M="))
    
        IF(bFieldElement_1 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_1)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("T="))
    
        IF(bFieldElement_2 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_2)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("S="))
    
        IF(bFieldElement_3 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_3)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("X="))
    
        IF(bFieldElement_4 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_4)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("Y="))
    
        IF(bFieldElement_5 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_5)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("Z="))
    
        IF(bFieldElement_6 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_6)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("F="))
    
        IF(bFieldElement_7 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_7)
        
        Terminal.Tx(32) {Space}
    
        Terminal.Str(STRING("E="))
    
        IF(bFieldElement_8 == 0)
          Terminal.Str(STRING("NULL"))
    
        ELSE
          Terminal.Str(@bFieldElement_8)
        
        Terminal.Tx(32) {Space}
    
        'Seperate G-Code field values line by line
        Terminal.Tx(13) {Carriage Return}
    
        IF STRCOMP(bChBuffer + 0, STRING("M107"))
          Terminal.Str(STRING("Fan Off"))
          Terminal.Tx(13) {Carriage Return}        
    
      'Unmount Partition
      SDCard.unmountPartition
    
      'Stop FATEngine
      SDCard.fatEngineStop
    
      WAITCNT(CNT + (1 * CLKFREQ))
    
      'Stop FullDuplexSerial  
      Terminal.Stop
    
    PUB GetNextValidFileLine
    
      REPEAT
    
        'Grab a file line as a string  
        SDCard.readString(@bChBuffer, 99)
    
        'Keep repeating while the following conditions are met,
        'because we don't want or need these lines beginning with
        'these characters.
        IF(bChBuffer[0] <> 59 {; Character} AND bChBuffer[0] <> 13 {Carriage Return} AND bChBuffer[0] <> 10 {Line Feed})
          QUIT
    
    PUB FillFieldElements | Char, Index, Field_Element, ValueIndex
    
      'Empty the field elements of any possible data
      BYTEFILL(@bFieldElement_0, 0, 2)
      BYTEFILL(@bFieldElement_1, 0, 3)
      BYTEFILL(@bFieldElement_2, 0, 1)
      BYTEFILL(@bFieldElement_3, 0, 3)
      BYTEFILL(@bFieldElement_4, 0, 7)
      BYTEFILL(@bFieldElement_5, 0, 7)
      BYTEFILL(@bFieldElement_6, 0, 7)
      BYTEFILL(@bFieldElement_7, 0, 7)
      'BYTEFILL(@bFieldElement_8, 0, 7) Temporary
      BYTEFILL(@bFieldElement_8, 0, 8)
    
      Index := 0
      ValueIndex := 0
    
      'Parse file line into seperate field values.  Various fields will remain empty
      REPEAT
    
        Char := bChBuffer[Index]
    
          'Exclude these characters from becoming part of are field entries
          IF(Char == 13 {Carriage Return} OR Char == 10 {Line Feed})
            QUIT
    
          ELSEIF(Char == 32 {Space})
            Index++
            ValueIndex := 0
            NEXT
    
          ELSEIF(Char == 71 {G Character})
    
            'Set current field element
            Field_Element := 0
            bValidFields[0] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 77 {M Character})
    
            'Set current field element
            Field_Element := 1
            bValidFields[1] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 84 {T Character})
    
            'Set current field element
            Field_Element := 2
            bValidFields[2] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 83 {S Character})
    
            'Set current field element
            Field_Element := 3
            bValidFields[3] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 88 {X Character})
    
            'Set current field element
            Field_Element := 4
            bValidFields[4] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 89 {Y Character})
    
            'Set current field element
            Field_Element := 5
            bValidFields[5] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 90 {Z Character})
    
            'Set current field element
            Field_Element := 6
            bValidFields[6] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 70 {F Character})
    
            'Set current field element
            Field_Element := 7
            bValidFields[7] := 1
            Index++
            NEXT
    
          ELSEIF(Char == 69 {E Character})
    
            'Set current field element
            Field_Element := 8
            bValidFields[8] := 1
            Index++
            NEXT
    
          ELSE
    
            IF(Field_Element == 0)
    
              'G Field element character
              bFieldElement_0[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 1)
    
              'M Field element character
              bFieldElement_1[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 2)
    
              'T Field element character
              bFieldElement_2[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 3)
    
              'S Field element character
              bFieldElement_3[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 4)
    
              'X Field element character
              bFieldElement_4[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 5)
    
              'Y Field element character
              bFieldElement_5[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 6)
    
              'Z Field element character
              bFieldElement_6[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 7)
    
              'F Field element character
              bFieldElement_7[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
            ELSEIF(Field_Element == 8)
    
              'E Field element character
              bFieldElement_8[ValueIndex] := Char
              ValueIndex++
              Index++
              NEXT
    
    PUB ElementConversion
    
    DAT
    
            Tag1 BYTE "M107",0
    
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-26 18:57
    Nice.

    did I read right? 40 foot of travel?

    How big is this printer you want to build?

    Curious!

    Mike
  • idbruceidbruce Posts: 6,197
    edited 2015-01-26 19:08
    Nice.

    did I read right? 40 foot of travel?

    How big is this printer you want to build?

    Curious!

    Mike

    Mike :)

    They are 12 inch actuators. There are 2 - REPEAT 10 loops in the Main method which call upon forward and reverse travel of each actuator, for a total of 40 feet of linear travel. The bulid area of the printer will be 12" wide X 12" deep X 18" high
  • msrobotsmsrobots Posts: 3,709
    edited 2015-01-26 22:20
    That sounds more logical.

    I got my 3D printer a couple of years ago. A Rapman 3.1 or something like that. UK company named BitsFromBytes now sold to some big player in the field.

    I spend over one year with it, adjusting, printing, testing different materials, heating, cooling, superglue, rafts, no rafts.

    Finally I gave up. As soon as your object gets bigger than a pack of cigarettes you are done. It's called warping. The layers are cooling down while being printed and change (slightly) size.

    Nice tool for small prototypes. Small brackets. Ornaments to put on somewhere. But production work? I was (and am) quite disappointed. It is a slow process. But you need to stay there or have a superb feeding mechanism. The filament comes in rolls, usually, and is therefore bend. I does not straight out a easy as - say - wire. I ended up feeding from the top having the rolls mounted on the ceiling and pre feed the extruders with some second motors. Still no joy.

    And when you need to watch them, all the time, you will be faster by bending and cutting some sheet metal with some pliers or even file that bracket or whatever out of a block of alu.

    Overall I spend more than $3000 on that 3d print experiment. Should have saved the money for a laser or a small router.

    My current plan is to replace the extruders (2) with some dremel or drill and a flexible drive to use it as a simple CNC. The Rapman came as a kit of rods and acryl pieces. I build it by myself and can reuse a lot of the existing stuff.

    And for sure the new contraception will use a propeller to drive it.

    So I am following your threads with a lot of attention.

    Enjoy!

    Mike
  • idbruceidbruce Posts: 6,197
    edited 2015-01-27 02:54
    Mike

    Although I have not yet experienced them, there are a lot of problems associated with 3D printing. I do believe that proper filament feeding will be one of the toughest problems to conquer, because wire feeding was one of the biggest problems to resolve on the wire bending CNC, and so far, I do not have what I consider to be a good plan for routing and feeding the filament. Besides that problem, I do believe that warping will be another major source of headaches. Either way, I will cross those bridges when I get to them.

    Occassionally I lose sight of my ultimate goals, because I get wrapped up in some process or another, and I am at the point where it could easily happen. The goal of the 3D printer project has always been to build and test my linear actuators, and perhaps build a usable prototype in the process. As it stands now, I am currently pretty darn happy with the actuators that I have constructed, but I am not yet 100% satisfied with their construction and operation. Even though my heart wants to go forward with the 3D printer project, my brain is telling me to take the time out to perfect the belt actuators, because I am currently at a point where it would be a very wise decision to do so, especially since they are on a workbench, all wired up, with the software ready to run and test them. I do not believe there are any major issues, just some small things that I would like to resolve or change. And before I start the real construction of the printer, I should probably finish building the screw driven actuator for the Z axis, so that I may test and perfect that as well. When I am 100% satisfied with the construction and operation of all the actuators, I will then build the printer to test their durability.
Sign In or Register to comment.