Κώδικας:
/* Arduino Control Stepper with Keyboard and LCD
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> // AccelStepper Library
#include <PS2Keyboard.h> // Keyboard Library
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "pitches.h" //notes file
#include "Signal_bar.h"
// Variables to hold entered number on Keypad
volatile int firstnumber=99; // used to tell how many numbers were entered on keypad(Χρησιμοποιούνται για να ορίσουν πόσα νούμερα θα εισαχθούν απο το πληλτρολόγιο)
volatile int secondnumber=99;
volatile int thirdnumber=99;
volatile int fourthnumber=99;
// Variables to hold Distance and CurrentPosition
int keyfullnumber=0; // used to store the final calculated distance value
String currentposition = ""; // Used for display on LCD
//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 Setup
AccelStepper stepper(1, A0, A1); // 1 = Easy Driver interface
// Arduino A0 connected to STEP pin of Easy Driver
// Arduino A1 connected to DIR pin of Easy Driver
const int SleepLed = 48; // <======= the number of the LED when Easy Driver go to SLEEP
const int RedLed = 9; // <======= the number of the LED RED pin
const int GreenLed = 8; // <======= the number of the LED GREEN pin
const int ledPin = 13;
//int step_speed = 2; // Speed of Stepper motor (higher = slower)on Homing mode
int buttonPin =12 ; //START HOMING BUTTON
boolean buttonState = LOW;
boolean previousButtonState = LOW;
int LimitSwitch = 4; // LIMIT SWITCH PIN
int Home_Switch=3; // HOME SWITCH
int stop = false;
volatile int Emergency_Button = 2; // INTERRUPT BUTTON
int state ;
int x;
#define step_pin A0 // Pin A0connected to Steps pin on EasyDriver
#define dir_pin A1 // Pin A1 connected to Direction pin
#define ENB 4 // Pin 7 connected to ENBL-,DIR-,STEP-
const int SLEEP = 4; // Pin 4 connected to SLEEP pin
int SLEEPState = LOW; //SLEEPState used to set the SLEEP on easy driver
unsigned long previousMillis = 0; // will store last time SLEEP-wake was updated
// constants won't change :
const long interval = 50000; // interval at which to SLEEP (milliseconds)
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display/adress for proteus 0x3F
const int sol = 10; //pin for solenoid
const int DataPin = 18; //Keyboard pin
const int IRQpin = 19; //Keyboard pin
PS2Keyboard keyboard;
void setup(void) {
keyboard.begin(DataPin, IRQpin);
Serial.begin(9600);
pinMode(LimitSwitch , INPUT);
pinMode(12,INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(A1, OUTPUT);
pinMode(A0, OUTPUT);
pinMode(SLEEP, OUTPUT);
pinMode(RedLed, OUTPUT);
pinMode(GreenLed, OUTPUT);
pinMode(SleepLed, OUTPUT);
pinMode(ENB, OUTPUT);
buttonState = digitalRead(12);
pinMode(13, OUTPUT);
pinMode(sol, OUTPUT);
lcd.begin(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("!START HOMMING!");
lcd.setCursor(4,1);
lcd.print("PLEASE PRESS");
lcd.setCursor(1,2);
lcd.print("! HOME [*] BUTTON !");
lcd.setCursor(2,3);
lcd.print("Power Need Homming");
lcd.blink();
delay(500);
digitalWrite(SLEEP,HIGH);
digitalWrite(sol,LOW);
unsigned long currentMillis = millis();
SLEEPState = HIGH;
previousMillis = currentMillis;
digitalWrite(SLEEP, SLEEPState); // Update the actual Sleep
delay(5); // Wait for EasyDriver wake up
pinMode (ledPin, OUTPUT);
pinMode (Emergency_Button, INPUT_PULLUP);
digitalWrite (Emergency_Button,HIGH);
attachInterrupt (0, switchPressed, LOW); // see https://www.arduino.cc/en/Main/ArduinoBoardMega2560 for No of pins(it's first No,here is 0-pin 2)
// External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2).
// These pins can be configured to trigger an interrupt on a low level, a rising or falling edge, or a change in level.
keyboard.begin(DataPin, IRQpin);
state=3; //state to run void Home
}
void loop(){
if(x == 1)
{
lcd.backlight();
lcd.setCursor(2,0);
lcd.print("ENTER DISTANCE");
lcd.setCursor(2,1);
lcd.print( "MM==>");
lcd.setCursor(0,2);
lcd.print("------------------");
lcd.setCursor(0,3);
lcd.print("cur-pos");
lcd.setCursor(8,3);
lcd.print(currentposition);
}
//SLEEP Mode with time (miliseconds)
// check to see if it's time to SLEEP; that is, if the
// difference between the current time and last time you WAKEUP
// the EASY DRIVER is bigger than the interval at which you want to stay wakeup
unsigned long currentMillis = millis();
if ((SLEEPState == HIGH)&& (currentMillis - previousMillis >= interval)) {
// save the last time you wakeup the easy driver
// if the sleep is on turn it off
{
SLEEPState = LOW;
previousMillis = currentMillis;
digitalWrite(SLEEP, SLEEPState); // Update the actual Sleep
digitalWrite(RedLed, HIGH); // turn the LED RED on (HIGH is the voltage level) ledSleeep
digitalWrite(SleepLed, HIGH);
}
}
if (keyboard.available()) {
// read the next key
char c = keyboard.read(); // Get value of keyboard (numeric) button if pressed
switch (c){
case '1':
checknumber(1);
break;
case '2':
checknumber(2);
break;
case '3':
checknumber(3);
break;
case '4':
checknumber(4);
break;
case '5':
checknumber(5);
break;
case '6':
checknumber(6);
break;
case '7':
checknumber(7);
break;
case '8':
checknumber(8);
break;
case '9':
checknumber(9);
break;
case '0':
checknumber(0);
break;
case '.':
deletenumber();
break;
case '*':
home();
break;
case '#':
calculatedistance();
break;
}
// check for some of the special keys
if (c == PS2_ENTER) {
unsigned long currentMillis = millis();
SLEEPState = HIGH;
previousMillis = currentMillis;
digitalWrite(SLEEP, SLEEPState); // Update the actual Sleep
delay(5); // Wait for EasyDriver wake up
digitalWrite(SleepLed, LOW);
digitalWrite(RedLed, LOW);
calculatedistance();
Serial.println();
}
}
}
void home() {
if(state == 3){
lcd.begin(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("START HOMMING!");
lcd.setCursor(1,1);
lcd.print("");
lcd.setCursor(4,2);
lcd.print("W A I T");
stepper.setMaxSpeed(600.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepper.setAcceleration(100.0); // Set Acceleration of Stepper
digitalWrite(sol, HIGH);
while (digitalRead(Home_Switch)) { // Make the Stepper move CCW until the switch is activated
digitalWrite(RedLed, HIGH);
stepper.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepper.run(); // Start moving the stepper
digitalWrite(RedLed, HIGH);
delay(5);
}
stepper.setCurrentPosition(0); // Set the current position as zero for now
stepper.setMaxSpeed(600.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepper.setAcceleration(100.0); // Set Acceleration of Stepper
initial_homing=1;
while (!digitalRead(Home_Switch)) { // Make the Stepper move CW until the switch is deactivated
stepper.moveTo(initial_homing);
stepper.run();
initial_homing++;
digitalWrite(RedLed, LOW);
digitalWrite(GreenLed, HIGH);
}
delay(10);
digitalWrite(sol, LOW);
stepper.setCurrentPosition(300);
currentposition="300";
state=0;
// Draw starting screen on LCD
lcd.begin(); // initialize the lcd
lcd.clear();
lcd.backlight();
lcd.setCursor(3,0);
lcd.print("HOMMING COMPLETE");
lcd.setCursor(3,1);
lcd.print("cur-pos: ");
lcd.setCursor(12 , 1);
lcd.print(currentposition);
lcd.setCursor(3,2);
lcd.print("PLEASE WAIT:");
lcd.clear();
// AccelStepper speed and acceleration setup
stepper.setMaxSpeed(1200); // Not to fast or you will have missed steps
stepper.setAcceleration(150); // Same here
lcd.backlight();
lcd.setCursor(2,0);
lcd.print("ENTER DISTANCE");
lcd.setCursor(2,1);
lcd.print( "MM==>");
lcd.setCursor(0,2);
lcd.print("------------------");
lcd.setCursor(0,3);
lcd.print("cur-pos");
lcd.setCursor(8,3);
lcd.print(currentposition);
}
x=1;
}
void checknumber(int x){
if (firstnumber == 99) { // Check if this is the first number entered
firstnumber=x;
String displayvalue = String(firstnumber); // Transform int to a string for display
lcd.setCursor(8,1);
lcd.print(displayvalue);
} else {
if (secondnumber == 99) { // Check if it's the second number entered
secondnumber=x;
String displayvalue = (String(firstnumber) + String(secondnumber));
lcd.setCursor(8,1);
lcd.print(displayvalue);
} else {
if (thirdnumber == 99) { // Check if it's the third number entered
thirdnumber=x;
String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber));
lcd.setCursor(8,1);
lcd.print(displayvalue);
} else { // It must be the 4rd number entered
if(fourthnumber==99){
fourthnumber=x;
String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber)+ String(fourthnumber));
lcd.setCursor(8,1);
lcd.print(displayvalue);
}
}
}
}
}
void deletenumber() { // Used to backspace entered numbers
if (fourthnumber !=99) {
String displaynumber = (String(firstnumber) + String(secondnumber) + String(thirdnumber));
lcd.clear();
lcd.setCursor(8,1);
lcd.print(displaynumber);
fourthnumber=99;
}
else
if (thirdnumber !=99) {
String displaynumber = (String(firstnumber) + String(secondnumber));
lcd.clear();
lcd.setCursor(8,1);
lcd.print(displaynumber);
thirdnumber=99;
}
else {
if (secondnumber !=99) {
String displaynumber = String(firstnumber);
lcd.clear();
lcd.setCursor(8,1);
lcd.print(displaynumber);
secondnumber=99;
}
else {
if (firstnumber !=99) {
String displaynumber = "";
lcd.clear();
lcd.setCursor(8,1);
lcd.print(displaynumber);
firstnumber=99;
}
}
}
}
void calculatedistance() { // Used to create a full number from entered numbers
if (fourthnumber == 99 && thirdnumber == 99 && secondnumber == 99 && firstnumber != 99 ) {
keyfullnumber=firstnumber;
movestepper(keyfullnumber);
}
if (secondnumber != 99 && thirdnumber == 99 && fourthnumber== 99) {
keyfullnumber=(firstnumber*10)+secondnumber;
movestepper(keyfullnumber);
}
if (thirdnumber != 99 && fourthnumber==99) {
keyfullnumber=(firstnumber*100)+(secondnumber*10)+thirdnumber;
movestepper(keyfullnumber);
}
if (fourthnumber != 99) {
keyfullnumber=(firstnumber*1000)+(secondnumber*100)+(thirdnumber*10)+fourthnumber;
movestepper(keyfullnumber);
}
resetnumbers(); // Reset numbers to get ready for new entry
}
void movestepper(int z) {
// Move the stepper
if(keyfullnumber > 3950 || keyfullnumber < 0){ //set the maximum and minimum distance
stepper.stop();
digitalWrite(RedLed, HIGH);
lcd.clear();
delay(5);
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("OVER LIMITS DISTANCE");
lcd.setCursor(1,3);
lcd.print("ENTER NEW DISTANCE");
lcd.setCursor(0,2);
lcd.print("");
lcd.setCursor(2,3);
lcd.print("");
delay(1000);
lcd.clear();
}
else {
long calculatedmove=((z*1600L)/80); // Calculate number of steps needed in mm
stepper.runToNewPosition(calculatedmove);
currentposition = String(z);
lcd.clear();
lcd.backlight();
lcd.setCursor(2,0);
lcd.print("ENTER DISTANCE");
lcd.setCursor(2,1);
lcd.print( "MM");
lcd.setCursor(0,2);
lcd.print("cur-pos");
lcd.setCursor(8,2);
lcd.print(currentposition);
lcd.clear();
}
}
void resetnumbers() { // Reset numbers for next entry
firstnumber=99;
secondnumber=99;
thirdnumber=99;
fourthnumber=99;
}
void drawlcdscreen(String y)
{
lcd.backlight();
lcd.setCursor(2,0);
lcd.print("ENTER DISTANCE");
lcd.setCursor(2,1);
lcd.print( "MM )");
lcd.setCursor(5,1);
lcd.print( y);
lcd.setCursor(2,3);
lcd.print("cur-pos");
lcd.setCursor(8,3);
lcd.print(currentposition);
lcd.clear();
}
// Interrupt Service Routine (ISR)
void switchPressed () //STOP ALL AS EMERGENCY STOP BUT NEEED RESTART
{
stepper.setSpeed(0);
}
void printHome(){
lcd.begin(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0,0);
lcd.print(" HOMMING IN PROGRES");
lcd.setCursor(1,1);
lcd.print("");
lcd.setCursor(4,2);
lcd.print("PLEASE W A I T");
}