Programmierung mit Arduino

Hallo Leute,

Bin Anfänger habe gerade rst angefangen mit Arduino zu arbeiten.

Habe gleich am Anfang ne Aufgabenstellung die ich gerne lösen würde, vielleicht kann mir da jemand unterstützend zur Seite stehen .

Aufgabenstellung kurzform:

Von einem Bedien-Panel aus soll eine Steuerung umgesetzt werden.
Das Panel hat 4 Taster ( Taster1 bis 4 beschriftet, Schließer ) und ein LC Display.

Das LC Display soll bei nicht gedrücktem Taster immer "Bitte Programm wählen" anzeigen.
Beim Drücken eines Tasters ( z.B. Taster1 ) soll eine LED aufleuchten und auf dem LC Display soll " Programm1" erscheinen.

Desweiteren soll sich ein Ventilator ( Im Versuch ein einfacher Motor ) anfangen zu drehen.

Durch nochmaliges Betätigen des Tasters soll alles zum stillstand kommen und im LC Display soll wieder "Bitte Programm wählen" erscheinen.

Hier mein Ansatz:

#include <LiquidCrystal.h>
const int TasterPin = 9;   
const int LaserPin =  7;     
int merker=0;
int TasterZustand = 0;       
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
  {
    pinMode(LaserPin, OUTPUT);     
    pinMode(TasterPin, INPUT);
  }

void loop()
{
 
   TasterZustand = digitalRead(TasterPin);

  if ((TasterZustand == HIGH)&&(merker==0))
    {   
      digitalWrite(LaserPin, LOW);
      merker=1;
      lcd.begin(16, 2);
      lcd.print("Bitte Programm  waehlen");
   
    }
   
  if ((TasterZustand == LOW)&&(merker==1))
    {   
      merker=2;
      lcd.begin(16, 2);
      lcd.print(" Programm 1");
    }
   
  if ((TasterZustand == HIGH)&&(merker==2))
    {
       digitalWrite(LaserPin, HIGH);
       merker=3;
    }
   if ((TasterZustand == LOW)&&(merker==3))
    {   
       merker=0;
    }

}

Das ist allerdings nur für einen Taster umgesetzt.
Wie baue ich die übrigen Taster2-4 ein ??
Und an welcher Stelle setzte ich den Motor Code ein ?? ( Also vielleicht eine Funktion void Motor(); )
Kann ich das ganze vielleicht auch mit Funktionen umsetzen ??

Ich bitte um Hilfe, vielleicht hat jemand gute Ideen für die Umsetzung

Mit Dank im Vorraus und freundlichen Grüßen

Chris

Willkommen im Forum :slight_smile:

Für die Taster 2 - 4 kannst du's genauso machen wie für den Taster 1.
Solltest dann vllt. "TasterZustand1", "TasterZustand2", usw. machen.

Der Code "lcd.begin(16,2);" kommt übrigens in's viod setup(), das brauchst du nur einmal.
Auch solltest du von "lcd.setCDursor(x,y);" gebrauch machen, sonst schreib er dir "Programm 1" in die 2 Zeile, in der ersten Zeile bleibt "Bitte Programm waehlen" stehen. Letzteres sind übrigens 22 Zeichen. Heißt, dass er die letzten 6 Zeichen entweder in Zeile 2 oder irgendwo im nirgendwo niederschreibt.

Wenn du eine Funktion Motor() schreiben willst, dann setzt du die außerhalb der anderen voids ein.
Also z. B.:

void setup()
{

}

void loop ()
{

}

void Motor()
{

}

Und in dem Teil, in dem du die Funktion Motor aufrufen willst, schreib du einfach "Motor();".

LG

Fipsi

Hallo,

Vielen Dank für die schnelle Antwort.

Also ich hab schon versucht TasterZustand2 .. 3... 4 mit reinzunehmen.
Hab dann in den if Anweisungen geschrieben :

TasterZustand=digitalRead(TasterPin);
TasterZustand2=digitalRead(TasterPin2);
....
....

if ( (TasterZustand=HIGH)||(TasterZustand2=HIGH)||.......()&&(merker==0))

aber funktioniert leider nicht.

Und bei der Motor Funktion ist mir noch nicht klar ob ich dann auch die ganzen Deklarationen mit reinnehmen muss wie : pinMode() und intMotorPin=12; also alles was sonst in setup und obendrüber in den globalen Deklarationen steht und sich auf den Motor bezieht .

