Problem mit Code für Projekt(Serielle Kommunikation)

Hallo,

ich arbeite in meinem Betrieb derzeit an einem Projekt:

Es sollen vier Relais und vier LEDs über die serielle Schnittstelle des PCs, mithilfe eines Arduino UNO, angesteuert werden.
Allerdings soll dies auch manuell, mithilfe eines Drehschalters geschehen können.
Deshalb gibt es einen Schalter, um zwischen diesen beiden Möglichkeiten zu wechseln.

Ich habe schon einen Code geschrieben, allerdings funktioniert dieser nur teilweise.

Die reine Steuerung über die serielle Schnittstelle funktioniert, doch sobald ich den Code für das manuelle Schalten hinzufüge, funktioniert nichts mehr...

Sobald das Programm startet, setzt der Arduino den Port 5 auf HIGH und ich weiß nicht warum.
Man kann den Port dann auch nicht mehr auf LOW setzen...

Am besten zeige ich euch mal mein Sketch:

/*

CODE V1
 
*/



//Deklarierung der Ports für die vier LEDs

const byte led1 = 2;
const byte led2 = 3;
const byte led3 = 4;
const byte led4 = 5;

//Deklarierung der Ports für die vier Relais
const byte rel1 = 6;
const byte rel2 = 7;
const byte rel3 = 8;
const byte rel4 = 9;

//Deklarierung der Ports für die vier Schaltereingänge
const byte sw1 = 10;
const byte sw2 = 11;
const byte sw3 = 12;
const byte sw4 = 13;

//Deklarierung des Ports für den Auswahlschalter für die Auswahl zwischen PC und Manuell
const byte modus = 0;

//Variable zum Speichern des Zustands des jeweiligen Schalters
int schalterstatus1 = 0;
int schalterstatus2 = 0;
int schalterstatus3 = 0;
int schalterstatus4 = 0;

//Variable zum Speichern des Zustand des Auswahlschalters
int auswahl = 0;



void setup()
{
  //Serielle Komminkation mit 9600 Baud, 8 Bit, keiner Parität und einem Stoppbit

  Serial.begin(9600,SERIAL_8N1);  
  
  pinMode(led1, OUTPUT);                                          //LED Ports als Ausgänge
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);

  pinMode(rel1, OUTPUT);                                          //Relais Ports als Ausgänge
  pinMode(rel2, OUTPUT);
  pinMode(rel3, OUTPUT);
  pinMode(rel4, OUTPUT);

  pinMode(sw1, INPUT);                                            //Schalter Ports als Eingänge
  pinMode(sw2, INPUT);
  pinMode(sw3, INPUT);
  pinMode(sw4, INPUT);
}

void loop() 
{
  auswahl = digitalRead(modus);                    // Auslesen und Speichern des Auswahlschalters


// Wenn der Auswahlschalter auf "HIGH" steht, soll die Steuerung der LEDs und Relais über die serielle Schnittstelle funktionieren


  if(auswahl == 1)                                      
  {
     if (Serial.available())                                      
     {
      switch (Serial.read())            // Dieser Abschnitt lässt die LEDs und die Relais ein- und ausschalten
      {
        case '1': digitalWrite(led1, !digitalRead(led1)); digitalWrite(rel1, !digitalRead(rel1)); break;
        case '2': digitalWrite(led2, !digitalRead(led2)); digitalWrite(rel2, !digitalRead(rel2)); break;
        case '3': digitalWrite(led3, !digitalRead(led3)); digitalWrite(rel3, !digitalRead(rel3)); break;
        case '4': digitalWrite(led4, !digitalRead(led4)); digitalWrite(rel4, !digitalRead(rel4)); break;
      }
     }
   }

 // Wenn der Auswahlschalter auf "LOS" steht, soll die Steuerung, manuell, über den Drehschalter erfolgen

  else if(auswahl == 0)                                                
    {
      schalterstatus1 = digitalRead(sw1);             // Auslesen und Speichern des Statuses der Eingänge
      schalterstatus2 = digitalRead(sw2);
      schalterstatus3 = digitalRead(sw3);
      schalterstatus4 = digitalRead(sw4);

//Wenn der erste Schalterstatus "HIGH" ist, soll LED1 und Relais1 geschaltet werden, ansonsten nicht

      if(schalterstatus1 == HIGH)
        {
          digitalWrite(led1, HIGH);
          digitalWrite(rel1, HIGH);
        }
        else
          {
           digitalWrite(led1, LOW);
           digitalWrite(rel1, LOW);
          }

//Wenn der zweite Schalterstatus "HIGH" ist, soll LED2 und Relais2 geschaltet werden, ansonsten nicht

      if(schalterstatus2 == HIGH)
        {
          digitalWrite(led2, HIGH);
          digitalWrite(rel2, HIGH);
        }
        else
          {
           digitalWrite(led2, LOW);
           digitalWrite(rel2, LOW);
          }

//Wenn der dritte Schalterstatus "HIGH" ist, soll LED3 und Relais3 geschaltet werden, ansonsten nicht

       if(schalterstatus3 == HIGH)
        {
          digitalWrite(led3, HIGH);
          digitalWrite(rel3, HIGH);
        }
        else
          {
           digitalWrite(led3, LOW);
           digitalWrite(rel3, LOW);
          } 

//Wenn der vierte Schalterstatus "HIGH" ist, soll LED4 und Relais4 geschaltet werden, ansonsten nicht

       if(schalterstatus4 == HIGH)
        {
          digitalWrite(led4, HIGH);
          digitalWrite(rel4, HIGH);
        }
        else
          {
           digitalWrite(led4, LOW);
           digitalWrite(rel4, LOW);
          } 
     }
}
//Deklarierung des Ports für den Auswahlschalter für die Auswahl zwischen PC und Manuell

