PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ich brauch professionelle Hilfe bei Programmierung meines Kranes



Schiffe Bodo
18.07.2015, 19:38
Hallo liebe Gemeinde,
Ich bin 49 Jahre alt, baue Schiffsmodelle mit möglichst viel Funktionen und hab vor ca. einem halben Jahr damit begonnen den Arduino mit in meine Schffe einzubauen.
Jetzt baue ich gerade die Calypso und hab den Kran funktionsfähig gemacht. Mechanisch funktioniert er und mit meinem geschriebenen Programm läuft er mit einigen Mängeln.
Könnte von Euch mal jemand ein Auge auf meinen Sketch werfen und mir mit Ideen zur Verbesserung weiterhelfen?

Folgende Probleme hab ich bis jetzt:
1. Blink LED blinkt auch weiter wenn Programm durchlaufen ist!
2. Seilposition verschiebt sich leicht ( ich denke das ist ein Problem mit den Delays)!
An der Startfreigabe arbeite ich noch( muss ich noch mit Pullup oder Pulldown Tastern verwirklichen)

Ich habe in dem Sketch auch alle Ideen die Ich schon probiert habe dringelassen, aber auskomplimentiert!
Hier der Sketch



//Kran*der*Calypso*ansteuern
//1*Stepper*und*1*DC*Motor


#include*<Stepper.h>
#include*"TimerOne.h"
#define*LED*7

int s1 = 4; //Starttaster von RC
int s2 = 6; //Endschalter Kran in Ruheposition
int value = LOW;
int Kranstart = HIGH;
//const*int*ledPin*=**7;******//*the*number*of*the*LED*pin

//*Variables*will*change:
//int*ledState*=*LOW;*************//*ledState*used*to*set*the*LED
//long*previousMillis*=*0;********//*will*store*last*time*LED*was*updated

//long*interval*=*250;***********//*interval*at*which*to*blink*(milliseconds)

//int*StartKran*=*HIGH;

int SPMU1 = 32;
int RELAISAUF = 2; // Seil aufrollen
int RELAISAB = 3; // Seil abrollen

Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
**pinMode(LED, OUTPUT);
**Timer1.initialize(100000); // initialize timer1, and set a 1/2 second period
**Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
**Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
**}
**// set the digital pin as output:
**//pinMode(ledPin, OUTPUT);
**
**pinMode(s1,INPUT); // Signal Kran starten
**pinMode(s2,INPUT); // Schalter Kran in Ruheposition
**
**pinMode(RELAISAUF,OUTPUT);
**pinMode(RELAISAB,OUTPUT);
**
**myStepper1.setSpeed(400);
}
void callback(){
**{
**// Die LED blinkt unabhängig vom Programmcode in loop()
**digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
*
**}
}

void loop()


*
**//digitalRead((s1,HIGH)&&(s2,HIGH) = digitalWrite (StartKran,HIGH));
*// {
*// unsigned long currentMillis = millis();
*
**//if(currentMillis - previousMillis > interval) {
****// save the last time you blinked the LED
***// previousMillis = currentMillis;
****// if the LED is off turn it on and vice-versa:
****//if(ledState ==LOW);
**// ledState =((ledState == LOW)? HIGH : LOW);
****//ledState = HIGH;
****//else
****//ledState = LOW;
****// set the LED with the ledState of the variable:
***// digitalWrite(ledPin, ledState);
*//}
//}
{
**value*=*digitalRead(s2);
**digitalWrite(Kranstart,value);{
**if (Kranstart,HIGH)
**
**digitalWrite (RELAISAUF, HIGH);
**delay(2600);
**digitalWrite (RELAISAUF, LOW);
**delay(2000);
**
**myStepper1.step(-3600); //Kran ausdrehen (Winkel einstellen)
**delay(2000); //Warten
**
**digitalWrite (RELAISAB, HIGH);
**delay(13000); //Seil ab für 13 sec
**digitalWrite (RELAISAB, LOW);
**delay(20000);
**
**digitalWrite (RELAISAUF, HIGH);
**delay(13000);
**digitalWrite (RELAISAUF, LOW);
**delay(2000);
**
**
**myStepper1.step(3600); //Kran eindrehen
**delay(3000);
**
**digitalWrite (RELAISAB, HIGH);
**delay(2600);
**digitalWrite (RELAISAB, LOW);
**delay(5000);
**}
**{
*// detachInterrupt (void callback);{
**// {
*// digitalWrite(LED, digitalRead(LED) ^ 0); // EXOR invertiert
*
**//}
//}
**while(s2,HIGH);
**
}}



Danke schonmal für eure Bemühungen und vielleicht wird mir ja geholfen

Gruß Bodo

HeXPloreR
19.07.2015, 08:36
Hallo Bodo,

ich kenne mich mit Arduino-Boards selbst jetzt nicht so gut aus, aber der Timer1 scheint zumindest bei "Timer1.pwm(9, 512);" doch schon von "Timer1.attachinterrupt(callback);" in Benutzung zu sein?! Alternative mal prüfen ob es einen anderen Timer gibt der eine der beiden Funktionen auch ausführen kann.
Wenn man Anfänger ist wäre meine Empfehlung nicht gleich mit einem derartige Code anzufangen der möglicherweise eine Mehrfachnutzung eines Timers benutzt, die man ggf noch nicht nachvollziehen kann.

Wenn man rumprobiert mit der gesamt Systemlaufzeit ( currentMillis ) und irgednwann alles durcheinander ist, dann kann es helfen einen kompletten loop-Block dafür anzulegen und dann durch auskommentiren ganzer loop-Blöcke (siehe unten) zu arbeiten.
Es sieht sehr nach zusammenkopiertenm Code aus. Zumal der Programmierstil echt unterirdisch ist und man wirklich nur schwer lesen kann. Sorry.

Was sollen diie ganzen Sternchen da? Ist dir bewußt dass des " * "-Symbol auch ein Programierelement von C ist.
Neben der mathematishcen Bedeutung vom " * ", wird der u.a. noch bei "Zeigern" benutzt. Dazu kommt das man damit ganze Codeblöcke (unter bestimmten Bedingungen ) auskommentieren kann. Es Ist also nicht nötig jede Zeile mit " // " rauszunehmen, hier bietet sich ein " /* bzw */ " an, womit der umschliessende Code auskommentiert wird. Also so: /* Code der auskommentiert werden soll */ .
Dazu schaut man sich am besten einen Tutoriel wie dieses Hier bei You Tube an (klick mich) (https://www.youtube.com/watch?v=K_FhVhRP0mg). Hier habe ich grade sogar noch was gelernt ;)
Für Codeeinrückungen bietet sich die Tab " ->| " an - kann man auch zweimal drücken um mehr einzurücken oder man stellt die Einstellungen so um das gleich mehr eingerückt wird.

Da die LED als Hardware-Interrupt programmiert ist, blinkt sie eben auch wenn "das Programm durchlaufen" ist. Hierzu muss man sagen dass das Programm nur im Ablauf durch Deine Eingaben abgezweigt wird. Das Programm selbst läuft immer in der loop - solange ausreichend Spannung vorhanden ist.
Um das abzustellen ist es nötig den Interrupt mit einem Ereignis innerhalb der loop zu verbinden welches die Blink-Bedingung auslöst oder anhält.

Das Seilwindenproblem entsteht vermutlich ganz genau wie Du schon sagst wegen den ganzen Delays. Wird der Arm jetzt per RC-Fernsteuerung auch mit Knüppel gesteuert oder nur per Taster an/aus auf der Fernsteuerung?

Viele Grüße
Jörg

Schiffe BodoUnregistriert
19.07.2015, 10:10
Danke erstmal für deine Antwort, das mit den vielen * kann ich mir nur damit erklären das es hier beim einfügen alle Leerzeichen in Sternchen umwandelt. Das mit der LED ist eigentlich so gewollt, sie soll neben dem Programm laufen. Nur weiß ich nicht wie ich sie bei Programmende auch abschalte. Du hast recht es ist viel zusammenkopiert. Der gesamte Kran wird nur mit einem Startsignal von der Fernsteuerung gestartet. Der Arm wird mit einem Schrittmotor gedreht und die Seilwinde mit einem Getriebemotor angetrieben. Für den Getriebemotor habe ich 2 Relais zu wechseln der Drehrichtung.
Schönen Sonntag

021aet04
19.07.2015, 10:22
Du muss den Interrupt wieder abschalten und die Led anschließend ausschalten. Wenn du nur den Interrupt abschaltest könnte es sein das die Led eingeschaltet bleibt.

Ansonsten würde ich empfehlen nicht einfach zusammen kopieren sondern Programme versuchen zu verstehen und im eigenen Programmierstil umzusetzten.

Ich weiß zwar nichts über arduino (bzw programmiersoftware), aber im avr Studio kann man einstellen wieviel ein Tabulatorsprung ist und ob diese in leerzeichen umgewandelt werden sollen. Vielleicht gibt es auch bei arduino so eine Einstellung.

MfG Hannes

HeXPloreR
19.07.2015, 11:30
Da es sich anscheinend um eine Demofunktion handelt würde versuchen an der Seilrolle eine Odometriescheibe oder ahnliches Verfahren anzubringen und direkt an der Rolle per Interrupt messen wie viele cm Seil abgerollt/aufgerollt wurden.
Bei ereichen eines vorher definiertem Wert hört die Seilwinde dann auf. Beachtem muss mann das man je nach Drehrichtung addiert oder subtrahiert. Aber da du ja eh Relais ansteuerts sollte es kein Problem darstellen das im programm mit zu erfassen.
Die LED soll/braucht vermutlich nicht so ganz genau im Sekundentakt blinken, dann reicht es hier die millis-Funktion zu nutzen.

Der nachfolgende Code ist für ein openCM9-Board welches auch mit Sketch/Arduino-IDE programmiert werden kann, und muss ggf angepasst werden:


millis()
: Returns the number of milliseconds since the Arduino board began running the current program.
This number will overflow (go back to zero), after approximately 50 days.
*/

// Variables:
long previousMillis = 0; // will store the last time the LED was updated
int interval = 1000; // interval at which to blink (in milliseconds)

void setup() {
// Set up the built-in LED pin as output:
pinMode(BOARD_LED_PIN, OUTPUT);
}

void loop() {
// Check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time we blinked
// the LED is bigger than the interval at which we want to blink

if ((int)millis() - previousMillis > interval) {
// Save the last time you blinked the LED
previousMillis = millis();

// If the LED is off, turn it on, and vice-versa:
toggleLED();
}
}

Es gibt auch noch andrere Lösungen die wo ein Interrupt alles 50ms ausgelöst wird und dann zwei Werte hochzählt (LED und Winde) und dann jenachdem das Programm abzweigt. Allerdings wird bei einem zeitlichen Ablauf der Seilwinde vermutlich immer wieder das Problem entsehen das die position nicht passt.

Einfache Endanschläge ( auch optische) könnten praktisch auch funktionieren. Allerdings kommt es darauf an wie gut man die hinzugefügt bekommt. Besonders beim Haken senken könnte es problematisch werden.

Valen
19.07.2015, 12:51
Kannst du auch diesen "TimerOne.h" Datei hochladen? sonnst können wir das nicht Kompilieren.

Oder ist das diesen Library?
https://github.com/PaulStoffregen/TimerOne

- - - Aktualisiert - - -

Oder einer von diese 2:
http://code.google.com/p/arduino-timerone/downloads/list

- - - Aktualisiert - - -

Wo sind s1 und s2 definiert in deine Code? Mein Arduino IDE meckert darüber beim Kompilieren.

- - - Aktualisiert - - -


Mechanisch funktioniert er und mit meinem geschriebenen Programm läuft er mit einigen Mängeln.
Könnte von Euch mal jemand ein Auge auf meinen Sketch werfen und mir mit Ideen zur Verbesserung weiterhelfen?Dann verwundere ich mich wie du diesen Mängeln behebst. Ich verstehe nicht wie du diesen Code auf dein Arduino hochgeladen hast. Ich sehe auf verschiedene stellen Code das nicht funktionieren/kompilieren kann.

Schiffe Bodo
19.07.2015, 15:45
Hallo und danke erstmal für eure Zeit die ihr mir spendet
Ich habe den ersten Timer aus der Libary (https://github.com/PaulStoffregen/TimerOne)

s1 Ist an Pin 4 und ist das Schaltsignal von der Fernsteuerung
s2 Ist an Pin 6 und ist ein Endschalter welcher am Zahnrad des Kran befestigt ist (zum Krandrehen), damit kann ich feststellen ob der Kran in der Drehbewegung in Grundstellung ist, Seil wird nicht abgefragt

Das musste ich machen da der Kran sonst in jeder beliebigen Position das Programm beginnen kann. Der Steppermotor hat keine Stellungsabfrage integriert.

Das Seilabrollen ist nicht sehr problematisch. Die Tauchtasse wird nur auf dem Deck abgestellt und an der anderen Position ins Wasser abgelassen. Da kommt es also auf ein paar millimeter nicht an. wichtig ist aber das Aufrollen, da der Haken den Arm berühren soll und diesen dann leicht mit anheben.

Die LED soll ab Startsignal blinken und wenn der Durchlauf beendet ist auch aufhören.

Noch zur Info ich benutze einen Arduino Uno.

Rabenauge
20.07.2015, 13:40
Das mit dem Seil wirst du mit Zeitsteuerung _nie_ in Griff bekommen. Motoren drehen sich ohne Regelung praktisch niemals reproduzierbar. Und für ne Regelung brauchst du ein Feedback.
Sinnvoll wäre hier sowas wie ein Mikrotaster, der dann gedrückt (oder losgelassen) wird, wenn der Haken den Kranarm bis Anschlag hochgezogen hat. Alternativ auch hier ein Schrittmotor, bei dem du die Umdrehungen mitzählen kannst-aber auch das geht daneben, wenn das Seil mal _etwas_ anders aufgewickelt wird.
Besser ist es in jedem Fall, die Endposition des Armes auszuwerden. Statt nem Taster kannst du hier zum Beispiel auch ne Lichtschranke benutzen, die in der Endposition unterbrochen wird, je nachdem, was sich besser nachrüsten lässt.

Schiffe Bodo
20.07.2015, 18:54
Danke Sly, ich hab mir das schon gedacht und mir schon einige Gedanken gemacht. es müsste mit einem Reedkontakt funktionieren, der am Kranausleger befestigt ist und vom am Haken befestigten Magneten ausgelöst wird. Ich dacht mir Haken oben( Kontakt geschlossen) Grundstellung Haken. aber bei einem Kran im Maßstab 1:45 ist das auch nicht ganz so einfach zu lösen ohne das Aussehen des Kranes zu sehr zu verändern. Eventuell geht auch ein kleiner Microschalter, muss ich mal schauen was es so gibt.
ich bin erstmal dabei mein Programm aufzuräumen und so zu laufen zu bringen wie ich es mir vorstelle.

Valen
21.07.2015, 20:58
Ok,

Ich habe S1 und S2 definiert wie du angegeben hat. Aber mit Großbuchstaben S, weil klein nicht erlaubt ist. (Verstehe ich auch nicht warum.) Jedenfals nicht ein einziges Kleinbuchstabe s (mit oder ohne weitere Nummer):

Und naturlich jeder stelle von s1 und s2 in den Code geändert zu S1, S2.


#define S1 4
#define S2 6

Und dann Kompiliert den IDE den Code ziemlich ohne Problemen. Ja, den Kompiler hat es Prima gefunden. Leider nicht für den Code-Polizei. :feuer

Weil du auf verschiedene stellen ein if-Befehl macht wie das hier:



if (Kranstart,HIGH) digitalWrite (RELAISAUF, HIGH);

Den Komma ist ein gültige Operator, aber es wird nicht ausgewertet wie du wahrscheinlich möchtest. (ausführen wenn Kranstart pin HIGH ist, oder nicht wann es LOW ist) Bei einer derartige if-Befehl wirdt den Komma-operator die erste Gesetzen vor den (letzte) Komma jedenfalls ausführen (den Variabel Kranstart macht nichts alleine). Aber nur das letzte Gesetz hinter der Komma wird für den Entscheidung sorgen. (HIGH=1, und alles was nicht gleich 0 ist wird immer als Wahr gekennzeichnet) Alles da vorne macht nichts dazu. Also was hier oben steht ist:


if ( 1!=0 ) digitalWrite (RELAISAUF, HIGH); // '1 ist nicht gleich an 0'
Deshalb wird das digitalWrite jedenfalls ausgeführt. Nur nicht wenn den Variabele Kranstart die wert 0 bekommen hat.

Die richtige Verwendung von ein if Befehl ist:

if ( digitalRead(Kranstart)==HIGH ) digitalWrite (RELAISAUF, HIGH);

Das gleiche passiert bei den while- loop am ende. Das hat nähmlich auch ein Quasi-if-Befehl in sich.

while(S2,HIGH);

Das ist ein Endloss-schleife, und dein Programm wird da niemals rauskommen. Arduino loop() wirdt nicht weiter loop-en.

Ok, dann haben wir nun die Logik Befehlen korrigiert. Dann stimmt es doch? Nein leider noch nicht.

Zurück zum anfang von den loop() Funktion:

void loop()
{ //Anfang der loop-Funktion

value = digitalRead(S2); // Endschalter wird eingelesen

digitalWrite(Kranstart,value); // Warte mall!! Kranstart ist als int definiert, und hat den wert HIGH (1) bekommen. Das ist doch kein Pin-bezeichnung!!!
// das ist gleich: digitalWrite(1, value); Wird kommisches verhalten geben mit den Seriele port (TX) Keine ahnung was Kranstart hier bedeuten soll.


{ // Wieso alles hiernach in ein {} scope einfassen? Sollte den { nicht gerade nach den ) kommen?

if ( digitalRead(Kranstart)==HIGH ) digitalWrite (RELAISAUF, HIGH);

// Hier ist das if-Befehl schon am ende, wegen der ; am ende des if-Befehls, und den fehlende { dazwischen. Alles hiernach wird jedenfalls ausgeführt.


delay(2600);
digitalWrite (RELAISAUF, LOW);
delay(2000);

myStepper1.step(-3600); //Kran ausdrehen (Winkel einstellen)
delay(2000); //Warten
digitalWrite (RELAISAB, HIGH);
delay(13000); //Seil ab für 13 sec
digitalWrite (RELAISAB, LOW);
delay(20000);

digitalWrite (RELAISAUF, HIGH);
delay(13000);
digitalWrite (RELAISAUF, LOW);
delay(2000);


myStepper1.step(3600); //Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH);
delay(2600);
digitalWrite (RELAISAB, LOW);
delay(5000);
} // Ende von if-Befehl Wahr-code

{
while(S2,HIGH); //Aber nür eines mall! Hängt hier ab. Gleich wie bei if Korrigieren.
}
} //Ende von loop()

- - - Aktualisiert - - -

Ok,

Ich habe S1 und S2 definiert wie du angegeben hat. Aber mit Großbuchstaben S, weil klein nicht erlaubt ist. Jedenfals nicht ein einzige Kleinbuchstabe s (mit oder ohne weiteres Nummer):

Und naturlich jeder stelle von s1 und s2 in den Code geändert zu S1, S2.


#define S1 4
#define S2 6

Und dann Kompiliert den IDE den Code ziemlich ohne Problemen. Ja, den Kompiler hat es Prima gefunden. Leider nicht für den Code-Polizei. :feuer

Weil du auf verschiedene stellen ein if-Befehl macht wie das hier:



if (Kranstart,HIGH) digitalWrite (RELAISAUF, HIGH);

Den Komma ist ein gültige Operator, aber es wird nicht ausgewertet wie du wahrscheinlich möchtest. (ausführen wenn Kranstart pin HIGH ist, oder nicht wann es LOW ist) Bei einer derartige if-Befehl wirdt den Komma-operator die erste Gesetzen vor den (letzte) Komma jedenfalls ausführen (den Variabel Kranstart macht nichts alleine), aber nur das letzte Gesetz hinter der Komma wird für den Entscheidung sorgen. (HIGH=1, und alles was nicht gleich 0 ist wird immer als Wahr gekennzeichnet) Alles da vorne macht nichts dazu. Also was hier oben steht ist:


if ( HIGH==1 ) digitalWrite (RELAISAUF, HIGH);
Deshalb wird das digitalWrite jedenfalls ausgeführt. Eben wenn Kranstart möglicherweise LOW oder 0 ist.

Die richtige Verwendung von ein if Befehl ist:

if ( digitalRead(Kranstart)==HIGH ) digitalWrite (RELAISAUF, HIGH);

Das gleiche passiert bei den while- loop am ende. Das hat nähmlich auch ein Quasi-if-Befehl in sich.

while(S2,HIGH);

Das ist ein Endloss-schleife, und dein Programm wird da niemals rauskommen. Arduino loop() wirdt nicht weiter loop-en.

Ok, dann haben wir nun die Logik Befehlen korrigiert. Dann stimmt es doch? Nein leider noch nicht.

Zurück zum anfang von den loop() Funktion:

void loop()
{ //Anfang der loop-Funktion

value = digitalRead(S2); // Endschalter wird eingelesen

digitalWrite(Kranstart,value); // Warte mall!! Kranstart ist als int definiert, und hat den wert HIGH (1) bekommen. Das ist doch kein Pin-bezeichnung!!!
// das ist gleich: digitalWrite(1, value); Wird kommisches verhalten geben mit den Seriele port (TX) Keine ahnung was Kranstart hier bedeuten soll.


{ // Wieso alles hiernach in ein {} scope einfassen? Sollte den { nicht gerade nach den ) kommen?

if ( digitalRead(Kranstart)==HIGH ) digitalWrite (RELAISAUF, HIGH);

// Hier ist das if-Befehl schon am ende, wegen der ; am ende des if-Befehls, und den fehlende { dazwischen. Alles hiernach wird jedenfalls ausgeführt.


delay(2600);
digitalWrite (RELAISAUF, LOW);
delay(2000);

myStepper1.step(-3600); //Kran ausdrehen (Winkel einstellen)
delay(2000); //Warten
digitalWrite (RELAISAB, HIGH);
delay(13000); //Seil ab für 13 sec
digitalWrite (RELAISAB, LOW);
delay(20000);

digitalWrite (RELAISAUF, HIGH);
delay(13000);
digitalWrite (RELAISAUF, LOW);
delay(2000);


myStepper1.step(3600); //Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH);
delay(2600);
digitalWrite (RELAISAB, LOW);
delay(5000);
} // Ende von if-Befehl Wahr-code

{
while(S2,HIGH); //Aber nür eines mall! Hängt hier ab. Gleich wie bei if Korrigieren.
}
} //Ende von loop()

Schiffe Bodo
22.07.2015, 07:19
Hallo Valen, erstmal vielen Dank an dich für deine Bemühung Ordnung in mein Programm(wenn man es so nennen will) zu bringen.
Ich werd mich jetzt ransetzen und versuchen deine Erklärungen zu übernehmen.

Valen
22.07.2015, 21:18
Bodo hat mir in einem PB geantwortet, aber ich möchte das gerner in dieses Thema weiter Diskusieren. Zo können mehrere mitlesen, und vielleicht auch davon lernen.

Seine letzte bearbeite code (Asteriks entfernt)


//Kran der Calypso ansteuern
//1 Stepper und 1 DC Motor


#include <Stepper.h>
#include "TimerOne.h"

#define LED 7 //WarnLED Kran in Bewegung
#define S1 4 //Starttaster von RC-Fernbedienung
#define S2 6 //Endschalter Kran in Ruheposition

int valueRC = digitalRead(S1); //Signal von RC-Fernbedienung OK
int KranOK = digitalRead(S2); //Signal vom Endschalter Kran Ruhepostion OK
int Kranstart = digitalRead((S1)&&(S2)); //Kran fertig zum Start

int SPMU1 = 32;
int RELAISAUF = 2; //Seil aufrollen
int RELAISAB = 3; //Seil abrollen


Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
pinMode(LED, OUTPUT);
Timer1.initialize(100000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
}

pinMode(S1,INPUT_PULLUP); // Signal Kran starten von RC-Fernbedienung
digitalWrite(S1,HIGH);
pinMode(S2,INPUT_PULLUP); // Schalter Kran in Ruheposition
digitalWrite(S2,HIGH);

pinMode(RELAISAUF,OUTPUT);
pinMode(RELAISAB,OUTPUT);

myStepper1.setSpeed(400);

valueRC = digitalRead(S1);
KranOK = digitalRead(S2);
Kranstart = digitalRead((S1,HIGH)&&(S2,HIGH))==HIGH; //Kran fertig zum Start
if(Kranstart==HIGH)
digitalWrite(Kranstart,HIGH);
else(Kranstart,LOW);
digitalWrite(Kranstart,LOW);
//digitalWrite(Kranstart)= (S1,HIGH)&&(S2,HIGH)==HIGH;
}
void callback(){
{
// Die LED blinkt unabhängig vom Programmcode in loop()
digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
}
}

void loop(){

valueRC = digitalRead(S1); //Signal von RC-Fernbedienung OK
KranOK = digitalRead(S2); //Signal vom Endschalter Kran Ruhepostion OK
Kranstart = digitalRead(Kranstart); //Kran fertig zum Start

Serial.begin(9600);

Serial.print("Channell 1:");
Serial.println (valueRC);

Serial.print ("Channell 2:");
Serial.println(KranOK);

Serial.print ("Channell 3:");
Serial.println(Kranstart);

delay(500);


if (digitalRead(Kranstart)==HIGH){

digitalWrite(RELAISAUF,HIGH);
delay(2600);
digitalWrite (RELAISAUF, LOW);
delay(2000);

myStepper1.step(-3600); //Kran ausdrehen (Winkel einstellen)
delay(2000); //Warten

digitalWrite (RELAISAB, HIGH);
delay(13000); //Seil ab für 13 sec
digitalWrite (RELAISAB, LOW);
delay(20000);

digitalWrite (RELAISAUF, HIGH);
delay(13000);
digitalWrite (RELAISAUF, LOW);
delay(2000);


myStepper1.step(3600); //Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH);
delay(2600);
digitalWrite (RELAISAB, LOW);
delay(5000);
}

else {

digitalWrite(RELAISAUF,HIGH);
delay(2600);
digitalWrite(RELAISAUF,LOW);
delay(2000);

myStepper1.step(S2==HIGH);
delay(2000);
}
{
while(Kranstart==HIGH);
}

}
Hilfe frage:
Ich habe aber folgendes Problem:
Der Schalter S1 soll ein Schaltkontakt von der RC-Fernbedienung sein.
Der Schalter S2 ist der Endlageschalter am Kran.
Kranstart soll High sein wenn S1 und S2 High sind.
Ich komme hier nicht weiter!!!!
Der Kran fährt los ohne die Schalter zu beachten! Was mache ich falsch?
Beide Schalter wechseln aber den Zustand wenn der Kran losfährt!
S1 kommt nur kurz von der RC-Fernbedienung zu Start.
S2 wird Low wenn der Kran sich vom Endschalter wegbewegt.
Wie kann ich das Lösen?
Wie kann ich die ganzen Delays vermeiden? Wie funktioniert das mit den Interrupts?


Bodo, bitte sag mal, was meinst du mit Kranstart? Ist das ein Speicherplatz das ein Zustand andeuten soll. Oder ist das ein Nummer das ein Schalter-pin für ein bestimmter Signal andeuten soll? Weil du das auf beiden Arten verwendest:

zbs Zeile 44 und 45:

if(Kranstart==HIGH) /* Kranstart als Zustand Variabele */
digitalWrite(Kranstart,HIGH); //Kranstart als Pin-nummer ....
Wenn Kranstart die Integer Wert 1 hat ist es gleich an HIGH, und deshalb wird digitalWrite dann die D1 Pin((Serial TX) HIGH machen. Dass wurde doch nicht deine Bedeutung sein!?!

Etwas höher in dein Programm:

#define S1 4 //Starttaster von RC-Fernbedienung
#define S2 6 //Endschalter Kran in Ruheposition

...
int Kranstart = digitalRead((S1)&&(S2)); //Kran fertig zum Start

"Kran fertig zum Start" ... Das sollte also den Anfangszustand bedeuten, oder?

Theoretisch sollte hier nur ein Anfangswert gegeben werden als initialisierung von den Speicherplatzt. Und nicht schon ein Pin-Messung gemacht werden. Das sollte am frühsten in setup() passieren, nach das einstellen der PinModus. (Eingang/Eingang mit Pull-up/Ausgang)

(S1 && S2) wird als (4 && 6) ausgewertet beim Kompilieren. Weil && ein Boolean/Boolesch Und-Operator ist meint dass (TRUE UND TRUE), was naturlich TRUE ist. Und das wird für digitalRead als ein Integer Wert 1 ausgewertet, und so wird wieder die Ausgangszustand von den Serial TX Pin eingelesen (Pin Nummer 1).


In setup():

Kranstart = digitalRead((S1,HIGH)&&(S2,HIGH))==HIGH; //Kran fertig zum StartIn meine Beitrag von gestern habe ich schon erklärt (hoffe ich, jedenfalls) das (S1,HIGH)&&(S2,HIGH) nicht stimmen kann mit deine Bedeutung. (Wenn ich das richtig verstehe) Das hat das gleiche Effekt als das Code Schnipsel hier oben.
Dann wird das: Kranstart= ( digitalRead(1)==HIGH );
Als Logik-Formel stimmt das, Kranstart wird hier TRUE wenn digitalRead ein HIGH eingelesen hat. Aber für dein Boot Projekt ist das wieder Unsinn weil 1 das Falscher Pin Nummer ist. Genauer wurde:


Kranstart = (digitalRead(S1)==HIGH) && (digitalRead(S2)==HIGH); //Kran fertig zum Start, wenn S1 HIGH ist UND S2 HIGH ist.


Am ende von setup():

if(Kranstart==HIGH) //Ist Kranstart ein Zustand?
digitalWrite(Kranstart,HIGH); // , ... oder Pin-nummer?
else (Kranstart,LOW); // else LOW; ... else 0; ... ??????

// Außerdem, achte auf das Punkt-Komma... hier kommt den else Befehl zu ende. Was hiernach kommt gehört nicht zu dem if-then-else!
digitalWrite(Kranstart,LOW); // Eben wenn die Zeile hier oben als "else Kranstart=LOW" gemeint ist, wieso danach noch die Pin LOW setzen?

Am Anfang von loop():

KranOK = digitalRead(S2); //Signal vom Endschalter Kran Ruhepostion OK
Kranstart = digitalRead(Kranstart); //Kran fertig zum Start

Nicht fertig, ... Kranstart = Pin-zustand von Serial RX oder TX Pin (Gewählt durch S2 Pin-zustand)

Am ende von loop():


{
while(Kranstart==HIGH);
}
Wieder ein Endloss-schleife, wenn Kranstart gleich 1 ist, kommt das Programm niemals weiter als den Punkt-Komma. (Ausserhalb den callback function, Flickern soll der LED schon weiter machen) Wieso die While-schleife hier eigentlich? Was hat das für Effekt in deiner Meinung?

- - - Aktualisiert - - -

Oh ja, nicht ganz Falsch, sondern die digitalWrites sind unnötig:

in setup()



pinMode(S1,INPUT_PULLUP); // Signal Kran starten von RC-Fernbedienung
Die richtige Kommentar wurde sein: Pin S1 als Eingang mit internen Pull-up einstellen; zu RCFernbedienung 'Kran starten'.


digitalWrite(S1,HIGH);
Wieso Pin S1 als Ausgang auf HIGH setzen? Es ist gerade noch als Eingang eingestellt. Den Pull-up macht das schon HIGH.


pinMode(S2,INPUT_PULLUP); // Schalter Kran in Ruheposition
Genau so wie oben bei S1: "Den Kran" oder "Den Schalter" ist nicht in Ruhe position. Sondern: diese Pin (zu dem Ruhe Position Schalter) ist eingestellt als Eingang (mit Pull-up)


digitalWrite(S2,HIGH);
Genau so wie oben bei S1.

Darf ich annehmen du verstehst was die Funktion einer Pull-up Widerstand ist? Es macht die Pin zustand HIGH eben wenn es nicht zu einer zustand gezwungen wird durch Spannungen von angeschlossen Leitungen.

Schiffe Bodo
23.07.2015, 06:56
Hallo Valen, danke für deine Erläuterungen. Ich weiß und hab es auch geschrieben gehabt das ich keine Erfahrung mit dem programmieren hab. Das kranprojekt läuft nun mal und ich bin auf Hilfe angewiesen.
Ich werde mich nochmal ransetzen und rumprobieren. Deine Erläuterungen helfen mir auf jeden Fall sehr. Du kannst das sehr gut erklären und ich denke ich habe auch verstanden was du geschrieben hast. Sorry für die PN. Du hast recht es wollen ja alle etwas lernen oder mitdiskutieren. Ich setze den überarbeiteten Code dann wieder rein. S1 soll der schaltimpuls von der Fernsteuerung sein. Ist also nicht die gesamte Zeit an. S2 ist ein Schalter der anzeigt das der Kran in anfangsstellung steht, also bereit ist zum starten. Auch S2 geht aus wenn der Kran sich von der grundstellung wegbewegt. Kranstart soll das Signal für den Arduino sein das der Kran sein Programm abspielen soll. Ich muss also S1 und S2 Zwischenspeichern bis zum Ende des Programmes. Die while Schleife habe ich reingemacht damit der Kran das Programm nur einmal durchläuft. Der Kran soll nach Ende des Programmablaufes warten bis zum nächsten Signal zum starten. Wenn S 2 nicht high oder true ist dann soll der Kran zu dieser Position hinfahren. Nur S1 und S2 high oder true zusammen ergeben kranstart true. Die pullup Funktion an den Tastern S1 und S2 hab ich reingemacht damit ich jetzt beim probieren nicht mit widerstanden arbeiten muss.
Danke Bodo

Schiffe Bodo
23.07.2015, 10:50
Hallo Zusammen, Hallo Valen. Ich hab mich jetzt nochmal hingesetzt und versucht deine Erklärungen zu befolgen. Hier der Code:



//Kran der Calypso ansteuern
//1 Stepper und 1 DC Motor

#include <Stepper.h>
#include "TimerOne.h"

#define LED 7 //WarnLED Kran in Bewegung
int S1 = 4; //Starttaster von RC-Fernbedienung
int S2 = 6; //Endschalter Kran in Ruheposition

boolean Kranstart = digitalRead((S1)&&(S2)); //Kran fertig zum Start

int SPMU1 = 32;
int RELAISAUF = 2; //Seil aufrollen
int RELAISAB = 3; //Seil abrollen


Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
pinMode(LED, OUTPUT);
Timer1.initialize(200000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
}
digitalWrite(S1,HIGH); // Taster von RC-Fernbedienung
digitalWrite(S2,HIGH); // Taster Kran in Ruheposition

pinMode(RELAISAUF,OUTPUT); // Relais für Seil AUF
pinMode(RELAISAB,OUTPUT); // Relais für Seil AB

myStepper1.setSpeed(400); // Steppermotor Kran drehen
}
void callback(){
{
// Die LED blinkt unabhängig vom Programmcode in loop()
digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
}

}
void loop() {

Kranstart = (digitalRead(S1)==HIGH) && (digitalRead(S2)==HIGH); //Kran fertig zum Start, wenn S1 HIGH ist UND S2 HIGH ist.

Serial.begin(9600);

Serial.print("Channell 1:");
Serial.println (digitalRead(S1));

Serial.print ("Channell 2:");
Serial.println(digitalRead(S2));

Serial.print ("Channell 3:");
Serial.println(digitalRead(Kranstart));

delay(50);

if (Kranstart == true){

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);

myStepper1.step(-3600); // Kran ausdrehen (Winkel einstellen)
delay(2000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(13000);
digitalWrite (RELAISAB, LOW); // Seil ab Stop

delay(20000); // Tauchtasse im Wasser (20sec)

digitalWrite (RELAISAUF, HIGH); // Seil auf Start
delay(13000);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);


myStepper1.step(3600); //Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(2600);
digitalWrite (RELAISAB, LOW); // Seil ab Stop
delay(5000);
}

else ((S2)==LOW);{ // Kran nicht fertig zum Start

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite(RELAISAUF,LOW); // Seil auf Stop
delay(1000);

myStepper1.step(100); // Kran drehen bis S2 HIGH
delay(1000);

digitalWrite(RELAISAB,HIGH); // Seil ab Start
delay(2600);
digitalWrite(RELAISAB,LOW); // Seil ab Stop
delay(1000);

digitalRead(S2==HIGH);

if((S2)==HIGH &&(S1)==LOW);{
while((S1)==HIGH); } // Warten bis zum neuen Programmstart
}
}

Ich habe für mich serial Monitor mit reingeschrieben um zu sehen was meine Taster machen.
Jetzt funktioniert Kranstart ( wenn S1 und S2 sind HIGH), leider funktioniert das Warten auf den nächsten Programmstart nur wenn S1 und S2 High sind.
Es wechseln ja beide S1 und S2 in low wenn der Kran sich bewegt. S1 geht weg weil das Signal von der Ferbsteuerung nur zum Starten benötigt wird. S 2 wechselt in Low wenn der Kran sich dreht und kommt am ende des Programmes wieder wenn der Kran in Ruheposition gefahren ist.
wenn jetzt S2 high ist und S1 low fährt der Kran immer weiter zum Taster S2. wenn dann Taster S1 high gesetzt wird läuft Programm normal weiter.
Wo liegt der Fehler? Ich komme nicht drauf.
Danke Bodo

Sisor
23.07.2015, 19:03
Sorry, aber ich seh nur Sterne!?

Schiffe Bodo
23.07.2015, 19:20
Die gesehenen Sterne kommen daher da ich die Leertaste benutze.

Valen
23.07.2015, 20:04
Bitte Recherchiere wie du das mit den Leertaste und * lösen kann. Weil das nicht normal ist. Ein Leertaste soll kein * anzeigen. Und es sehr ärgerlich wird wenn wir das jedes mal umsetzen müssen.