Bitte um Klärung, dankeschön :slight_smile:

Grüße

Chris

= ist eine Zuweisung
== ist ein Vergleich

Variablen die überall sichtbar sein müssen, müssen außerhalb von Funktionen deklariert werden. Variablen die innerhalb einer Funktion deklariert werden existieren auch nur dort.

So wird das mit den Tastern nicht funktionieren. Die solltest du richtig entprellen (entweder über Hardware oder Software(bevorzugt!)).

Chris85:
Aufgabenstellung kurzform:

Von einem Bedien-Panel aus soll eine Steuerung umgesetzt werden.
Das Panel hat 4 Taster ( Taster1 bis 4 beschriftet, Schließer ) und ein LC Display.

Das LC Display soll bei nicht gedrücktem Taster immer "Bitte Programm wählen" anzeigen.
Beim Drücken eines Tasters ( z.B. Taster1 ) soll eine LED aufleuchten und auf dem LC Display soll " Programm1" erscheinen.

Desweiteren soll sich ein Ventilator ( Im Versuch ein einfacher Motor ) anfangen zu drehen.

Durch nochmaliges Betätigen des Tasters soll alles zum stillstand kommen und im LC Display soll wieder "Bitte Programm wählen" erscheinen.

Deine Aufgabenstellung ist in sich widersprüchlich formuliert und kann schon alleine deshalb nicht in ein Arduino-Programm umgesetzt werden. Was Du in der Sprache "Deutsch" nicht eindeutig und in sich fehlerfrei formulieren kannst, das kannst Du auch nicht in die Programmiersprache "C" so übersetzen, dass es als Programm eindeutig und feherfrei funktioniert.

Einerseits schreibst Du "Das LC Display soll bei nicht gedrücktem Taster immer "Bitte Programm wählen" anzeigen" und das bedeutet: Sobald man einen Button drückt und diesen wieder loslässt, ist alles wieder auf Null.

Danach schreibst Du "Durch nochmaliges Betätigen des Tasters soll alles zum stillstand kommen und im LC Display soll wieder "Bitte Programm wählen" erscheinen" und das passt mit der ersten Aussage nicht zusammen. Denn wenn Du aus dem Zustand "nicht gedrückt" den Schalter runterdrückst, soll das Programm ja starten.

Als erstes mal müßtest Du die Programmaufgabe in vernünftigem Deutsch logisch Fehlerfrei formulieren können, sonst wird das auch mit dem Programm nichts.

Entweder ist die Programmlogik wie folgt:

  • Wenn kein Schalter gedrückt ist: "Bitte Programm wählen"
  • Wenn ein Schalter gedrückt und gehalten wird "Programm1"
  • Wenn dieser Schalter losgelassen wird: Programmende und "Bitte Programm wählen"

Oder die Programmlogik ist wie folgt:

  • Wenn kein Schalter gedrückt ist: "Bitte Programm wählen"
  • Wenn Schalter gedrückt wird "Programm1"
  • Der Schalter wird losgelassen - nichts ändert sich
  • Der Schalter wird nochmals gedrückt: Programmende und "Bitte Programm wählen"

Und in beiden Fällen gäbe es noch die Untervarianten:

  • es kann stets nur ein Programm zur selben Zeit gestartet sein
  • es können verschiedene Programme zur selben Zeit gestartet sein

Die erste Aufgabe beim Programmieren ist immer eine Deutschaufgabe (oder eine Englischaufgabe, falls Englisch Dir besser liegt): Formuliere die gewünschte Programmfunktion!

Und zwar sowohl vom Ablauf her eindeutig als auch in sich logisch und fehlerfrei.

jurs:
Entweder ist die Programmlogik wie folgt:

  • Wenn kein Schalter gedrückt ist: "Bitte Programm wählen"
  • Wenn ein Schalter gedrückt und gehalten wird "Programm1"
  • Wenn dieser Schalter losgelassen wird: Programmende und "Bitte Programm wählen"

Oder die Programmlogik ist wie folgt:

  • Wenn kein Schalter gedrückt ist: "Bitte Programm wählen"
  • Wenn Schalter gedrückt wird "Programm1"
  • Der Schalter wird losgelassen - nichts ändert sich
  • Der Schalter wird nochmals gedrückt: Programmende und "Bitte Programm wählen"

noch eine weitere Variante ist denkbar:

  • Wenn Schalter1 gedrückt wird "Programm1"
  • Der Schalter wird losgelassen - nichts ändert sich
  • Wenn eine beliebige Taste gedrückt wird: Programmende und "Bitte Programm wählen"

Das setzt voraus, dass nach der Auswahl eines Programms kein alternatives Programm gewählt werden kann, bis das zuerst gestartete beendet ist.

Manfred

Hallo,

Danke für die vielen Antworten zu meinem Problem.

Ich hätte vielleicht die Aufgabenstellung eins zu eins abschreiben sollen, dann wäre es für euch verständlicher gewesen :slight_smile:

Also das was Sie schreiben:

  • Wenn kein Taster gedrückt ist: "Bitte Programm wählen"
  • Wenn Taster gedrückt wird "Programm1"
  • Der Taster wird losgelassen - nichts ändert sich
  • Der Taster wird nochmals gedrückt: Programmende und "Bitte Programm wählen"

und

  • es kann stets nur ein Programm zur selben Zeit gestartet sein

Diese Variante würde die Aufgabenstellung am besten erfüllen.

Ich bitte um Endschuldigung wenn ich für Verwirrung gesorgt habe, dass war nicht meine Absicht.

Desweiteren möchte ich mich bedanken, für die Zeit die Sie alle investieren um mir Hilfeleistung zu geben.

Mit freundlichen Grüßen

Chris

Chris85:

  • Wenn kein Taster gedrückt ist: "Bitte Programm wählen"
  • Wenn Taster gedrückt wird "Programm1"
  • Der Taster wird losgelassen - nichts ändert sich
  • Der Taster wird nochmals gedrückt: Programmende und "Bitte Programm wählen"

und

  • es kann stets nur ein Programm zur selben Zeit gestartet sein

Was mich mal interessiert:
Hat Dich mit der Aufgabe eigentlich jemand ins kalte Wasser geschmissen, ohne dass Du zur Lösung der Aufgabe irgendwie in geeigneter Weise fachlich ausgebildet worden bist?

Oder hast Du Dich in eigener Selbstüberschätzung für diese Aufgabe freiwillig gemeldet?

Anyway.
Bei einer solchen Aufgabe mit fünf Tastern und fünf einzeln zu schaltenden Ausgängen kommen natürlich schon ein paar Dinge zusammen. Datenstrukturen und Algorithmen, globale und lokale Variablen, selbstgeschriebene Funktionen, Enumerationen, Arrays, for-Schleifen, if-Bedingungen. Strukturierte Programmierung, wenn es übersichtlich bleiben soll.

Ich poste Dir mal ein Programmgrundgerüst.
Vielleicht kannst Du Dir was abgucken und dann für Deine Aufgabe soweit fertigstellen.

Das meiste sollte drin sein, und ich habe versucht, das Programm nach dem EVA-Prinzip zu strukturieren, so dass wenigstens die loop-Funktion einfach aussieht:

void loop() 
{
  eingabe();
  verarbeitung();
  ausgabe();
}

In der eingabe() Funktion werden die Taster abgefragt und deren Zustände gespeichert.

In der verarbeitung()-Funktion werden die Tastendrücke zum Umschalten der Programme verarbeitet. Für das Setzen der Ausgänge entsprechend dem geschalteten Programm habe ich eine leere switch-case-Anweisung vorgesehen, die entsprechend ausgefüllt werden kann.

Und zum Schluss lauert die ausgabe()-Funktion darauf, dass sich das laufende Programm ändert, und falls das passiert, wird ein anderer Text ausgegeben. Im Beispielprogramm auf Serial, das müßtest Du dann für Textausgabe auf Deinem LCD-Display umschreiben.

Ach ja, mein Programm ist für INPUT_PULLUP geschrieben, also "direkt angeschlossene Taster mit Benutzung der internen PullUp-Widerstände. Falls Du Deine Taster mit externen PullDown-Widerständen beschaltet hast, kann derselbe Code verwendet werden, wenn der INPUTMODE auf INPUT gesetzt wird.

#define INPUTMODE INPUT_PULLUP    // INPUT oder INPUT_PULLUP
#define BOUNCETIME 10             // maximale Prellzeit in Millisekunden
byte buttonPins[]={2, 3, 4, 5, 6, 7};// Pin-Nummern der angeschlossenen Buttons
#define NUMBUTTONS sizeof(buttonPins) // Anzahl der Buttons (automatisch definiert)
byte buttonState[NUMBUTTONS];  // Speichert den aktuellen HIGH/LOW Status der Pins
byte buttonChange[NUMBUTTONS]; // Speichert Flankenwechsel an den Pins
enum{UNCHANGED,BUTTONUP,BUTTONDOWN};

