Станок для нарезки кабеля на базе Arduino


Похоже, Edward Carlson устал отмерять и нарезать кабель и он решил сделать автоматизированный станок для нарезки кабеля.
Для этого, ему понадобились:
— контроллер Arduino Mega,
— LCD-шилд с кнопками — для организации меню,
— шаговый двигатель — для перемещения кабеля между роликами на нужную длину,
— мощная сервомашинка — для приведения в действие ручные кусачки.

Скетч для Arduino

#include <Servo.h>
#include <Stepper.h>
#include <LiquidCrystal.h>


//////////////////////////////////////
// LCD buttons
//////////////////////////////////////
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

int pinSwitch = 52;
int pinServo = 53;

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
const int stepsPerFoot = 1209; // steps per stepsPerFoot of cable

int calSteps;           // steps counted during calibration
unsigned long startTime;
unsigned long endTime;
unsigned long calTime;
int switchLastState;    // switch change state

int cutPos = 0;         // servo cutter closed position
int openPos = 180;        // servo cutter open position
int servoDelay = 1000;   // servo movement time
int baseDelay = 6100;   // time to measure one stepsPerFoot of cable
int speed1 = 150;        // stepper speed in RPMs
int cutDelay;           // how long it takes to measure entire length
int setLen;             // requested length
int setQty;             // requested quantity
int currQty = 0;        // current quantity
int totalSteps;         // how many steps we need to measure the requested length
int measureLen = 0;     // measured length (float for decimals!)
int measureInch;
int measureFeet;
int cutLen;             // Measured length during cutting operation


unsigned long lastDelayTime = 0;
unsigned long delayTime = 300;
unsigned long lastInteraction = 0;
unsigned long lastUpdate = 0;
//int buttonState = 0;

int cursorPos = 0;
int menuState = 0;        // Menu position, starts at Menu 0

Stepper myStepper(stepsPerRevolution, 22, 24, 26, 28);
Servo myservo;

// Set up lcd global variable
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

/////////////////////////////////////////////
// New way to read buttons
////////////////////////////////////////////
int read_LCD_buttons()
{
  adc_key_in = analogRead(0); // read the value from the buttons
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50) return btnRIGHT;
  if (adc_key_in < 195) return btnUP;
  if (adc_key_in < 380) return btnDOWN;
  if (adc_key_in < 555) return btnLEFT;
  if (adc_key_in < 790) return btnSELECT;

  return btnNONE; // when all others fail, return this...
}

void setup() {
  Serial.begin(9600);
  Serial.println("======== Automated Cable Cutter Online =========");

  pinMode(10, OUTPUT);    // LCD backlight control
  digitalWrite(10, 255);
  pinMode(pinSwitch, INPUT_PULLUP);

  lcd.begin(16, 2);     // Begin 16 x 2 LCD
  myservo.attach(pinServo);
  myStepper.setSpeed(speed1);

  myservo.write(openPos); // make sure we start with cutter open

  showMenus();
}

void loop() {
  lcd_key = read_LCD_buttons(); // read the buttons
  processButtons();             // do the thing
  if (digitalRead(pinSwitch) != switchLastState) {
    showMenus();
    switchLastState = digitalRead(pinSwitch);   // checks to see if the wire sensor switch has changed
  }

}

