Dit is de samengestelde sketch:
//*************************************** VARIABLES & SETTINGS *****************************************
//*************************************** VARIABLES & SETTINGS *****************************************
#include <rotary.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#include <VarSpeedServo.h>
#include <Bounce2.h>
#include <Wire.h>
//Define the LCD screen & the Nema17 motor on TB6600
//LiquidCrystal_I2C lcd(0x27,20,4); // GREEN LCD ADDRESS TO 0x27 FOR A 20 CHARS. & 4 LINE DISPLAY
LiquidCrystal_I2C lcd(0x3F,20,4); // BLUE LCD ADDRESS TO 0x3F FOR A 20 CHARS. & 4 LINE DISPLAY
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);
//Define the pins & steps for the TB6600, Hall switch & toggle switches
#define dirPin 8 // TB6600 DRIVER
#define stepPin 9 // TB6600 DRIVER
#define enaPin 10 // TB6600 DRIVER
#define home_switch 12 // Pin 12 CONNECTED TO THE "HOME" SWITCH (Hall Switch)
#define pinPushCW 14 // PUSH SWITCH POSITION CW
#define pinPushCCW 15 // PUSH SWITCH POSITION CCW
#define switchResetZero 16 // MANUALY RESET TO ZERO SWITCH
#define LED 13 // PILOT-LED
#define stepsPerRevolution 3200 // NUMBER OF STEPS FOR 1 REVOLUTION -> TB6600 = OFF-OFF-ON-ON-ON-OFF
//Define rotary encoder pins
#define PINA 19
#define PINB 18
#define PUSHB 17
// SET PIN NUMBERS FOR THE DOORS AND THE WELDER LED
#define button1Pin 22
#define button2Pin 23
#define servo1Pin 3
#define servo2Pin 4
#define led1Pin 27 // PIN NUMBER FOR SIMULATED WELDER
#define led2Pin 28 // PIN NUMBER FOR SIMULATED WELDER
// Initialize the Rotary object
// Rotary Encoder Pin 1, Encoder Pin 2 & Button Pin. Attach center to ground
Rotary r = Rotary(PINA, PINB, PUSHB); // there is no must for using interrupt pins !!
int CursorLine = 1;
int DisplayFirstLine = 1;
int pd = 12000; // SET MOTOR SPEED FOR STEPPING DURING ZERO SEARCH (12000 = BEST RESULTS 300 = TESTS -> TOO LOW = OVERSHOOT)
// Initialise the array for the "Menu"
const int maxItemSize = 12; //longest menu item + one
char MenuLine[][maxItemSize] = {" Rail 1 CW", " Rail 1 CCW", " Rail 2 CW", " Rail 2 CCW", " Rail 3 CW", " Rail 3 CCW", " Reset HOME"};
int MenuItems = 7;
// Initialise the two dimensional array for the "Exits" - values determined via trial & error
int ExitPositions[3][2] = {//{CW, CCW}
{787, -2415}, // Exit nr1 - index 0
{2464, -740}, // Exit nr2 - index 1
{2595, -613} // Exit nr3 - index 2
};
boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;
boolean buttonZeropressed = false;
//---------------ITEMS AND CONTROLS----------------
// TIMING VARIABLES
unsigned long currentMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // use of milliseconds
bool button1State;
bool button2State;
bool button1StatePrev = 1;
bool button2StatePrev = 1;
bool button1WasPressed = 0;
bool button2WasPressed = 0;
// DEBOUNCING BUTTONS
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
// STATUS
enum { WAITING1, MOVING1} currentState1 = WAITING1;
enum { WAITING2, MOVING2} currentState2 = WAITING2;
//LED 1
int led1State = LOW; // STATUS OF LED 1 AT START
long previousMillis = 0; // STORAGE FOR LAST TIME LED 1 WAS UPDATED
long interval1; // INTERVAL AT WHICH TO BLINK (milliseconds) FOR LED 1
long onTime = 100;
long offTime = 200;
//LED 2
int led2State = LOW; // STATUS OF LED 2 AT START
long previousMillis2 = 0; // STORAGE FOR LAST TIME LED 2 WAS UPDATED
long interval2; // INTERVAL AT WHICH TO BLINK (milliseconds) FOR LED 2
long onTime2 = 75;
long offTime2 = 150;
//-----------ITEMS FOR SERVOS CONTROL-------------
VarSpeedServo theServo1;
byte servo1Pos = 0;
int servo1Pause = 1000;
int servo1Speed = 5;
unsigned long previousMillisServo1;
VarSpeedServo theServo2;
byte servo2Pos = 0;
int servo2Pause = 1000;
int servo2Speed = 5;
unsigned long previousMillisServo2;
//********************************************** SETUP *************************************************
//********************************************** SETUP *************************************************
void setup ()
{
//ROTARY ENCODER
digitalWrite (PINA, HIGH);
digitalWrite (PINB, HIGH);
digitalWrite (PUSHB, HIGH);
//DRIVER TB6600
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(enaPin,OUTPUT);
//PILOT-LED
pinMode(LED,OUTPUT);
//STEPMOTOR SETTINGS
stepper.setMaxSpeed(100); // maximum speed during rotation to target
stepper.setAcceleration(40); // acceleration speed for rotation to target
unsigned int setMinPulseWidth(20); // Sets the minimum pulse width in microseconds allowed by the stepper driver.
//BUTTONS AND SWITCHES
pinMode(pinPushCW, INPUT_PULLUP);
pinMode(pinPushCCW, INPUT_PULLUP);
pinMode(switchResetZero,INPUT_PULLUP);
pinMode(home_switch,INPUT);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(button1Pin, INPUT_PULLUP); //active low
pinMode(button2Pin, INPUT_PULLUP); //active low
debouncer1.attach(button1Pin);
debouncer2.attach(button2Pin);
debouncer1.interval(50);
debouncer2.interval(50);
//SERVOS
theServo1.write(servo1Pos,servo1Speed);
theServo1.attach(servo1Pin);
theServo2.write(servo2Pos,servo2Speed);
theServo2.attach(servo2Pin);
//INITIAL HOMING
Serial.begin(9600);
lcd.init();
lcd.backlight();
welcome();
homeFunction(); // perform the initial homing routine
lcd.clear();
delay(2000);
print_menu();
} // end of setup
//********************************************** LOOP **************************************************
//********************************************** LOOP **************************************************
void loop ()
{
currentMillis = millis();
readButtonDoor1();
readButtonDoor2();
readButtonsTurntable();
actOnButtonsTurnTable();
//++++++++++++++++++++++++ TURNTABLE LOOP ++++++++++++++++++++++++++++++
// readButtonsTurntable();
// actOnButtonsTurnTable();
volatile unsigned char result = r.process();
if (result == DIR_CCW) {
move_up();
print_menu();
} else if (result == DIR_CW) {
move_down();
print_menu();
}
if (r.buttonPressedReleased(25)) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Rotating to:");
lcd.setCursor(0, 2);
selection();
print_menu();
} //end if r.buttonPressedReleased
//++++++++++++++++++++++++ BARNDOORS LOOP ++++++++++++++++++++++++++++++
// readButtonDoor1();
// readButtonDoor2();
switch (currentState1)
{
case WAITING1:
//Serial.println("STATE WAITING");
servo1Pos = 30; // CONSIDER THIS AS BEING THE STARTING DEGREES OF THE SERVO 1
theServo1.write(servo1Pos,servo1Speed); // GO TO POSITION AT SLOW SPEED
if (button1WasPressed)
{
currentState1 = MOVING1;
}
break;
case MOVING1:
//Serial.println("STATE MOVING");
if (currentMillis - previousMillisServo1 >= servo1Pause) // TIME TO MOVE THE SERVO1
{
moveTheServo1();
}
if (button1WasPressed)
{
currentState1 = WAITING1;
}
break;
}
switch (currentState2)
{
case WAITING2:
//Serial.println("STATE WAITING");
servo2Pos = 30; // CONSIDER THIS AS BEING THE STARTING DEGREES OF THE SERVO 2
theServo2.write(servo2Pos,servo2Speed); // GO TO POSITION AT SLOW SPEED
if (button2WasPressed)
{
currentState2 = MOVING2;
}
break;
case MOVING2:
//Serial.println("STATE MOVING");
if (currentMillis - previousMillisServo2 >= servo2Pause) // TIME TO MOVE THE SERVO2
{
moveTheServo2();
}
if (button2WasPressed)
{
currentState2 = WAITING2;
}
break;
} // END "currentState" 1 & 2
{
if (((servo1Pos < 150) || (servo2Pos < 150)) && ((servo1Pos > 30) || (servo2Pos > 30))) // CHECK THE ANGLES OF BOTH SERVO WITH "WAITING1" & "WAITING2" FOR BLINKING LEDs
{
blinkLED1(); //START BLINKING LED 1
blinkLED2(); //START BLINKING LED 2
}
else if ((digitalRead(led1Pin) == HIGH) && (digitalRead(led2Pin) == HIGH)){
led1State = LOW;
led2State = LOW;
}
}
} //End loop()
//******************************************** FUNCTIONS MENU KY-040 ***********************************************
//******************************************** FUNCTIONS MENU KY-040 ***********************************************
void welcome()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" INITIALISING");
lcd.setCursor(0, 1);
lcd.print(" SYSTEM");
lcd.setCursor(0, 2);
lcd.print(" **************");
lcd.setCursor(0, 3);
lcd.print("Menu_OPS_Ver6 09/22");
delay(2000);
}//end welcome
void print_menu()
{
int n = 4; //4 rows
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" MAIN MENU ");
if (MenuItems == 1) { //if only 1 item
n = 2;
} else if (MenuItems == 2) { //if only 2 item
n = 3;
}
for (int i = 1; i < n; i++) // row 0 is used for title Main Menu
{
lcd.setCursor(1, i);
lcd.print(MenuLine[DisplayFirstLine + i - 2]);
}
lcd.setCursor(0, (CursorLine - DisplayFirstLine) + 1);
lcd.print("=");
lcd.setCursor(1, (CursorLine - DisplayFirstLine) + 1);
lcd.print(">");
} //end print_menu
void move_down()
{
if (CursorLine == (DisplayFirstLine + 3 - 1)) {
DisplayFirstLine++;
}
//If reached last item...roll over to first item
if (CursorLine == MenuItems) {
CursorLine = 1;
DisplayFirstLine = 1;
} else {
CursorLine = CursorLine + 1;
}
} //end move_down
void move_up()
{
if ((DisplayFirstLine == 1) & (CursorLine == 1)) {
if (MenuItems < 3) {
//Do nothing
} else {
DisplayFirstLine = MenuItems - 2;
}
} else if (DisplayFirstLine == CursorLine) {
DisplayFirstLine--;
}
if (CursorLine == 1) {
if (MenuItems < 3) {
//Do nothing
} else {
CursorLine = MenuItems; //roll over to last item
}
} else {
CursorLine = CursorLine - 1;
}
} //end move_up
void selection()
{
switch (CursorLine - 1) {
case 0:
lcd.print("Exit 1 CW ");
//set a flag or do something....
GoToCWExit1 ();
break;
case 1:
lcd.print("Exit 1 CCW ");
GoToCCWExit1 ();
break;
case 2:
lcd.print("Exit 2 CW ");
GoToCWExit2 ();
break;
case 3:
lcd.print("Exit 2 CCW ");
GoToCCWExit2 ();
break;
case 4:
lcd.print("Exit 3 CW ");
GoToCWExit3 ();
break;
case 5:
lcd.print("Exit 3 CCW ");
GoToCCWExit3 ();
break;
case 6:
lcd.print("Reset HOME ");
homeFunction();
break;
default:
break;
} //end switch
delay(2000);
DisplayFirstLine = 1;
CursorLine = 1;
} //End selection
//******************************************** FUNCTIONS STEPMOTOR ***********************************************
//******************************************** FUNCTIONS STEPMOTOR ***********************************************
void homeFunction() { //ONLY AT (RE)STARTUP OF ARDUINO
printGoingToHome ();
while (digitalRead(home_switch) == 1) { // ROTATE CW (== 1) UNTIL HOME POSITION REACHED
digitalWrite(dirPin, LOW); // LOW = CCW & HIGH = CW ROTATION
digitalWrite(stepPin, HIGH); // HIGH = START ROTATION TO ZERO POINT
delayMicroseconds (pd);
digitalWrite(stepPin, LOW); // LOW = STOP THE ROTATION
}
stepper.setCurrentPosition(0); // RECORD THIS POSITION AS BEING THE ZERO POINT
int Position = stepper.currentPosition(); // ASSIGN THE CURRENT (ZERO) POINT TO A VARIABLE "Position" BEFORE PRINTING
lcd.clear();
}
void powerOffMotor() {
digitalWrite(dirPin, LOW); // IF STEPPER GETS WARM – REPLACE LOW INTO HIGH
digitalWrite(stepPin, LOW); // IF STEPPER GETS WARM – REPLACE LOW INTO HIGH
digitalWrite(enaPin, HIGH);
}
void printGoingToHome (){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print (" ROTATING TO");
lcd.setCursor(0, 1);
lcd.print(" HOME");
lcd.setCursor(0, 2);
lcd.print(" ==============");
}
void readButtonsTurntable() {
buttonCCWpressed = false;
buttonCWpressed = false;
buttonZeropressed = false;
if (digitalRead(switchResetZero) == LOW) {
buttonZeropressed = true;
}
if (digitalRead(pinPushCW) == LOW) {
buttonCWpressed = true;
}
if (digitalRead(pinPushCCW) == LOW) {
buttonCCWpressed = true;
}
}
void actOnButtonsTurnTable() {
if (buttonZeropressed == true) {
homeFunction();
print_menu();
}
if (buttonCWpressed == true) {
digitalWrite(dirPin, LOW);
singleStep();
}
if (buttonCCWpressed == true) {
digitalWrite(dirPin, HIGH);
singleStep();
}
}
void singleStep() {
if (currentMillis - prevStepMillis >= millisBetweenSteps) {
prevStepMillis = currentMillis;
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}
}
//******************************************** FUNCTIONS TURNTABLE ***********************************************
//******************************************** FUNCTIONS TURNTABLE ***********************************************
//++++++++++++++++++++++++ EXIT 1 ++++++++++++++++++++++++++++++
void GoToCWExit1 () { // EXIT1 CW
stepper.moveTo (ExitPositions[0][0]); // NUMBER OF STEPS FROM ZERO TO EXIT IN CW
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 1 (CW)");
delay (2000);
lcd.clear();
}
void GoToCCWExit1 () { // EXIT1 CCW
stepper.moveTo (ExitPositions[0][1]); // NUMBER OF STEPS FROM ZERO TO EXIT IN CCW
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 1 (CCW)");
delay (2000);
lcd.clear();
}
//++++++++++++++++++++++++ EXIT 2 ++++++++++++++++++++++++++++++
void GoToCWExit2 () { // EXIT2 CW
stepper.moveTo (ExitPositions[1][0]);
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 2 (CW)");
delay (2000);
lcd.clear();
}
void GoToCCWExit2 () { // EXIT2 CCW
stepper.moveTo (ExitPositions[1][1]);
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 2 (CCW)");
delay (2000);
lcd.clear();
}
//++++++++++++++++++++++++ EXIT 3 ++++++++++++++++++++++++++++++
void GoToCWExit3 () { // EXIT3 CW
stepper.moveTo (ExitPositions[2][0]);
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 3 (CW)");
delay (2000);
lcd.clear();
}
void GoToCCWExit3 () { // EXIT3 CCW
stepper.moveTo (ExitPositions[2][1]);
stepper.runToPosition();
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("ARRIVED");
lcd.setCursor(2,1);
lcd.print("EXIT 3 (CCW)");
delay (2000);
lcd.clear();
}
//******************************************** FUNCTIONS BARNDOORS ***********************************************
//******************************************** FUNCTIONS BARNDOORS ***********************************************
void readButtonDoor1()
{
debouncer1.update();
button1State = debouncer1.read();
//button1State=digitalRead(buttonPin1); // USE THIS IF NOT USING DEBOUNCE
if (button1State != button1StatePrev) // BUTTON 1 CHANGED?
{
if (!button1State) // BUTTON 1 PRESSED = ACTIVE = LOW
{
button1WasPressed = 1; // TELL "currentState1" TO PERFORM THE "switch"
}
} // END changed
else // BUTTON 1 NOT CHANGED?
{
button1WasPressed = 0; // TELL "currentState1" TO not PERFORM THE "switch"
}
button1StatePrev = button1State;
} // END "readButtonDoor1"
void readButtonDoor2()
{
debouncer2.update();
button2State = debouncer2.read();
//button2State=digitalRead(buttonPin2); // USE THIS IF NOT USING DEBOUNCE
if (button2State != button2StatePrev) // BUTTON 2 CHANGED?
{
if (!button2State) // BUTTON 2 PRESSED = ACTIVE = LOW
{
button2WasPressed = 1; // TELL "currentState2" TO PERFORM THE "switch"
}
} // END changed
else // BUTTON 2 NOT CHANGED?
{
button2WasPressed = 0; // TELL "currentState2" TO not PERFORM THE "switch"
}
button2StatePrev = button2State;
} // END "readButtonDoor2"
void moveTheServo1()
{
Serial.print("moving the servo 1 to ");
bool newMove=true; // OTHERWISE SERVO1 WILL DO THE MOVES ALL THE TIME
if (servo1Pos == 30 && newMove) // DO NOT EXCLUDE THIS PART = DEGREES IN "WAITING1"
{
servo1Pos = 150; // INPUT THE MAX POSITION FOR SERVO 1
newMove=false;
}
Serial.println(servo1Pos);
theServo1.write(servo1Pos,servo1Speed); // GO TO POSITION AT SLOW SPEED
previousMillisServo1 = currentMillis;
} // END "moveTheServo1"
void moveTheServo2()
{
Serial.print("moving the servo 2 to ");
bool newMove=true; // OTHERWISE SERVO2 WILL DO THE MOVES ALL THE TIME
if (servo2Pos == 30 && newMove) // DO NOT EXCLUDE THIS PART = DEGREES IN "WAITING2"
{
servo2Pos = 150; // INPUT THE MAX POSITION FOR SERVO 2
newMove=false;
}
Serial.println(servo2Pos);
theServo2.write(servo2Pos,servo2Speed); // GO TO POSITION AT SLOW SPEED
previousMillisServo2 = currentMillis;
} // END "moveTheServo2"
void blinkLED1()
{
// check to see if it's time to blink the LED; that is, if the difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval1) {
// SAVE THE LAST TIME LED 1 BLINKED
previousMillis = currentMillis;
// IF LED 1 IS OFF, TURN IT ON AND VICE-VERSA
if (led1State == LOW)
{
led1State = HIGH;
interval1 = onTime;
}
else
{
led1State = LOW;
interval1 = offTime;
}
// SET THE LED 1 WITH THE "led1State" VALUE OF THE VARIABLE
digitalWrite(led1Pin, led1State);
}
}
// END OF blinkLED1()
//-----------------------------------------------
//-----------------------------------------------
void blinkLED2()
{
// check to see if it's time to blink the LED; that is, if the difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to blink the LED.
unsigned long currentMillis2 = millis();
if (currentMillis2 - previousMillis2 > interval2) {
// SAVE THE LAST TIME LED 2 BLINKED
previousMillis2 = currentMillis2;
// IF LED 2 IS OFF, TURN IT ON AND VICE-VERSA
if (led2State == LOW)
{
led2State = HIGH;
interval2 = onTime2;
}
else
{
led2State = LOW;
interval2 = offTime2;
}
// SET THE LED 2 WITH THE "led1State" VALUE OF THE VARIABLE
digitalWrite(led2Pin, led2State);
}
}
// END OF blinkLED2()