void eingabe(){
// Tasterstatus und Flankenwechsel an den Tastern auswerten  
  static unsigned long lastButtonTime; // Zeitstempel, wann die Routine zuletzt durchlief
  memset(buttonChange,0,sizeof(buttonChange)); // Alle alten Flankenwechsel verwerfen
  if (millis()-lastButtonTime<BOUNCETIME) return;  // innerhalb der Prellzeit die Funktion verlassen
  lastButtonTime=millis(); // Zeitstempel der letzten Buttonabfrage aktualisieren
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    byte curState=digitalRead(buttonPins[i]);        // Aktueller Buttonstatus
    if (INPUTMODE==INPUT_PULLUP) curState=!curState; // Vertauschte Logik bei INPPUT_PULLUP
    if (curState!=buttonState[i])                    // Flankenwechsel erkannt
    {
      if (curState==HIGH) buttonChange[i]=BUTTONDOWN;
      else buttonChange[i]=BUTTONUP;
    }
    buttonState[i]=curState;  // den jetzigen Buttonzustand speichern
  }
}


int programRunning=-1; // globale Variable speichert das laufende Programm, -1= kein Programm

void verarbeitung()
{ // Verarbeite Tastendrücke
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    if (programRunning==i && buttonChange[i]==BUTTONDOWN) // wenn Programm läuft und Taster gedrückt
      programRunning=-1; // Programm aus
    else if (programRunning<0 && buttonChange[i]==BUTTONDOWN) // wenn kein Programm läuft und Taster gedrückt
      programRunning=i; // laufendes Programm setzen
  }
  // Verarbeite laufendes Programm
  switch (programRunning)
  {
    case 0:
      // Hier Befehl zum Einschalten von Programm-0
      break;  
    case 1:
      // Hier Befehl zum Einschalten von Programm-1
      break;  
    case 2:
      // Hier Befehl zum Einschalten von Programm-2
      break;  
    case 3:
      // Hier Befehl zum Einschalten von Programm-3
      break;  
    case 4:
      // Hier Befehl zum Einschalten von Programm-4
      break;  
    default:
      // Hier Befehl zum Ausschalten aller Programme
  }  
}


void ausgabe()
{ // Ausgabe von Programmänderungen als Text (hier: auf Serial)
  static int lastProgram; // Merker für das zuletzt in der Anzeige angezeigte Programm
  // Nur wenn sich das Programm ändert, wird auch die Anzeige neu geschrieben
  if (lastProgram!= programRunning)
  {
    if (programRunning<0) 
      Serial.println("Kein Programm");
    else
    {  
      Serial.print("Programm-");
      // Programme zählen von 0 bis 4, angezeigt werden soll aber von 1 bis 5, daher "+1"
      Serial.println(programRunning+1);
    }
    lastProgram=programRunning;
  }
}


void setup() {
  Serial.begin(9600);
  for (int i=0;i<NUMBUTTONS;i++) pinMode(buttonPins[i],INPUTMODE);
}

void loop() {
  eingabe();
  verarbeitung();
  ausgabe();
}

Wenn irgendwas unklar ist, einfach nachfragen!

P.S.: Es gibt natürlich immer mehrere Möglichkeiten, so etwas zu programmieren.

Hallo,

Ernst mal möchte ich mich herzlich bedanken und dann fällt mir erstmal nur "wow" ein.
Das sieht sehr professionell aus.

Also ich muss dazu sagen, habe etwas fachlichen Hintergrund.
Habe einen 21 tägigen Kurs in C++ Programmierung gemacht, davon war auch ein geringer Teil projektorientierte Programmierung.

Desweiteren komme ich aus der IT Welt, aber habe immer wenig mit programmierung zu tun gehabt. Ich war eher im administrativen Teil tätig.

Also ich hab mich freiwillig für das Projekt gemeldet, aber hab mich sehr verschätzt, was den Umfang und die Komplexität der Aufgabe angeht. Musste feststellen das ein kurs lediglich ein erster Anstoß ist und das es eher auf erfahrung ankommt. Um die Aufgabe richtig lösen zu können. Vielleicht hätte ich eher mit leichteren Sachen beginnen sollen. Aber Naja, aus solchen Ehrfahrungen lernt man.

Ok genug jetzt zu mir.