void processButtons () { // Reads the buttons and exectues the proper actions based on the menu currently open

  if ((millis() - lastDelayTime) > delayTime) {                                 // Only read buttons every 0.3 second

    switch (menuState) {
      case 0:
        ///////////////////////////////////////////////////
        // Menu 0: Cut mode
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT: // Select
            if (digitalRead(pinSwitch) == HIGH) {  // if we haven't loaded a cable
              releaseStepper();
            }
            menuState = 1;
            cursorPos = 1;
            showMenus();
            break;
          case btnRIGHT: // Right
            if (digitalRead(pinSwitch) == HIGH) {  // if we haven't loaded a cable
              releaseStepper();
            }
            menuState = 1;
            cursorPos = 1;
            showMenus();
            break;
          case btnUP: //Up
            menuState = 7;
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 2;
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 0;
            showMenus();
            break;
        }
        break;
      case 1:
        ///////////////////////////////////////////////////
        // Menu 0 Sub 1: Set cuts
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:   // Select
            if (setQty > 0) { // only if we've set Qty and if there's a cable loaded
              cutCables();
            }
            break;
          case btnRIGHT: // Right
            if (cursorPos == 1) {
              cursorPos = 2;
            } else if (cursorPos == 2) {
              cursorPos = 1;
            }
            showMenus();
            break;
          case btnUP: //Up
            if (cursorPos == 1) {
              setLen ++;
            } else if (cursorPos == 2) {
              setQty ++;
            }
            showMenus();
            break;
          case btnDOWN: // Down
            if (cursorPos == 1 && setLen > 0) {
              setLen --;
            } else if (cursorPos == 2 && setQty > 0) {
              setQty --;
            }
            showMenus();
            break;
          case btnLEFT: // Left
            menuState = 0;
            showMenus();
            break;
        }
        break;
      case 2:
        ///////////////////////////////////////////////////
        // Menu 1: Measure Mode
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            menuState = 5;    // measure menu
            showMenus();
            break;
          case btnRIGHT: // Right
            menuState = 5;    // measure menu
            showMenus();
            break;
          case btnUP: //Up
            menuState = 0;    // Go back to Top menu
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 7;    // Go to calibrate menu
            showMenus();
            break;
          case btnLEFT: // ESC

            break;
        }
        break;
      case 4:
        ///////////////////////////////////////////////////
        // Cut summary
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            menuState = 1;    // Go back to Cut menu
            showMenus();
            break;
          case btnRIGHT: // Right
            menuState = 1;    // Go back to Cut menu
            showMenus();
            break;
          case btnUP: //Up
            menuState = 1;    // Go back to Cut menu
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 1;    // Go back to Cut menu
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 0;    // Go back to Top menu
            showMenus();
            break;
        }
        break;

      case 5:
        ///////////////////////////////////////////////////
        // Measurement mode
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            measureCable();
            break;
          case btnRIGHT: // Right
            // do nothing
            break;
          case btnUP: //Up
            // do nothing
            break;
          case btnDOWN: // Down
            // do nothing
            break;
          case btnLEFT: // ESC
            menuState = 2;    // Go back to Measure top menu
            showMenus();
            break;
        }
        break;
      case 6:
        ///////////////////////////////////////////////////
        // Cut summary
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            menuState = 5;    // Go back to Measure menu
            showMenus();
            break;
          case btnRIGHT: // Right
            menuState = 5;    // Go back to Measure menu
            showMenus();
            break;
          case btnUP: //Up
            menuState = 5;    // Go back to Measure menu
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 5;    // Go back to Measure menu
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 5;    // Go back to Measure menu
            showMenus();
            break;
        }
        break;
      case 7:
        ///////////////////////////////////////////////////
        // Calibrate
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            menuState = 8;    // calibrate menu
            showMenus();
            releaseStepper();
            break;
          case btnRIGHT: // Right
            menuState = 0;    //
            showMenus();
            break;
          case btnUP: //Up
            menuState = 2;    //
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 0;    //
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 0;    //
            showMenus();
            break;
        }
        break;
      case 8:
        ///////////////////////////////////////////////////
        // Calibrate
        ///////////////////////////////////////////////////
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            //menuState = 8;    //
            calibrate();
            showMenus();
            break;
          case btnRIGHT: // Right
            menuState = 0;    //
            showMenus();
            break;
          case btnUP: //Up
            menuState = 2;    //
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 0;    //
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 0;    //
            showMenus();
            break;
        }
        break;

      default:
        switch (lcd_key) {
          case btnNONE: // No buttons
            // Do nothing
            break;
          case btnSELECT:
            menuState = 0;    //
            showMenus();
            break;
          case btnRIGHT: // Right
            menuState = 0;    //
            showMenus();
            break;
          case btnUP: //Up
            menuState = 0;    //
            showMenus();
            break;
          case btnDOWN: // Down
            menuState = 0;    //
            showMenus();
            break;
          case btnLEFT: // ESC
            menuState = 0;    //
            showMenus();
            break;
        }
        break;
    }
    lastDelayTime = millis();
  }
}



