diff --git a/code/cane_control/cane_control.ino b/code/cane_control/cane_control.ino
index a4f312bc8117ce8655b33d183549198576c18577..8f14d8c314a6ae424c4c2ace0baed91a16d72659 100644
--- a/code/cane_control/cane_control.ino
+++ b/code/cane_control/cane_control.ino
@@ -1,121 +1,66 @@
-#include <TMC2209.h>
-#include <AccelStepper.h>
 #include <Adafruit_SSD1306.h>
- 
-#define PIN_STEP1 28
-#define PIN_DIR1 29
-#define PIN_STEP2 26
-#define PIN_DIR2 27
+
+#include "knob.hpp"
+#include "motion.hpp"
+
+// encoder settings
 #define PIN_BTN 2
 #define PIN_ENC_A 3
 #define PIN_ENC_B 4
-#define READ_FAST(pin) ((sio_hw->gpio_in & (1 << pin)) > 0)
-
-#define SCREEN_WIDTH 128 // OLED display width, in pixels
-#define SCREEN_HEIGHT 64 // OLED display height, in pixels
-
+#define LENGTH_INC (0.05)
 #define LENGTH_MIN (0.05)
 #define LENGTH_MAX (4000.0)
+#define LENGTH_DEFAULT (5.00)
 
-#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
-#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
-
+// stepper settings
+#define PIN_STEP1 28
+#define PIN_DIR1 29
+#define PIN_STEP2 26
+#define PIN_DIR2 27
 #define SERIAL_BAUD_RATE 115200
+#define MICROSTEPS 4
 #define RUN_CURRENT_PERCENT 80
 #define STALL_GUARD_THRESHOLD 80
 #define HOMING_VELOCITY 400
-
 #define MOVE_SPEED 800
 #define MOVE_ACC 1200
+#define STEPPER_SERIAL Serial1
 
-#define MICROSTEPS 4
-
-HardwareSerial & serial_stream = Serial1;
+// screen settings
+#define SCREEN_WIDTH 128
+#define SCREEN_HEIGHT 64
+#define OLED_RESET    -1
+#define SCREEN_ADDRESS 0x3C
 
 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
 
-AccelStepper stepper1(AccelStepper::DRIVER, PIN_STEP1, PIN_DIR1);
-AccelStepper stepper2(AccelStepper::DRIVER, PIN_STEP2, PIN_DIR2);
-
-TMC2209 stepper_driver1;
-TMC2209 stepper_driver2;
-
-int state_now = 0b00;
-int state_prev = 0b00;
-
-int lookup_move[] = {0,-1,1,-2,1,0,2,-1,-1,2,0,1,-2,1,-1,0};
-
-float length = 5.00;
-
 int counter = 0;
-int active = false;
-bool update_screen = true;
-
-int k = 0;
-
-inline void update_knob() {
-  int key = (state_now << 2) | state_prev;
-  if (!active) {
-    k += lookup_move[key];
-    if (k >= 4) {
-      length += 0.05;
-      k -= 4;
-      if (length > LENGTH_MAX) {
-        length = LENGTH_MAX;
-      }
-    } else if (k <= -4) {
-      length -= 0.05;
-      k += 4;
-      if (length < LENGTH_MIN) {
-        length = LENGTH_MIN;
-      }
-    }
-    update_screen = true;
-  }
-  state_prev = state_now;
-}
-
-void pin_AB_change() {
-  state_now = (READ_FAST(PIN_ENC_B) << 1) | READ_FAST(PIN_ENC_A);
-  update_knob();
-}
+int cutting = false;
 
-void homing() {
-  stepper_driver2.moveAtVelocity(-HOMING_VELOCITY);
-  delay(200);
-  stepper_driver2.moveAtVelocity(HOMING_VELOCITY);
-  delay(100);
-  bool done = false;
-  while (!done) {
-    uint16_t stall_guard_result = stepper_driver2.getStallGuardResult();
-    done = stall_guard_result < STALL_GUARD_THRESHOLD;
-  }
-  stepper_driver2.moveAtVelocity(0);
-  stepper_driver2.enable();
-}
+Knob knob(PIN_ENC_A, PIN_ENC_B, LENGTH_INC, LENGTH_MIN, LENGTH_MAX);
 
 void setup() {
   Serial.begin(0);
 
-  pinMode(PIN_ENC_A, INPUT);
-  pinMode(PIN_ENC_B, INPUT);
   pinMode(PIN_BTN, INPUT_PULLUP);
 
+  // screen init
   display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
-  display.setTextSize(1);      // Normal 1:1 pixel scale
-  display.setTextColor(SSD1306_WHITE); // Draw white text
+  display.setTextSize(1);
+  display.setTextColor(SSD1306_WHITE);
   display.display();
   delay(100);
   display.clearDisplay();
   display.cp437(true);
 
-  stepper_driver1.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_1);
+  /*
+  stepper_driver1.setup(STEPPER_SERIAL, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_1);
   stepper_driver1.setRunCurrent(RUN_CURRENT_PERCENT);
   stepper_driver1.setMicrostepsPerStep(MICROSTEPS);
-  
+
   delay(50);
 
-  stepper_driver2.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_0);
+  stepper_driver2.setup(STEPPER_SERIAL, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_0);
   stepper_driver2.setRunCurrent(RUN_CURRENT_PERCENT);
   stepper_driver2.setMicrostepsPerStep(MICROSTEPS);
   stepper_driver2.enable();
@@ -134,50 +79,59 @@ void setup() {
 
   stepper2.setMaxSpeed(MOVE_SPEED);
   stepper2.setAcceleration(MOVE_ACC);
+  */
 