Ich wäre z.B. nie darauf gekommen es nach der Eingabe,Verarbeitung, Ausgabe Logik aufzubauen.
Obwohl dies genau der richtig Ansatz ist.

Also es wird noch etwas dauern bis ich ganz bei diesem Code durchblicke, aber es ist mir eine große Hilfe um mal ein Beispiel zu haben wie man es machen kann.

Eine Frage hätte ich noch zu Anfang

In der switch-case Anweißung würde ich dann quasi das reinschreiben was in den Programmen passieren soll

z.B.

switch (programRunning)
  {
    case 0:
               digitalWrite(LEDPin,HIGH);
               MotorGeschw1();
      break;  
    case 1:
               digitalWrite(LEDPin,HIGH);
               MotorGeschw2();
      break;  
    case 2:
      // Hier Befehl zum Einschalten von Programm-2
      break;  
    case 3:
      // Hier Befehl zum Einschalten von Programm-3
      break;  
    case 4:
      // Hier Befehl zum Einschalten von Programm-4
      break;  
    default:
                digitalWrite(LEDPin,LOW);
                MotorAus();
  }

Also so z.B.
weitere Funktionen auszuführen ist da auch möglich ?

Vielen Vielen Dank

Grüße
Chris

weitere Funktionen auszuführen ist da auch möglich ?

Einfache Frage, einfache Antwort : Ja.

Schwieriger wird es erst, wenn eine "Funktion" etwas ist, was längere Zeit dauert, und in dieser Zeit auch anderes (z.B. andere Tasten) abgefragt werden soll. Aber auch das geht, wenn man's richtig macht.

Chris85:
Also so z.B.
weitere Funktionen auszuführen ist da auch möglich ?

Das Programmgrundgerüst ist eigentlich von der Struktur her so angelegt, dass Du es an unterschiedlichste Anforderungen leicht anpassen kannst.

Also nicht nur die Funktion "ausgabe()", die derzeitig Textmeldungen auf Serial ausgibt, kann leicht umgeschrieben werden, dass die Ausgabe zum Beispiel auf einem 16x2 LCD ausgegeben werden.

Auch wenn Du Dir bei der Eingabe etwa überlegen solltest, dass Du keine Taster an der Schaltung direkt drücken möchtest, sondern die Programme "schnurlos" gestartet werden sollen, zum Beispiel mit einer Infrarotfernbedienung, wäre das leicht machbar. Dann schließt Du statt fünf Tastern einen IR-Empfänger am Arduino an, programmierst eine andere "eingabe()" Funktion, und kannst dann die Programme mit Deiner Fernseher-Fernbedienung schalten. Oder Du schließt ein GSM-Modul an und schaltest die Programme ein und aus, indem Du eine SMS an das Modul sendest. Nur um mal Beispiele zu nennen. Wäre natürlich alles aufwändiger als das Schalten mit den Buttons, aber machbar.

Und auch bei den Programmen selbst bist Du flexibel und kannst die "verarbeitung()" so anpassen, wie Du es gerade brauchst. Falls die Programme darin bestehen sollen, dass nicht nur irgendwas HIGH oder LOW geschaltet werden soll, sondern komplexere Steuerprogramme ablaufen sollen, könntest Du zum Beispiel für jedes Programm eine eigene Funktion schreiben und der Funktion als Parameter übergeben, ob sie aktiv ist oder nicht.

void Programm3(boolean aktiv)
{
  if (aktiv)
  {
    // hier steht, was das aktive Programm tun soll
  }
  else
  {
    // hier steht, was zum Abschalten des Programms nötig ist
  }
}

Die Funktion "verarbeitung()" würde dann laufend Aufrufe von "Programm3(true);" machen, solange Programm-3 aktiv ist. Und wenn das Programm abgeschaltet werden soll, reicht ein einmaliger Aufruf von "Programm3(false);" zum Abschalten der Programmfunktionen.

Wenn im Ablauf der Faktor "Zeit" eine Rolle spielt, wäre es auch nützlich, sich die Zeit zu merken, wann eine Funktion aktiv geschaltet wird. Das wäre zum Beispiel hilfreich, wenn das Programm zeitabhängige Aktionen ausführen soll:

  • zeitgesteuerte Schaltvorgänge (z.B. Blinken einer LED)
  • zeitgesteuerte Steuervorgänge (z.B. Drehzahlregelung eines Motors)
  • zeitgesteuerte Anzeigen (z.B. Ausgabe der Programmlaufzeit auf LCD)