void showMenus() {
  // 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.
  switch (menuState) {
    case 0:
      ///////////////////////////////////////////////////
      // Menu 0: Cut Mode
      ///////////////////////////////////////////////////

      lcd.noCursor(); // Don't show the cursor
      lcd.setCursor(0, 0);
      lcd.write("    Cut Mode    ");
      lcd.setCursor(0, 1);
      lcd.write("  Press Select  ");
      break;

    case 1:
      ///////////////////////////////////////////////////
      // Menu 0, Submenu 1: Cut Setup
      ///////////////////////////////////////////////////
      lcd.clear();
      lcd.cursor(); // Show the cursor
      lcd.setCursor(0, 0);
      lcd.write("Length (ft): ");
      lcd.setCursor(13, 0);
      lcd.print(setLen);
      lcd.setCursor(0, 1);
      lcd.write("Qty: ");
      lcd.print(setQty);
      if (digitalRead(pinSwitch) == HIGH) { // if we've not loaded a cable
        lcd.setCursor(10, 1);
        lcd.print("Load");
      } else {
        lcd.setCursor(10, 1);
        lcd.print("Ready");
      }

      if (cursorPos == 1) {
        lcd.setCursor(13, 0);
      } else if (cursorPos == 2) {
        lcd.setCursor(5, 1);
      }
      break;

    case 2:
      ///////////////////////////////////////////////////
      // Menu 1: Measure Mode
      ///////////////////////////////////////////////////
      lcd.noCursor(); // Don't show the cursor
      lcd.setCursor(0, 0);
      lcd.write("  Measure Mode  ");
      lcd.setCursor(0, 1);
      lcd.write("  Press Select  ");

      break;

    case 3:
      //////////////////////////////////////////////////
      // Cutting in Progress
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 1);
      lcd.print("Qty cut:");
      lcd.setCursor(8, 1);
      lcd.print(currQty);
      break;

    case 4:
      //////////////////////////////////////////////////
      // Cut summary
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      lcd.print("Complete");
      lcd.setCursor(0, 1);
      lcd.print("Cut ");
      lcd.setCursor(4, 1);
      lcd.print(currQty);
      lcd.print(" @ ");
      lcd.print(setLen);
      lcd.print(" ft.");
      break;
    case 5:
      //////////////////////////////////////////////////
      // Measure mode
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      if (digitalRead(pinSwitch) == HIGH) {
        lcd.print(" Load cable now ");
      } else {
        lcd.print("      Ready     ");
      }

      lcd.setCursor(0, 1);
      lcd.print("  Press Select  ");
      break;
    case 6:
      //////////////////////////////////////////////////
      // Measure summary
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      lcd.print("Measurement Done");
      lcd.setCursor(0, 1);
      lcd.print("Len: ");
      lcd.print(measureFeet);
      lcd.print("' ");
      lcd.print(measureInch);
      lcd.print("\"");
      break;

    case 7:
      //////////////////////////////////////////////////
      // Calibrate
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      lcd.print("Calibration Mode");
      lcd.setCursor(0, 1);
      lcd.print("  Press Select  ");
      break;

    case 8:
      //////////////////////////////////////////////////
      // Calibrate
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      lcd.print("Load exactly 1'");
      lcd.setCursor(0, 1);
      lcd.print("of cable.");
      break;

    case 9:
      //////////////////////////////////////////////////
      // Calibrate
      //////////////////////////////////////////////////
      lcd.clear();
      lcd.noCursor();
      lcd.setCursor(0, 0);
      lcd.print("Cal. Complete!");
      lcd.setCursor(0, 1);
      lcd.print(calSteps);
      lcd.print(" steps/ft");
      break;
  }
}

