//------------------------------- librarys --------------------------------
#include <Wire.h>
//#include <rgb_lcd.h>
//#include <LiquidCrystal.h>
#include <Servo.h>
#include <Keypad.h>
#include "AccelStepper.h"
//------------------------------- lcd -------------------------------------
//rgb_lcd lcd;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//------------------------------- Stepper Variables -----------------------
//#define stepPin 49
//#define dirPin 50
#define stepPin 51
#define dirPin 61
#define enablePin 4
long TravelX; // Used to store the X value entered in the Serial Monitor
int move_finished = 1; // Used to check if move is completed
long initial_homing = -1; // Used to Home Stepper at startup
AccelStepper stepperX( 1, 5, 6);
//------------------------------- input -----------------------------------
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', '.' },
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {13, 12, 11, 10};
byte colPins[COLS] = {9, 8, 7, 2};
//byte rowPins[ROWS] = {18,19,22,23};
//byte colPins[COLS] = {14,15,16,17};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
char ButtonState = 0;
#define START '*' //Maps Character inputs to logical Button Names
#define STOP '#'
#define F1 'A'
#define F2 'B'
#define F3 'C'
#define F4 'D'
#define NOKEY 0
#define LEFT '4'
#define RIGHT '6'
#define UP '2'
#define DOWN '5'
//--------------------------------output ----------------------------------
//#define Mpos 37
//#define Mcut 38
#define Anixneusi A0
#define Cutter A1
#define Mpos A3
#define Mcut A2
#define McutOff 1
#define home_switch 3
//------------------------------- user settings ---------------------------
float wireLength = 0.0;
unsigned int wireQuantity = 0;
int cuttime = 5000;
int positiontime = 500;
int Maintimer = 500;
int Homed = 1000;
bool isDecimal = false; // A flag to indicate if the decimal point has been pressed
int decimalPart = 0; // The decimal part of the length
int decimalPlace = 1; // To keep track of the position of the decimal place
//------------------------------- system settings -------------------------
int state = 6;
int incrementSpeed = 0;
float previousWireLength = 0.0;
int previousWireQuantity = 0;
//float mmPerStep = 0.003125;
float mmPerStep = 0.3125;
void setup() {
//Serial.begin(9600);
lcd.init(); // initialize the lcd
lcd.backlight();
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(Mpos, OUTPUT);
pinMode(Mcut, OUTPUT);
pinMode(McutOff, OUTPUT);
pinMode(Cutter, OUTPUT);
pinMode(home_switch, INPUT_PULLUP);
pinMode(Anixneusi, INPUT_PULLUP);
// Set Max Speed and Acceleration of each Steppers at startup for homing
stepperX.setMaxSpeed(2000.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(1500.0); // Set Acceleration of Stepper
}
void loop() {
if (ButtonState == STOP) {
if (state == 5) {
state = 0;
}
else {
state += 1;
}
delay(100);
lcd.clear();
}
if (ButtonState == START && state > 0 && state < 4) {
state -= 1;
delay(100);
lcd.clear();
}
ButtonState = keypad.getKey();
switch (state) {
case 0:
homeScreen();
break;
// case 1:
// chooseWireLength();
// break;
case 1:
handleLengthInput();
break;
// case 2:
// chooseWireQuantity();
// break;
case 2:
handleQuantityInput();
break;
case 3:
confirm();
break;
case 4:
currentlyCutting();
break;
case 5:
finishedCutting();
break;
case 6:
Homing();
break;
case 7:
MaterialFinish();
break;
}
}
void homeScreen() {
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("VALTZAKIS ");
lcd.setCursor(8, 1);
lcd.print("CNC ");
lcd.setCursor(5, 2);
lcd.print("MACHINERY ");
lcd.setCursor(15, 3);
lcd.print("NEXT>");
delay(200);
}
void Homing() {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("PATHSE C GIA ");
lcd.setCursor(6, 1);
lcd.print("MHDENISMO");
delay(200);
char key = keypad.getKey();
if (key == 'C')
{
//Serial.print("Stepper is Homing . . . . . . . . . . . ");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DIADIKASIA");
lcd.setCursor(0, 1);
lcd.print("MHDENISMOU");
while (digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is activated
stepperX.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepperX.run(); // Start moving the stepper
delay(5);
}
while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
stepperX.moveTo(initial_homing);
stepperX.run();
initial_homing++;
delay(5);
}
stepperX.setCurrentPosition(0); // Set the current position as zero for now
stepperX.setMaxSpeed(2000.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(1000.0); // Set Acceleration of Stepper
//stepperX.setCurrentPosition(2000);
// stepperX.runToNewPosition(2000);
delay(500);
state = 0;
}
}
void handleLengthInput() {
char key = keypad.getKey();
if (wireLength < 0.0 || wireLength > 600.0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("EKTOS ORIWN");
delay(1000);
lcd.setCursor(0, 1);
lcd.print("EISAGETE");
lcd.setCursor(0, 2);
lcd.print("0 to 600 mm");
delay(2000);
wireLength = 0.0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
delay(100);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
displayNavigation();
char key = keypad.getKey();
if (key == '#') {
// Handle '#' key press (confirmation)
state = 2; // Go to the next state for wire quantity input
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
displayNavigation();
} else if (key == '*') {
// Handle '*' key press (back)
state = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
} else if (key == 'D') {
// Handle 'D' key press (clear input)
wireLength = 0.0; // Remove the decimal part
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
displayNavigation();
} else if (isdigit(key) || key == '.') {
// Accumulate length input
if (key == '.' && !String(wireLength).endsWith(".")) {
// Check if the decimal point is pressed and not already present in the input
// Set a flag to indicate that the next digits will be decimal digits
wireLength = wireLength * 0.1; // Move the decimal point to the right
} else if (isdigit(key)) {
// Update the wire length based on the key pressed
wireLength = wireLength * 10 + (key - '0');
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + String(wireLength, 1) + " mm");
displayNavigation();
}
}
}
void handleQuantityInput() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
char key = keypad.getKey();
if (key == '#') {
// Handle '#' key press (confirmation)
state = 3; // Go to the next state for wire quantity input
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
} else if (key == '*') {
// Handle '*' key press (back)
state = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
} else if (key == 'D') {
// Handle 'D' key press (clear input)
wireQuantity = 0;
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
} else if (isdigit(key)) {
// Accumulate length input
wireQuantity = wireQuantity * 10 + (key - '0');
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
}
}
void confirm() {
if (wireLength != 0 && wireQuantity != 0)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print((String)wireLength + "mm x " + (String)wireQuantity + "pcs");
lcd.setCursor(0, 3);
lcd.print("<PISW");
lcd.setCursor(11, 3);
lcd.print("EKKINHSH>");
delay(100);
}
else if (wireLength == 0)
{
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("MHKOS / POSOTHTA");
lcd.setCursor(5, 1);
lcd.print("MHDENIKA");
lcd.setCursor(0, 3);
lcd.print("<PISW");
lcd.setCursor(11, 3);
lcd.print("EKKINHSH>");
delay(1500);
state = 1;
}
else if (wireQuantity == 0)
{
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("MHKOS / POSOTHTA");
lcd.setCursor(5, 1);
lcd.print("MHDENIKA");
lcd.setCursor(0, 3);
lcd.print("<PISW");
lcd.setCursor(11, 3);
lcd.print("EKKINHSH>");
delay(1500);
state = 1;
}
}
void currentlyCutting() {
lcd.clear();
lcd.setCursor(0, 2);
long jobLength = wireLength * wireQuantity;
lcd.print((String)jobLength + "mm ");
delay(1500);
while (jobLength > 0) {
if (jobLength <= 600) {
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("UNDER 600");
delay(1500);
MCutOn();
MposOff();
long stepsToTake = wireLength / mmPerStep;
long fullstepsToTake = jobLength / mmPerStep;
lcd.setCursor(3, 0);
lcd.print("METAKINHSH");
stepperX.runToNewPosition(fullstepsToTake);
delay(Maintimer);
long tempsteps = fullstepsToTake - wireLength;
for (int i = 0; i < wireQuantity; i++ ) {
tempsteps = tempsteps - stepsToTake;
jobLength = jobLength - wireLength;
MposOn();
MCutOff();
stepperX.runToNewPosition(tempsteps);
unsigned long timeForOneCycle = millis();
lcd.setCursor(3, 0);
lcd.print("H METAKINHSH");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
MCutOn();
Kopi();
MCutOff();
lcd.clear();
lcd.setCursor(0, 2);
lcd.print((String)(i + 1) + "/" + (String)wireQuantity);
lcd.setCursor(0, 3);
unsigned long timeRemaining = ((millis() - timeForOneCycle) * (wireQuantity - (i + 1))) / 1000;
lcd.print((String)timeRemaining + "s ");
lcd.print(jobLength);
delay(Maintimer);
}
}
else {
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("OVER 600");
delay(1500);
MCutOn();
MposOff();
long stepsToTake = wireLength / mmPerStep;
long fullstepsToTake = 600 / mmPerStep;
lcd.setCursor(3, 0);
lcd.print("METAKINHSH");
stepperX.runToNewPosition(fullstepsToTake);
delay(Maintimer);
long tempsteps = fullstepsToTake - wireLength;
for (int i = 0; i < wireQuantity; i++) {
tempsteps = tempsteps - stepsToTake;
jobLength = jobLength - wireLength;
MposOn();
MCutOff();
stepperX.runToNewPosition(tempsteps);
unsigned long timeForOneCycle = millis();
lcd.setCursor(3, 0);
lcd.print("H METAKINHSH");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
MCutOn();
Kopi();
MCutOff();
lcd.clear();
lcd.setCursor(0, 2);
lcd.print((String)(i + 1) + "/" + (String)wireQuantity);
lcd.setCursor(0, 3);
unsigned long timeRemaining = ((millis() - timeForOneCycle) * (wireQuantity - (i + 1))) / 1000;
lcd.print((String)timeRemaining + "s ");
lcd.print(jobLength);
delay(Maintimer);
}
}
}
wireLength = 0;
wireQuantity = 0;
state = 5;
}
void currentlyCutting2()
{
lcd.clear();
lcd.setCursor(0, 2);
long jobLength = wireLength*wireQuantity;
lcd.print((String)jobLength + "mm ");
delay(4500);
if (jobLength < 600){
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("UNDER 600");
delay(1500);
MCutOn();
MposOff();
long stepsToTake = wireLength / mmPerStep;
long fullstepsToTake = jobLength / mmPerStep;
lcd.setCursor(3, 0);
lcd.print("METAKINHSH");
stepperX.runToNewPosition(fullstepsToTake);
delay(Maintimer);
long tempsteps=fullstepsToTake-wireLength;
while (jobLength >0){
for (int i = 0; i < wireQuantity; i++) {
tempsteps=tempsteps-stepsToTake;
jobLength=jobLength-wireLength;
/*if(!digitalRead(Anixneusi)) {break; }*/
MposOn();
MCutOff();
stepperX.runToNewPosition(tempsteps);
unsigned long timeForOneCycle = millis();
lcd.setCursor(3, 0);
lcd.print("H METAKINHSH");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
MCutOn();
Kopi();
MCutOff();
lcd.clear();
lcd.setCursor(0, 2);
lcd.print((String)(i + 1) + "/" + (String)wireQuantity);
lcd.setCursor(0, 3);
unsigned long timeRemaining = ((millis() - timeForOneCycle) * (wireQuantity - (i + 1))) / 1000;
lcd.print((String)timeRemaining + "s ");
lcd.print(jobLength);
delay(Maintimer);
}
}
}
else
{
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("OVER 600");
delay(1500);
int integerPart = floor(600 / wireLength);
MCutOn();
MposOff();
//Metakinisi sto 600mm
long stepsToTake = wireLength / mmPerStep;
long fullstepsToTake = 600 / mmPerStep;
lcd.setCursor(3, 0);
lcd.print("METAKINHSH");
stepperX.runToNewPosition(fullstepsToTake);
delay(Maintimer);
long tempsteps=fullstepsToTake-wireLength;
while (jobLength >0){
for (int i = 0; i < wireQuantity; i++) {
tempsteps=tempsteps-stepsToTake;
jobLength=jobLength-wireLength;
/*if(!digitalRead(Anixneusi)) {break; }*/
MposOn();
MCutOff();
stepperX.runToNewPosition(tempsteps);
unsigned long timeForOneCycle = millis();
lcd.setCursor(3, 0);
lcd.print("H METAKINHSH");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
MCutOn();
Kopi();
MCutOff();
lcd.clear();
lcd.setCursor(0, 2);
lcd.print((String)(i + 1) + "/" + (String)wireQuantity);
lcd.setCursor(0, 3);
unsigned long timeRemaining = ((millis() - timeForOneCycle) * (wireQuantity - (i + 1))) / 1000;
lcd.print((String)timeRemaining + "s ");
lcd.print(jobLength);
delay(Maintimer);
}
}
}
wireLength = 0;
wireQuantity = 0;
state = 5;
}
void MposOn()
{
lcd.clear();
lcd.setCursor(12, 3);
lcd.print("MPOS ON");
digitalWrite(Mpos, HIGH);
delay(Maintimer);
}
void MposOff()
{
lcd.clear();
lcd.setCursor(12, 3);
lcd.print("MPOS OFF");
digitalWrite(Mpos, LOW);
delay(Maintimer);
}
void MCutOn()
{
lcd.clear();
lcd.setCursor(12, 2);
lcd.print("MCUT ON");
digitalWrite(Mcut, HIGH);
delay(Maintimer);
digitalWrite(Mcut, LOW);
delay(Maintimer);
}
void MCutOff()
{
lcd.clear();
lcd.setCursor(12, 2);
lcd.print("MCUT OFF");
digitalWrite(McutOff, HIGH);
delay(Maintimer);
digitalWrite(McutOff, LOW);
delay(Maintimer);
}
void Kopi() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DIADIKASIA KOPHS");
digitalWrite(Cutter, HIGH);
while (!digitalRead(Anixneusi))
{}
digitalWrite(Cutter, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("H KOPH TELEIWSE");
delay(Maintimer);
}
void finishedCutting() {
lcd.clear();
lcd.setCursor(7, 0);
lcd.print("H KOPH ");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
lcd.setCursor(13, 3);
lcd.print("EMPROS>");
delay(100);
}
void MaterialFinish() {
lcd.clear();
lcd.setCursor(7, 0);
lcd.print("TO YLIKO ");
lcd.setCursor(3, 1);
lcd.print("TELEIWSE");
lcd.setCursor(13, 3);
lcd.print("EMPROS>");
delay(100);
}
void displayNavigation() {
lcd.setCursor(0, 3);
lcd.print("<PISW");
lcd.setCursor(13, 3);
lcd.print("EMPROS>");
delay(200);
}