-  state_now = READ_FAST(PIN_ENC_A) | (READ_FAST(PIN_ENC_B) << 1);
-  state_prev = state_now;
-
-  attachInterrupt(digitalPinToInterrupt(PIN_ENC_A), pin_AB_change, CHANGE);
-  attachInterrupt(digitalPinToInterrupt(PIN_ENC_B), pin_AB_change, CHANGE);
+  knob.begin(LENGTH_DEFAULT);
 }
 
 void loop() {
+  static float knob_value = LENGTH_DEFAULT;
+
+  bool update_screen = false;
+
+  if (knob->value != knob_value) {
+      knob_value = knob->value;
+      update_screen = true;
+  }
+
   static int btn_pressed = false;
-  
+
   int btn_pressed_now = !digitalRead(PIN_BTN);
 
   if (btn_pressed_now && !btn_pressed) {
-    active = !active;
+    cutting = !cutting;
     update_screen = true;
-    if (active) {
-      stepper_driver1.enable();
+    if (cutting) {
+      //stepper_driver1.enable();
+      knob.disable();
     } else {
-      stepper_driver1.disable();
+      //stepper_driver1.disable();
+      knob.enable();
     }
   }
 
-  if (active) {
+  /*
+  if (cutting) {
     stepper1.moveTo(800);
     stepper1.runToPosition();
     stepper1.setCurrentPosition(0);
-    active = false;
-    update_screen = true;
+    cutting = false;
   }
+  */
 
-  if (update_screen) {
+ if (update_screen) {
     update_screen = false;
     display.clearDisplay();
     display.setCursor(0, 0);
-    display.printf("Length: %8.2f in\n", length);
+    display.printf("Length: %8.2f in\n", knob_value);
 
     display.setCursor(0, 16);
     display.printf("Counter: %7d cuts\n", counter);
 
     display.setCursor(0, 40);
-    display.println(active ? "RUNNING..." : "STOPPED");
+    display.println(cutting ? "RUNNING..." : "STOPPED");
     display.setCursor(0, 56);
-    display.println(active ? "[ press to stop ]" : "[ press to start ]");
+    display.println(cutting ? "[ press to stop ]" : "[ press to start ]");
     display.display();
   }
 
diff --git a/code/cane_control/knob.cpp b/code/cane_control/knob.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92e68d10e9b687f3f0beb763d7eedb9cc82101e3
--- /dev/null
+++ b/code/cane_control/knob.cpp
@@ -0,0 +1,49 @@
+#include "knob.hpp"
+
+Knob::Knob(int pin_A, int pin_B, float val_inc, float val_min, float val_max) {
+  this->pin_A = pin_A;
+  this->pin_B = pin_B;
+  this->val_inc = val_inc;
+  this->val_min = val_min;
+  this->val_max = val_max;
+  this->value = val_min;
+}
+
+void Knob::begin(float start_value) {
+  pinMode(this->pin_A, INPUT);
+  pinMode(this->pin_B, INPUT);
+
+  this->value = start_value;
+
+  this->state = READ_FAST(this->pin_A) | (READ_FAST(this->pin_B) << 1);
+  this->state_prev = state;
+
+  enable();
+
+  attachInterrupt(digitalPinToInterrupt(this->pin_A), this->pin_callback, CHANGE);
+  attachInterrupt(digitalPinToInterrupt(this->pin_B), this->pin_callback, CHANGE);
+}
+
+void Knob::enable() {
+  this->active = true;
+}
+
+void Knob::disable() {
+  this->active = false;
+}
+
+void Knob::pin_callback() {
+  this->state = READ_FAST(this->pin_A) | (READ_FAST(this->pin_B) << 1);
+  int key = (this->state << 2) | this->state_prev;
+  if (this->active) {
+    k += this->lookup_move[key];
+    if (k >= 4) {
+      this->value = min(this->value+this->val_inc, this->val_max);
+      k -= 4;
+    } else if (k <= -4) {
+      this->value = min(this->value-this->val_inc, this->val_min);
+      k += 4;
+    }
+  }
+  this->state_prev = this->state;
+}
diff --git a/code/cane_control/knob.hpp b/code/cane_control/knob.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..33227ced25850f58d0ab567186be30e5b404cf50
--- /dev/null
+++ b/code/cane_control/knob.hpp
@@ -0,0 +1,29 @@
+#ifndef KNOB_H
+#define KNOB_H
+
+#include <Arduino.h>
+
+#define READ_FAST(pin) ((sio_hw->gpio_in & (1 << pin)) > 0)
+
+class Knob {
+  public:
+    Knob(int pin_A, int pin_B, float val_inc, float val_min, float val_max);
+    void begin(float start_value);
+    float value;
+    bool active = false;
+    void pin_callback();
+  private:
+    void enable();
+    void disable();
+    void update_value();
+    int pin_A;
+    int pin_B;
+    float val_inc;
+    float val_min;
+    float val_max;
+    int state;
+    int state_prev;
+    static constexpr const int lookup_move[] = {0,-1,1,-2,1,0,2,-1,-1,2,0,1,-2,1,-1,0};
+};
+
+#endif
diff --git a/code/cane_control/motion.cpp b/code/cane_control/motion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..926d3623784e434a59a231a643cfd0fce579710b
--- /dev/null
+++ b/code/cane_control/motion.cpp
@@ -0,0 +1,21 @@
+/*
+void homing() {
+  stepper_driver2.moveAtVelocity(-HOMING_VELOCITY);
+  delay(200);
+  stepper_driver2.moveAtVelocity(HOMING_VELOCITY);
+  delay(100);
+  bool done = false;
+  while (!done) {
+    uint16_t stall_guard_result = stepper_driver2.getStallGuardResult();
+    done = stall_guard_result < STALL_GUARD_THRESHOLD;
+  }
+  stepper_driver2.moveAtVelocity(0);
+  stepper_driver2.enable();
+}
+
+AccelStepper stepper1(AccelStepper::DRIVER, PIN_STEP1, PIN_DIR1);
+AccelStepper stepper2(AccelStepper::DRIVER, PIN_STEP2, PIN_DIR2);
+
+TMC2209 stepper_driver1;
+TMC2209 stepper_driver2;
+*/
diff --git a/code/cane_control/motion.hpp b/code/cane_control/motion.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5e556ed74f2921119e9f7df2d8e175bbb4c715c1
--- /dev/null
+++ b/code/cane_control/motion.hpp
@@ -0,0 +1,8 @@
+#ifndef MOTION_H
+#define MOTION_H
+
+#include <Arduino.h>
+#include <TMC2209.h>
+#include <AccelStepper.h>
+
+#endif