void calibrate() {
  calTime = 0;
  calSteps = 0;           // reset
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Calibrating...");


  while (digitalRead(pinSwitch) == LOW) {
    myStepper.step(1);
    calSteps ++;
    lcd.setCursor(0, 1);
    lcd.print(calSteps);
  }

  menuState = 9;        // Calibrate summary menu
  showMenus();
  releaseStepper();
}

void cutCables() {
  cutLen = 0;                     // reset measured length
  currQty = 0;                    // reset current quantity

  if (digitalRead(pinSwitch) == HIGH) {    // switch reads HIGH if we haven't loaded a wire
    lcd.setCursor(0, 0);
    lcd.print("Load Wire! ");
  } else {
    Serial.println("-_-_-_ Cutting subroutine activated _-_-_-");
    Serial.print("~ Cutting ");
    Serial.print(setQty);
    Serial.print(" pieces with length ");
    Serial.print(setLen);
    Serial.println(" feet.");
    Serial.print("~ Current quantity cut: ");
    Serial.println(currQty);

    //totalSteps = (setLen * stepsPerFoot);     // total steps per cut
    menuState = 3;                  // Cutting in progress menu
    showMenus();

    while (currQty < setQty) {
      myStepper.step(-20);
      delay(100);
      myStepper.step(20);             // unstick the wire from the cutter
      cutLen = 0;                     // reset measured length
      Serial.println("~~~ Measuring... ~~~");
      lcd.setCursor(0, 0);
      lcd.print("Measuring...    ");
      while (cutLen < setLen) {
        myStepper.step(stepsPerFoot);
        cutLen ++;
        lcd.setCursor(13, 0);
        lcd.print(cutLen);
      }
      Serial.println("~~~ Cutter Closed ~~~");
      lcd.setCursor(0, 0);
      lcd.print("Cutter closed   ");
      myservo.write(cutPos);
      delay(servoDelay);
      Serial.println("~~~ Cutter Open ~~~");
      lcd.setCursor(0, 0);
      lcd.print("Cutter open     ");
      myservo.write(openPos);
      delay(servoDelay);
      Serial.println("~~~ Cut made ~~~");
      currQty ++;
      showMenus();
    }

    menuState = 4;     // Cut summary
    showMenus();
  }
}

void measureCable() {
  int stepsPerInch = (stepsPerFoot / 12);
  measureLen = 0;

  lcd.clear();
  lcd.noCursor();
  lcd.setCursor(0, 0);
  lcd.print("  Measuring...  ");
  lcd.setCursor(0, 1);
  lcd.print("Len: ");
  lcd.print(measureLen);
  lcd.print(" in.");
  while (digitalRead(pinSwitch) == LOW) {
    myStepper.step(stepsPerInch);
    measureLen = measureLen + 1;
    lcd.setCursor(4, 1);
    lcd.print(measureLen);
  }

  //some math

  measureInch = measureLen % 12;
  measureFeet = measureLen / 12;

  menuState = 6;  // Summary menu
  showMenus();

  releaseStepper();
}

void releaseStepper() {
  digitalWrite(22, LOW);
  digitalWrite(24, LOW);
  digitalWrite(26, LOW);
  digitalWrite(28, LOW);
}

По теме
Автомат для нарезания провода
Робот-бендер для проволоки
RopeBot - робот для перерезания верёвки
Arduino-механизм для нарезки пенки
Простой ЧПУ под управлением Arduino

Arduino
Ардуино что это и зачем?
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение