//
// Ansteuerung Faller Kran
/*
* Automatischeer Betrieb zur Drehbewegung bis 270 Grad rechts und links.
* LED in Kanzel und Führerhaus
* Je zwei Taster auf A0 bis A3
* A0 für direkte manuelle Drehung rechts links
* A1 für zweiten Motor
* A2 für Relais 1
* A3 zur freien Verfügung
*/
// Wolfgang aka Running_Wolf
// 2020-07-24
//
// LED
const int Kabine = 13; // Führer Kabine
const int verzKabine = 3000; // Einchaltverzug vor Drehstart
unsigned long previousMillis_Kabine = 0; // Zeitmerker Kabinenlicht
const int rotPin1 = 12; // rotes Blinklicht
unsigned long previousMillis_rotPin1 = 0; // Zeitmerker Blinklicht
unsigned long wann_rotPin1 = 200 ; // rotes Blinklicht
const int deckPin1 = 11; // weisses Licht innen
const int verzDeck = 5000; // Einchaltverzug vor Drehstart
unsigned long previousMillis_deckPin1 = 0; // Zeitmerker Deckenlicht
//
// Motorpins generell
//
int bridgePins [2][2] = {{9, 8 }, {7, 6}} ; // Array für zwei Motor Pins,
// Motor 1: 9,8 / Motor 2: 7,6
boolean an = HIGH; // definiere für Motor Zustand an
boolean aus = LOW; // definiere für Motor Zustand aus
boolean links = LOW ; // definiere für Motor Linkslauf
boolean rechts = HIGH ; // definiere für MotorvRechtslauf
//
// Motor 1
//
const int PWM_1 = 10; // PWM für Motor 1
const int Mot1 = 1; // Motor 1
unsigned long previousMillis_Mot1 = 0; // Zeitmerker Motor 1
unsigned long wann_Mot1[2] = { 60000,8000} ; // Startabstand 60000, Laufzeit Motor 1 8000
boolean next_Mot1 = rechts ; // nächste Drehrichtung vorbelegen
int status_Mot1 = 0 ; // 0 = soll laufen, 1 = soll stoppen
//
// Motor 2
//
const int PWM_2 = 5; // PWM für Motor 2
const int Mot2 = 2; // Motor 2
unsigned long previousMillis_Mot2 = 0; // Zeitmerker Motor 2
unsigned long wann_Mot2[2] = { 30000,8000} ; // Startabstand 30000, Laufzeit Motor 2 8000
boolean next_Mot2 = rechts ; // nächste Drehrichtung vorbelegen
int status_Mot2 = 0 ; // 0 = soll laufen, 1 = soll stoppen
//
// Motor Märklin Kran Drehen
//
//const int PWM_2 = 5; // PWM für Motor 2
//const int Mot2 = 2; // Motor 2
unsigned long previousMillis_Mark = 0; // Zeitmerker Märklin Kran
unsigned long wann_Mark[2] = { 40000,8000} ; // Startabstand 30000, Laufzeit Motor 2 8000
boolean next_Mark = rechts ; // nächste Drehrichtung vorbelegen
int status_Mark = 0 ; // 0 = soll laufen, 1 = soll stoppen
//
// Relaisausgänge
//
const int Rel_1 = 4; // Digitalpins für Relais
const int Rel_2 = 3; //
const int Rel_3 = 2; //
//
// Analogeingänge
// An jedem Analogeingang sind zwei Taster
// Pull-up Widerstand eingeschaltet
// 10 K Widerstand gegen GND
// Taster a über 470 Ohm gegen Vcc
// Taster b über 4,7 K gegen Vcc
//
const int Taste_1 = A0; // Steuertaste 1 auf Analag 0 liefert integer 14
const int Taste_2 = A1; // Steuertaste 2 15
const int Taste_3 = A2; // Steuertaste 3 16
const int Taste_4 = A3; // Steuertaste 4 17
const int Pin_0 = 0 ; // Noch frei, als Test Pin genutzt
const int Pin_1 = 1 ; // Noch frei, als Test Pin genutzt
int Taste_Wert [4] = { 0, 0, 0, 0 }; // Variable für Tastenabfrage, als 0 vorbelegt
int entprellzeit = 100 ; // Tastenprellen abwarten in msec
const int ohne_Drueck = 500 ; // Analogwert unter 500: nichts gedrückt
const int klein_Drueck = 850 ; // Analogwert über 850: 470 Ohm gedrückt
const int gross_Drueck_u = 600 ; // Analogwert zw. 600 und 800: 4,7 K gedrückt
const int gross_Drueck_o = 800 ;
//
void setup()
{
// Serial.begin(9600);
//
// Tasten / Relais einstellen auf INPUT / OUTPUT
//
pinMode(Pin_0 , OUTPUT);
pinMode(Pin_1 , OUTPUT);
pinMode(Rel_1 , OUTPUT);
pinMode(Rel_2 , OUTPUT);
pinMode(Rel_3 , OUTPUT);
pinMode(rotPin1, OUTPUT);
pinMode(deckPin1, OUTPUT);
pinMode(Kabine, OUTPUT);
//
// Motoranschlusspins setzen
//
pinMode(PWM_1, OUTPUT);
pinMode(PWM_2, OUTPUT);
pinMode(bridgePins[0][0], OUTPUT);
pinMode(bridgePins[0][1], OUTPUT);
pinMode(bridgePins[1][0], OUTPUT);
pinMode(bridgePins[1][1], OUTPUT);
//
// Interner Pullup Widerstand einschalten
//
pinMode(Taste_1, INPUT_PULLUP) ;
pinMode(Taste_2, INPUT_PULLUP) ;
pinMode(Taste_3, INPUT_PULLUP) ;
pinMode(Taste_4, INPUT_PULLUP) ;
}
//
// --------------------------------- LOOP geht los ----------------------------
//
void loop() {
//
unsigned long currentMillis = millis(); // abgelaufene Zeit abfragen
//
analogWrite(PWM_1, 40); // Motor 1 speed
analogWrite(PWM_2, 80); // Motor 2 speed
//
digitalWrite (Pin_0, HIGH) ; // Test Pin 0 aus
digitalWrite (Pin_1, LOW) ; // Test Pin 1 aus
//
// Motor 1 checken, wird über Drucktaste an A0 gestartet
//
if (Druck_Taste(Taste_1-14)==1) // nur wenn die Taste überhaupt
{ // gedrückt wurde
while (Druck_Taste(Taste_1-14)==1) // Schleife solange Taste gedrückt
{
Motor (Mot1, an , Taste_Wert[Taste_1-14] > klein_Drueck) ; // Motor 1 anschalten
} // Richtung je nach Taste an A0
Motor (Mot1, aus , HIGH) ; // Nach Loslassen der Taste
} // Motor 1 ausschalten
//
// Motor 2 manuell drehen über A1
//
if (Druck_Taste(Taste_2-14)==1) // nur wenn die Taste überhaupt
{ // gedrückt wurde
while (Druck_Taste(Taste_2-14)==1) // Schleife solange Taste gedrückt
{
Motor (Mot2, an , Taste_Wert[Taste_2-14] > klein_Drueck) ; // Motor 2 anschalten
} // Richtung je nach Taste an A1
Motor (Mot2, aus , HIGH) ; // Nach Loslassen der Taste
} // Motor 2 ausschalten
//
// Relais 1 & 2 manuell über A2 / Taste_3
//
if (Druck_Taste(Taste_3-14)==1) // nur wenn die Taste überhaupt
{ // gedrückt wurde
while (Druck_Taste(Taste_3-14)==1) // Schleife solange Taste gedrückt
{
if (Taste_Wert[Taste_3-14] > klein_Drueck)
{
digitalWrite(Rel_1, HIGH); // Relais 1 ein
}
else
{
digitalWrite(Rel_2, HIGH); // Relais 2 ein
} // Ende WHILE
digitalWrite(Rel_1, LOW); // Nach Loslassen der Taste
digitalWrite(Rel_2, LOW); // Nach Loslassen der Taste
} // Relais 1 & 2 ausschalten
}
//
// Relais 3 manuell über A3 oben
//
if (Druck_Taste(Taste_4-14)==1) // nur wenn die Taste überhaupt
{ // gedrückt wurde
while (Druck_Taste(Taste_4-14)==1 && (Taste_Wert[Taste_3-14] > klein_Drueck))
// Schleife solange Taste gedrückt
{
digitalWrite(Rel_3, HIGH); // Relais 2 ein
} // Ende WHILE
digitalWrite(Rel_3, LOW); // Nach Loslassen der Taste
} // Relais 1 ausschalten
//
//
/*
Taste A0 ausgeblendet da Motor 2 darüber gestartet werden soll
if (Druck_Taste(Taste_1-14)==1) { // A0 ist #14, also 14 abziehen
// da ==1 wurde eine Taste gedrückt
if (Taste_Wert[0] > klein_Drueck) { // Taste für kleinen Widerstand
// Serial.println("Taste 1 unten gedrückt ") ;
digitalWrite (Pin_0, HIGH) ; // Testausgabe
digitalWrite (Pin_1, LOW) ; // Testausgabe
}
else { // da Taste gedrück, ist großer Widerstand
Serial.println("Taste 1 oben gedrückt ") ;
digitalWrite (Pin_1, HIGH) ;
digitalWrite (Pin_0, LOW) ;
}
}
if (Druck_Taste(Taste_2-14)==1) { // A0 ist #14, also 14 abziehen
// da ==1 wurde eine Taste gedrückt
if (Taste_Wert[1] > klein_Drueck) { // Taste für kleinen Widerstand
// Serial.println("Taste 2 unten gedrückt ") ;
digitalWrite (Pin_0, HIGH) ; // Testausgabe
digitalWrite (Pin_1, LOW) ; // Testausgabe
}
else {
// Serial.println("Taste 2 oben gedrückt ") ;
digitalWrite (Pin_1, HIGH) ;
digitalWrite (Pin_0, LOW) ;
}
}
*/
//
if (Druck_Taste(Taste_4-14)==1) {
if (Taste_Wert[3] > klein_Drueck) {
// Serial.println("Taste 4 unten gedrückt ") ;
digitalWrite (Pin_0, HIGH) ; // Testausgabe
digitalWrite (Pin_1, LOW) ; // Testausgabe
}
else {
// Serial.println("Taste 4 oben gedrückt ") ;
digitalWrite (Pin_1, HIGH) ;
digitalWrite (Pin_0, LOW) ;
}
}
//
// Deckenlicht Fallerkran
//
if ((currentMillis-previousMillis_Mot1 >= wann_Mot1[status_Mot1]-verzDeck) && status_Mot1==0)
{
previousMillis_deckPin1 = currentMillis; // Merke Zeitpunkt für Deckenlicht
digitalWrite(deckPin1, HIGH) ; // Deckenlicht an
}
//
if (currentMillis - previousMillis_deckPin1 >= verzDeck && status_Mot1 == 0)
{
previousMillis_deckPin1 = currentMillis; // Merke Zeitpunkt für Deckenlicht
digitalWrite(deckPin1, LOW) ; // Deckenlicht aus
}
//
// Kabinenlicht Fallerkran
//
if ((currentMillis-previousMillis_Mot1 >= wann_Mot1[status_Mot1]-verzKabine) && status_Mot1==0)
{
previousMillis_Kabine = currentMillis; // Merke Zeitpunkt für Kabinenlicht
digitalWrite(Kabine, HIGH) ; // Kabinenlicht an
}
//
if (currentMillis - previousMillis_Kabine >= verzKabine && status_Mot1 == 0)
{
previousMillis_Kabine = currentMillis; // Merke Zeitpunkt für Kabinenlicht
digitalWrite(Kabine, LOW) ; // Kabinenlicht aus
}
//
// Motor 1: Drehmotor Fallerkran
//
if ((currentMillis - previousMillis_Mot1 >= wann_Mot1[status_Mot1]) && status_Mot1 == 0)
{ // soll loslaufen
previousMillis_Mot1 = currentMillis; // Merke Zeitpunkt für Motor 1
Motor (Mot1, an , next_Mot1) ; // Motor an
next_Mot1 = !next_Mot1 ; // Motor Richtung umkehren
status_Mot1 = 1-status_Mot1 ; // ändern auf stehenbleiben
}
//
if ((currentMillis - previousMillis_Mot1 >= wann_Mot1[status_Mot1]) && status_Mot1 == 1)
{ // soll stehen bleiben
previousMillis_Mot1 = currentMillis; // Merke Zeitpunkt für Motor 2
status_Mot1 = 1-status_Mot1; // ändern auf loslaufen
Motor (Mot1, aus, HIGH) ; // Motor aus
previousMillis_Kabine = currentMillis; // merken für Kabinenlicht
previousMillis_deckPin1 = currentMillis; // merken für Deckenlicht
}
//
// Blinklichr Bewegung Faller Kran
//
if (currentMillis - previousMillis_rotPin1 >= wann_rotPin1)
{ // rotes Blinklicht,
// wenn Kran bewegt
previousMillis_rotPin1 = currentMillis; // merken für Blinklicht
if (status_Mot1==1) {
digitalWrite(Rel_2, !digitalRead(Rel_2)); // Relaistest an dieser Stelle
digitalWrite(rotPin1, !digitalRead(rotPin1));
} // Blinklicht an/aus
else {
digitalWrite(Rel_2, LOW); // Relaistest an dieser Stelle
digitalWrite(rotPin1, LOW); } // Blinklicht aus
}
//
// Motor 2: Drehmotor
//
if ((currentMillis - previousMillis_Mot2 >= wann_Mot2[status_Mot2]) && status_Mot2 == 0)
{ // soll loslaufen
previousMillis_Mot2 = currentMillis; // Merke Zeitpunkt für Motor 2
Motor (Mot2, an , next_Mot2) ; // Motor an
next_Mot2 = !next_Mot2 ; // Motor Richtung umkehren
status_Mot2 = 1-status_Mot2 ; // ändern auf stehenbleiben
}
//
if ((currentMillis - previousMillis_Mot2 >= wann_Mot2[status_Mot2]) && status_Mot1 == 1)
{ // soll stehen bleiben
previousMillis_Mot2 = currentMillis; // Merke Zeitpunkt für Motor 2
status_Mot2 = 1-status_Mot2; // ändern auf loslaufen
Motor (Mot2, aus, HIGH) ; // Motor aus
}
//
// Märklin Kran: Drehmotor
//
if ((currentMillis - previousMillis_Mark >= wann_Mark[status_Mark]) && status_Mark == 0)
{ // soll loslaufen
previousMillis_Mark = currentMillis; // Merke Zeitpunkt für Drehkran
if (next_Mark)
{
digitalWrite(Rel_1, HIGH); // Relais 1 für rechts
}
else
{
digitalWrite(Rel_2, HIGH); // Relais 2 für links
}
next_Mark = !next_Mark ; // Motor Richtung umkehren
status_Mark = 1-status_Mark ; // ändern auf stehenbleiben
}
//
if ((currentMillis - previousMillis_Mark >= wann_Mark[status_Mark]) && status_Mark == 1)
{ // soll stehen bleiben
previousMillis_Mark = currentMillis; // Merke Zeitpunkt für Drehkran
status_Mark = 1-status_Mark; // ändern auf loslaufen
digitalWrite(Rel_1, LOW); // Relais 1 aus
digitalWrite(Rel_2, LOW); // Relais 2 aus
}
//
}
//
// --------------------------------- LOOP zu Ende ----------------------------
//
// --------------------------- Motor ansteuern -------------------------------
//
int Motor(int wen, boolean start, boolean wie){ // drei Parameter
// Motornummer
// wenn start HIGH lauf los
// wenn start LOW bleib stehen
// wenn wie HIGH rechts herum
// wenn wie LOW links herum
if (!start) { // soll stehen bleiben
digitalWrite(bridgePins[wen-1][0], LOW) ; // setzte H-Bridge auf Stop
digitalWrite(bridgePins[wen-1][1], LOW) ;
return wen; // gib Motornummer zurück
}
else if (start) { // soll loslaufen
digitalWrite(bridgePins[wen-1][0], wie) ; // setzte H-Bridge auf Los
digitalWrite(bridgePins[wen-1][1], !wie) ;
return wen;
}
else {return 0;}
}
//
// ----------------------------Tastenabfrage -----------------------------
//
int Druck_Taste(int dieseTaste){ // Fragt Tasten ab
int Druck_Wert = analogRead(dieseTaste); // Lese Tastennummer von Analog Port
delay (entprellzeit); // warte wegen Prellen
Druck_Wert = analogRead(dieseTaste); // frag Taste noch einmal
Taste_Wert [dieseTaste] = Druck_Wert ; // lese Wert in Array
if (Druck_Wert < ohne_Drueck) {return 0; } // keine Taste gedrückt
else if (Druck_Wert > ohne_Drueck) {return 1; } // Taste gedrückt
}
//