diff --git a/code/cane_control/cane_control.ino b/code/cane_control/cane_control.ino index dd0ebe35e23f3cd2c6de26a1393f667393123957..c434eb5f11491a6503c1ed801b36e52b94299b24 100644 --- a/code/cane_control/cane_control.ino +++ b/code/cane_control/cane_control.ino @@ -2,6 +2,8 @@ #include <AccelStepper.h> #include <Adafruit_SSD1306.h> +//#define DRYRUN + #define PIN_STEP1 28 #define PIN_DIR1 29 #define PIN_STEP2 26 @@ -11,6 +13,8 @@ #define PIN_ENC_B 4 #define READ_FAST(pin) ((sio_hw->gpio_in & (1 << pin)) > 0) +#define T_DEBOUNCE 100 + #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels @@ -21,21 +25,25 @@ #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 #define SERIAL_BAUD_RATE 115200 -#define RUN_CURRENT_PERCENT 80 -#define STALL_GUARD_THRESHOLD 70 -#define HOMING_VELOCITY 400 +#define RUN_CURRENT_PERCENT 85 +#define STALL_GUARD_THRESHOLD 90 +#define HOMING_VELOCITY 200 -#define MOVE_SPEED 800 -#define MOVE_ACC 1200 +#define MOVE_SPEED1 1200 +#define MOVE_ACC1 2000 + +#define MOVE_SPEED2 350 +#define MOVE_ACC2 600 #define MICROSTEPS 4 -#define MICROSTEPS_PER_TURN (200L*MICROSTEPS) +#define MICROSTEPS_PER_TURN1 (57*200L*MICROSTEPS/11) +#define MICROSTEPS_PER_TURN2 (200L*MICROSTEPS) #define ANGLE_INIT 16 #define ANGLE_READY 340 #define STATE_MENU 0 -#define STATE_COCKING 1 +#define STATE_ARMING 1 #define STATE_FEEDING 2 int machine_state = STATE_MENU; @@ -47,8 +55,8 @@ 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; +TMC2209 stepper1_driver; +TMC2209 stepper2_driver; int state_now = 0b00; int state_prev = 0b00; @@ -59,17 +67,17 @@ float length = 5.00; int counter = 0; int cutting = false; -bool update_screen = true; +bool refresh_screen = true; int k = 0; long int length_to_step(float d) { // 1 inch per revolution - return MICROSTEPS_PER_TURN * d / 3.14159; + return MICROSTEPS_PER_TURN1 * d / M_PI; } long int angle_to_step(int angle) { - return 2 * MICROSTEPS_PER_TURN * angle / 360; + return MICROSTEPS_PER_TURN2 * angle / 360; } inline void update_knob() { @@ -89,7 +97,7 @@ inline void update_knob() { length = LENGTH_MIN; } } - update_screen = true; + refresh_screen = true; } state_prev = state_now; } @@ -100,32 +108,28 @@ void pin_AB_change() { } void homing() { - stepper_driver2.moveAtVelocity(-HOMING_VELOCITY); - delay(200); - stepper_driver2.moveAtVelocity(HOMING_VELOCITY); + stepper2_driver.moveAtVelocity(HOMING_VELOCITY); delay(100); bool done = false; while (!done) { - uint16_t stall_guard_result = stepper_driver2.getStallGuardResult(); + uint16_t stall_guard_result = stepper2_driver.getStallGuardResult(); done = stall_guard_result < STALL_GUARD_THRESHOLD; Serial.println(stall_guard_result); } - stepper_driver2.moveAtVelocity(0); - stepper_driver2.enable(); - + stepper2_driver.moveAtVelocity(0); + delay(100); + stepper2_driver.enable(); stepper2.moveTo(angle_to_step(ANGLE_INIT)); stepper2.runToPosition(); stepper2.setCurrentPosition(0); + stepper2.moveTo(angle_to_step(ANGLE_READY)); + stepper2.runToPosition(); } void setup() { Serial.begin(0); - delay(2000); - - pinMode(PIN_ENC_A, INPUT); - pinMode(PIN_ENC_B, INPUT); - pinMode(PIN_BTN, INPUT_PULLUP); + delay(1000); display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); display.setTextSize(1); // Normal 1:1 pixel scale @@ -135,91 +139,140 @@ void setup() { display.clearDisplay(); display.cp437(true); - stepper_driver1.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_1); - stepper_driver1.setRunCurrent(RUN_CURRENT_PERCENT); - stepper_driver1.setMicrostepsPerStep(MICROSTEPS); + #ifndef DRYRUN + stepper1_driver.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_1); + stepper1_driver.setRunCurrent(RUN_CURRENT_PERCENT); + stepper1_driver.setHoldCurrent(RUN_CURRENT_PERCENT); + stepper1_driver.setMicrostepsPerStep(MICROSTEPS); - delay(50); - - stepper_driver2.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_0); - stepper_driver2.setRunCurrent(RUN_CURRENT_PERCENT); - stepper_driver2.setMicrostepsPerStep(MICROSTEPS); - stepper_driver2.enable(); - - delay(50); + stepper2_driver.setup(serial_stream, SERIAL_BAUD_RATE, TMC2209::SERIAL_ADDRESS_0); + stepper2_driver.setRunCurrent(RUN_CURRENT_PERCENT); + stepper2_driver.setHoldCurrent(RUN_CURRENT_PERCENT); + stepper2_driver.setMicrostepsPerStep(MICROSTEPS); + stepper2_driver.enable(); display.clearDisplay(); display.setCursor(0, 0); display.print("Homing..."); display.display(); + #endif - stepper1.setMaxSpeed(MOVE_SPEED); - stepper1.setAcceleration(MOVE_ACC); + stepper1.setMaxSpeed(MOVE_SPEED1); + stepper1.setAcceleration(MOVE_ACC1); stepper1.setPinsInverted(true); - stepper2.setMaxSpeed(MOVE_SPEED); - stepper2.setAcceleration(MOVE_ACC); + stepper2.setMaxSpeed(MOVE_SPEED2); + stepper2.setAcceleration(MOVE_ACC2); + #ifndef DRYRUN homing(); + #endif state_now = READ_FAST(PIN_ENC_A) | (READ_FAST(PIN_ENC_B) << 1); state_prev = state_now; + // encoder + pinMode(PIN_ENC_A, INPUT); + pinMode(PIN_ENC_B, INPUT); + pinMode(PIN_BTN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(PIN_ENC_A), pin_AB_change, CHANGE); attachInterrupt(digitalPinToInterrupt(PIN_ENC_B), pin_AB_change, CHANGE); } void loop() { - static int btn_pressed = false; - - int btn_pressed_now = !digitalRead(PIN_BTN); - bool just_pressed = btn_pressed_now && !btn_pressed; + static int btn_pressed_prev = false; + static int machine_state_prev = machine_state; + static bool init = false; + static unsigned long t_last_changed = 0; + static unsigned long dt_debounce = T_DEBOUNCE; + + bool just_pressed = false; + int btn_pressed = btn_pressed_prev; + + if (dt_debounce < T_DEBOUNCE) { + dt_debounce = millis() - t_last_changed; + } else { + btn_pressed = !digitalRead(PIN_BTN); + just_pressed = btn_pressed && !btn_pressed_prev; + + if (btn_pressed != btn_pressed_prev) { + t_last_changed = millis(); + dt_debounce = 0; + } + } stepper1.run(); stepper2.run(); - switch machine_state { + machine_state_prev = machine_state; + + switch (machine_state) { case STATE_MENU: if (just_pressed) { // prepare - machine_state = STATE_COCKING; - stepper_driver1.enable(); + stepper1.setCurrentPosition(0); + #ifndef DRYRUN + stepper1_driver.enable(); + #endif stepper2.moveTo(angle_to_step(ANGLE_READY)); - update_screen = true; + if (stepper2.distanceToGo() == 0) { + machine_state = STATE_FEEDING; + stepper1.moveTo(length_to_step(length)); + } else { + machine_state = STATE_ARMING; + } } break; - case STATE_COCKING: + case STATE_ARMING: if (just_pressed) { machine_state = STATE_MENU; - stepper_driver1.disable(); - update_screen = true; + stepper1.stop(); + #ifndef DRYRUN + stepper1_driver.disable(); + #endif } else if (!stepper2.isRunning()) { machine_state = STATE_FEEDING; - stepper1.moveTo(lengt_to_step(length)); + stepper1.moveTo(length_to_step(length)); } break; case STATE_FEEDING: if (just_pressed) { machine_state = STATE_MENU; - stepper_driver1.disable(); - update_screen = true; + stepper1.stop(); + #ifndef DRYRUN + stepper1_driver.disable(); + #endif } else if (!stepper1.isRunning()) { - // chop! + // CHOP! + display.clearDisplay(); + display.setCursor(0, 0); + display.printf("Length: %8.2f in\n", length); + + display.setCursor(0, 16); + display.printf("Counter: %7d cuts\n", counter); + + display.setCursor(4, 50); + display.println("CHOP!"); + display.display(); + stepper2.moveTo(angle_to_step(360)); stepper2.runToPosition(); stepper2.setCurrentPosition(0); counter++; - update_screen = true; // prepare - machine_state = STATE_COCKING; + machine_state = STATE_ARMING; + stepper1.setCurrentPosition(0); stepper2.moveTo(angle_to_step(ANGLE_READY)); } break; } - if (update_screen) { - update_screen = false; + refresh_screen |= machine_state_prev != machine_state; + + if (refresh_screen) { + refresh_screen = false; + display.clearDisplay(); display.setCursor(0, 0); display.printf("Length: %8.2f in\n", length); @@ -228,11 +281,26 @@ void loop() { display.printf("Counter: %7d cuts\n", counter); display.setCursor(0, 40); - display.println(cutting ? "RUNNING..." : "STOPPED"); - display.setCursor(0, 56); - display.println(cutting ? "[ press to stop ]" : "[ press to start ]"); + switch (machine_state) { + case STATE_MENU: + display.println("STOPPED"); + display.setCursor(0, 56); + display.println("[ press to START ]"); + break; + case STATE_ARMING: + display.println("ARMING..."); + display.setCursor(0, 56); + display.println("[ press to STOP ]"); + break; + case STATE_FEEDING: + display.println("FEEDING..."); + display.setCursor(0, 56); + display.println("[ press to STOP ]"); + break; + } display.display(); } - btn_pressed = btn_pressed_now; + machine_state_prev = machine_state; + btn_pressed_prev = btn_pressed; }