Advertisement
edinc90

Arduino-based automatic cable cutter

Jan 13th, 2018
6,306
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.93 KB | None | 1 0
  1. #include <Servo.h>
  2. #include <Stepper.h>
  3. #include <LiquidCrystal.h>
  4.  
  5.  
  6. //////////////////////////////////////
  7. // LCD buttons
  8. //////////////////////////////////////
  9. int lcd_key = 0;
  10. int adc_key_in = 0;
  11. #define btnRIGHT 0
  12. #define btnUP 1
  13. #define btnDOWN 2
  14. #define btnLEFT 3
  15. #define btnSELECT 4
  16. #define btnNONE 5
  17.  
  18. int pinSwitch = 52;
  19. int pinServo = 53;
  20.  
  21. const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
  22. const int stepsPerFoot = 1209; // steps per stepsPerFoot of cable
  23.  
  24. int calSteps;           // steps counted during calibration
  25. unsigned long startTime;
  26. unsigned long endTime;
  27. unsigned long calTime;
  28. int switchLastState;    // switch change state
  29.  
  30. int cutPos = 0;         // servo cutter closed position
  31. int openPos = 180;        // servo cutter open position
  32. int servoDelay = 1000;   // servo movement time
  33. int baseDelay = 6100;   // time to measure one stepsPerFoot of cable
  34. int speed1 = 150;        // stepper speed in RPMs
  35. int cutDelay;           // how long it takes to measure entire length
  36. int setLen;             // requested length
  37. int setQty;             // requested quantity
  38. int currQty = 0;        // current quantity
  39. int totalSteps;         // how many steps we need to measure the requested length
  40. int measureLen = 0;     // measured length (float for decimals!)
  41. int measureInch;
  42. int measureFeet;
  43. int cutLen;             // Measured length during cutting operation
  44.  
  45.  
  46. unsigned long lastDelayTime = 0;
  47. unsigned long delayTime = 300;
  48. unsigned long lastInteraction = 0;
  49. unsigned long lastUpdate = 0;
  50. //int buttonState = 0;
  51.  
  52. int cursorPos = 0;
  53. int menuState = 0;        // Menu position, starts at Menu 0
  54.  
  55. Stepper myStepper(stepsPerRevolution, 22, 24, 26, 28);
  56. Servo myservo;
  57.  
  58. // Set up lcd global variable
  59. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  60.  
  61. /////////////////////////////////////////////
  62. // New way to read buttons
  63. ////////////////////////////////////////////
  64. int read_LCD_buttons()
  65. {
  66.   adc_key_in = analogRead(0); // read the value from the buttons
  67.   if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  68.   if (adc_key_in < 50) return btnRIGHT;
  69.   if (adc_key_in < 195) return btnUP;
  70.   if (adc_key_in < 380) return btnDOWN;
  71.   if (adc_key_in < 555) return btnLEFT;
  72.   if (adc_key_in < 790) return btnSELECT;
  73.  
  74.   return btnNONE; // when all others fail, return this...
  75. }
  76.  
  77. void setup() {
  78.   Serial.begin(9600);
  79.   Serial.println("======== Automated Cable Cutter Online =========");
  80.  
  81.   pinMode(10, OUTPUT);    // LCD backlight control
  82.   digitalWrite(10, 255);
  83.   pinMode(pinSwitch, INPUT_PULLUP);
  84.  
  85.   lcd.begin(16, 2);     // Begin 16 x 2 LCD
  86.   myservo.attach(pinServo);
  87.   myStepper.setSpeed(speed1);
  88.  
  89.   myservo.write(openPos); // make sure we start with cutter open
  90.  
  91.   showMenus();
  92. }
  93.  
  94. void loop() {
  95.   lcd_key = read_LCD_buttons(); // read the buttons
  96.   processButtons();             // do the thing
  97.   if (digitalRead(pinSwitch) != switchLastState) {
  98.     showMenus();
  99.     switchLastState = digitalRead(pinSwitch);   // checks to see if the wire sensor switch has changed
  100.   }
  101.  
  102. }
  103.  
  104. void processButtons () { // Reads the buttons and exectues the proper actions based on the menu currently open
  105.  
  106.   if ((millis() - lastDelayTime) > delayTime) {                                 // Only read buttons every 0.3 second
  107.  
  108.     switch (menuState) {
  109.       case 0:
  110.         ///////////////////////////////////////////////////
  111.         // Menu 0: Cut mode
  112.         ///////////////////////////////////////////////////
  113.         switch (lcd_key) {
  114.           case btnNONE: // No buttons
  115.             // Do nothing
  116.             break;
  117.           case btnSELECT: // Select
  118.             if (digitalRead(pinSwitch) == HIGH) {  // if we haven't loaded a cable
  119.               releaseStepper();
  120.             }
  121.             menuState = 1;
  122.             cursorPos = 1;
  123.             showMenus();
  124.             break;
  125.           case btnRIGHT: // Right
  126.             if (digitalRead(pinSwitch) == HIGH) {  // if we haven't loaded a cable
  127.               releaseStepper();
  128.             }
  129.             menuState = 1;
  130.             cursorPos = 1;
  131.             showMenus();
  132.             break;
  133.           case btnUP: //Up
  134.             menuState = 7;
  135.             showMenus();
  136.             break;
  137.           case btnDOWN: // Down
  138.             menuState = 2;
  139.             showMenus();
  140.             break;
  141.           case btnLEFT: // ESC
  142.             menuState = 0;
  143.             showMenus();
  144.             break;
  145.         }
  146.         break;
  147.       case 1:
  148.         ///////////////////////////////////////////////////
  149.         // Menu 0 Sub 1: Set cuts
  150.         ///////////////////////////////////////////////////
  151.         switch (lcd_key) {
  152.           case btnNONE: // No buttons
  153.             // Do nothing
  154.             break;
  155.           case btnSELECT:   // Select
  156.             if (setQty > 0) { // only if we've set Qty and if there's a cable loaded
  157.               cutCables();
  158.             }
  159.             break;
  160.           case btnRIGHT: // Right
  161.             if (cursorPos == 1) {
  162.               cursorPos = 2;
  163.             } else if (cursorPos == 2) {
  164.               cursorPos = 1;
  165.             }
  166.             showMenus();
  167.             break;
  168.           case btnUP: //Up
  169.             if (cursorPos == 1) {
  170.               setLen ++;
  171.             } else if (cursorPos == 2) {
  172.               setQty ++;
  173.             }
  174.             showMenus();
  175.             break;
  176.           case btnDOWN: // Down
  177.             if (cursorPos == 1 && setLen > 0) {
  178.               setLen --;
  179.             } else if (cursorPos == 2 && setQty > 0) {
  180.               setQty --;
  181.             }
  182.             showMenus();
  183.             break;
  184.           case btnLEFT: // Left
  185.             menuState = 0;
  186.             showMenus();
  187.             break;
  188.         }
  189.         break;
  190.       case 2:
  191.         ///////////////////////////////////////////////////
  192.         // Menu 1: Measure Mode
  193.         ///////////////////////////////////////////////////
  194.         switch (lcd_key) {
  195.           case btnNONE: // No buttons
  196.             // Do nothing
  197.             break;
  198.           case btnSELECT:
  199.             menuState = 5;    // measure menu
  200.             showMenus();
  201.             break;
  202.           case btnRIGHT: // Right
  203.             menuState = 5;    // measure menu
  204.             showMenus();
  205.             break;
  206.           case btnUP: //Up
  207.             menuState = 0;    // Go back to Top menu
  208.             showMenus();
  209.             break;
  210.           case btnDOWN: // Down
  211.             menuState = 7;    // Go to calibrate menu
  212.             showMenus();
  213.             break;
  214.           case btnLEFT: // ESC
  215.  
  216.             break;
  217.         }
  218.         break;
  219.       case 4:
  220.         ///////////////////////////////////////////////////
  221.         // Cut summary
  222.         ///////////////////////////////////////////////////
  223.         switch (lcd_key) {
  224.           case btnNONE: // No buttons
  225.             // Do nothing
  226.             break;
  227.           case btnSELECT:
  228.             menuState = 1;    // Go back to Cut menu
  229.             showMenus();
  230.             break;
  231.           case btnRIGHT: // Right
  232.             menuState = 1;    // Go back to Cut menu
  233.             showMenus();
  234.             break;
  235.           case btnUP: //Up
  236.             menuState = 1;    // Go back to Cut menu
  237.             showMenus();
  238.             break;
  239.           case btnDOWN: // Down
  240.             menuState = 1;    // Go back to Cut menu
  241.             showMenus();
  242.             break;
  243.           case btnLEFT: // ESC
  244.             menuState = 0;    // Go back to Top menu
  245.             showMenus();
  246.             break;
  247.         }
  248.         break;
  249.  
  250.       case 5:
  251.         ///////////////////////////////////////////////////
  252.         // Measurement mode
  253.         ///////////////////////////////////////////////////
  254.         switch (lcd_key) {
  255.           case btnNONE: // No buttons
  256.             // Do nothing
  257.             break;
  258.           case btnSELECT:
  259.             measureCable();
  260.             break;
  261.           case btnRIGHT: // Right
  262.             // do nothing
  263.             break;
  264.           case btnUP: //Up
  265.             // do nothing
  266.             break;
  267.           case btnDOWN: // Down
  268.             // do nothing
  269.             break;
  270.           case btnLEFT: // ESC
  271.             menuState = 2;    // Go back to Measure top menu
  272.             showMenus();
  273.             break;
  274.         }
  275.         break;
  276.       case 6:
  277.         ///////////////////////////////////////////////////
  278.         // Cut summary
  279.         ///////////////////////////////////////////////////
  280.         switch (lcd_key) {
  281.           case btnNONE: // No buttons
  282.             // Do nothing
  283.             break;
  284.           case btnSELECT:
  285.             menuState = 5;    // Go back to Measure menu
  286.             showMenus();
  287.             break;
  288.           case btnRIGHT: // Right
  289.             menuState = 5;    // Go back to Measure menu
  290.             showMenus();
  291.             break;
  292.           case btnUP: //Up
  293.             menuState = 5;    // Go back to Measure menu
  294.             showMenus();
  295.             break;
  296.           case btnDOWN: // Down
  297.             menuState = 5;    // Go back to Measure menu
  298.             showMenus();
  299.             break;
  300.           case btnLEFT: // ESC
  301.             menuState = 5;    // Go back to Measure menu
  302.             showMenus();
  303.             break;
  304.         }
  305.         break;
  306.       case 7:
  307.         ///////////////////////////////////////////////////
  308.         // Calibrate
  309.         ///////////////////////////////////////////////////
  310.         switch (lcd_key) {
  311.           case btnNONE: // No buttons
  312.             // Do nothing
  313.             break;
  314.           case btnSELECT:
  315.             menuState = 8;    // calibrate menu
  316.             showMenus();
  317.             releaseStepper();
  318.             break;
  319.           case btnRIGHT: // Right
  320.             menuState = 0;    //
  321.             showMenus();
  322.             break;
  323.           case btnUP: //Up
  324.             menuState = 2;    //
  325.             showMenus();
  326.             break;
  327.           case btnDOWN: // Down
  328.             menuState = 0;    //
  329.             showMenus();
  330.             break;
  331.           case btnLEFT: // ESC
  332.             menuState = 0;    //
  333.             showMenus();
  334.             break;
  335.         }
  336.         break;
  337.       case 8:
  338.         ///////////////////////////////////////////////////
  339.         // Calibrate
  340.         ///////////////////////////////////////////////////
  341.         switch (lcd_key) {
  342.           case btnNONE: // No buttons
  343.             // Do nothing
  344.             break;
  345.           case btnSELECT:
  346.             //menuState = 8;    //
  347.             calibrate();
  348.             showMenus();
  349.             break;
  350.           case btnRIGHT: // Right
  351.             menuState = 0;    //
  352.             showMenus();
  353.             break;
  354.           case btnUP: //Up
  355.             menuState = 2;    //
  356.             showMenus();
  357.             break;
  358.           case btnDOWN: // Down
  359.             menuState = 0;    //
  360.             showMenus();
  361.             break;
  362.           case btnLEFT: // ESC
  363.             menuState = 0;    //
  364.             showMenus();
  365.             break;
  366.         }
  367.         break;
  368.  
  369.       default:
  370.         switch (lcd_key) {
  371.           case btnNONE: // No buttons
  372.             // Do nothing
  373.             break;
  374.           case btnSELECT:
  375.             menuState = 0;    //
  376.             showMenus();
  377.             break;
  378.           case btnRIGHT: // Right
  379.             menuState = 0;    //
  380.             showMenus();
  381.             break;
  382.           case btnUP: //Up
  383.             menuState = 0;    //
  384.             showMenus();
  385.             break;
  386.           case btnDOWN: // Down
  387.             menuState = 0;    //
  388.             showMenus();
  389.             break;
  390.           case btnLEFT: // ESC
  391.             menuState = 0;    //
  392.             showMenus();
  393.             break;
  394.         }
  395.         break;
  396.     }
  397.     lastDelayTime = millis();
  398.   }
  399. }
  400.  
  401.  
  402.  
  403. void showMenus() {
  404.   // This function holds all the menu designs. Each case is a different menu/submenu. Cases are set by the Enter button incrementing the menuState variable.
  405.   switch (menuState) {
  406.     case 0:
  407.       ///////////////////////////////////////////////////
  408.       // Menu 0: Cut Mode
  409.       ///////////////////////////////////////////////////
  410.  
  411.       lcd.noCursor(); // Don't show the cursor
  412.       lcd.setCursor(0, 0);
  413.       lcd.write("    Cut Mode    ");
  414.       lcd.setCursor(0, 1);
  415.       lcd.write("  Press Select  ");
  416.       break;
  417.  
  418.     case 1:
  419.       ///////////////////////////////////////////////////
  420.       // Menu 0, Submenu 1: Cut Setup
  421.       ///////////////////////////////////////////////////
  422.       lcd.clear();
  423.       lcd.cursor(); // Show the cursor
  424.       lcd.setCursor(0, 0);
  425.       lcd.write("Length (ft): ");
  426.       lcd.setCursor(13, 0);
  427.       lcd.print(setLen);
  428.       lcd.setCursor(0, 1);
  429.       lcd.write("Qty: ");
  430.       lcd.print(setQty);
  431.       if (digitalRead(pinSwitch) == HIGH) { // if we've not loaded a cable
  432.         lcd.setCursor(10, 1);
  433.         lcd.print("Load");
  434.       } else {
  435.         lcd.setCursor(10, 1);
  436.         lcd.print("Ready");
  437.       }
  438.  
  439.       if (cursorPos == 1) {
  440.         lcd.setCursor(13, 0);
  441.       } else if (cursorPos == 2) {
  442.         lcd.setCursor(5, 1);
  443.       }
  444.       break;
  445.  
  446.     case 2:
  447.       ///////////////////////////////////////////////////
  448.       // Menu 1: Measure Mode
  449.       ///////////////////////////////////////////////////
  450.       lcd.noCursor(); // Don't show the cursor
  451.       lcd.setCursor(0, 0);
  452.       lcd.write("  Measure Mode  ");
  453.       lcd.setCursor(0, 1);
  454.       lcd.write("  Press Select  ");
  455.  
  456.       break;
  457.  
  458.     case 3:
  459.       //////////////////////////////////////////////////
  460.       // Cutting in Progress
  461.       //////////////////////////////////////////////////
  462.       lcd.clear();
  463.       lcd.noCursor();
  464.       lcd.setCursor(0, 1);
  465.       lcd.print("Qty cut:");
  466.       lcd.setCursor(8, 1);
  467.       lcd.print(currQty);
  468.       break;
  469.  
  470.     case 4:
  471.       //////////////////////////////////////////////////
  472.       // Cut summary
  473.       //////////////////////////////////////////////////
  474.       lcd.clear();
  475.       lcd.noCursor();
  476.       lcd.setCursor(0, 0);
  477.       lcd.print("Complete");
  478.       lcd.setCursor(0, 1);
  479.       lcd.print("Cut ");
  480.       lcd.setCursor(4, 1);
  481.       lcd.print(currQty);
  482.       lcd.print(" @ ");
  483.       lcd.print(setLen);
  484.       lcd.print(" ft.");
  485.       break;
  486.     case 5:
  487.       //////////////////////////////////////////////////
  488.       // Measure mode
  489.       //////////////////////////////////////////////////
  490.       lcd.clear();
  491.       lcd.noCursor();
  492.       lcd.setCursor(0, 0);
  493.       if (digitalRead(pinSwitch) == HIGH) {
  494.         lcd.print(" Load cable now ");
  495.       } else {
  496.         lcd.print("      Ready     ");
  497.       }
  498.  
  499.       lcd.setCursor(0, 1);
  500.       lcd.print("  Press Select  ");
  501.       break;
  502.     case 6:
  503.       //////////////////////////////////////////////////
  504.       // Measure summary
  505.       //////////////////////////////////////////////////
  506.       lcd.clear();
  507.       lcd.noCursor();
  508.       lcd.setCursor(0, 0);
  509.       lcd.print("Measurement Done");
  510.       lcd.setCursor(0, 1);
  511.       lcd.print("Len: ");
  512.       lcd.print(measureFeet);
  513.       lcd.print("' ");
  514.       lcd.print(measureInch);
  515.       lcd.print("\"");
  516.       break;
  517.  
  518.     case 7:
  519.       //////////////////////////////////////////////////
  520.       // Calibrate
  521.       //////////////////////////////////////////////////
  522.       lcd.clear();
  523.       lcd.noCursor();
  524.       lcd.setCursor(0, 0);
  525.       lcd.print("Calibration Mode");
  526.       lcd.setCursor(0, 1);
  527.       lcd.print("  Press Select  ");
  528.       break;
  529.  
  530.     case 8:
  531.       //////////////////////////////////////////////////
  532.       // Calibrate
  533.       //////////////////////////////////////////////////
  534.       lcd.clear();
  535.       lcd.noCursor();
  536.       lcd.setCursor(0, 0);
  537.       lcd.print("Load exactly 1'");
  538.       lcd.setCursor(0, 1);
  539.       lcd.print("of cable.");
  540.       break;
  541.  
  542.     case 9:
  543.       //////////////////////////////////////////////////
  544.       // Calibrate
  545.       //////////////////////////////////////////////////
  546.       lcd.clear();
  547.       lcd.noCursor();
  548.       lcd.setCursor(0, 0);
  549.       lcd.print("Cal. Complete!");
  550.       lcd.setCursor(0, 1);
  551.       lcd.print(calSteps);
  552.       lcd.print(" steps/ft");
  553.       break;
  554.   }
  555. }
  556.  
  557. void calibrate() {
  558.   calTime = 0;
  559.   calSteps = 0;           // reset
  560.   lcd.clear();
  561.   lcd.setCursor(0, 0);
  562.   lcd.print("Calibrating...");
  563.  
  564.  
  565.   while (digitalRead(pinSwitch) == LOW) {
  566.     myStepper.step(1);
  567.     calSteps ++;
  568.     lcd.setCursor(0, 1);
  569.     lcd.print(calSteps);
  570.   }
  571.  
  572.   menuState = 9;        // Calibrate summary menu
  573.   showMenus();
  574.   releaseStepper();
  575. }
  576.  
  577. void cutCables() {
  578.   cutLen = 0;                     // reset measured length
  579.   currQty = 0;                    // reset current quantity
  580.  
  581.   if (digitalRead(pinSwitch) == HIGH) {    // switch reads HIGH if we haven't loaded a wire
  582.     lcd.setCursor(0, 0);
  583.     lcd.print("Load Wire! ");
  584.   } else {
  585.     Serial.println("-_-_-_ Cutting subroutine activated _-_-_-");
  586.     Serial.print("~ Cutting ");
  587.     Serial.print(setQty);
  588.     Serial.print(" pieces with length ");
  589.     Serial.print(setLen);
  590.     Serial.println(" feet.");
  591.     Serial.print("~ Current quantity cut: ");
  592.     Serial.println(currQty);
  593.  
  594.     //totalSteps = (setLen * stepsPerFoot);     // total steps per cut
  595.     menuState = 3;                  // Cutting in progress menu
  596.     showMenus();
  597.  
  598.     while (currQty < setQty) {
  599.       myStepper.step(-20);
  600.       delay(100);
  601.       myStepper.step(20);             // unstick the wire from the cutter
  602.       cutLen = 0;                     // reset measured length
  603.       Serial.println("~~~ Measuring... ~~~");
  604.       lcd.setCursor(0, 0);
  605.       lcd.print("Measuring...    ");
  606.       while (cutLen < setLen) {
  607.         myStepper.step(stepsPerFoot);
  608.         cutLen ++;
  609.         lcd.setCursor(13, 0);
  610.         lcd.print(cutLen);
  611.       }
  612.       Serial.println("~~~ Cutter Closed ~~~");
  613.       lcd.setCursor(0, 0);
  614.       lcd.print("Cutter closed   ");
  615.       myservo.write(cutPos);
  616.       delay(servoDelay);
  617.       Serial.println("~~~ Cutter Open ~~~");
  618.       lcd.setCursor(0, 0);
  619.       lcd.print("Cutter open     ");
  620.       myservo.write(openPos);
  621.       delay(servoDelay);
  622.       Serial.println("~~~ Cut made ~~~");
  623.       currQty ++;
  624.       showMenus();
  625.     }
  626.  
  627.     menuState = 4;     // Cut summary
  628.     showMenus();
  629.   }
  630. }
  631.  
  632. void measureCable() {
  633.   int stepsPerInch = (stepsPerFoot / 12);
  634.   measureLen = 0;
  635.  
  636.   lcd.clear();
  637.   lcd.noCursor();
  638.   lcd.setCursor(0, 0);
  639.   lcd.print("  Measuring...  ");
  640.   lcd.setCursor(0, 1);
  641.   lcd.print("Len: ");
  642.   lcd.print(measureLen);
  643.   lcd.print(" in.");
  644.   while (digitalRead(pinSwitch) == LOW) {
  645.     myStepper.step(stepsPerInch);
  646.     measureLen = measureLen + 1;
  647.     lcd.setCursor(4, 1);
  648.     lcd.print(measureLen);
  649.   }
  650.  
  651.   //some math
  652.  
  653.   measureInch = measureLen % 12;
  654.   measureFeet = measureLen / 12;
  655.  
  656.   menuState = 6;  // Summary menu
  657.   showMenus();
  658.  
  659.   releaseStepper();
  660. }
  661.  
  662. void releaseStepper() {
  663.   digitalWrite(22, LOW);
  664.   digitalWrite(24, LOW);
  665.   digitalWrite(26, LOW);
  666.   digitalWrite(28, LOW);
  667. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement