Mit RC Empfänger Arduino steuern

#include <Servo.h>

const byte PulseInCh1 = 4;
const byte PulseInCh2 = 5;
Servo servoRauch;
Servo motor;
Servo servo1;
const byte endschalter1 = 9;
const byte endschalter2 = 10;

const int aufheizen = 3000;
const int abkuehlen = 3000;
const int stuetze = 5000;
unsigned long rauchMillis;
unsigned long rauchIntervall;


enum RAUCH {warteAufRauch, servo90Grad, warteBisAufheizenFertig, servo180Grad, servoHalbZurueck, warteBisAbgekuehlt, servo0Grad};
byte rauch = warteAufRauch;

void setup()
{
  pinMode(PulseInCh1, INPUT);
  pinMode(PulseInCh2, INPUT);
  pinMode(endschalter1, INPUT);
  pinMode(endschalter2, INPUT);
  servoRauch.attach(6);
  motor.attach(7);
  servo1.attach(8);
}


void loop()
{
  switch (rauch)
  {
    case (warteAufRauch):
      if (PulseInCh1 > (1500))
        rauch = servo90Grad;
      break;

    case (servo90Grad):
      servoRauch.write(90);
      rauch = warteBisAufheizenFertig;
      break;

    case (warteBisAufheizenFertig):
      if (millis() - rauchIntervall >= aufheizen) {
        rauch = servo180Grad;
      }
      break;

    case (servo180Grad):
      servoRauch.write(180);
      rauch = servoHalbZurueck;
      break;

    case (servoHalbZurueck):
      if (PulseInCh1 < 1500) {
        rauch = servoHalbZurueck;
      }
      servoRauch.write(90);
      // abkuehlen = millis();
      rauch = warteBisAbgekuehlt;
      break;

    case (warteBisAbgekuehlt):
      if (millis() - rauchIntervall >= abkuehlen) {
        rauch = servo0Grad;
      }
      break;

    case (servo0Grad):
      servoRauch.write(0);
      rauch = warteAufRauch;
    break;
  }
}

Bitte schön.

Danke.

Jetzt kommt der böse Onkel und sagt: Wird so leider nicht funktionieren.

Jetzt schaust Dir nochmal in Ruhe Deine Zeitbehandlung an und prüfst, wann die if (millis()... jemals zutreffen werden.

Du musst es verstehen wollen, sonst wird das nix.

Pins benamsen!

  servoRauch.attach(6);
  motor.attach(7);
  servo1.attach(8);

Und für die "Erweiterungen":

const int aufheizen = 3000;

unsigned long.

Die Klammern sind noch immer drum.
Die 1500 ist auch noch immer ohne Benamsung.

Ist halt Potential...
Rest hat @wno158 schon angesagt.

Das kann ich mir vorstellen, aber für mich reichts.

Da lässt sich bestimmt noch drüber sprechen.

Ok. Habe mich mal an die 2. Funktion gesetzt. Hierdas komplette Skript:

#include <Servo.h>

const byte PulseInCh1 = 4;
const byte PulseInCh2 = 5;
Servo servoRauch;
Servo motor;
Servo servo1;
const byte endschalter1 = 9;
const byte endschalter2 = 10;

const int aufheizen = 3000;
const int abkuehlen = 3000;
const int stuetze = 5000;
unsigned long rauchMillis;
unsigned long rauchIntervall;
unsigned long stuetzenMillis;
unsigned long stuetzenIntervall;

enum RAUCH {warteAufRauch, servo90Grad, warteBisAufheizenFertig, servo180Grad, servoHalbZurueck, warteBisAbgekuehlt, servo0Grad};
byte rauch = warteAufRauch;

enum STUETZEN {warteAufStuetzen, tuerenAuf, warteBisOffen, stuetzenRaus, stuetzenStopRaus, stuetzenRein, stuetzenStopRein, tuerenZu};
byte stuetzen = warteAufStuetzen;

void setup()
{
  pinMode(PulseInCh1, INPUT);
  pinMode(PulseInCh2, INPUT);
  pinMode(endschalter1, INPUT);
  pinMode(endschalter2, INPUT);
  servoRauch.attach(6);
  motor.attach(7);
  servo1.attach(8);
}


void loop()
{
  switch (rauch)
  {
    case (warteAufRauch):
      if (PulseInCh1 > (1500))
        rauch = servo90Grad;
      break;

    case (servo90Grad):
      servoRauch.write(90);
      rauch = warteBisAufheizenFertig;
      break;

    case (warteBisAufheizenFertig):
      if (millis() - rauchIntervall >= aufheizen) {
        rauch = servo180Grad;
      }
      break;

    case (servo180Grad):
      servoRauch.write(180);
      rauch = servoHalbZurueck;
      break;

    case (servoHalbZurueck):
      if (PulseInCh1 < 1500) {
        rauch = servoHalbZurueck;
      }
      servoRauch.write(90);
      // abkuehlen = millis();
      rauch = warteBisAbgekuehlt;
      break;

    case (warteBisAbgekuehlt):
      if (millis() - rauchIntervall >= abkuehlen) {
        rauch = servo0Grad;
      }
      break;

    case (servo0Grad):
      servoRauch.write(0);
      rauch = warteAufRauch;
  }
  switch (stuetzen)
  {
    case (warteAufStuetzen):
      if (PulseInCh2 > (1500) && (digitalRead(endschalter2 == LOW)))
        stuetzen = tuerenAuf;
      break;

    case (tuerenAuf):
      servo1.write(90);
      stuetzen = warteBisOffen;
      break;

    case (warteBisOffen):
      if (millis() - stuetzenIntervall >= stuetze) {
        stuetzen = stuetzenRaus;
      }
      break;

    case (stuetzenRaus):
      if (digitalRead(endschalter2 == LOW)); {
        motor.write(90);      // muss noch auf Motorshield geändert werden
        stuetzen = stuetzenStopRaus;
      }
      break;

    case (stuetzenStopRaus):
      if (digitalRead(endschalter2 == HIGH)); {
        // Motor bleibt stehen. weiß noch nicht was hier hin kommt
      }
      stuetzen = stuetzenRein;
      break;


    case (stuetzenRein):
      if ((digitalRead(endschalter1 == LOW)) && (PulseInCh2 < 1500)); {
        motor.write(0);     // muss noch auf Motorshield geändert werden
      }
      stuetzen = stuetzenStopRein;
      break;

    case (stuetzenStopRein):
      if (digitalRead(endschalter1 == HIGH)) {
        // Motor bleibt stehen. weiß noch nicht was hier hin kommt
        stuetzen = tuerenZu;
      }
      break;

    case (tuerenZu):
      servo1.write(0);
      stuetzen = warteAufStuetzen;
      break;
  }
}

Nun habe ich noch ein paar Warnmeldungen wegen einiger Klammern, die ich wohl falsch gesetzt habe. Hier die Fehlerliste:

C:\Users\User\Documents\Arduino\Wrecker2\Wrecker2.ino: In function 'void loop()':
C:\Users\User\Documents\Arduino\Wrecker2\Wrecker2.ino:100:44: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
       if (digitalRead(endschalter2 == LOW)); {
                                            ^
C:\Users\User\Documents\Arduino\Wrecker2\Wrecker2.ino:107:45: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
       if (digitalRead(endschalter2 == HIGH)); {
                                             ^
C:\Users\User\Documents\Arduino\Wrecker2\Wrecker2.ino:115:69: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
       if ((digitalRead(endschalter1 == LOW)) && (PulseInCh2 < 1500)); {

Nun muss ich die Geschwindigkeit von "servo1" noch drosseln und statt "motor" als Servo zu behandeln, ihn über das Motorshield ansteuern.

Aber nicht mehr heute.
Und die Klammern entferne ich auch noch...

Das muss anders aussehen:

      if (digitalRead(endschalter2) == LOW)
      {
        motor.write(90);      // muss noch auf Motorshield geändert werden
        stuetzen = stuetzenStopRaus;
      }

Kurzschreibweise:

    case stuetzenRaus:
      if (!digitalRead(endschalter2))
      {

Das mag ja sein.
Um es mal mit einem positiven Ausblick in die Zukunft auszudrücken:
Du hast ein riesiges Verbesserungspotential was deine Programmierkenntnisse angeht!.

Weil du eher wenig Gehirnschmalz reinsteckst sondern fragst sobald du nicht weiterkommst.
Du könntest auch mal mit der Fehlermeldung des Compilers googlen.

Der momentane Wissensstand ist so klein, dass dir noch nicht einmal die Konseqenzen diese nachlässigen Programmierstils klar sind.

Und dann haben die anderen die doppelte Arbeit bis sie dein Programm nachvollziehen können. Wenn da einfach nur "7" steht. Dann muss man nachschauen was die "7" bedeutet. Man muss dann an vielen Stellen immer hin- und herschauen nur weil du zu bequem warst konsequent selbsterklärende Namen zu vergeben. Oder diese Arbeit die selbsterklärenden Namen einzufügen müssen auch noch die anderen machen.

Das Userforum ist schon zum Helfen da das ist völlig klar. Aber bei dir kommt das im Endeffekt doch beinahe einem "Kann mir mal jemand den Code schreiben?" gleich.
vgs

Sorry, beleidigen muss ich mich hier nicht lassen. Sie haben Ihre Art und ich meine. Ich möchte Sie höflich bitten sich hier einfach raus zu halten. Und es sind nicht alle Menschen so intelligent wie Sie. Also bitte einfach HIER mal die Klappe halten.

thread muted

Hallo, habe mich nochmal mit den milis() auseinander gesetzt. Und folgende Änderungen vorgenommen:

const int aufheizen = 3000;
const int abkuehlen = 3000;
const int stuetze = 5000;
//unsigned long rauchMillis;
unsigned long rauchInterval = 0;
//unsigned long stuetzenMillis;
unsigned long stuetzenInterval = 0;

Wobei meiner Meinung nach Zeile 4 und 6 überflüssig ist, da weder rauchMillis noch stuetzenMillis später irgendwo auftauchen.
Hier die erste Zeitfunktion:

 case warteBisAufheizenFertig:
      if (millis() > rauchInterval + aufheizen) {
        rauchInterval = millis();
        rauch = servo180Grad;
      }
      break;

Hoffe es ist richtig.
Und nochmal das ganze Skript (ohne Fehlermeldungen und Warnungen):

#include <Servo.h>

const byte PulseInCh1 = 4;
const byte PulseInCh2 = 5;
Servo servoRauch;
Servo motor;
Servo servo1;
const byte endschalter1 = 9;
const byte endschalter2 = 10;

const int aufheizen = 3000;
const int abkuehlen = 3000;
const int stuetze = 5000;
//unsigned long rauchMillis;
unsigned long rauchInterval = 0;
//unsigned long stuetzenMillis;
unsigned long stuetzenInterval = 0;

enum RAUCH {warteAufRauch, servo90Grad, warteBisAufheizenFertig, servo180Grad, servoHalbZurueck, warteBisAbgekuehlt, servo0Grad};
byte rauch = warteAufRauch;

enum STUETZEN {warteAufStuetzen, tuerenAuf, warteBisOffen, stuetzenRaus, stuetzenStopRaus, stuetzenRein, stuetzenStopRein, warteBisZu, tuerenZu};
byte stuetzen = warteAufStuetzen;

void setup()
{
  pinMode(PulseInCh1, INPUT);
  pinMode(PulseInCh2, INPUT);
  pinMode(endschalter1, INPUT);
  pinMode(endschalter2, INPUT);
  servoRauch.attach(6);
  motor.attach(7);
  servo1.attach(8);
}


void loop()
{
  switch (rauch)
  {
    case warteAufRauch:
      if (PulseInCh1 > (1500))
        rauch = servo90Grad;
      break;

    case servo90Grad:
      servoRauch.write(90);
      rauch = warteBisAufheizenFertig;
      break;

    case warteBisAufheizenFertig:
      if (millis() > rauchInterval + aufheizen) {
        rauchInterval = millis();
        rauch = servo180Grad;
      }
      break;

    case servo180Grad:
      servoRauch.write(180);
      rauch = servoHalbZurueck;
      break;

    case servoHalbZurueck:
      if (PulseInCh1 < (1500)) {
        rauch = servoHalbZurueck;
      }
      servoRauch.write(90);
      // abkuehlen = millis();
      rauch = warteBisAbgekuehlt;
      break;

    case warteBisAbgekuehlt:
      if (millis() > rauchInterval + abkuehlen) {
        rauchInterval = millis();
        rauch = servo0Grad;
      }
      break;

    case servo0Grad:
      servoRauch.write(0);
      rauch = warteAufRauch;
  }
  switch (stuetzen)
  {
    case warteAufStuetzen:
      if (PulseInCh2 > (1500))
        stuetzen = tuerenAuf;
      break;

    case tuerenAuf:
      servo1.write(90);
      stuetzen = warteBisOffen;
      break;

    case warteBisOffen:
      if (millis() > stuetzenInterval + stuetze) {
        stuetzenInterval = millis();
        stuetzen = stuetzenRaus;
      }
      break;

    case stuetzenRaus:
      digitalRead(endschalter2);
      if (endschalter2 == LOW) {
        motor.write(90);      // muss noch auf Motorshield geändert werden
        stuetzen = stuetzenStopRaus;
      }
      break;

    case stuetzenStopRaus:
      digitalRead(endschalter2);
      if (endschalter2 == HIGH) {
        // Motor bleibt stehen. weiß noch nicht was hier hin kommt
      }
      stuetzen = stuetzenRein;
      break;


    case stuetzenRein:
      if (PulseInCh2 < 1500) {
        motor.write(0);     // muss noch auf Motorshield geändert werden
      }
      stuetzen = stuetzenStopRein;
      break;

    case stuetzenStopRein:
      digitalRead(endschalter1);
      if (endschalter1 == HIGH) {
        // Motor bleibt stehen. weiß noch nicht was hier hin kommt
        stuetzen = warteBisZu;
      }
      break;

    case warteBisZu:
      if (millis() > stuetzenInterval + stuetze) {
        stuetzenInterval = millis();
        stuetzen = tuerenZu;
      }
      break;

    case tuerenZu:
      servo1.write(0);
      stuetzen = warteAufStuetzen;
      break;
  }
}

Bitte um kurze Rückmeldung.

Dann kennst Du Deinen Code nicht.
-> Du hast die ja auskommentiert - das ist dann aber nicht Zeile 4 und 6 ! GRMPF!
Der Compiler hat recht.
STRG-F

Das positive ist: Du hast gemerkt, dass der Startpunkt für die Wartezeit in rauchInterval gesetzt werden muss. Schön!

Du solltest nochmal überlegen, in welchem Zustand (an welcher Stelle) das passieren sollte. Da wo es jetzt steht bin ich nicht einverstanden.

Ich meinte Zeile 4 und 6 in dem kurzen Skript-schnipsel. Im gesamt Skript ist es Zeile 14 und 16. Und auch mit der Suchfunktion finde ich rauchMillis und stuetzenMillis nicht.
Oder meinst du was anderes? Dann verstehe ich nicht was du meinst.

Muss das rauchInterval = millis(); vor dem if stehen?

Alles gut :wink:
Ich war nur verwirrt.
ZeilenAngaben nehm ich immer aus dem vollständigen Code...
Mein Fehler.

Wenn der Compiler meint, er findet nichts unzugewiesenes, ist das ok.

Hmm - ja.
Aber nicht da wo Du vermutlich vermutest :slight_smile:
Die richtige Stelle ist m.E. dort, wo Du den Heizer startest und damit die Wartezeit anfängt.

    case servo90Grad:
      servoRauch.write(90);
      rauchInterval = millis();
      rauch = warteBisAufheizenFertig;
      break;

    case warteBisAufheizenFertig:
      if (millis() > rauchInterval + aufheizen) {
        rauch = servo180Grad;
      }
      break;

Einverstanden?

Daran habe ich überhaupt nicht gedacht...

Wenn Du mich fragst: Nein.
Die Beschreibung "rauchIntervall" bringt schon alles durcheinander.
Beim Überlauf frisst Dich das auf. Das machst doch sonst auch nicht.
Mach aus dem Intervall einen Merker und dann anders vergleichen.

rauchStartZeit = millis();
[...]
if (millis() - rauchStartZeit > aufheizen) {

Ach nee :wink:
Ich habe nur im existierenden Code die Verschiebung des Setzens der (wohl missverständlich benannten) Variablen an die richtige Stelle vorgenommen.

Für den Rest gilt die schon geäußerte "Potentialvermutung". Da André nach eigener Aussage ja soweit zufrieden ist und kein Raucherzeuger 40 Tage läuft... lasse ich zumindest es dabei.

Was ich gerne sehen würde wäre ein kleines Video, wo statt des Raucherzeugers ein Servo mit Hebelarm (Zeiger) angeschlossen ist und an der Funke der Schalter betätigt wird und das Programm dann abläuft. Bis hierhin scheint mir das doch eine Trockenübung gewesen zu sein - aber auch ich irre (und das nicht selten).

Das ganze ist schon für ein reales Modellbauprojekt. Allerdings bin ich auch da noch nicht allzuweit.

1 Like