const byte modus = 0;

Das wird sich mit Serial beissen, da Serial beim UNO die Pins 0 und 1 verwendet.

Wenn LED und Relais immer gleich geschaltet werden, kannst du die Hälfte deiner OUTPUT Pins sparen.


Wir nennen die Dinger übigens Pins
Ports heissen A, B, C, D usw. und haben (bis zu) 8 Pins

Ok, dass ändere ich sofort, aber ist das auch die Lösung für das Problem mit Port5?

Hallo ProgoX,
ich kenne deinen Schaltplan natürlich nicht, also wie du z.B. die Schalter angeschlossen hast u.s.w.
Und ich weiß auch nicht wieviel Erfahrung du mit Mikrocontrollern hast.

Ein häufiger Fehler, der gerade zu Beginn der Beschäftigung mit Mikrocontrollern passiert, ist, dass Eingänge "in der Luft hängen", also keine definierte Spannung haben (z.B. 0 Volt oder 5 Volt). Dann sind die Ergebnisse "zufällig" und verwunderlich. Ich vermute, das könnte hier der Fall sein.
Du schaltest deine Eingänge "active high" - in deinem Programm heißt es ja beispielsweise in den Kommentaren

//Wenn der erste Schalterstatus "HIGH" ist, soll LED1 und Relais1 geschaltet werden, ansonsten nicht

Das ist zwar möglich, aber eher unüblich. Meist wird mit "active low" gerabeitet, also abgefragt, ob der Eingang, an dem der Taster/Schalter hängt LOW ist.
Warum?
Es gibt einen "wunderbaren" Befehl

pinMode(x, INPUT_PULLUP);

dabei wird ein interner sogenannter Pullup-Widerstand aktiviert, der den Eingang auf HIGH zieht, wenn der Taster/Schalter inaktiv (also nicht geschlossen) ist.
Wenn der Taster/Schalter geschlossen (also "aktiv" ist), dann zieht er den Eingang auf LOW. Also deine Taster/Schalter müssen alle mit GND (Ground) verbunden sein.

Die Ausführungen von michael_x solltest du auch beachten - also nichts an Pin (verwende besser diesen Begriff, denn "Port" hat in Verbindung mit Mikrocontrollern eine ganz andere spezielle Bedeutung) 0 und 1 anzuschließen, weil diese für die serielle Kommunikation verwendet werden.

Es ist auch nicht nötig, extra Pins für LEDs und Relais zu verwenden.
Aber es geht auch so wie du es machst.
Falls dir die Pins ausgehen: Auch die analogen Pins lassen sich als Digitalpins verwenden (die heißen dann 14, 15, 16, 17, 18, 19).

Zu Relais ist zu sagen:
Relais direkt an Arduino-Pins anzuschließen ist "gefährlich".
Ein Pin kann max. 40 mA liefern - es sollten aber eher weniger sein. Relais (falls sie überhaupt mit 5 Volt funktionieren) brauchen oft mehr.
Du kannst einen Transistor zum Schalten des Relais verwenden.
Eine Diode (antiparallel zum Relais) nicht vergessen!
Es gibt auch eigene Relais-Schields, die die Relais nicht direkt über die Arduino-Pin steuern.

Dein Programm/Sketch könnte noch ein wenig eleganter programmiert sein, aber das ist auch ein wenig Geschmackssache :slight_smile:

Ich habe ein paar Veränderungen vorgenommen, und so funktioniert es bei mir (ich habe allerdings keine Relais, sondern überall nur LEDs verwendet).

/*
CODE V1.1
*/

// Deklarierung der Pins für die vier LEDs
const byte led1 = 2;
const byte led2 = 3;
const byte led3 = 4;
const byte led4 = 5;

// Deklarierung der Pins für die vier Relais
const byte rel1 = 6;
const byte rel2 = 7;
const byte rel3 = 8;
const byte rel4 = 9;

// Deklarierung der Pins für die vier Schaltereingänge
const byte sw1 = 10;
const byte sw2 = 11;
const byte sw3 = 12;
const byte sw4 = 13;

// Deklarierung des Pins für den Auswahlschalter für die Auswahl zwischen PC und Manuell
const byte modus = 14;    // das ist der Anschluss A0    

// Variable zum Speichern des Zustands des jeweiligen Schalters
int schalterstatus1 = 0;
int schalterstatus2 = 0;
int schalterstatus3 = 0;
int schalterstatus4 = 0;

// Variable zum Speichern des Zustand des Auswahlschalters
int auswahl = 0;


void setup()
{
  // Serielle Komminkation mit 9600 Baud, 8 Bit, keiner Parität und einem Stoppbit
  Serial.begin(9600);  
  
  pinMode(led1, OUTPUT);           //LED Pins als Ausgänge
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);

  pinMode(rel1, OUTPUT);           //Relais Pins als Ausgänge
  pinMode(rel2, OUTPUT);
  pinMode(rel3, OUTPUT);
  pinMode(rel4, OUTPUT);

  pinMode(sw1, INPUT_PULLUP);     //Schalter Pins als Eingänge mit Pullup-Widerständen
  pinMode(sw2, INPUT_PULLUP);
  pinMode(sw3, INPUT_PULLUP);
  pinMode(sw4, INPUT_PULLUP);
  
  pinMode(modus, INPUT_PULLUP);
}


void loop() 
{
  auswahl = digitalRead(modus);       // Auslesen und Speichern des Auswahlschalters

  // Wenn der Auswahlschalter auf "HIGH" steht, soll die Steuerung der LEDs und Relais über die serielle Schnittstelle funktionieren
  if(auswahl == HIGH)                                      
  {
     if (Serial.available())                                      
     {
      switch (Serial.read())        // Dieser Abschnitt lässt die LEDs und die Relais ein- und ausschalten
      {
        case '1': digitalWrite(led1, !digitalRead(led1)); digitalWrite(rel1, !digitalRead(rel1)); break;
        case '2': digitalWrite(led2, !digitalRead(led2)); digitalWrite(rel2, !digitalRead(rel2)); break;
        case '3': digitalWrite(led3, !digitalRead(led3)); digitalWrite(rel3, !digitalRead(rel3)); break;
        case '4': digitalWrite(led4, !digitalRead(led4)); digitalWrite(rel4, !digitalRead(rel4)); break;
      }
     }
   }

 // Wenn der Auswahlschalter auf "LOW" steht, soll die Steuerung, manuell, über den Drehschalter erfolgen
  else if(auswahl == LOW)                                                
    {
      schalterstatus1 = digitalRead(sw1);      // Auslesen und Speichern des Statuses der Eingänge
      schalterstatus2 = digitalRead(sw2);
      schalterstatus3 = digitalRead(sw3);
      schalterstatus4 = digitalRead(sw4);

//Wenn der erste Schalterstatus "LOW" ist, soll LED1 und Relais1 geschaltet werden, ansonsten nicht
      if(schalterstatus1 == LOW)
        {
          digitalWrite(led1, HIGH);
          digitalWrite(rel1, HIGH);
        }
        else
        {
           digitalWrite(led1, LOW);
           digitalWrite(rel1, LOW);
        }

//Wenn der zweite Schalterstatus "LOW" ist, soll LED2 und Relais2 geschaltet werden, ansonsten nicht
      if(schalterstatus2 == LOW)
      {
          digitalWrite(led2, HIGH);
          digitalWrite(rel2, HIGH);
      }
      else
      {
           digitalWrite(led2, LOW);
           digitalWrite(rel2, LOW);
      }

//Wenn der dritte Schalterstatus "LOW" ist, soll LED3 und Relais3 geschaltet werden, ansonsten nicht
       if(schalterstatus3 == LOW)
       {
          digitalWrite(led3, HIGH);
          digitalWrite(rel3, HIGH);
        }
        else
        {
           digitalWrite(led3, LOW);
           digitalWrite(rel3, LOW);
        } 

//Wenn der vierte Schalterstatus "LOW" ist, soll LED4 und Relais4 geschaltet werden, ansonsten nicht
       if(schalterstatus4 == LOW)
       {
          digitalWrite(led4, HIGH);
          digitalWrite(rel4, HIGH);
       }
       else
       {
           digitalWrite(led4, LOW);
           digitalWrite(rel4, LOW);
       } 
     }
}