{"id":19129248,"url":"https://github.com/dstechlabs/smc","last_synced_at":"2026-04-12T12:40:41.559Z","repository":{"id":249204491,"uuid":"830759455","full_name":"DSTechLabs/SMC","owner":"DSTechLabs","description":"This Arduino/ESP32 class gives you complete control of a bipolar stepper motor.","archived":false,"fork":false,"pushed_at":"2024-07-19T00:39:12.000Z","size":429,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-03T10:46:00.603Z","etag":null,"topics":["3d","3dprinter","arduino","automation","control","drive","driver","esp32","firmware","motor","printer","robot","robotics","software","step","stepper"],"latest_commit_sha":null,"homepage":"http://localhost:3022/CodeLab/codeLab_ArduinoMotor.html","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DSTechLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-19T00:01:35.000Z","updated_at":"2024-07-19T00:39:15.000Z","dependencies_parsed_at":"2024-07-19T08:55:16.940Z","dependency_job_id":"33471931-e485-4f9f-aaf5-9ccfef28789b","html_url":"https://github.com/DSTechLabs/SMC","commit_stats":null,"previous_names":["dstechlabs/smc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DSTechLabs%2FSMC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DSTechLabs%2FSMC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DSTechLabs%2FSMC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DSTechLabs%2FSMC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DSTechLabs","download_url":"https://codeload.github.com/DSTechLabs/SMC/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240199257,"owners_count":19763827,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d","3dprinter","arduino","automation","control","drive","driver","esp32","firmware","motor","printer","robot","robotics","software","step","stepper"],"created_at":"2024-11-09T06:06:57.222Z","updated_at":"2026-04-12T12:40:36.518Z","avatar_url":"https://github.com/DSTechLabs.png","language":"C++","funding_links":["https://buymeacoffee.com/dstechlabs"],"categories":[],"sub_categories":[],"readme":"\n# Stepper Motor Controller\n\nThis is a single C++ class that provides full control of a stepper motor.\n\nThis class is designed to be included in the firmware of MCU's such as Arduino and ESP32.  It will interface with most digital stepper drivers that have Enable, Direction and Step pins, such as the [BTT TMC2209](https://biqu.equipment/products/bigtreetech-tmc2209-stepper-motor-driver-for-3d-printer-board-vs-tmc2208).\n\n## Features:\n- Can be used by directly calling class methods -OR- sending text commands\n- Uses soft limits with lower and upper values\n- Optionally uses hard limits by specifying one or two limit switch pins\n- Includes Enable (engage) and Disable (disengage) of the motor\n- Allows for any step speed from 1 to 9999 steps per second\n- Allows for both Absolute and Relative motion\n- Includes adjustable Velocity Ramping for soft start and stop motion\n- Includes physical Homing using limit switch\n- Includes Emergency Stop (E-Stop)\n- Includes query methods/commands\n\n---\n### If you use this code, please \u003ca href=\"https://buymeacoffee.com/dstechlabs\" target=\"_blank\"\u003eBuy Me A Coffee ☕\u003c/a\u003e\n\n\n## Some Background\nA \"digital\" stepper motor driver requires three(3) GPIO pins to operate: Enable, Direction\nand Step.  The default GPIO pins used by this class are the following, but can be set using Constructor params:\n\n~~~\nEnable    = digital pin 2 (D2)\nDirection = digital pin 3 (D3)\nStep      = digital pin 4 (D4)\n~~~\n\n(GND) should be used for common logic ground.\u003cbr\u003e\nTwo extra pins may also be specified in the Constructor for optional upper and lower limit switches.\n\n---\nThis class keeps track of the motor's step count from its HOME position, which is zero(0).\n- The Motor's ABSOLUTE position is the number of steps away from HOME.  This number can be\npositive (clockwise) or negative (counter-clockwise).\n- The motor's RELATIVE position is the number of steps away from its last position.\n\n~~~\n                         🠈 -   + 🠊\n ▐── ··· ──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼── ··· ──▌\n ▐               │           │           │               ▌\nLower         -10000         0         10000           Upper\nLimit                       HOME                       Limit\n~~~\n\nLOWER and UPPER range limit values can be specified.\nThe default LOWER and UPPER range limits are set to +2 billion and -2 billion at start up.\nIt is assumed the user will set these \"soft\" limits from a configuration file or other means.\n\nIf a range limit has been reached, then the motor's motion is stopped and a Range Error\nis returned from the Run() method.\n\nTwo GPIO pins can also be optionally specified for checking upper and lower limit switches.\n\n---\nAt startup, this class initializes the motor as DISABLED (the driver is not engaged) and\nnot homed (the motor is at an unknown position).  Before motion can begin, the motor must\nbe Enabled with Enable() method or \"EN\" command.  This will also \"Home\" to motor by setting\nthe current ABSOLUTE position to zero(0).\n\n## Velocity Ramping\nMotor rotation velocity follows a trapezoidal shape.\nA linear ramp-up/ramp-down rate is set with the SetRamp() method or \"SR\" command.\n\n                                     ┌────────────────────────────────┐\n    A ramp value of 0                │                                │\n    specifies no ramping:            │                                │\n    (not recommended !!!)            │                                │\n                                   ──┴────────────────────────────────┴── time 🠊\u003cbr\u003e\n                                         .────────────────────────.\n    A ramp value of 5                   /                          \\.\n    specifies moderate ramping:        /                            \\.\n    This is the default at startup    /                              \\.\n                                   ──┴────────────────────────────────┴── time 🠊\u003cbr\u003e\n                                             .────────────────.\n    A ramp value of 9                      /                    \\.\n    specifies gradual ramping            /                        \\.\n    for heavy loads                    /                            \\.\n                                   ───┴──────────────────────────────┴─── time 🠊\u003cbr\u003e\n\nUse low values (2, 3, ..) for fast accelerations with light loads.  Use high values (.., 8, 9)\nfor slow accelerations with heavy loads.  It is highly recommended to use slow acceleration\nwhen moving high inertial loads.\n\n                                              ──────────    \u003c── full velocity\n    If there is not enough time to achieve\n    full velocity, then rotation velocity         /\\.\n    follows a \"stunted\" triangle path:           /  \\.\n                                              ──┴────┴──\n\nOnce a ramp value is set, all rotate commands will use that ramp value.\nThe default ramp value at startup is 5.\n\n## How To Use\n\nInclude the StepperMotorController .cpp and .h files in your firmware.\nDecide which GPIO pins to use for Enable, Direction and Step signals to your driver board.\nThe defaults are 2, 3 and 4 respectively.\n\nInstantiate a StepperMotorController as a global so the rest of your firmware can access it:\n\n    StepperMotorController MyMotor = StepperMotorController (enablePin, directionPin, stepPin);\n\nOptionally, you can also specify one or two GPIO pins to use for Limit Switches:\n\n    StepperMotorController MyMotor = StepperMotorController (enablePin, directionPin, stepPin, lowerLimitSwitch, upperLimitSwitch);\n\nOnce you have a StepperMotorController object, you will need to Enable the driver before\nmotion can begin:\n\n    setup()\n    {\n      ...\n      MyMotor.Enable();\n      ...\n    }\n\nIf your motor is attached to equipment then \"Homing\" is usually necessary to place the motor\nin a known beginning position.  You can do this with the `FindHome()` method or the `FH` command.\n`FindHome()` Enables the driver and uses the physical lower limit switch specified in the constructor.\n\n    setup()\n    {\n      ...\n      MyMotor.FindHome();\n      ...\n    }\n\nOnce Enabled and ready, you __MUST__ continually call the `Run()` method in your `loop()` function:\n\n    loop()\n    {\n      ...\n      RunReturn rr = MyMotor.Run();\n      ...\n    }\n\nDon't worry about any timings, its handled for you. If it's not time to take a step then\nRun() immediately returns without delay.\n\nThe Run() method returns one of the following `RunReturn` enum results:\n~~~\nOKAY                - Idle or still running\nRUN_COMPLETE        - Motion complete, reached target position normally\nRANGE_ERROR_LOWER   - Reached lower range soft limit\nRANGE_ERROR_UPPER   - Reached upper range soft limit\nLIMIT_SWITCH_LOWER  - Lower limit switch triggered\nLIMIT_SWITCH_UPPER  - Upper limit switch triggered\n~~~\n\u003cbr\u003e\n\n---\nAll control can be performed either by directly calling methods or by executing\na command string - from a UI for example.\n\nYour firmware should normally wait until the motor is finished with a previous Rotate method/command\nbefore issuing a new Rotate command.  If a Rotate command is called while the motor is already\nrunning, then the current rotation is interrupted and the new Rotate command is executed from\nthe motor's current position.\n\n## Class Methods\nSee the `StepperMotorController.h` file for all methods.\n\nThis class also has an `ExecuteCommand()` method to allow external interfaces to run the motor,\nsay from a browser app or other UI.\n\n`ExecuteCommand()` takes a short 2-char string command.  Some commands require additional parameters.\n\n\u003ctable\u003e\n  \u003ctr\u003e\u003ctd\u003eEN   \u003c/td\u003e\u003ctd\u003eENABLE               \u003c/td\u003e\u003ctd\u003eEnables the motor driver (energizes the motor) and also sets the HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eDI   \u003c/td\u003e\u003ctd\u003eDISABLE              \u003c/td\u003e\u003ctd\u003eDisables the motor driver (releases the motor)\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eFH   \u003c/td\u003e\u003ctd\u003eFIND HOME            \u003c/td\u003e\u003ctd\u003eSeeks counter-clockwise until lower limit switch is triggered, backs off a bit and sets HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eSH   \u003c/td\u003e\u003ctd\u003eSET HOME POSITION    \u003c/td\u003e\u003ctd\u003eSets the current position of the motor as its HOME position (Sets Absolute position to zero)\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eSL...\u003c/td\u003e\u003ctd\u003eSET LOWER LIMIT      \u003c/td\u003e\u003ctd\u003eSets the LOWER LIMIT (minimum Absolute Position) of the motor's range\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eSU...\u003c/td\u003e\u003ctd\u003eSET UPPER LIMIT      \u003c/td\u003e\u003ctd\u003eSets the UPPER LIMIT (maximum Absolute Position) of the motor's range\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eSRr  \u003c/td\u003e\u003ctd\u003eSET RAMP             \u003c/td\u003e\u003ctd\u003eSets the trapezoidal velocity RAMP (up/down) for smooth motor start and stop\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eRA...\u003c/td\u003e\u003ctd\u003eROTATE ABSOLUTE      \u003c/td\u003e\u003ctd\u003eRotates motor to an Absolute target position from its HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eRR...\u003c/td\u003e\u003ctd\u003eROTATE RELATIVE      \u003c/td\u003e\u003ctd\u003eRotates motor clockwise or counter-clockwise any number of steps from its current position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eRH   \u003c/td\u003e\u003ctd\u003eROTATE HOME          \u003c/td\u003e\u003ctd\u003eRotates motor to its HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eRL   \u003c/td\u003e\u003ctd\u003eROTATE TO LOWER LIMIT\u003c/td\u003e\u003ctd\u003eRotates motor to its LOWER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eRU   \u003c/td\u003e\u003ctd\u003eROTATE TO UPPER LIMIT\u003c/td\u003e\u003ctd\u003eRotates motor to its UPPER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eES   \u003c/td\u003e\u003ctd\u003eE-STOP               \u003c/td\u003e\u003ctd\u003eStops motion immediately (emergency stop) and DIsables the motor. It must be re-enabled with EN\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGA   \u003c/td\u003e\u003ctd\u003eGET ABSOLUTE position\u003c/td\u003e\u003ctd\u003eReturns the motor's current step position relative to its HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGR   \u003c/td\u003e\u003ctd\u003eGET RELATIVE position\u003c/td\u003e\u003ctd\u003eReturns the motor's current step position relative to its last targeted position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGL   \u003c/td\u003e\u003ctd\u003eGET LOWER LIMIT      \u003c/td\u003e\u003ctd\u003eReturns the motor's Absolute LOWER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGU   \u003c/td\u003e\u003ctd\u003eGET UPPER LIMIT      \u003c/td\u003e\u003ctd\u003eReturns the motor's Absolute UPPER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGT   \u003c/td\u003e\u003ctd\u003eGET TIME             \u003c/td\u003e\u003ctd\u003eReturns the remaining time in ms for motion to complete\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eGV   \u003c/td\u003e\u003ctd\u003eGET VERSION          \u003c/td\u003e\u003ctd\u003eReturns this firmware's current version\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003eBLp  \u003c/td\u003e\u003ctd\u003eBLINK LED            \u003c/td\u003e\u003ctd\u003eBlink the specified LED to indicate identification\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\nwhere r is the velocity ramp rate (0-9), p is the pin number of an LED\n\n~~~\n───────────────────────────────────────────────────\n Command String Format: (no spaces between fields)\n───────────────────────────────────────────────────\n                           cc vvvv sssssssssss...\u003clf\u003e\n                           │   │        │\n  Command/Query ───────────┘   │        │\n    [2-chars]                  │        │\n      EN = ENABLE              │        │\n      DI = DISABLE             │        │\n      FH = FIND HOME           │        │\n      SH = SET HOME            │        │\n      SL = SET LOWER LIMIT     │        │\n      SU = SET UPPER LIMIT     │        │\n      SR = SET RAMP            │        │\n      RA = ROTATE ABSOLUTE     │        │\n      RR = ROTATE RELATIVE     │        │\n      RH = ROTATE HOME         │        │\n      RL = ROTATE LOWER LIMIT  │        │\n      RU = ROTATE UPPER LIMIT  │        │\n      ES = E-STOP              │        │\n      GA = GET ABS POSITION    │        │\n      GR = GET REL POSITION    │        │\n      GL = GET LOWER LIMIT     │        │\n      GU = GET UPPER LIMIT     │        │\n      GT = GET TIME            │        │\n      GV = GET VERSION         │        │\n      BL = BLINK ────pin#──────┤        │\n                               │        │\n  Velocity (steps per sec) ────┤        │\n    [4-digits] 1___ - 9999     │        │\n    Right-padded with spaces   │        │\n                               │        │\n  Ramp Slope ──────────────────┘        │\n    [1-digit] 0 - 9                     │\n    (For SR command only)               │\n                                        │\n  Absolute or Relative Step Position ───┘ ───┐\n    [1 to 10-digits plus sign]               │\n    No padding necessary                     ├─── For ROTATE commands only\n    -2147483648 to 2147483647 (long)         │\n    Positive values = Clockwise              │\n    Negative values = Counter-Clockwise  ────┘\n~~~\n\n### Example String Commands: (quotes are not included in string)\n\n\u003ctable\u003e\n  \u003ctr\u003e\u003ctd\u003e\"EN\"          \u003c/td\u003e\u003ctd\u003eENABLE               \u003c/td\u003e\u003ctd\u003eEnable the stepper motor driver\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"DI\"          \u003c/td\u003e\u003ctd\u003eDISABLE              \u003c/td\u003e\u003ctd\u003eDisable the stepper motor driver\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"SR6\"         \u003c/td\u003e\u003ctd\u003eSET RAMP             \u003c/td\u003e\u003ctd\u003eSet the velocity ramp-up/ramp-down rate to 6\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"RA500 2000\"  \u003c/td\u003e\u003ctd\u003eROTATE ABSOLUTE      \u003c/td\u003e\u003ctd\u003eRotate the motor at 500 steps per second, to Absolute position of +2000 steps clockwise from HOME\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"RR3210-12000\"\u003c/td\u003e\u003ctd\u003eROTATE RELATIVE      \u003c/td\u003e\u003ctd\u003eRotate the motor at 3210 steps per second, -12000 steps counter-clockwise from its current position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"RH\"          \u003c/td\u003e\u003ctd\u003eROTATE HOME          \u003c/td\u003e\u003ctd\u003eRotate motor back to its HOME position (0)\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"RL\"          \u003c/td\u003e\u003ctd\u003eROTATE to LOWER LIMIT\u003c/td\u003e\u003ctd\u003eRotate motor to its LOWER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"ES\"          \u003c/td\u003e\u003ctd\u003eEMERGENCY STOP       \u003c/td\u003e\u003ctd\u003eImmediately stop the motor and cancel rotation command\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GR\"          \u003c/td\u003e\u003ctd\u003eGET RELATIVE POSITION\u003c/td\u003e\u003ctd\u003eGet the current relative step position of the motor\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\nThis class may also be queried for position, range limits, remaining motion time and firmware version with the following commands:\n\n\u003ctable\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GA\"\u003c/td\u003e\u003ctd\u003eGET ABSOLUTE position\u003c/td\u003e\u003ctd\u003eReturns the motor's current step position relative to its HOME position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GR\"\u003c/td\u003e\u003ctd\u003eGET RELATIVE position\u003c/td\u003e\u003ctd\u003eReturns the motor's current step position relative to its last targeted position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GL\"\u003c/td\u003e\u003ctd\u003eGET LOWER LIMIT      \u003c/td\u003e\u003ctd\u003eReturns the motor's Absolute LOWER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GU\"\u003c/td\u003e\u003ctd\u003eGET UPPER LIMIT      \u003c/td\u003e\u003ctd\u003eReturns the motor's Absolute UPPER LIMIT position\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GT\"\u003c/td\u003e\u003ctd\u003eGET TIME             \u003c/td\u003e\u003ctd\u003eReturns the remaining time in ms for motion to complete\u003c/td\u003e\u003c/tr\u003e\n  \u003ctr\u003e\u003ctd\u003e\"GV\"\u003c/td\u003e\u003ctd\u003eGET VERSION          \u003c/td\u003e\u003ctd\u003eReturns this firmware's current version\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\u003cbr\u003e\n\nThe returned result is a string with the following format:\n~~~\nAPs... = Absolute Position of motor is s steps from its HOME position\nRPs... = Relative Position of motor is s steps from its last targeted position\nLLs... = LOWER LIMIT of motion\nULs... = UPPER LIMIT of motion\n~~~\nwhere s is a positive or negative long integer (depending on clockwise or counter-clockwise position)\nand represents a number of steps which may be 1 to 10 digits plus a possible sign.\n\n---\n### If you use this code, please \u003ca href=\"https://buymeacoffee.com/dstechlabs\" target=\"_blank\"\u003eBuy Me A Coffee ☕\u003c/a\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdstechlabs%2Fsmc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdstechlabs%2Fsmc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdstechlabs%2Fsmc/lists"}