//******************************************************************************************************************************
// K40 MotoLift Table Sketch for Arduino nano and A4988 Stepper-Driver
// created by SnakeP
// Version 2.0 BETA (OLED included)
// 31.01.2021
//******************************************************************************************************************************
//************************Benoetigte Bibliotheken (müssen vor dem Compilieren eingebunden werden!)******************************
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
//******************************************************************************************************************************
Adafruit_SSD1306 display(5);
// Zuordnung der E/As
#define ENA 2 //Enable
#define STP 3 //Steps
#define DIR 4 //Direction
#define MS1 5 //MS1 an Treiber
#define MS2 6 //MS2 an Treiber
#define MS3 7 //MS3 an Treiber
#define STPD 8 //Endschalter Down
#define UP01 9 //Eingang Aufwaerts 0,1mm
#define UP1 10 //Eingang Aufwaerts 1mm / Dauerbetrieb
#define DOWN01 11 //Eingang Abwaerts 0,1mm
#define DOWN1 12 //Eingang Abwaerts 1mm / Dauerbetrieb
#define COUNTERRESET 13 //Nullenstellen der OLED-Anzeige
bool bUP1 = LOW; //Merker Aufwaerts 1mm aktiv
bool bUP01 = LOW; //Merker Aufwaerts 0,1mm aktiv
bool bDOWN1 = LOW; //Merker Abwaerts 1mm aktiv
bool bDOWN01 = LOW; //Merker Abwaerts 0,1mm aktiv
float poscount = 0; //Merker fuer OLED-Anzeige
float poscount_cont_up = 0;
float poscount_cont_up_mm = 0;
float poscount_cont_down = 0;
float poscount_cont_down_mm = 0;
//********************************************************************************************************************************************************
//Hilfsmerker Zaehler (Diese Kennzahlen individuell befuellen!)
int steps_01 = 20; //Hier ausgemessene Anzahl Steps fuer 0,1mm Fahrt eintragen
int steps_1 = 200; //Hier ausgemessene Anzahl Steps fuer 1mm Fahrt
int stepperspeed_l = 500; //Delay Stepperschritte in Microsekunden (Einstellung Steppergeschwindigkeit) langsame Einzelstep-Fahrt
int stepperspeed_h = 250; //Delay Stepperschritte in Microsekunden (Einstellung Steppergeschwindigkeit) schnelle Dauerfahrt
int dec_continious = 1000; //Delay fuer Start Dauerfahrt
bool bPosHold = LOW; //Dauerhafter Haltestrom fuer Stepper (Positionshaltung) HIGH = ein / LOW = aus
//********************************************************************************************************************************************************
void setup() {
// put your setup code here, to run once:
lcd.init();
lcd.backlight();
display.begin(SSD1306_SWITCHCAPVCC, 60);
// Definition der E/As
pinMode(ENA, OUTPUT);
pinMode(STP, OUTPUT);
pinMode(DIR, OUTPUT);
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(MS3, OUTPUT);
pinMode(UP01, INPUT);
pinMode(UP1, INPUT);
pinMode(DOWN01, INPUT);
pinMode(DOWN1, INPUT);
pinMode(STPD, INPUT);
pinMode(COUNTERRESET, INPUT);
digitalWrite(ENA, HIGH); // Motor Enable (EIN)
//********************************************************************************************************************************************************
//Arbeitsmodus (Microsteps) Einstellung der Treiberstufe (Default 1/8 Step):
digitalWrite(MS1, HIGH); // Einstellung Microsteps A4988:
digitalWrite(MS2, HIGH); // MS1 MS2 MS3
digitalWrite(MS3, LOW); // L L L 1/1 Step
// H L L 1/2 Step
// L H L 1/4 Step
// H H L 1/8 Step
// H H H 1/16 Step
//********************************************************************************************************************************************************
}
void loop() {
// put your main code here, to run repeatedly:
display.clearDisplay(); //Ansteuerung OLED-Display
display.fillRect(0, 0, 127, 63, WHITE);
display.fillRect(3, 3, 121, 57, BLACK);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(11, 10);
display.println("K40 MotoLift-Table");
lcd.setCursor(0, 0);
lcd.print("K40 MotoLift-Table");
("K40 MotoLift-Table");
display.setCursor(18, 20);
display.setTextSize(2);
lcd.setCursor(2, 2);
lcd.print("pozicija");
display.println ("Position");
display.setCursor(45, 40);
display.println (poscount, 1);
display.display();
bUP01 = digitalRead(UP01); //Abfrage Eingang UP01, setzen Merker fuer Abarbeitung
bUP1 = digitalRead(UP1); //Abfrage Eingang UP1, setzen Merker fuer Abarbeitung
bDOWN01 = digitalRead(DOWN01); //Abfrage Eingang DOWN01, setzen Merker fuer Abarbeitung
bDOWN1 = digitalRead(DOWN1); //Abfrage Eingang DOWN1, setzen Merker fuer Abarbeitung
if (digitalRead(COUNTERRESET) == HIGH) {
poscount = 0;
}
if (bPosHold == HIGH) {
digitalWrite(ENA, LOW);
}
if (bDOWN01 == HIGH && !digitalRead(STPD)) { //wenn Down 0,1mm aktiv und Endschalter unten nicht belegt, dann
digitalWrite(ENA, LOW); //Stepper EIN
for (int index = 0; index <= steps_01; index = index + 1) //Anzahl der Schleifenwiederholungen/Schritte fuer 0,1mm Down
{
digitalWrite(DIR, HIGH); //langsame Einzelstep-Fahrt DOWN 0,1mm pro Tastendruck
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_l);
digitalWrite(DIR, HIGH);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_l);
}
while (digitalRead(DOWN01) == HIGH) { //Vereinzelung je Tastendruck DOWN, wait for DOWN01 == LOW
delay (100);
}
if (bPosHold == LOW) {
digitalWrite(ENA, HIGH); //Stepper AUS wenn Haltestrom nicht angewaehlt
}
poscount = poscount - 0.1;
}
if (bDOWN1 == HIGH && !digitalRead(STPD)) { //wenn Down 1mm aktiv und Endschalter unten nicht belegt, dann
digitalWrite(ENA, LOW); //Stepper EIN
for (int index = 0; index <= steps_1; index = index + 1) //Anzahl der Schleifenwiederholungen/Schritte fuer 1mm Down
{
digitalWrite(DIR, HIGH); //langsame Einzelstep-Fahrt DOWN 1mm pro Tastendruck
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_l);
digitalWrite(DIR, HIGH);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_l);
}
while ((digitalRead(DOWN1)) && !(digitalRead(STPD))) { //wait for DOWN1 == LOW oder Dauerfahrt DOWN nach Verzoegerung
delay (dec_continious);
display.fillRect(0, 0, 127, 63, WHITE); // OLED Displayanzeige FAST-DOWN
display.setTextColor(BLACK);
display.setCursor(10, 40);
display.display();
do {
digitalWrite(DIR, HIGH); //schnelle Dauerfahrt DOWN solange DOWN-Taste gedrueckt bleibt und Endschalter unten nicht betaetigt ist
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_h);
digitalWrite(DIR, HIGH);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_h);
poscount_cont_down = poscount_cont_down + 1; //Inkrementieren Positionscounter Dauerfahrt DOWN
} while ((digitalRead(DOWN1)) && !(digitalRead(STPD)));
poscount_cont_down_mm = poscount_cont_down / steps_1; //Umrechnen Positionscounter Dauerfahrt DOWN in mm
poscount_cont_down = 0; //Reset Positionscounter Dauerfahrt DOWN
}
if (bPosHold == LOW) {
digitalWrite(ENA, HIGH); //Stepper AUS wenn Haltestrom nicht angewaehlt
}
if (poscount_cont_down_mm != 0) { //Beschreiben Positionscounter global mit aktuellem Wert aus Dauerfahrt
poscount = ((poscount - 1) - poscount_cont_down_mm);
poscount_cont_down_mm = 0;
}
else { //Beschreiben Positionscounter global mit aktuellem Wert bei Einzelfahrt
poscount = poscount - 1;
}
}
if (bUP01 == HIGH) { //wenn Up 0,1mm aktiv, dann
digitalWrite(ENA, LOW); //Stepper EIN
for (int index = 0; index <= steps_01; index = index + 1) //Anzahl der Schleifenwiederholungen/Schritte fuer 0,1mm Up
{
digitalWrite(DIR, LOW); //langsame Einzelstep-Fahrt UP 0,1mm pro Tastendruck
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_l);
digitalWrite(DIR, LOW);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_l);
}
while (digitalRead(UP01) == HIGH) { //Vereinzelung je Tastendruck UP, wait for UP01 == LOW
delay (100);
}
if (bPosHold == LOW) {
digitalWrite(ENA, HIGH); //Stepper AUS wenn Haltestrom nicht angewaehlt
}
poscount = poscount + 0.1;
}
if (bUP1 == HIGH) { //wenn Up 1mm aktiv, dann
digitalWrite(ENA, LOW); //Stepper EIN
for (int index = 0; index <= steps_1; index = index + 1) //Anzahl der Schleifenwiederholungen/Schritte fuer 1mm Up
{
digitalWrite(DIR, LOW); //langsame Einzelstep-Fahrt UP 1mm pro Tastendruck
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_l);
digitalWrite(DIR, LOW);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_l);
}
while (digitalRead(UP1) == HIGH) { //wait for UP1 == LOW oder Dauerfahrt UP nach Verzoegerung
delay (dec_continious);
display.fillRect(0, 0, 127, 63, WHITE); // OLED Displayanzeige FAST-UP
display.setTextColor(BLACK);
display.setCursor(25, 10);
lcd.setCursor(0, 0);
lcd.clear();
lcd.print("Fast UP");
display.println("FAST-UP");
display.display();
do {
digitalWrite(DIR, LOW); //schnelle Dauerfahrt UP solange UP-Taste gedrueckt bleibt
digitalWrite(STP, HIGH);
delayMicroseconds(stepperspeed_h);
digitalWrite(DIR, LOW);
digitalWrite(STP, LOW);
delayMicroseconds(stepperspeed_h);
poscount_cont_up = poscount_cont_up + 1; //Inkrementieren Positionscounter Dauerfahrt UP
} while (digitalRead(UP1));
poscount_cont_up_mm = poscount_cont_up / steps_1; //Umrechnen Positionscounter Dauerfahrt UP in mm
poscount_cont_up = 0; //Reset Positionscounter Dauerfahrt UP
}
if (poscount_cont_up_mm != 0) { //Beschreiben Positionscounter global mit aktuellem Wert aus Dauerfahrt
poscount = ((poscount + 1) + poscount_cont_up_mm);
poscount_cont_up_mm = 0;
}
else { //Beschreiben Positionscounter global mit aktuellem Wert bei Einzelfahrt
poscount = poscount + 1;
}
}
if (bPosHold == LOW) {
digitalWrite(ENA, HIGH); //Stepper AUS wenn Haltestrom nicht angewaehlt
}
}