//------------------------------- 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 = 2500;
int Maintimer =2500;
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;
int previousWireLength = 0.0;
int previousWireQuantity = 0;
float mmPerStep = 0.003125;
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(500.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(100);
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;
}
/*else if ((key != NO_KEY ))
{
// Handle '*' key press (back)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press C to Home");
}
else if (key != (isdigit(key) ))
{
// Handle '*' key press (back)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Press D to Home");
}*/
}
void chooseWireQuantity(){
wireQuantity = changeValue(wireQuantity);
//clear LCD if required
if(previousWireQuantity != wireQuantity){
lcd.clear();
previousWireQuantity = wireQuantity;
}
//Display information on LCD
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
}
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 chooseWireLength() {
static String inputBuffer = ""; // Buffer to store user input
// Handle keypad input
char key = keypad.getKey();
if (key == NO_KEY) {
if (key != '#') {
// Use the '*' key to confirm the input and set the wire length
if (inputBuffer.length() > 0) {
// Convert the inputBuffer to a float
wireLength = inputBuffer.toInt();
inputBuffer = ""; // Clear the input buffer
lcd.clear(); // Clear the LCD
displayNavigation();
}
} else if (key != '*') {
// Use the '#' key to clear the input
inputBuffer = "";
lcd.clear();
displayNavigation();
} else if (isdigit(key) && inputBuffer.length() < 6) {
// Allow only digits and limit input to 6 characters
inputBuffer += key;
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + inputBuffer + "mm"); // Display the input
lcd.setCursor(0, 1);
lcd.print("<BACK *CONFIRM>");
}
}
else {
lcd.setCursor(0, 0);
lcd.print("MHKOS: " + inputBuffer + "mm"); // Display the input
lcd.setCursor(0, 1);
lcd.print("<BACK *CONFIRM>");
}
}
void handleQuantityInput() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("POSOTHTA:" + (String)wireQuantity);
displayNavigation();
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(){
int stepsToTake = wireLength/mmPerStep;
MCutOn();
delay(Maintimer);
MposOff();
delay(Maintimer);
//Metakinisi stin epithimiti thesi
lcd.setCursor(3, 0);
lcd.print("METAKINHSH");
stepperX.runToNewPosition(stepsToTake);
delay(Maintimer);
for(int i = 0; i < wireQuantity; i++){
if(!digitalRead(Anixneusi))
{
break;
}
MposOn();
delay(Maintimer);
MCutOff();
delay(Maintimer);
stepperX.runToNewPosition(0);
unsigned long timeForOneCycle = millis();
/* digitalWrite(dirPin,HIGH);
for(int x = 0; x < stepsToTake; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(200);
digitalWrite(stepPin,LOW);
delayMicroseconds(200);
}*/
// Oloklirwsi metakinhshs
lcd.setCursor(3, 0);
lcd.print("H METAKINHSH");
lcd.setCursor(3, 1);
lcd.print("OLOKLIROTHIKE");
delay(Maintimer);
MCutOn();
delay(Maintimer);
MposOff();
delay(Maintimer);
delay(Maintimer);
stepperX.runToNewPosition(stepsToTake);
/* int stepsToTake = (float)wireLength/mmPerStep;
digitalWrite(dirPin,LOW);
for(int x = 0; x < stepsToTake; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(200);
digitalWrite(stepPin,LOW);
delayMicroseconds(200);
}
*/
lcd.clear();
lcd.setCursor(0,0);
lcd.print("DIADIKASIA KOPHS");
digitalWrite(Cutter,HIGH);
delay(cuttime);
digitalWrite(Cutter,LOW);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("H KOPH TELEIWSE");
delay(Maintimer);
lcd.setCursor(12, 2);
lcd.print("MCUT OFF");
digitalWrite(Mcut,LOW);
delayMicroseconds(positiontime);
lcd.setCursor(12,3);
lcd.print("MPOS ON");
digitalWrite(Mpos,HIGH);
delay(positiontime);
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 ");
// snippers.write(closedAngle);
}
wireLength = 0;
wireQuantity = 0;
state = 5;
}
void MposOn()
{
lcd.setCursor(12,3);
lcd.print("MPOS ON");
digitalWrite(Mpos,HIGH);
}
void MposOff()
{
lcd.setCursor(12,3);
lcd.print("MPOS OFF");
digitalWrite(Mpos,LOW);
}
void MCutOn()
{
lcd.setCursor(12,2);
lcd.print("MCUT ON");
digitalWrite(Mcut,HIGH);
delayMicroseconds(2000);
digitalWrite(Mcut,LOW);
}
void MCutOff()
{
lcd.setCursor(12,2);
lcd.print("MCUT OFF");
digitalWrite(McutOff,HIGH);
delayMicroseconds(2000);
digitalWrite(McutOff,LOW);
}
void Kopi() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DIADIKASIA KOPHS");
digitalWrite(Cutter, HIGH);
delay(cuttime);
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);
}
float changeValue(float currentValue){
if (ButtonState == UP) {
currentValue ++;
incrementSpeed =1;
}
if (ButtonState == START) {
currentValue = currentValue+0.1;
incrementSpeed =10;
}
if (ButtonState == DOWN) {
if(currentValue - incrementSpeed >= 0){
currentValue -= incrementSpeed;
incrementSpeed =1;
}
else{
currentValue = 0;
}
}
return currentValue;
}
void displayNavigation(){
lcd.setCursor(0, 3);
lcd.print("<PISW");
lcd.setCursor(13, 3);
lcd.print("EMPROS>");
delay(50);
}
/* Motor Homing code using AccelStepper and the Serial Monitor
Created by Yvan / https://Brainy-Bits.com
This code is in the public domain...
You can: copy it, use it, modify it, share it or just plain ignore it!
Thx!
#include "AccelStepper.h"
// Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/
// AccelStepper Setup
AccelStepper stepperX( 1, 3, 2); // 1 = Easy Driver interface
// NANO Pin 2 connected to STEP pin of Easy Driver
// NANO Pin 3 connected to DIR pin of Easy Driver
// Define the Pins used
#define home_switch 5 // Pin 9 connected to Home Switch (MicroSwitch)
#define enablePin 4
// Stepper Travel ariables
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
void setup() {
Serial.begin(9600); // Start the Serial monitor with speed of 9600 Bauds
pinMode(enablePin,OUTPUT);
pinMode(home_switch, INPUT_PULLUP);
delay(5); // Wait for EasyDriver wake up
// Set Max Speed and Acceleration of each Steppers at startup for homing
stepperX.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(100.0); // Set Acceleration of Stepper
// Start Homing procedure of Stepper Motor at startup
Serial.print("Stepper is Homing . . . . . . . . . . . ");
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);
}
stepperX.setCurrentPosition(0); // Set the current position as zero for now
stepperX.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(100.0); // Set Acceleration of Stepper
initial_homing=1;
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);
Serial.println("Homing Completed");
Serial.println("");
stepperX.setMaxSpeed(1000.0); // Set Max Speed of Stepper (Faster for regular movements)
stepperX.setAcceleration(1000.0); // Set Acceleration of Stepper
// Print out Instructions on the Serial Monitor at Start
Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
}
void loop() {
while (Serial.available()>0) { // Check if values are available in the Serial Buffer
move_finished=0; // Set variable for checking move of the Stepper
TravelX= Serial.parseInt(); // Put numeric value from buffer in TravelX variable
if (TravelX < 0 || TravelX > 1350) { // Make sure the position entered is not beyond the HOME or MAX position
Serial.println("");
Serial.println("Please enter a value greater than zero and smaller or equal to 1350.....");
Serial.println("");
} else {
Serial.print("Moving stepper into position: ");
Serial.println(TravelX);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
delay(1000); // Wait 1 seconds before moving the Stepper
}
}
if (TravelX >= 0 && TravelX <= 1350) {
// Check if the Stepper has reached desired position
if ((stepperX.distanceToGo() != 0)) {
stepperX.run(); // Move Stepper into position
}
// If move is completed display message on Serial Monitor
if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
Serial.println("COMPLETED!");
Serial.println("");
Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
move_finished=1; // Reset move variable
}
}
}
*/