radbruch
23.07.2015, 20:31
Das ist vielleicht eine Einstellung im Editor. Leerzeichen durch Tab ersetzen oder so was

Valen
24.07.2015, 01:18
Erstmal etwas wichtiges was noch nicht erklärt ist:

Welcher Zustand hat das Fernbedienung S1 signal wenn den Kran nicht ausgehen soll? Ist es im rühe(nicht starten) HIGH oder LOW? Mit Pull-ups wird das HIGH, aber was macht der Fernbedienung?

Von S2 Schalter-signal hast du schon in das Privat Bericht angegeben das es LOW wird/ist wenn es nicht mehr gegen die Endschalter steht.

Hier unter habe ich dein Programm aufgeteilt in Stückchen, und unterbrochen auf Stellen wo du etwas falsch macht oder wo ein Problem entsteht.:


//Kran der Calypso ansteuern
//1 Stepper und 1 DC Motor

#include <Stepper.h>
#include "TimerOne.h"

#define LED 7 //WarnLED Kran in Bewegung
int S1 = 4; //Starttaster von RC-Fernbedienung
int S2 = 6; //Endschalter Kran in Ruheposition

// boolean Kranstart = digitalRead((S1)&&(S2)); //Kran fertig zum Start
Nein, S1 und S2 sind gerade als Pin-nummer definiert, aber die Pins sind noch nicht als Eingang eingestellt in setup(). Deshalb können wir nicht darauf verlassen das digitalRead die Schaltern richtig ausliest. Deshalb annehmen das die Kran nicht fertig ist. Es geht nur darum ein Fail-Safe anfangswert zu geben:

boolean Kranstart = false; //Kran Zustand-variabele





int SPMU1 = 32;
int RELAISAUF = 2; //Seil aufrollen
int RELAISAB = 3; //Seil abrollen


Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
pinMode(LED, OUTPUT);
Timer1.initialize(200000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
}
// digitalWrite(S1,HIGH); // Taster von RC-Fernbedienung
// digitalWrite(S2,HIGH); // Taster Kran in Ruheposition
Wieder nein! S1 und S2 bezeichnen die Pins wo den Ruheposition-Schalter und Fernbedienung angeschlossen sind. Da kommen Signalen rein! Deshalb ist es sinnlos die als Ausgang zu benutzen. Diese 2 digitalWrite Befehlen sollen ausgetauscht werden durch pinMode Befehlen die S1 und S2 als Eingängen machen:

pinMode(S1,INPUT_PULLUP); // RC-Fernbedienung Eingang mit Pull-up
pinMode(S2,INPUT_PULLUP); // Taster Eingang mit Pull-up, Kran in Ruheposition




pinMode(RELAISAUF,OUTPUT); // Relais für Seil AUF
pinMode(RELAISAB,OUTPUT); // Relais für Seil AB

myStepper1.setSpeed(400); // Steppermotor Kran drehen
}
void callback(){
{
// Die LED blinkt unabhängig vom Programmcode in loop()
digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
}

}
void loop() {

Kranstart = (digitalRead(S1)==HIGH) && (digitalRead(S2)==HIGH); //Kran fertig zum Start, wenn S1 HIGH ist UND S2 HIGH ist.

Serial.begin(9600);
Serial.begin gehört in den setup() Funktion. Nur wenn ein Programm die Serielle Port an/ausschalten möchtest, oder auf eine andere Baudtakt umstellen möchtest, sollte das irgendwo in ein weitere Funktion oder in den loop() Funktion vor kommen. Ein mal das Befehl ausführen soll hier reichen.



Serial.print("Channell 1:");
Serial.println (digitalRead(S1));

Serial.print ("Channell 2:");
Serial.println(digitalRead(S2));

Serial.print ("Channell 3:");
// Serial.println(digitalRead(Kranstart));
Kranstart ist kein Pin-nummer! Kann deshalb nicht an digitalRead gegeben werden als Parameter. Sonnst:

Serial.println(Kranstart);



delay(50);

if (Kranstart == true){

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);

myStepper1.step(-3600); // Kran ausdrehen (Winkel einstellen)
delay(2000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(13000);
digitalWrite (RELAISAB, LOW); // Seil ab Stop

delay(20000); // Tauchtasse im Wasser (20sec)

digitalWrite (RELAISAUF, HIGH); // Seil auf Start
delay(13000);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);


myStepper1.step(3600); //Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(2600);
digitalWrite (RELAISAB, LOW); // Seil ab Stop
delay(5000);
}

else ((S2)==LOW);{ // Kran nicht fertig zum Start

Was bedeutet ((S2)==LOW)? S2 ist als Pin-nummer Bezeichnung gemeint, und ist nur das Nummer 6. Das kann theoretisch nicht mit ein LOW Eingang-zustand verglichen werden. Dafür brauchen wir digitalRead(S2). Weil S2 und LOW im Gehirn von Arduino als ein Nummer geschrieben sind kann das Trotzdem kompiliert werden. Ist aber Kwatsch: "6==0".
Und else an-sich kann kein Bedingung haben. Für weitere Bedingungen sollte man mit ein neues if danach anfangen. ((S2)==LOW); wird nur als ein Vergleich-befehl ausgeführt, aber das Resultat wird ignoriert. Und den Punkt-Komma beendet den ese-Zweig. Das {} Code block danach steht also isoliert davon.

Besser:

else if (digitalRead(S2)==LOW) { // Kran nicht im Ruheposition -> zurück drehen





digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite(RELAISAUF,LOW); // Seil auf Stop
delay(1000);

myStepper1.step(100); // Kran drehen bis S2 HIGH
delay(1000);

digitalWrite(RELAISAB,HIGH); // Seil ab Start
delay(2600);
digitalWrite(RELAISAB,LOW); // Seil ab Stop
delay(1000);

digitalRead(S2==HIGH);Wieder Kwatsch! digitalRead braucht ein Pin Nummer als Parameter, du gibt ihn aber ein Logik-test wovon das Resultat entweder 1 oder 0 ist. Was versuchst du hier zu machen? S2 einlesen, oder HIGH machen?



// if((S2)==HIGH &&(S1)==LOW);{ Ich sehe kein digitalReads. Du vergleichst (6 gleich 1) und (4 gleich 0). Kwatsch-Logik, es ist nicht von den Elektronische Umwelt abhängig! Dazu, die Punkt-Komma ohne ein Befehl da vorne sagt das nichts gemacht werden soll. Die Code zwischen den {} danach ist deshalb wieder davon unabhängig.


if(digitalRead(S2)==HIGH && digitalRead(S1)==LOW) {



while((S1)==HIGH); } // Warten bis zum neuen Programmstart
}
}Gehen wir mal davon aus das du das if-Befehl als Bedingung für das eintreten von den while-loop möchtest, und den Punkt-Komma am ende von das if-Befehl dort nicht steht. Dann stimmt das hier nicht. Die bedingung zur eintreten der while-schleife ist das S1 LOW sein soll. Aber den Bedingung in den while-schleife zu bleiben ist das S1 HIGH sein soll. Ist es nicht, deshalb endet den while-schleife gleich den erste mal. Warten tut es denn nicht.

Schiffe Bodo
24.07.2015, 07:46
Vielen Dank an Valen, ich habe jetzt die von dir beschriebenen Codestellen verbessert und siehe da der Kran läuft. Ich Stelle den fertigen Code nochmal rein. Ich habe jetzt auch die Erläuterungen von Valen verstanden und hoffe ich kann es mir merken.

//Kran der Calypso ansteuern
//1 Stepper und 1 DC Motor

#include <Stepper.h>
#include "TimerOne.h"

#define LED 7 //WarnLED Kran in Bewegung
int S1 = 4; //Starttaster von RC-Fernbedienung
int S2 = 6; //Endschalter Kran in Ruheposition

boolean Kranstart = false; //Kran Zustand- Variable

int SPMU1 = 32;
int RELAISAUF = 2; //Seil aufrollen
int RELAISAB = 3; //Seil abrollen


Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
pinMode(LED, OUTPUT);
Timer1.initialize(200000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
}
pinMode(S1,INPUT_PULLUP); // RC-Fernbedienung Eingang mit Pull-up
pinMode(S2,INPUT_PULLUP); // Taster Eingang mit Pull-up, in Ruheposition

pinMode(RELAISAUF,OUTPUT); // Relais für Seil AUF
pinMode(RELAISAB,OUTPUT); // Relais für Seil AB

myStepper1.setSpeed(400); // Steppermotor Kran drehen

Serial.begin(9600);
}
void callback(){
{
// Die LED blinkt unabhängig vom Programmcode in loop()
digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
}

}
void loop() {

Kranstart = (digitalRead(S1)==HIGH) && (digitalRead(S2)==HIGH); //Kran fertig zum Start, wenn S1 HIGH ist UND S2 HIGH ist.



Serial.print("Channell 1:");
Serial.println (digitalRead(S1));

Serial.print ("Channell 2:");
Serial.println(digitalRead(S2));

Serial.print ("Channell 3:");
Serial.println(Kranstart);

delay(500);

if (Kranstart == true){

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);

myStepper1.step(-3600); // Kran ausdrehen (Winkel einstellen)
delay(2000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(13000);
digitalWrite (RELAISAB, LOW); // Seil ab Stop

delay(20000); // Tauchtasse im Wasser (20sec)

digitalWrite (RELAISAUF, HIGH); // Seil auf Start
delay(13000);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);


myStepper1.step(3600); // Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(2600);
digitalWrite (RELAISAB, LOW); // Seil ab Stop
delay(5000);
}

else if (digitalRead(S2)==LOW){ // Kran nicht fertig zum Start

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite(RELAISAUF,LOW); // Seil auf Stop
delay(1000);

myStepper1.step(50); // Kran drehen bis S2 HIGH
delay(1000);

digitalWrite(RELAISAB,HIGH); // Seil ab Start
delay(2600);
digitalWrite(RELAISAB,LOW); // Seil ab Stop
delay(1000);

//digitalRead(S2==HIGH);

if(digitalRead(S2)==HIGH && digitalRead(S1)==LOW)
{
while((S1)==LOW); } // Warten bis zum neuen Programmstart
}
}

Soweit alles gut.
Wie kann ich die LED nur dann zum blinken bringen wenn der Kran sich bewegt?
Bringt es etwas die Delays mit Interrupts zu steuern? Im Moment kann ich die Zeiten sehr gut einzeln einstellen. Ich denke dem Programm ist es Wurst wo es seine Zeiten herbekommt.
Ich muss jetzt noch beobachten wie sich die Position vom Seil (Haken) verhält, nach mehreren Durchläufen. Falls sich die Position des Hakens sehr verschiebt muss ich mir da auch noch eine Abfrage der Grundstellung einfallen lassen. Vielleicht überwache ich den Haken mit einem Microschalter wenn er in oberster Position ist.

Ich habe noch die Taster von high auf low umgeschrieben und den Kran angeschlossen. Läuft!!!!!!!!!!!!!!!

Nochmals vielen Dank, besonders an Valen, für eure Hilfe.

oberallgeier
24.07.2015, 08:16
Hallo Bodo!

... Ich Stelle den fertigen Code nochmal rein. Ich habe jetzt auch die Erläuterungen von Valen verstanden und ..Code, auch Teile davon, werden wesentlich leserlicher wenn Du den Code in ein Codefenster schreibst. Im Codefenster sind nämlich Einrückungen und Tabs deutlich(er) zu erkennen. Ich habe mal zur Demonstration nur Deinen Text von oben in ein Codefenster kopiert . . .

//Kran der Calypso ansteuern
//1 Stepper und 1 DC Motor

#include <Stepper.h>
#include "TimerOne.h"

#define LED 7 //WarnLED Kran in Bewegung
int S1 = 4; //Starttaster von RC-Fernbedienung
int S2 = 6; //Endschalter Kran in Ruheposition

boolean Kranstart = false; //Kran Zustand- Variable

int SPMU1 = 32;
int RELAISAUF = 2; //Seil aufrollen
int RELAISAB = 3; //Seil abrollen


Stepper myStepper1(SPMU1,10,11,12,13); //Kran drehen

void setup() {
{
pinMode(LED, OUTPUT);
Timer1.initialize(200000); // initialize timer1, and set a 1/2 second period
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
Timer1.pwm(9, 512); // setup pwm on pin 9, 50% duty cycle
}
pinMode(S1,INPUT_PULLUP); // RC-Fernbedienung Eingang mit Pull-up
pinMode(S2,INPUT_PULLUP); // Taster Eingang mit Pull-up, in Ruheposition

pinMode(RELAISAUF,OUTPUT); // Relais für Seil AUF
pinMode(RELAISAB,OUTPUT); // Relais für Seil AB

myStepper1.setSpeed(400); // Steppermotor Kran drehen

Serial.begin(9600);
}
void callback(){
{
// Die LED blinkt unabhängig vom Programmcode in loop()
digitalWrite(LED, digitalRead(LED) ^ 1); // EXOR invertiert
}

}
void loop() {

Kranstart = (digitalRead(S1)==HIGH) && (digitalRead(S2)==HIGH); //Kran fertig zum Start, wenn S1 HIGH ist UND S2 HIGH ist.



Serial.print("Channell 1:");
Serial.println (digitalRead(S1));

Serial.print ("Channell 2:");
Serial.println(digitalRead(S2));

Serial.print ("Channell 3:");
Serial.println(Kranstart);

delay(500);

if (Kranstart == true){

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);

myStepper1.step(-3600); // Kran ausdrehen (Winkel einstellen)
delay(2000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(13000);
digitalWrite (RELAISAB, LOW); // Seil ab Stop

delay(20000); // Tauchtasse im Wasser (20sec)

digitalWrite (RELAISAUF, HIGH); // Seil auf Start
delay(13000);
digitalWrite (RELAISAUF, LOW); // Seil auf Stop
delay(2000);


myStepper1.step(3600); // Kran eindrehen
delay(3000);

digitalWrite (RELAISAB, HIGH); // Seil ab Start
delay(2600);
digitalWrite (RELAISAB, LOW); // Seil ab Stop
delay(5000);
}

else if (digitalRead(S2)==LOW){ // Kran nicht fertig zum Start

digitalWrite(RELAISAUF,HIGH); // Seil auf Start
delay(2600);
digitalWrite(RELAISAUF,LOW); // Seil auf Stop
delay(1000);

myStepper1.step(50); // Kran drehen bis S2 HIGH
delay(1000);

digitalWrite(RELAISAB,HIGH); // Seil ab Start
delay(2600);
digitalWrite(RELAISAB,LOW); // Seil ab Stop
delay(1000);

//digitalRead(S2==HIGH);

if(digitalRead(S2)==HIGH && digitalRead(S1)==LOW)
{
while((S1)==LOW); } // Warten bis zum neuen Programmstart
}
}

Dazu wird beim Antworten (evtl. auf [Erweitert] drücken - rechts unten der mittlere Button) auf den Hashbutton (das # rechts oben) gedrückt. Es werden zwei Tags aufgemacht [.CODE.][./CODE.] , zwischen diesen kannst Du den Code einfügen. Alternativ die Einfügung markieren (linke Maustaste und mit Cursor-drüberfahren den betreffenden Text überstreichen) und DANACH sofort auf den #-Button.

Weiter viel Erfolg in Deinem Trockendock - und auf dem Wasser.

Schiffe Bodo
24.07.2015, 10:07
Danke für den Hinweis, ich versuch es zu beachten.

Valen
24.07.2015, 20:17
...
while((S1)==LOW); } // Warten bis zum neuen Programmstart
}
}

Soweit alles gut.Nein. Nicht ganz. Viel besser, aber das ende stimmt noch nicht. Die Bedingung von der while-schleife macht immer noch keinen Sinn. S1 ist 4, und LOW ist den Wert 0, also wird diese Vergleichung immer falsch.



Wie kann ich die LED nur dann zum blinken bringen wenn der Kran sich bewegt?Du verbindest gleich von Anfang ab in setup() den callback Funktion an den Timer1 Interrupt. Dann blinkt sie doch auch gleich wann Arduino auf-startet? Wieso das nicht nur machen auf das moment das den Kran anfangen soll sich zu bewegen? Und es gibt auch noch ein Funktion detachInterrupt womit das blinken gestoppt werden kann wenn nötig.
https://www.arduino.cc/en/Reference/DetachInterrupt



Nochmals vielen Dank, besonders an Valen, für eure Hilfe.Gerne gemacht. :)

Schiffe Bodo
24.07.2015, 22:54
Hallo Valen ich hab den LOW reingeschrieben weil ich doch interne pullup verwende. Also muss ich jetzt warten wenn ich wieder starten will bis ich LOW hab da der S 1 sonst immer HIGH hat. Ich hab es am Kran mit den Schaltern ausprobiert. Deshalb kann ich schreiben Kran funktioniert. Muss mir nur noch was überlegen wie ich den Kranhaken überwachen kann. Nach mehreren durchlaufen verschiebt sich die Position vom Haken. Der Kran ist ja nicht sehr groß deshalb muss ich erst schauen was ich am besten einbauen kann. Kran ist circa 10 cm hoch. Das mit den Interrupt hab ich mir schon öfters durchgelesen aber irgendwie verstehe ich das nicht wirklich. Könntest du mir das mal erklären? Vielleicht begreife ich das dann. Danke nochmal besonders an dich für deine Hilfe. Schönes Wochenende.

Rabenauge
25.07.2015, 13:48
Ist doch ganz einfach:

Wenn sich der Kran bewegt, startest du das Blinken mit
attachInterrupt(blinken);

Wird der Kran gestoppt, stoppst du auch das Blinken wieder mit

detachInterrupt(blinken);
und um sicher zu gehen, dass die LED hier auch aus geht (sie könnte in dem Moment ja an sein), schaltest du sie noch zusätzlich aus:
digitalWrite(LedPin, LOW);// das schaltet die LED ab-wenn sie zufällig schon aus war, passiert hier einfach nix

und fertig.

Schiffe Bodo
25.07.2015, 20:04
Danke für den Hinweis. Ich werde mal versuchen das umzusetzen.

Valen
25.07.2015, 21:02
Hallo Valen ich hab den LOW reingeschrieben weil ich doch interne pullup verwende. Also muss ich jetzt warten wenn ich wieder starten will bis ich LOW hab da der S 1 sonst immer HIGH hat.... Meine Verzeihung. Ich hab mich geirrt.

Schiffe Bodo
26.07.2015, 21:19
Valen bist halt ein guter Lehrer. Mit dem blinken nur wenn der Kran läuft komme ich immer noch nicht weiter. Ich hab in der Zwischenzeit einen Schalter für das Seil am Kran verbaut und den Code angepasst. Stelle ich morgen dann mal rein. Ich hab das ganze ja jetzt auf einem Uno laufen kann ich den Code auch auf einem Nano oder Mini betreiben oder muss da dann noch etwas angepasst werden.
Schönen Sonntag noch.

021aet04
26.07.2015, 22:09
Normalerweise muss man den Controller Typ beim Compiler umstellen, damit die ganzen Register passen. Die verwendeten Pins müssen natürlich auch passen.
Wie das geht weiß ich jedoch nicht.

MfG Hannes

Rabenauge
27.07.2015, 10:56
In der IDE selber geht das. Menüpunkt Tools->Board.
Beachte aber dass der Mini keinen USB-Anschluss hat.