Ein aufgebohrtes Programmgrundgerüst mit leeren Hüllen für fünf verschiedene Programme und einer Variablen, in der die Startzeit jedes Programms vermerkt steht, poste ich mal gleich mit:

#define INPUTMODE INPUT_PULLUP    // INPUT oder INPUT_PULLUP
#define BOUNCETIME 10             // maximale Prellzeit in Millisekunden
byte buttonPins[]={2, 3, 4, 5, 6};// Pin-Nummern der angeschlossenen Buttons
#define NUMBUTTONS sizeof(buttonPins) // Anzahl der Buttons (automatisch definiert)
byte buttonState[NUMBUTTONS];  // Speichert den aktuellen HIGH/LOW Status der Pins
byte buttonChange[NUMBUTTONS]; // Speichert Flankenwechsel an den Pins
enum{UNCHANGED,BUTTONUP,BUTTONDOWN};

void eingabe(){
// Tasterstatus und Flankenwechsel an den Tastern auswerten  
  static unsigned long lastButtonTime; // Zeitstempel, wann die Routine zuletzt durchlief
  memset(buttonChange,0,sizeof(buttonChange)); // Alle alten Flankenwechsel verwerfen
  if (millis()-lastButtonTime<BOUNCETIME) return;  // innerhalb der Prellzeit die Funktion verlassen
  lastButtonTime=millis(); // Zeitstempel der letzten Buttonabfrage aktualisieren
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    byte curState=digitalRead(buttonPins[i]);        // Aktueller Buttonstatus
    if (INPUTMODE==INPUT_PULLUP) curState=!curState; // Vertauschte Logik bei INPPUT_PULLUP
    if (curState!=buttonState[i])                    // Flankenwechsel erkannt
    {
      if (curState==HIGH) buttonChange[i]=BUTTONDOWN;
      else buttonChange[i]=BUTTONUP;
    }
    buttonState[i]=curState;  // den jetzigen Buttonzustand speichern
  }
}


int programRunning=-1; // globale Variable speichert das laufende Programm, -1= kein Programm
unsigned long programmAktivSeit;

void Programm0(boolean aktiv)
{
  if (aktiv) 
  {
    // was das aktive Programm tun soll
  }
  else
  {
    // was das inaktive Programm beim Abschalten tun soll
  }
}

void Programm1(boolean aktiv)
{
  if (aktiv) 
  {
    // was das aktive Programm tun soll
  }
  else
  {
    // was das inaktive Programm beim Abschalten tun soll
  }
}

void Programm2(boolean aktiv)
{
  if (aktiv) 
  {
    // was das aktive Programm tun soll
  }
  else
  {
    // was das inaktive Programm beim Abschalten tun soll
  }
}

void Programm3(boolean aktiv)
{
  if (aktiv) 
  {
    // was das aktive Programm tun soll
  }
  else
  {
    // was das inaktive Programm beim Abschalten tun soll
  }
}

void Programm4(boolean aktiv)
{
  if (aktiv) 
  {
    // was das aktive Programm tun soll
  }
  else
  {
    // was das inaktive Programm beim Abschalten tun soll
  }
}





void verarbeitung()
{ // Verarbeite Tastendrücke
  for (int i=0;i<NUMBUTTONS;i++) 
  {
    if (programRunning==i && buttonChange[i]==BUTTONDOWN) // wenn Programm läuft und Taster gedrückt
    {
      // Das laufende Programm ausschalten
      if (i==0) Programm0(false);
      if (i==1) Programm1(false);
      if (i==2) Programm2(false);
      if (i==3) Programm3(false);
      if (i==4) Programm4(false);
      programRunning=-1; // laufendes Programm aus
    }  
    else if (programRunning<0 && buttonChange[i]==BUTTONDOWN) // wenn kein Programm läuft und Taster gedrückt
    {
      programRunning=i; // laufendes Programm setzen
      programmAktivSeit=millis(); // Zeit merken, wann das Programm aktiv wurde
    }
  }
  // Verarbeite laufendes Programm
  switch (programRunning)
  {
    case 0:
      Programm0(true); // Hier aktives Programm0 aufrufen
      break;  
    case 1:
      Programm1(true); // Hier aktives Programm1 aufrufen
      break;  
    case 2:
      Programm2(true); // Hier aktives Programm2 aufrufen
      break;  
    case 3:
      Programm3(true); // Hier aktives Programm3 aufrufen
      break;  
    case 4:
      Programm4(true); // Hier aktives Programm4 aufrufen
      break;  
    default:
      // der einzige andere Fall ist, dass kein Programm läuft,
      // in dem Fall ist nichts weiter notwendig
      ;
  }  
}


void ausgabe()
{ // Ausgabe von Programmänderungen als Text (hier: auf Serial)
  static int lastProgram; // Merker für das zuletzt in der Anzeige angezeigte Programm
  // Nur wenn sich das Programm ändert, wird auch die Anzeige neu geschrieben
  if (lastProgram!= programRunning)
  {
    if (programRunning<0) 
      Serial.println("Kein Programm");
    else
    {  
      Serial.print("Programm-");
      // Programme zählen von 0 bis 4, angezeigt werden soll aber von 1 bis 5, daher "+1"
      Serial.println(programRunning+1);
    }
    lastProgram=programRunning;
  }
}


void setup() {
  Serial.begin(9600);
  for (int i=0;i<NUMBUTTONS;i++) pinMode(buttonPins[i],INPUTMODE);
}

void loop() {
  eingabe();
  verarbeitung();
  ausgabe();
}

Vielen Dank für diese ausgiebige Hilfeleistung.

Wenn man mal einen Einblick bekommen hat wie man so ein Programmgerüst aufbaut, wird der Einstieg gleich viel einfacher.
Nachdem ich mich ausgiebig mit dem vorgebenen Programmgerüst beschäftigt habe, fiel es mir viel leichter die aufgegeben Aufgabe zu lösen.

Habe natürlich jetzt blut geleckt, tiefer in die Arduino Welt einzutauchen :slight_smile:

Mein nächstes Ziel das ich mir vorgenommen hab ist die Kommunikation 2 oder mehrerer Arduino´s.

Habe schon viel recherchiert darüber,aber was mir nicht verständlich ist, wie man das im Code umsetzt??

Also was ich bis jetzt weiß:

Man kann die Boards auf 2 Weisen miteinander verbinden:

  1. Über Master Slave also SCL - SCL und SDA - SDA und GND - GND
    danach einfach die Wire Bibiothek laden und anpassen

  2. über TX und RX also TX - RX und RX - TX und GND - GND

Natürlich ist die Stromversorgung noch wichtig, aber hab ich jetzt nicht oben aufgeführt, weil es da auch nochmal verschiedene Varianten gibt.

da ich mir einige NANO´s zugelegt habe und gemerkt habe, dass die NANO Boards nur die Möglichkeit haben TX und RX zu benutzen, bevorzuge ich die 2. Variante.

Aber wie funktioniert die Kommunikation dann. ( Also wie muss der Code aussehen, wird das auch über die Wire.h gemacht? ).

TX = Pin1 Senden
RX = Pin0 Empfangen

Ich bedanke mich schon mal im Vorraus bei euch.

MfG
Chris

hi,

die nanos haben auch eine SDA-SCL (Wire) schnittstelle, die ist an den pins 4 und 5.
RX und TX, also seriell, wird mit den serial-befehlen genutzt (schau hier im forum bei Learning > Reference) oder bei den beispielen, die in der IDE schon enthalten sind (sowohl für wire als auch für serial).

I²C, also die sache mit wire, geht nur über kurze distanzen, das ist für die kommunikation auf einer platine gedacht, serial geht einige meter, für größere entfernungen nimmst Du serial mit speziellen ICs dazwischen (nennt sich dann RS485).

viel spaß noch mit Deinen neuen arduinos und

gruß stefan

Chris85:
da ich mir einige NANO´s zugelegt habe und gemerkt habe, dass die NANO Boards nur die Möglichkeit haben TX und RX zu benutzen, bevorzuge ich die 2. Variante.

Aber wie funktioniert die Kommunikation dann. ( Also wie muss der Code aussehen, wird das auch über die Wire.h gemacht? ).

TX = Pin1 Senden
RX = Pin0 Empfangen

Damit die USB-Serial Schnittstelle frei bleibt, um damit Debug-Meldungen zum PC senden zu können (und sei es nur während der Programmentwicklung), und da ein Nano-Board nur eine einzige Hardware-Serial Schnittstelle hat, richtest Du Dir am besten auf zwei Pins eine zusätzliche serielle Schnittstelle ein. Standardmäßig und im schlechtesten Fall mit Hilfe der "SoftwareSerial" Library. Besser aber mit der "AltSoftSerial" Library, die dazu erstemal installiert werden müßte.

