Go Down

Topic: Servo in 4 Verschiedene Positionen fahren mit 3 Tastern (Read 1 time) previous topic - next topic

BeMarvelous

#45
Feb 01, 2019, 06:25 pm Last Edit: Feb 01, 2019, 06:31 pm by BeMarvelous
Hallo,

hab mir mal Gedanken gemacht u.a. auch wegen der Zündungsverzögerung.

Das switch case besteht nur aus Funktionsaufrufen die fast alle einen bool Status zurückmelden, sobald sie fertig sind. Wenn die Funktion ein "okay" (true) zurück gibt, dann springt switch zum nächsten case.
Wenn ich im Ablauf nichts falsch verstanden habe sollte es funktionieren wie gewünscht.

Du musst jetzt die Werte in Zeile
17, 18, 19
und
Zeile 44 bis 47
und
die Verzögerungszeiten für die Zündung in Zeile 86 und 112 anpassen. Derzeit beide auf 1000 ms gesetzt, damit was sieht.

Code: [Select]

/*
  Doc_Arduino - german Arduino Forum
  IDE 1.8.8
  Arduino Mega2560
  21.12.2018

  https://forum.arduino.cc/index.php?topic=564644.0

  Pinouts  >>> http://www.pighixxx.net/pinoutspg/boards/
  Uno      >>> http://www.pighixxx.net/portfolio-items/uno/?portfolioID=314
  Mega2560 >>> http://www.pighixxx.net/portfolio-items/mega/?portfolioID=314
*/

#include <Servo.h>

Servo S1;                         // Stellservo für Gänge
const byte pinPoti = A2;          // analoger Eingang vom Poti
const byte pinZuendung = 34;
const byte pinServo = 11;

enum state {WARTEN, ZUEND_AUS, SCHALTEN, CHECK_POS, ZUEND_EIN};
state zustand = WARTEN;

enum debug {RELEASE, DEBUG};    // serielle Debugausgaben nein/ja
const debug debugging = DEBUG;   

struct t_setup
{
  const byte taster;
  const byte servoWinkel;
  const unsigned int potiMin;
  const unsigned int potiMax;

  // Konstruktor
  t_setup (byte _t, byte _w, unsigned int _min, unsigned int _max):
    taster(_t),
    servoWinkel(_w),
    potiMin(_min),
    potiMax(_max)
  {}
};

t_setup Getriebe[] = {  // sämtliche konstante Einstellungen, Gänge gleich Indexnummer
  {2, 30, 780,  820},   // Tasterpin, Servowinkel, Poti Min/Max
  {3,  9, 950, 1000},
  {4, 60, 480,  520},
  {5, 90,  10,  100},
};
 
const byte ANZAHL = sizeof(Getriebe) / sizeof(Getriebe[0]);

struct t_aktuell  // Merker bzw. Zwischenspeicher
{
  byte gang = 0;                          // Neutralgang Startbedingung
  byte winkel = Getriebe[0].servoWinkel;  // Servo in Neutralgang Position
  unsigned long zeit = 0;
} merker;


void setup()
{
  Serial.begin(9600);
 
  for (byte i = 0; i < ANZAHL; i++) {
    pinMode(Getriebe[i].taster, INPUT);
  }
 
  pinMode(pinZuendung, OUTPUT);
  S1.attach(pinServo);
}

void loop()
{
 
  switch (zustand) {
    case WARTEN:  if (update_GetriebeGang() ){
                    zustand = ZUEND_AUS; 
                    merker.zeit = millis();
                    if (debugging == DEBUG) {
                      Serial.print("Gangwechsel zu "); Serial.println(merker.gang); 
                      Serial.println("status: ZUEND AUS");
                    }
                  } 
                  break;

    case ZUEND_AUS: if (delayZuendungAUS(1000, merker.gang, merker.zeit) ) {  // erster Wert Verzögerung zum Zündung ausschalten
                      zustand = SCHALTEN;
                      if (debugging == DEBUG) {
                        Serial.println(F("Zuendung ist aus"));
                        Serial.println(F("status: SCHALTEN "));
                      }
                    }
                    break;
     
    case SCHALTEN:  merker.winkel = Getriebe[merker.gang].servoWinkel;
                    zustand = CHECK_POS;
                    if (debugging == DEBUG) {
                      Serial.print(F("Servo move to "));Serial.println(merker.winkel);
                      Serial.println(F("status: CHECK_POS"));
                    }
                    break;
     
    case CHECK_POS: if (checkServoPosition(merker.gang) ) {
                      zustand = ZUEND_EIN;
                      merker.zeit = millis();
                      if (debugging == DEBUG) {
                        Serial.println(F("status: ZUEND EIN"));
                      }
                    }
                    break;

    case ZUEND_EIN: if (delayZuendungEIN(1000, merker.zeit) ) { // erster Wert Verzögerung zum Zündung einschalten
                      zustand = WARTEN;
                      if (debugging == DEBUG) {
                        Serial.println(F("Zuendung ist ein"));
                        Serial.println(F("status: WARTEN"));
                      }
                    }
                    break;               

    default: break;
  }

  moveServo(merker.winkel);   // Servo muss immer angesteuert werden

}


//

void moveServo(byte winkel)
{
  static unsigned long last_ms = 0;

  if (millis() - last_ms > 19) {
    S1.write(winkel);
    last_ms = millis();
  }

}

bool delayZuendungAUS(unsigned int delay, byte gang, unsigned long last_ms)
{
  static byte last_Gang = 0;
  bool state = false;

  if (last_Gang != gang)
  {
    if (millis() - last_ms >= delay) {
      digitalWrite(pinZuendung, LOW);
      last_Gang = gang;
      state = true;
    }
  }
  return state;
}


bool delayZuendungEIN(unsigned int delay, unsigned long last_ms)
{
  bool state = false;

  if (millis() - last_ms >= delay) {
    digitalWrite(pinZuendung, HIGH);
    state = true;
  }
  return state;
}


bool checkServoPosition(byte i)   // Gangnummer = Indexnummer
{
  bool state = false;

  unsigned int value = analogRead(pinPoti);

  if ( (Getriebe[i].potiMin < value) && (value < Getriebe[i].potiMax) )
  {
    state = true;
  }
  return state;
}


bool update_GetriebeGang()
{
  static byte last_Gang = 0;
  static byte new_Gang = 0;
  bool state = false;
 
  for (byte i = 0; i < ANZAHL; i++) {
    if (!digitalRead(Getriebe[i].taster) )
    {
      new_Gang = i;
    }
  }
 
  if (last_Gang != new_Gang) {
    last_Gang = new_Gang;
    merker.gang = new_Gang;
    state = true;
  }
 
  return state;
}

/*
// wie vorher nur mit Tasterentprellung
bool update_GetriebeGang()
{
  static byte last_Gang = 0;
  static byte new_Gang = 0;
  static unsigned long last_ms = 0;
  bool state = false;
 
  if (millis() - last_ms > 10) {
    last_ms = millis();
   
    for (byte i = 0; i < ANZAHL; i++) {
      if (digitalRead(Getriebe[i].taster) )
      {
        new_Gang = i;
      }
    }
  }

  if (last_Gang != new_Gang) {
    last_Gang = new_Gang;
    merker.gang = new_Gang;
    state = true;
  }
 
  return state;
}
*/


Hey :)

ich hatte jetzt endlich mal die Zeit und Lust wieder weiter zu machen (hab mich in letzter Zeit etwas mit dem anbauen der Komponenten beschäftigt) und hab deinen Sketch ausporbieren wollen, aber irendwie fährt bei mir der servo nur wenn ich gang 3 drücke, auf 60°, dann wird gewartet bis das poti anspricht und dann wird wieder auf 90° gefahren :O
Bei allen anderen Tastern passiert garnichts, angepasst habe ich die Werte aber alle...

Go Up