Compare commits

...

3 Commits

8 changed files with 1024 additions and 65 deletions

5
Seilbahn/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
Seilbahn/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

37
Seilbahn/include/README Normal file
View File

@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
Seilbahn/lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

14
Seilbahn/platformio.ini Normal file
View File

@ -0,0 +1,14 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino

668
Seilbahn/src/main.cpp Normal file
View File

@ -0,0 +1,668 @@
#include <Arduino.h>
//Pindefinitionen
#define LED_ANLAGE_EIN_AUS 2
#define KNOPF_ANLAGE_EIN_AUS 3
#define LED_STATION_BESETZT_UNBESETZT 4
#define KNOPF_STATION_BESETZT_UNBESETZT 5
#define LED_SERVICEBETRIEB 6
#define KNOPF_SERVICEBETRIEB 7
#define LED_FAHRGASTBETRIEB 22
#define KNOPF_FAHRGASTBETRIEB 23
#define LED_ROT_EREIGNISANZEIGE 13
#define LED_GELB_EREIGNISANZEIGE 12
#define LED_GRUEN_EREIGNISANZEIGE 11
#define LED_QUIT_BETRIEB 9
#define KNOPF_QUIT_BETRIEB 10
#define LED_START_BETRIEB 36
#define KNOPF_START_BETRIEB 37
#define LED_HALT 38
#define KNOPF_HALT 39
#define LED_NOTHALT 40
#define KNOPF_NOTHALT 41
#define LED_VORWAERTS 30
#define KNOPF_VORWAERTS 31
#define LED_RUECKWAERTS 32
#define KNOPF_RUECKWAERTS 33
// Hilfsvariablen zum merken des Zustands
bool buttonStateAnlageEinAus = false;
bool currentButtonStateAnlageEinAus = false;
bool buttonStateStationBesetztUnbesetzt = false;
bool currentButtonStateStationBesetztUnbesetzt = false;
bool buttonStateServicebetrieb = false;
bool currentButtonStateServicebetrieb = false;
bool buttonStateFahrgastbetrieb = false;
bool currentButtonStateFahrgastbetrieb = false;
bool buttonStateQuitBetrieb = false;
bool currentButtonStateQuitBetrieb = false;
bool buttonStateStart = false;
bool currentButtonStateStart = false;
bool buttonStateHalt = false;
bool currentButtonStateHalt = false;
bool buttonStateNothalt = false;
bool currentButtonStateNothalt = false;
bool buttonStateVorwaerts = false;
bool currentButtonStateVorwaerts = false;
bool buttonStateRueckwaerts = false;
bool currentButtonStateRueckwaerts = false;
// Anlagenzustände
enum
{
AUS,
SERVICE_QUITTIEREN,
SERVICE,
FAHRGAST_QUITTIEREN,
FAHRGAST,
} anlagenzustand;
// Fahrtrichtungen
enum Fahrtrichtung
{
HALT, // Anlage steht
NOTHALT, // Anlage steht (Notstop)
VORWAERTS_QUITTIEREN, // Richtungsknopf vorwärts gedrückt, warte auf quittieren
WARTE_START_VORWAERTS, // Anlage steht und wartet auf starten (in die entsprechende Richtung)
VORWAERTS, // Anlage fährt vorwärts
RUECKWAERTS_QUITTIEREN, // Richtungsknopf rückwärts gedrückt, warte auf quittieren
WARTE_START_RUECKWAERTS, // Anlage steht und wartet auf starten (in die entsprechende Richtung)
RUECKWAERTS, // Anlage fährt rückwärts
} fahrtrichtung;
Fahrtrichtung vorherigeRichtung = HALT;
void quittierenButtonAbfragen()
{
// ========== Quittieren Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateQuitBetrieb && !buttonStateQuitBetrieb)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateQuitBetrieb == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
switch(fahrtrichtung)
{
case HALT:
case NOTHALT:
if(vorherigeRichtung == RUECKWAERTS)
{
fahrtrichtung = WARTE_START_RUECKWAERTS;
}
else
{
fahrtrichtung = WARTE_START_VORWAERTS;
}
break;
case VORWAERTS_QUITTIEREN:
fahrtrichtung = WARTE_START_VORWAERTS;
break;
case RUECKWAERTS_QUITTIEREN:
fahrtrichtung = WARTE_START_RUECKWAERTS;
break;
}
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateQuitBetrieb = currentButtonStateQuitBetrieb;
}
}
}
void startButtonAbfragen()
{
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateStart = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateStart && !buttonStateStart)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateStart = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateStart == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
switch(fahrtrichtung)
{
case WARTE_START_VORWAERTS:
fahrtrichtung = VORWAERTS;
vorherigeRichtung = VORWAERTS;
break;
case WARTE_START_RUECKWAERTS:
fahrtrichtung = RUECKWAERTS;
vorherigeRichtung = RUECKWAERTS;
break;
}
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateStart = currentButtonStateStart;
}
}
}
// FERTIG
void haltButtonAbfragen()
{
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateHalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateHalt && !buttonStateHalt)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateHalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateHalt == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = HALT;
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateHalt = currentButtonStateHalt;
}
}
}
//FERTIG
void nothaltButtonAbfragen()
{
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateNothalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateNothalt && !buttonStateNothalt)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateNothalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateNothalt == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = NOTHALT;
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateNothalt = currentButtonStateNothalt;
}
}
}
//FERTIG
void vorwaertsButtonAbfragen()
{
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateVorwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateVorwaerts && !buttonStateVorwaerts)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateVorwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateVorwaerts == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
// In jeder beliebigen Fahrtrichtung, Fahrtrichtung Ändern (HALT, NOTHALT, RUECKWAERTS_QUITTIEREN, )
fahrtrichtung = VORWAERTS_QUITTIEREN;
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateVorwaerts = currentButtonStateVorwaerts;
}
}
}
//FERTIG
void rueckwaertsButtonAbfragen()
{
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateRueckwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateRueckwaerts && !buttonStateRueckwaerts)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateRueckwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateRueckwaerts == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = RUECKWAERTS_QUITTIEREN;
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateRueckwaerts = currentButtonStateRueckwaerts;
}
}
}
void setup() {
anlagenzustand = AUS;
fahrtrichtung = HALT;
Serial.begin(9600);
// Pindefinitonen
pinMode(LED_ANLAGE_EIN_AUS, OUTPUT);
pinMode(KNOPF_ANLAGE_EIN_AUS, INPUT_PULLUP);
pinMode(LED_STATION_BESETZT_UNBESETZT, OUTPUT);
pinMode(KNOPF_STATION_BESETZT_UNBESETZT, INPUT_PULLUP);
pinMode(LED_SERVICEBETRIEB, OUTPUT);
pinMode(KNOPF_SERVICEBETRIEB, INPUT_PULLUP);
pinMode(LED_FAHRGASTBETRIEB, OUTPUT);
pinMode(KNOPF_FAHRGASTBETRIEB, INPUT_PULLUP);
pinMode(LED_QUIT_BETRIEB, OUTPUT);
pinMode(KNOPF_QUIT_BETRIEB, INPUT_PULLUP);
pinMode(LED_ROT_EREIGNISANZEIGE, OUTPUT);
pinMode(LED_GELB_EREIGNISANZEIGE, OUTPUT);
pinMode(LED_GRUEN_EREIGNISANZEIGE, OUTPUT);
}
void loop() {
switch(anlagenzustand)
{
// #################### Anlage ausgeschaltet
case AUS:
{
// ========== LEDs entsprechend des Zustands setzen
digitalWrite(LED_ANLAGE_EIN_AUS, LOW);
digitalWrite(LED_STATION_BESETZT_UNBESETZT, LOW);
digitalWrite(LED_SERVICEBETRIEB, LOW);
digitalWrite(LED_FAHRGASTBETRIEB, LOW);
digitalWrite(LED_ROT_EREIGNISANZEIGE, LOW);
digitalWrite(LED_GELB_EREIGNISANZEIGE, LOW);
digitalWrite(LED_GRUEN_EREIGNISANZEIGE, LOW);
digitalWrite(LED_QUIT_BETRIEB, LOW);
// ========== Ein/Aus Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateAnlageEinAus && !buttonStateAnlageEinAus)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateAnlageEinAus == LOW)
{
// Anlage in den Zustand "SERVICE" versetzen und damit starten
anlagenzustand = SERVICE;
digitalWrite(LED_ANLAGE_EIN_AUS, HIGH);
digitalWrite(LED_STATION_BESETZT_UNBESETZT, HIGH);
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateAnlageEinAus = currentButtonStateAnlageEinAus;
}
}
break;
}
// #################### Anlage im Service-quittieren Zustand
// Anlage wechselt in den Servicezustand, sobald der Zustandswechsel durch den Nutzer quittiert wird
case SERVICE_QUITTIEREN:
{
// ========== LEDs entsprechend des Zustands setzen
digitalWrite(LED_QUIT_BETRIEB, HIGH);
digitalWrite(LED_GELB_EREIGNISANZEIGE, HIGH);
digitalWrite(LED_GRUEN_EREIGNISANZEIGE, LOW);
// ========== Ein/Aus Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateAnlageEinAus && !buttonStateAnlageEinAus)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateAnlageEinAus == LOW)
{
// Anlage in den Zustand "AUS" versetzen und damit stoppen
anlagenzustand = AUS;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateAnlageEinAus = currentButtonStateAnlageEinAus;
}
}
// ========== Quittieren Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateQuitBetrieb && !buttonStateQuitBetrieb)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateQuitBetrieb == LOW)
{
// Anlage in den Zustand "SERVICE" versetzen
anlagenzustand = SERVICE;
digitalWrite(LED_QUIT_BETRIEB, LOW);
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateQuitBetrieb = currentButtonStateQuitBetrieb;
}
}
break;
}
// #################### Anlage im Servicezustand
case SERVICE:
{
// ========== LEDs entsprechend des Zustands setzen
digitalWrite(LED_SERVICEBETRIEB, HIGH);
digitalWrite(LED_FAHRGASTBETRIEB, LOW);
digitalWrite(LED_ROT_EREIGNISANZEIGE, HIGH);
digitalWrite(LED_GELB_EREIGNISANZEIGE, LOW);
digitalWrite(LED_GRUEN_EREIGNISANZEIGE, LOW);
// ========== Fahrtrichtungsabhängige Steuerung
switch(fahrtrichtung)
{
// Anlage steht
case HALT:
{
quittierenButtonAbfragen(); // => "WARTE_START" Anhand Richtung
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
// Anlage steht
case NOTHALT:
{
quittierenButtonAbfragen(); // => "WARTE_START"
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
// Anlage steht
// Anlage fährt vorwärts
case VORWAERTS_QUITTIEREN:
{
quittierenButtonAbfragen(); // => "WARTE_START_VORWAERTS"
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
case WARTE_START_VORWAERTS:
{
startButtonAbfragen(); // => "VORWAERTS"
break;
}
// Anlage fährt vorwärts
case VORWAERTS:
{
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
break;
}
// Anlage fährt rückwärts
case RUECKWAERTS_QUITTIEREN:
{
quittierenButtonAbfragen(); // => "WARTE_START_RUECKWAERTS"
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
break;
}
case WARTE_START_RUECKWAERTS:
{
startButtonAbfragen(); // => "RUECKWAERTS"
break;
}
// Anlage fährt rückwärts
case RUECKWAERTS:
{
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
break;
}
default:
{
break;
}
}
// ========== Ein/Aus Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateAnlageEinAus && !buttonStateAnlageEinAus)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateAnlageEinAus == LOW)
{
// Anlage in den Zustand "AUS" versetzen und damit stoppen
anlagenzustand = AUS;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateAnlageEinAus = currentButtonStateAnlageEinAus;
}
}
// ========== Fahrgast Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateFahrgastbetrieb = digitalRead(KNOPF_FAHRGASTBETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateFahrgastbetrieb && !buttonStateFahrgastbetrieb)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateFahrgastbetrieb = digitalRead(KNOPF_FAHRGASTBETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateFahrgastbetrieb == LOW)
{
// Anlage in den Zustand "SERVICE_QUITTIEREN" versetzen
anlagenzustand = SERVICE_QUITTIEREN;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateFahrgastbetrieb = currentButtonStateFahrgastbetrieb;
}
}
break;
}
// #################### Anlage im Fahrgast-quittieren Zustand
// Anlage wechselt in den Fahrgastzustand, sobald der Zustandswechsel durch den Nutzer quittiert wird
case FAHRGAST_QUITTIEREN:
{
// ========== LEDs entsprechend des Zustands setzen
digitalWrite(LED_QUIT_BETRIEB, HIGH);
digitalWrite(LED_GELB_EREIGNISANZEIGE, HIGH);
digitalWrite(LED_ROT_EREIGNISANZEIGE, LOW);
// ========== Ein/Aus Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateAnlageEinAus && !buttonStateAnlageEinAus)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateAnlageEinAus == LOW)
{
// Anlage in den Zustand "AUS" versetzen und damit stoppen
anlagenzustand = AUS;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateAnlageEinAus = currentButtonStateAnlageEinAus;
}
}
// ========== Quittieren Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateQuitBetrieb && !buttonStateQuitBetrieb)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateQuitBetrieb == LOW)
{
// Anlage in den Zustand "SERVICE" versetzen
anlagenzustand = SERVICE;
digitalWrite(LED_QUIT_BETRIEB, LOW);
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateQuitBetrieb = currentButtonStateQuitBetrieb;
}
}
break;
}
// #################### Anlage im Fahrgastzustand
case FAHRGAST:
{
// ========== LEDs entsprechend des Zustands setzen
digitalWrite(LED_SERVICEBETRIEB, LOW);
digitalWrite(LED_FAHRGASTBETRIEB, HIGH);
digitalWrite(LED_GRUEN_EREIGNISANZEIGE, HIGH);
digitalWrite(LED_GELB_EREIGNISANZEIGE, LOW);
// ========== Fahrtrichtungsabhängige Steuerung
// switch(fahrtrichtung)
// {
// // Anlage steht
// case HALT:
// {
// break;
// }
// // Anlage fährt vorwärts
// case VORWAERTS:
// {
// break;
// }
// // Anlage fährt rückwärts
// case RUECKWAERTS:
// {
// break;
// }
// default:
// {
// break;
// }
// }
// ========== Vorwärts Button abfragen
vorwaertsButtonAbfragen();
// ========== Ein/Aus Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateAnlageEinAus && !buttonStateAnlageEinAus)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateAnlageEinAus = digitalRead(KNOPF_ANLAGE_EIN_AUS) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateAnlageEinAus == LOW)
{
// Anlage in den Zustand "AUS" versetzen und damit stoppen
anlagenzustand = AUS;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateAnlageEinAus = currentButtonStateAnlageEinAus;
}
}
// ========== Service Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateServicebetrieb = digitalRead(KNOPF_SERVICEBETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateServicebetrieb && !buttonStateServicebetrieb)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateServicebetrieb = digitalRead(KNOPF_SERVICEBETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateServicebetrieb == LOW)
{
// Anlage in den Zustand "SERVICE_QUITTIEREN" versetzen
anlagenzustand = SERVICE_QUITTIEREN;
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateServicebetrieb = currentButtonStateServicebetrieb;
}
}
break;
}
// ####################
default:
{
break;
}
}
}

11
Seilbahn/test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html

View File

@ -18,6 +18,20 @@
#define LED_QUIT_BETRIEB 9
#define KNOPF_QUIT_BETRIEB 10
#define LED_START_BETRIEB 36
#define KNOPF_START_BETRIEB 37
#define LED_HALT 38
#define KNOPF_HALT 39
#define LED_NOTHALT 40
#define KNOPF_NOTHALT 41
#define LED_VORWAERTS 30
#define KNOPF_VORWAERTS 31
#define LED_RUECKWAERTS 32
#define KNOPF_RUECKWAERTS 33
// Hilfsvariablen zum merken des Zustands
bool buttonStateAnlageEinAus = false;
@ -35,6 +49,21 @@ bool currentButtonStateFahrgastbetrieb = false;
bool buttonStateQuitBetrieb = false;
bool currentButtonStateQuitBetrieb = false;
bool buttonStateStart = false;
bool currentButtonStateStart = false;
bool buttonStateHalt = false;
bool currentButtonStateHalt = false;
bool buttonStateNothalt = false;
bool currentButtonStateNothalt = false;
bool buttonStateVorwaerts = false;
bool currentButtonStateVorwaerts = false;
bool buttonStateRueckwaerts = false;
bool currentButtonStateRueckwaerts = false;
// Anlagenzustände
enum
{
@ -48,79 +77,203 @@ enum
// Fahrtrichtungen
enum Fahrtrichtung
{
HALT,
NOTHALT,
WARTE_START,
VORWAERTS_QUITTIEREN,
VORWAERTS,
RUECKWAERTS_QUITTIEREN,
RUECKWAERTS,
HALT, // Anlage steht
NOTHALT, // Anlage steht (Notstop)
VORWAERTS_QUITTIEREN, // Richtungsknopf vorwärts gedrückt, warte auf quittieren
WARTE_START_VORWAERTS, // Anlage steht und wartet auf starten (in die entsprechende Richtung)
VORWAERTS, // Anlage fährt vorwärts
RUECKWAERTS_QUITTIEREN, // Richtungsknopf rückwärts gedrückt, warte auf quittieren
WARTE_START_RUECKWAERTS, // Anlage steht und wartet auf starten (in die entsprechende Richtung)
RUECKWAERTS, // Anlage fährt rückwärts
} fahrtrichtung;
Fahrtrichtung vorherigerichtung = HALT;
Fahrtrichtung vorherigeRichtung = HALT;
void quittierenButtonAbfragen()
{
// Button Code [...]
if(fahrtrichtung == NOTHALT || fahrtrichtung == HALT)
// ========== Quittieren Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateQuitBetrieb && !buttonStateQuitBetrieb)
{
fahrtrichtung = WARTE_START;
}
else if(fahrtrichtung == VORWAERTS_QUITTIEREN)
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateQuitBetrieb = digitalRead(KNOPF_QUIT_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateQuitBetrieb == LOW)
{
fahrtrichtung = WARTE_START;
}
else if(fahrtrichtung == RUECKWAERTS_QUITTIEREN)
// Knopf gedrückt => Code ausführen
// ============================================================
switch(fahrtrichtung)
{
fahrtrichtung = WARTE_START;
case HALT:
case NOTHALT:
if(vorherigeRichtung == RUECKWAERTS)
{
fahrtrichtung = WARTE_START_RUECKWAERTS;
}
else
{
fahrtrichtung = WARTE_START_VORWAERTS;
}
break;
case VORWAERTS_QUITTIEREN:
fahrtrichtung = WARTE_START_VORWAERTS;
break;
case RUECKWAERTS_QUITTIEREN:
fahrtrichtung = WARTE_START_RUECKWAERTS;
break;
}
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateQuitBetrieb = currentButtonStateQuitBetrieb;
}
}
// Button Code [...]
}
void startButtonAbfragen()
{
// Button Code [...]
if(vorherigerichtung == VORWAERTS)
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateStart = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateStart && !buttonStateStart)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateStart = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateStart == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
switch(fahrtrichtung)
{
case WARTE_START_VORWAERTS:
fahrtrichtung = VORWAERTS;
vorherigeRichtung = VORWAERTS;
break;
case WARTE_START_RUECKWAERTS:
fahrtrichtung = RUECKWAERTS;
vorherigeRichtung = RUECKWAERTS;
break;
}
else if(vorherigerichtung == RUECKWAERTS)
{
fahrtrichtung = VORWAERTS;
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateStart = currentButtonStateStart;
}
else
{
fahrtrichtung = VORWAERTS;
}
// Button Code [...]
}
// FERTIG
void haltButtonAbfragen()
{
// Button Code [...]
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateHalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateHalt && !buttonStateHalt)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateHalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateHalt == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = HALT;
// Button Code [...]
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateHalt = currentButtonStateHalt;
}
}
}
//FERTIG
void nothaltButtonAbfragen()
{
// Button Code [...]
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateNothalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateNothalt && !buttonStateNothalt)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateNothalt = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateNothalt == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = NOTHALT;
// Button Code [...]
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateNothalt = currentButtonStateNothalt;
}
}
}
//FERTIG
void vorwaertsButtonAbfragen()
{
// Button Code [...]
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateVorwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateVorwaerts && !buttonStateVorwaerts)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateVorwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateVorwaerts == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
// In jeder beliebigen Fahrtrichtung, Fahrtrichtung Ändern (HALT, NOTHALT, RUECKWAERTS_QUITTIEREN, )
fahrtrichtung = VORWAERTS_QUITTIEREN;
// Button Code [...]
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateVorwaerts = currentButtonStateVorwaerts;
}
}
}
//FERTIG
void rueckwaertsButtonAbfragen()
{
// Button Code [...]
// ========== Start Button abfragen
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateRueckwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Aktuellen Zustand mit vorherigem vergleichen
if (currentButtonStateRueckwaerts && !buttonStateRueckwaerts)
{
// Warten zum entprellen
delay(20);
// Taster abfragen und aktuellen Zustand zwischenspeichern
currentButtonStateRueckwaerts = digitalRead(KNOPF_START_BETRIEB) == LOW;
// Prüfen ob immernoch gedrückt
if (currentButtonStateRueckwaerts == LOW)
{
// Knopf gedrückt => Code ausführen
// ============================================================
fahrtrichtung = RUECKWAERTS_QUITTIEREN;
// Button Code [...]
// ============================================================
// Speichern des ButtonStates als Vergleichswert für den nächsten Durchlauf
buttonStateRueckwaerts = currentButtonStateRueckwaerts;
}
}
}
void setup() {
@ -240,7 +393,6 @@ void loop() {
buttonStateQuitBetrieb = currentButtonStateQuitBetrieb;
}
}
break;
}
@ -260,48 +412,64 @@ void loop() {
// Anlage steht
case HALT:
{
quittierenButtonAbfragen();
vorwaertsButtonAbfragen();
rueckwaertsButtonAbfragen();
quittierenButtonAbfragen(); // => "WARTE_START" Anhand Richtung
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
// Anlage steht
case NOTHALT:
{
quittierenButtonAbfragen();
vorwaertsButtonAbfragen();
rueckwaertsButtonAbfragen();
quittierenButtonAbfragen(); // => "WARTE_START"
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
// Anlage steht
case WARTE_START:
{
startButtonAbfragen();
break;
}
// Anlage fährt vorwärts
case VORWAERTS_QUITTIEREN:
{
quittierenButtonAbfragen(); // => "WARTE_START_VORWAERTS"
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
rueckwaertsButtonAbfragen(); // => "RUECKWAERTS_QUITTIEREN"
break;
}
case WARTE_START_VORWAERTS:
{
startButtonAbfragen(); // => "VORWAERTS"
break;
}
// Anlage fährt vorwärts
case VORWAERTS:
{
haltButtonAbfragen();
nothaltButtonAbfragen();
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
break;
}
// Anlage fährt rückwärts
case RUECKWAERTS_QUITTIEREN:
{
quittierenButtonAbfragen(); // => "WARTE_START_RUECKWAERTS"
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
vorwaertsButtonAbfragen(); // => "VORWAERTS_QUITTIEREN"
break;
}
case WARTE_START_RUECKWAERTS:
{
startButtonAbfragen(); // => "RUECKWAERTS"
break;
}
// Anlage fährt rückwärts
case RUECKWAERTS:
{
haltButtonAbfragen();
nothaltButtonAbfragen();
haltButtonAbfragen(); // => "HALT"
nothaltButtonAbfragen(); // => "NOTHALT"
break;
}
default:
@ -425,13 +593,13 @@ void loop() {
break;
}
// Anlage fährt vorwärts
case VORWÄRTS:
case VORWAERTS:
{
break;
}
// Anlage fährt rückwärts
case RÜCKWÄRTS:
case RUECKWAERTS:
{
break;