Dann verkabelst Du die RX/TX-Pins der beiden Arduinos über Kreuz und verbindest GND-GND.
Dann definierst Du Dir die AltSoftSerial-Schnittstelle im Programm.

Wenn ein Arduino etwas empfangen soll, würde das in der eingabe() Funktion z.B. mit "softSerial.read()" eingelesen werden. Wenn ein Arduino etwas senden soll, würde das in der ausgabe() Funktion z.B. mit "softSerial.print" oder "softSerial.write()" gesendet werden. Wenn beide Arduinos sowohl senden als auch empfangen sollen, würde jeder der beiden entsprechende Funktionen nutzen.

Hängt natürlich immer vom konkreten Programmprojekt ab.

Eisebaer:
hi,

die nanos haben auch eine SDA-SCL (Wire) schnittstelle, die ist an den pins 4 und 5.

Genaugesagt I2C ist bei Arduinos mit ATmega328 an den Pins A4 und A5. Beim Arduino UNO R3 sind diese beiden Pins nur nochmal als SDA und SCL vorhanden.

Meiner Ansicht ist RX und TX einfacher zu programmieren als I2C, hat aber den Nachteil, daß dadurch der Upload blockiert wird. Zum Programmieren mußt Du immer die Verbindung der beiden Arduinos trennen oder üner ISp uploaden.

Grüße Uwe

Hallo, Danke erstmal für deine Antwort.

Also mit installieren meinst du, die library ( also den Ordner AltSoftSerial ) in die library von Arduino reinkopieren ??

Also ich hab das mal probiert mit der AltSoftSerial Library zu arbeiten, doch es will noch nicht funktionieren.

Vielleicht könnte mir mal jemand wieder ein praktisches Beispiel geben ?
So verstehe ich es einfach besser, wenn ich es mir mal ansehen kann.

Also ich wollte zu Anfang die werte von einem Poti zu einem anderen Arduino übertragen um eine LED zu dimmen. Anhand dieses einfachen Versuchs.
Die Library AltSoftSerial.h hab ich schon eingebunden.
Was muss ich jetzt ergänzen, dass das 1. Arduino die Werte an den zweiten sendet??

  1. Arduino Nano:
#include <AltSoftSerial.h>

int potPin= A0;
int sendeDaten=0;

void setup()
{
  Serial.begin(9600);
}


void loop()
{
  sendeDaten=map(analogRead(potPin),0,1023,0,255);
  Serial.println(sendeDaten);
}
  1. Arduino Nano:
#include <AltSoftSerial.h>

int LedPin=9;
int EingabeDaten=0;

void setup()
{
  pinMode(LedPin,OUTPUT);
  Serial.begin(9600);
}


void loop()
{
  Serial.println(EingabeDaten);
  analogWrite(LedPin,EingabeDaten);
}

Vielen Dank schon mal im Vorraus

beim "2. Arduino Nano" sehe ich keinen Datenempfang!
Abgesehen davon, dass ich mir noch keine Gedanken dazu gemacht habe, sehe ich zumindest keine Zeile,
in der Daten seriell empfangen werden.
Serial.println(Eingabedaten) sendet Daten und empfängt nicht.

Chris85:
Also ich hab das mal probiert mit der AltSoftSerial Library zu arbeiten, doch es will noch nicht funktionieren.

Vielleicht könnte mir mal jemand wieder ein praktisches Beispiel geben ?
So verstehe ich es einfach besser, wenn ich es mir mal ansehen kann.

Bei eigentlich allen Libraries gehört mindestens ein Beispiel mit dazu.

Sobald Du irgendeine Library mit ihren Beispielen korrekt installiert und die Aduino-IDE danach einmal neu gestartet hast, findest Du die zur Library gehörenden Beispiele unter dem Menüpunkt:
Datei - Beispiele - Name der Library

Dein Fehler ist offensichtlich, dass Du zwar die AltSoftSerial Library inkludierst, aber

  • weder ein AltSoftSerial Objekt anlegst
  • noch ein AltSoftSerial Objekt ansteuerst

Deine in Antwort #16 geposteten Beispiele steuern weiterhin ausschließlich die Serial Schnittstelle an.

Und wenn du Binär ein Byte übertragen willst, musst du dies mit write() senden! print() schickt ASCII Daten. Und println() dann noch ein CR + LF hinterher.