Start / Stop Knopf

Hallo, ich habe zwar schon gute Erfahrungen mit Arduino gemacht, aber beim schreiben der Programme habe ich leider so meine Probleme. Leider helfen mir hierbei die ganzen Anleitungen nicht weiter.

Also das ganze soll ein Start Stop knopf fürs Auto werden. Er soll aber auch die zündung ein und ausschalten. Zudem das ganze über eine zwei Farbige LED Anzeigen.

Soweit habe ich die Ein und Ausgänge bestimmt und ihnen Namen gegeben.

Also: wenn ´´Knopf´´ ein mal kurz auf HIGH geht soll ´´Zündung´´ und ´´Rot´´ auf HIGH gehen und dort bleibt.
Geht ´´Knopf´´ nochmal kurz auf HIGH soll ´´Zündung´´ und ´´ROT´´ wieder auf LOW gehen und dort bleiben.
Das immer wieder als Schleife.

AUßER ´´Bremse´´ geht auf HIGH.
Wenn ´´Bremse´´ HIGH ist, und ´´Zündung´´sowei´´ROT´´ HIGH sind und dann ´´Knopf`` für 3sek. auf HIGH geht soll ´´Start´´ so lange auf HIGH gehen bis ´´Knopf´´ wieder auf LOW geht.

Wenn ´´Ladung´´ auf HIGH ist darf ´´Start´´ Niemlas auf HIGH gehen und ´´Gruen´´ soll HIGH sein.
Wenn ´´Ladung´´ auf HIGH ist und ´´Bremse´´ sowei ´´Knopf´´ für 3sek. auf HIGH gehen, soll ´´Zündung´´, ´´Gruen´´ und ´´Rot´´ auf LOW gehen.
Ich hoffe das ist verständlich.

Kann man eine Art Warheitstabelle in ein Arduino Programm schreiben?

Der Code unten zeig was ich schon gremacht habe.

void setup() {
 int Ladung = 13;
 int Knopf = 12; 
 int Bremse = 11;
 int Rot = 3; 
 int Gruen = 2; 
 int Zuendung = 1; 
 int Start = 0;

 pinMode(Ladung, INPUT),
        (Knopf, INPUT),
        (Bremse, INPUT),
        (Rot, OUTPUT),
        (Gruen, OUTPUT),
        (Zuendung, OUTPUT),
        (Start, OUTPUT);
 
 
}

void loop(){

}

da du die Pins auch im Loop benötigen wirst, wirst du die Pins ober setup() definieren müssen, damit sie global werden.
Da die Pins sich während der Laufzeit nicht verschieben, kannst sie auch const machen

const int Ladung = 13;

zur Umsetzungsfrage: Im ersten Schritt könntest du das ja "einfach" mit entsprechenden if/if else machen.

Dass du einen Arduino nicht so ohne weiteres im KFZ einsetzen kannst ist dir hoffentlich klar, ansonsten Google noch entsprechend danach.
Lesestoff: de.sci.electronics-FAQ V3.63 Stand: 5.11.23

Timbonade:
Also: wenn ...

Zeichne einen Programmablaufplan. Von dort bis zum fertigen Programm ist es dann nicht mehr weit.

Gruß

Gregor

Timbonade:
Kann man eine Art Warheitstabelle in ein Arduino Programm schreiben?

Mit logischen Operatoren kann man eine Menge machen. Allerdings hast Du auch zeitliche Bedingungen formuliert, weshalb ich eine Kombination aus Schrittkette (endlicher Automat = finite state machine) und Logik als mögliche Lösung sehe.

Hallo

noiasca:
da du die Pins auch im Loop benötigen wirst, wirst du die Pins ober setup() definieren müssen, damit sie global werden.
Da die Pins sich während der Laufzeit nicht verschieben, kannst sie auch const machen

Das ´´ober´´ soll bestimmt ´´über´´ heißen. Aber warum über Setup? Ich dachte alle Pin Belegungen usw. werden im Setup definiert.
Und was ist bitte Global machen?
Und wozu noch das ´´Const´´vor das ´´Int´´ ?

noiasca:
Dass du einen Arduino nicht so ohne weiteres im KFZ einsetzen kannst ist dir hoffentlich klar, ansonsten Google noch entsprechend danach.
Lesestoff: de.sci.electronics-FAQ V3.63 Stand: 5.11.23

Ja das ist mir klar, dass ich dazwischen noch Transistoren und Relais packen muss. Im angehängten Bild ist der erste aufbau gezeichnet. Aber ich wollte erst mal das Programm schreiben. Das was dahinter kommt kann ich immer noch ändern.

gregorss:
Zeichne einen Programmablaufplan. Von dort bis zum fertigen Programm ist es dann nicht mehr weit.

Ja mit sowas habe ich mich letztens schon beruflich befassen müssen, zwar mit einem Logik Diagram aber das ist auf den ersten Blick ja ähnlich. Ich werde es mal machen.

agmue:
...weshalb ich eine Kombination aus Schrittkette (endlicher Automat = finite state machine) und Logik als mögliche Lösung sehe.

Ja und da bin ich leider wieder raus. Was bedeutet was? Also Schrittkette kann ich mir ja noch denken aber endlicher Automat???

Andere Frage, ich habe was von Port Manipulation gehört von wegen ´´DDRD = B111100´´ womit man ja die pins in blöcke unterteilt und mit 1 und 0, HIGH und LOW bestimmt.
Oder sprengt das jetzt den Rahmen?

Timbonade:
Hallo
Das ´´ober´´ soll bestimmt ´´über´´ heißen. Aber warum über Setup? Ich dachte alle Pin Belegungen usw. werden im Setup definiert.
Und was ist bitte Global machen?
Und wozu noch das ´´Const´´vor das ´´Int´´ ?

schau dir das Beispiel in der IDE an BlinkWithoutDelay:

// constants won't change. Used here to set a pin number:
 const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
 const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
   // set the digital pin as output:
   pinMode(ledPin, OUTPUT);
}

const int ledPin = LED_BUILTIN;

steht oben/über/außerhalb von setup()
damit ist es eine Globale Variable. Sie steht in setup() und im loop() zur Verfügung.
würdest du sie in setup() definieren, stünde sie im loop() nicht zur Verfügung.

im setup (alles was einmalig bei Programstart gemacht werden soll) legst du dann den pinmode fest.

mit dem const teilst du dem Kompiler mit dass sich die Variable nicht ändert, und wenn du irrtümlich der Variable einen neuen Wert zuweisen würdest, weist dich der Kompiler darauf hin.

Timbonade:
Ja und da bin ich leider wieder raus. Was bedeutet was? Also Schrittkette kann ich mir ja noch denken aber endlicher Automat???

Ein Endlicher Automat ist eine Art Strickmuster für eine bestimmte Sorte von Abläufen. Evtl. hilft das hier.

Timbonade:
Andere Frage, ich habe was von Port Manipulation gehört von wegen ´´DDRD = B111100´´ womit man ja die pins in blöcke unterteilt und mit 1 und 0, HIGH und LOW bestimmt.
Oder sprengt das jetzt den Rahmen?

Ja, das ist wie mit A-, B- und C-Waffen auf Mücken loszugehen. Die normalen Arduino-Befehle genügen voll und ganz.

Gruß

Gregor

 int Ladung = 13;
 int Knopf = 12;
 int Bremse = 11;
 int Rot = 3;
 int Gruen = 2;
 int Zuendung = 1;
 int Start = 0;

Für den UNO gilt: Pin 13 als Eingang ist unglücklich und Pin 0 und 1 gehören USB. Wenn Du eine andere Hardware nutzt, kann es anders sein.

Timbonade:
Ja und da bin ich leider wieder raus. Was bedeutet was? Also Schrittkette kann ich mir ja noch denken aber endlicher Automat???

Ich habe ein Gleichheitszeichen vergessen: "eine Kombination aus Schrittkette (= endlicher Automat = finite state machine)"

Unterschiedliche Bezeichnungen für dieselbe Sache.

In einem anderen Thema findest Du ein Beispiel mit switch (schritt) als Schrittkette.

So wie ich das sehe fangen deine Probleme schon mit der Spannungsversorgung an.
Deinen Arduino direkt an das 12V Boardnetz zu hängen wird ohne weiter Maßnahmen einen
Absturz nach dem Selben erzeugen. Und damit dann "vitale" Systeme schalten ......

Du solltest schon mal über "fail save" Verhalten nachdenken.
Ok, wenn du vorm Baum hängst ist das auch eine Art von "fail save".

Ulli

Als Einstieg in die Schrittkette:

#include <CombieTimer.h> // Quelle: https://forum.arduino.cc/index.php?topic=542332.msg3716132#msg3716132
using Combie::Timer::EntprellTimer;

EntprellTimer entprellenLadung(30);
EntprellTimer entprellenKnopf(30);
EntprellTimer entprellenBremse(30);

const byte Ladung = 2;
const byte Knopf = 3;
const byte Bremse = 4;
const byte Rot = 9;
const byte Gruen = 10;
const byte Zuendung = 11;
const byte Start = 12;
uint32_t jetzt, vorhin;
const uint32_t drueckzeit = 3000;
byte schritt;
bool aktLadung, altLadung, aktKnopf, altKnopf, aktBremse, altBremse, einmal;
enum {WARTEN, ROT, ZEIT, GRUEN};

void setup() {
  pinMode(Ladung, INPUT_PULLUP);
  pinMode(Knopf, INPUT_PULLUP);
  pinMode(Bremse, INPUT_PULLUP);
  pinMode(Rot, OUTPUT);
  pinMode(Gruen, OUTPUT);
  pinMode(Zuendung, OUTPUT);
  pinMode(Start, OUTPUT);
}

void loop()
{
  jetzt = millis();
  altLadung = aktLadung;
  aktLadung = entprellenLadung(!digitalRead(Ladung)); // invers, wg. pullup
  altKnopf = aktKnopf;
  aktKnopf = entprellenKnopf(!digitalRead(Knopf)); // invers, wg. pullup
  altBremse = aktBremse;
  aktBremse = entprellenBremse(!digitalRead(Bremse)); // invers, wg. pullup

  switch (schritt)
  {
    case WARTEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, LOW);
        digitalWrite(Start, LOW);
      }
      if (aktBremse)
      {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ZEIT;
        }
      } else {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ROT;
        }
      }
      break;
    case ROT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
      }
      if (!altKnopf && aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
    case ZEIT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
        vorhin = jetzt;
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      if (jetzt - vorhin >= drueckzeit)
      {
        einmal = true;
        schritt = GRUEN;
      }
      break;
    case GRUEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, HIGH);
        digitalWrite(Zuendung, HIGH);
        digitalWrite(Start, HIGH);
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
  }
}

Wenn man CombieTimer zum Entprellen nimmt, kann man die Bibliuothek auch gleich für die Verzögerung verwenden:

Combie::Timer::SimpleTimer timer; // timer Instanz anlegen
using Combie::Timer::EntprellTimer;
EntprellTimer entprellenLadung(30);
EntprellTimer entprellenKnopf(30);
EntprellTimer entprellenBremse(30);

const byte Ladung = 2;
const byte Knopf = 3;
const byte Bremse = 4;
const byte Rot = 9;
const byte Gruen = 10;
const byte Zuendung = 11;
const byte Start = 12;
const uint32_t drueckzeit = 3000;
byte schritt;
bool aktLadung, altLadung, aktKnopf, altKnopf, aktBremse, altBremse, einmal;
enum {WARTEN, ROT, ZEIT, GRUEN};

void setup() {
  pinMode(Ladung, INPUT_PULLUP);
  pinMode(Knopf, INPUT_PULLUP);
  pinMode(Bremse, INPUT_PULLUP);
  pinMode(Rot, OUTPUT);
  pinMode(Gruen, OUTPUT);
  pinMode(Zuendung, OUTPUT);
  pinMode(Start, OUTPUT);
}

void loop()
{
  altLadung = aktLadung;
  aktLadung = entprellenLadung(!digitalRead(Ladung)); // invers, wg. pullup
  altKnopf = aktKnopf;
  aktKnopf = entprellenKnopf(!digitalRead(Knopf)); // invers, wg. pullup
  altBremse = aktBremse;
  aktBremse = entprellenBremse(!digitalRead(Bremse)); // invers, wg. pullup

  switch (schritt)
  {
    case WARTEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, LOW);
        digitalWrite(Start, LOW);
      }
      if (aktBremse)
      {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ZEIT;
        }
      } else {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ROT;
        }
      }
      break;
    case ROT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
      }
      if (!altKnopf && aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
    case ZEIT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
        timer.start();
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      if (timer(drueckzeit))
      {
        einmal = true;
        schritt = GRUEN;
      }
      break;
    case GRUEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, HIGH);
        digitalWrite(Zuendung, HIGH);
        digitalWrite(Start, HIGH);
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
  }
}

Hallo, und danke für die weiteren Antworten.

agmue:

 int Ladung = 13;

int Knopf = 12;
int Bremse = 11;
int Rot = 3;
int Gruen = 2;
int Zuendung = 1;
int Start = 0;



Für den UNO gilt: Pin 13 als Eingang ist unglücklich und Pin 0 und 1 gehören USB. Wenn Du eine andere Hardware nutzt, kann es anders sein.
Ich habe ein Gleichheitszeichen vergessen: "eine Kombination aus Schrittkette (= endlicher Automat = finite state machine)"

Unterschiedliche Bezeichnungen für dieselbe Sache.

In einem anderen Thema findest Du ein [Beispiel](https://forum.arduino.cc/index.php?topic=620652.msg4210768#msg4210768) mit switch (schritt) als Schrittkette.

Die genaue pin Belegung kann ich ja noch ändern. Danke für den Link.

beeblebrox:
So wie ich das sehe fangen deine Probleme schon mit der Spannungsversorgung an.
Deinen Arduino direkt an das 12V Boardnetz zu hängen wird ohne weiter Maßnahmen einen
Absturz nach dem Selben erzeugen. Und damit dann "vitale" Systeme schalten ......

Du solltest schon mal über "fail save" Verhalten nachdenken.
Ok, wenn du vorm Baum hängst ist das auch eine Art von "fail save".

Ulli

Ja irgend ein Fail Save werde ich mit hinein nehmen. Ich bin am überlegen z.B. die Zündung über ein selbst tragendes Relais zu machen und die zündung über ein öffner relai dann wieder aus zu Schalten, das lässt sich ja alles ändern sobald ich erst mal die Grund Programierung habe.
Und ich wollte den Arduino nicht direckt auf 12V Bordspannung legen, da ja eh von der Lichtmaschine bis zu 15 Volt geliefert werden. Es wird auf jeden fall ein DC/DC Step Up und Step Down davor gemacht, Zusätzlich ein Condensator um eventuelle Spannungsspitzen ab zu fangen.

agmue:
Als Einstieg in die Schrittkette:

#include <CombieTimer.h> // Quelle: https://forum.arduino.cc/index.php?topic=542332.msg3716132#msg3716132

using Combie::timer::EntprellTimer;

EntprellTimer entprellenLadung(30);
EntprellTimer entprellenKnopf(30);
EntprellTimer entprellenBremse(30);

const byte Ladung = 2;
const byte Knopf = 3;
const byte Bremse = 4;
const byte Rot = 9;
const byte Gruen = 10;
const byte Zuendung = 11;
const byte Start = 12;
uint32_t jetzt, vorhin;
const uint32_t drueckzeit = 3000;
byte schritt;
bool aktLadung, altLadung, aktKnopf, altKnopf, aktBremse, altBremse, einmal;
enum {WARTEN, ROT, ZEIT, GRUEN};

void setup() {
  pinMode(Ladung, INPUT_PULLUP);
  pinMode(Knopf, INPUT_PULLUP);
  pinMode(Bremse, INPUT_PULLUP);
  pinMode(Rot, OUTPUT);
  pinMode(Gruen, OUTPUT);
  pinMode(Zuendung, OUTPUT);
  pinMode(Start, OUTPUT);
}

void loop()
{
  jetzt = millis();
  altLadung = aktLadung;
  aktLadung = entprellenLadung(!digitalRead(Ladung)); // invers, wg. pullup
  altKnopf = aktKnopf;
  aktKnopf = entprellenKnopf(!digitalRead(Knopf)); // invers, wg. pullup
  altBremse = aktBremse;
  aktBremse = entprellenBremse(!digitalRead(Bremse)); // invers, wg. pullup

switch (schritt)
  {
    case WARTEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, LOW);
        digitalWrite(Start, LOW);
      }
      if (aktBremse)
      {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ZEIT;
        }
      } else {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ROT;
        }
      }
      break;
    case ROT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
      }
      if (!altKnopf && aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
    case ZEIT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
        vorhin = jetzt;
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      if (jetzt - vorhin >= drueckzeit)
      {
        einmal = true;
        schritt = GRUEN;
      }
      break;
    case GRUEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, HIGH);
        digitalWrite(Zuendung, HIGH);
        digitalWrite(Start, HIGH);
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
  }
}



Wenn man CombieTimer zum Entprellen nimmt, kann man die Bibliuothek auch gleich für die Verzögerung verwenden:



Combie::timer::SimpleTimer timer; // timer Instanz anlegen
using Combie::timer::EntprellTimer;
EntprellTimer entprellenLadung(30);
EntprellTimer entprellenKnopf(30);
EntprellTimer entprellenBremse(30);

const byte Ladung = 2;
const byte Knopf = 3;
const byte Bremse = 4;
const byte Rot = 9;
const byte Gruen = 10;
const byte Zuendung = 11;
const byte Start = 12;
const uint32_t drueckzeit = 3000;
byte schritt;
bool aktLadung, altLadung, aktKnopf, altKnopf, aktBremse, altBremse, einmal;
enum {WARTEN, ROT, ZEIT, GRUEN};

void setup() {
  pinMode(Ladung, INPUT_PULLUP);
  pinMode(Knopf, INPUT_PULLUP);
  pinMode(Bremse, INPUT_PULLUP);
  pinMode(Rot, OUTPUT);
  pinMode(Gruen, OUTPUT);
  pinMode(Zuendung, OUTPUT);
  pinMode(Start, OUTPUT);
}

void loop()
{
  altLadung = aktLadung;
  aktLadung = entprellenLadung(!digitalRead(Ladung)); // invers, wg. pullup
  altKnopf = aktKnopf;
  aktKnopf = entprellenKnopf(!digitalRead(Knopf)); // invers, wg. pullup
  altBremse = aktBremse;
  aktBremse = entprellenBremse(!digitalRead(Bremse)); // invers, wg. pullup

switch (schritt)
  {
    case WARTEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, LOW);
        digitalWrite(Start, LOW);
      }
      if (aktBremse)
      {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ZEIT;
        }
      } else {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ROT;
        }
      }
      break;
    case ROT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
      }
      if (!altKnopf && aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
    case ZEIT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
        timer.start();
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      if (timer(drueckzeit))
      {
        einmal = true;
        schritt = GRUEN;
      }
      break;
    case GRUEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, HIGH);
        digitalWrite(Zuendung, HIGH);
        digitalWrite(Start, HIGH);
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
  }
}

Was ist denn jetzt ´´entprellen´´? und wieso ´´byte´´? Also zum teil verstehe ich den Code ja aber der rest sagt mir nur Bahnhof. Sorry das ich so etwas machen will obwohl ich ein totaler Anfänger bin, und nicht mal irgend eine Programmiersprache kann.

Timbonade:
Was ist denn jetzt ´´entprellen´´?

Mechanische Kontakte "hüpfen" und geben viel An-Aus-Sequenzen, die Du in Deiner Logik nicht gebrauchen kannst. Daher werden die mechanischen Taster entprellt.

Timbonade:
wieso ´´byte´´?

Weil es nicht mehr als 256 Pins gibt. Anstelle von byte geht auch uint8_t.

Timbonade:
Was ist denn jetzt ´´entprellen´´?

Wenn ein Schalter oder Taster betätigt wird, wird der Kontakt nicht sofort geschlossen. Die Kontakte „federn“ und es kommt eine kurze Sequenz von an/aus-Impulsen zustande. Diese Prellzeit kann sehr kurz sein - sie ist aber bei allen mechanischen Kontakten vorhanden. Siehe Prellen – Wikipedia.

Timbonade:
Sorry das ich so etwas machen will obwohl ich ein totaler Anfänger bin, und nicht mal irgend eine Programmiersprache kann.

Ja, pfui, schäm' Dich! Restlos alle hier haben noch nie in Ihrem Leben etwas angefangen. Wir waren alle schon immer total fit in allem, was wir gemacht haben.

Gruß

Gregor :slight_smile:

Hallo.

agmue:
Mechanische Kontakte "hüpfen" und geben viel An-Aus-Sequenzen, die Du in Deiner Logik nicht gebrauchen kannst. Daher werden die mechanischen Taster entprellt.

Ok, entprellen leuchtet mir jetzt ein.

agmue:
Weil es nicht mehr als 256 Pins gibt. Anstelle von byte geht auch uint8_t.

Ich verstehe leider nicht warum man überhaupt das byte oder uint8_t davor schreiben muss?

mfg

warum man überhaupt das byte oder uint8_t davor schreiben muss?

Im Grunde kannst du davor schreiben, was du willst....

Hauptsache, es erfüllt seinen Zweck!

Und was seinen Zweck erfüllt ist:
const davor, denn der Pin wird sich über die Laufzeit hinweg nie ändern.
Und byte, da der Bereich ausreicht.
Auch ermöglicht es dem Compiler den erzeugten Code und Ramverbrauch zu optimieren.

Es erfüllt folgende Mantras:

  1. Sei explizit!
  2. Spare Ressourcen, wo es geht, ohne den Code unleserlich zu machen.

Ein Compiler braucht Festlegungen, wie er mit den zur Verfügung stehenden Informationen umgehen soll. Speicher ist bei Arduinos knapp, weshalb man durch geschickte Typenwahl diesen effektiv einsetzen kann. Die richtige Typenwahl gehört einfach zu einer Programmierung dazu und zeigt mir als Leser, ob Du Dir darüber Gedanken gemacht hast.

Allerdings hat der selbstoptimierende Compiler die eine oder andere Überraschung auf Lager, aber das ist dann ein Thema für Leute, die den erzeugten Maschinencode vergleichen.

Timbonade:
Ich verstehe leider nicht warum man überhaupt das byte oder uint8_t davor schreiben muss?

Gegenfrage. Warum schreibst du int? Erst dann kann deine Frage sinnvoll beantwortet werden.

Hallo mal wieder.

Ich habe den Code :

Combie::Timer::SimpleTimer timer; // timer Instanz anlegen
using Combie::Timer::EntprellTimer;
EntprellTimer entprellenLadung(30);
EntprellTimer entprellenKnopf(30);
EntprellTimer entprellenBremse(30);

const byte Ladung = 2;
const byte Knopf = 3;
const byte Bremse = 4;
const byte Rot = 9;
const byte Gruen = 10;
const byte Zuendung = 11;
const byte Start = 12;
const uint32_t drueckzeit = 3000;
byte schritt;
bool aktLadung, altLadung, aktKnopf, altKnopf, aktBremse, altBremse, einmal;
enum {WARTEN, ROT, ZEIT, GRUEN};

void setup() {
  pinMode(Ladung, INPUT_PULLUP);
  pinMode(Knopf, INPUT_PULLUP);
  pinMode(Bremse, INPUT_PULLUP);
  pinMode(Rot, OUTPUT);
  pinMode(Gruen, OUTPUT);
  pinMode(Zuendung, OUTPUT);
  pinMode(Start, OUTPUT);
}

void loop()
{
  altLadung = aktLadung;
  aktLadung = entprellenLadung(!digitalRead(Ladung)); // invers, wg. pullup
  altKnopf = aktKnopf;
  aktKnopf = entprellenKnopf(!digitalRead(Knopf)); // invers, wg. pullup
  altBremse = aktBremse;
  aktBremse = entprellenBremse(!digitalRead(Bremse)); // invers, wg. pullup

  switch (schritt)
  {
    case WARTEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, LOW);
        digitalWrite(Start, LOW);
      }
      if (aktBremse)
      {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ZEIT;
        }
      } else {
        if (!altKnopf && aktKnopf)
        {
          einmal = true;
          schritt = ROT;
        }
      }
      break;
    case ROT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
      }
      if (!altKnopf && aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
    case ZEIT:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, HIGH);
        digitalWrite(Gruen, LOW);
        digitalWrite(Zuendung, HIGH);
        timer.start();
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      if (timer(drueckzeit))
      {
        einmal = true;
        schritt = GRUEN;
      }
      break;
    case GRUEN:
      if (einmal) {
        einmal = false;
        digitalWrite(Rot, LOW);
        digitalWrite(Gruen, HIGH);
        digitalWrite(Zuendung, HIGH);
        digitalWrite(Start, HIGH);
      }
      if (!aktKnopf)
      {
        einmal = true;
        schritt = WARTEN;
      }
      break;
  }
}

Einfach mal kopiert, aber der Compiler meldet fehler. Ich muss bestimmt diese Bibliothek herunter laden oder eintragen. Oder was habe ich nun wieder nicht verstanden?

Sorry wenn ich hier alles von anderen machen lasse. ich muss wirklich mal C++ lernen glaube ich, damit ich so manche Abkürzungen einfach verstehe. Den mal wieder verstehe ich den Code zum teil, aber irgend wann hört es dann wieder auf und ich sehe nur noch irgend welche Zeichen, auf gut Deutsch, ich sehe den Wald vor lauter Bäumen nicht.

Ich weiß nicht jeder kann alles wissen, aber ich komme mir hier wie der Totale Depp vor...
Ich bin ja schon kurz davor zu sagen, komm schreib mir einer bitte das Fertige Programm mit allem was ich auf den Arduino aufspielen muss und er bekommt x € dafür.

:cold_sweat:

Danke erst mal an alle die sich an dem Thema beteiligen.

Ich habe den Code :

Ja, das nutzt Teile meiner Lib.

Ich muss bestimmt diese Bibliothek herunter laden oder eintragen. Oder was habe ich nun wieder nicht verstanden?

Ja, das hast du total richtig verstanden.
Im Quellcode findet sich ein Verweis auf die Lib.
Folge diesem.

Und ja, ganz einfach ist das Zeugs nicht zu verstehen, wenn man das dicke, über 1000 seitige, C++ Buch noch nicht auswendig gelernt hat.

Timbonade:
Ich weiß nicht jeder kann alles wissen, aber ich komme mir hier wie der Totale Depp vor...

Wenn ich mir die Bibliotheken von combie ansehe, geht es mir Hobbyprogrammierer nicht anders. Darum habe ich sie in diesem Beispiel mal als schwarze Kiste ausprobiert (mein Lerneffekt). Bei meinem Auto kenne ich auch nicht die Bedeutung jeder Strippe. Es genügt, wenn ich weiß, wo der Benzineinfüllstutzen ist und wie ich den Gasschlauch anschließe :smiley:

Timbonade:
Ich bin ja schon kurz davor zu sagen, komm schreib mir einer bitte das Fertige Programm mit allem was ich auf den Arduino aufspielen muss und er bekommt x € dafür.

Gute C++-Programmierer sind teuer, sei gewarnt 8)