Im void setup() mehrere inputs gruppieren?

Hallo zusammen,

ich bin blutiger Anfänger im Programmieren und schreibe mein erstes "eigenes" Programm ohne Tutorialvorlagen.

Auf diversen Videos und Guides wurde bisher nie erwähnt, ob es eine Möglichkeit gibt, mehrere inputs in eine Gruppe zu stecken und alle pinModes als INPUT festzulegen.

Mein setup sieht aktuell so aus:

  pinMode(limitSwitch1, INPUT);
  pinMode(limitSwitch2, INPUT);
  pinMode(limitSwitch3, INPUT);
  pinMode(limitSwitch4, INPUT);
  pinMode(limitSwitch5, INPUT);
  pinMode(limitSwitch6, INPUT);
  pinMode(limitSwitch7, INPUT);
  pinMode(limitSwitch8, INPUT);
  pinMode(limitSensor1, INPUT);
  pinMode(limitSensor2, INPUT);
  pinMode(limitSensor3, INPUT);
  pinMode(limitSensor4, INPUT);
  pinMode(limitSensor5, INPUT);
  pinMode(limitSensor6, INPUT);
  pinMode(limitSensor7, INPUT);
  pinMode(limitSensor8, INPUT);

Da alle Variablen sehr ähnlich sind, würde ich gern alle Variablen gruppieren und alle auf einmal als INPUT zu deklarieren um mir so einige Zeilen zu sparen.

Ich hoffe, meine Frage ist verständlich.

Gibt es diese Möglichkeit? Wenn ja, wie setze ich so etwas um?

Vielen Dank vorab!
Ich bin begeistert von der hilfsbereiten Community.

Sie sollten die Verwendung von Arrays erforschen. Es wird Ihre Skizze viel kürzer machen

Nach einem RESET sind alle Pins Eingänge. Die größte Ersparnis wäre also das komplette Weglassen der pinModes dafür.

Da sensor und switch die gleiche Anzahl haben, ist es ein zweizeiler:

const byte limitSwitch[8] = {2, 3, 4, 5, 6, 7, 8, 9};
const byte limitSensor[8] = {10, 11, 12, 13, 14, 15, 16, 17};


void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b <= 7; b++)
  {
    pinMode(limitSwitch[b], INPUT);
    pinMode(limitSensor[b], INPUT);
  }
}

void loop()
{
}

Im Array werden die PinNummern hinterlegt - im setup mit einer Schleife durch alle Elemente des array.

Einzelner Zugriff unter Angabe des Elementes - Achtung: Es wird mit 0 begonnen!

1 Like

ist das Absicht? Ansonsten rate ich dir mal zu dieser (meiner) Seite:

da gehts auch Schrittweise um

  • nicht blockierendes programmieren - von delay zu millis
  • Arrays
  • Strukturen
  • die Kombination von Struktur und Array
  • range based for

https://werner.rothschopf.net/202003_arduino_retriggerbares_nachlaufrelais.htm

1 Like
template<unsigned i, unsigned j> struct Inputs
{
  union
  {
    struct
    {
      byte limitSwitch[i];
      byte limitSensor[j];
    };
    byte all[i+j];
  };  
};

template<size_t N> void pinMode(const byte (&pins)[N], const int mode)
{
  for(const byte pin:pins)  pinMode(pin,mode);
}

constexpr Inputs<8,8> inputs{ {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}};

void setup() 
{
  pinMode(inputs.all,INPUT);

 // bool merker = digitalRead(inputs.limitSwitch[3]);
}

void loop() 
{}

Sieht etwas wahnsinnig aus, aber spart sogar noch ein paar Bytes Flash ein.

1 Like

Das sieht tatsächlich sehr faszinierend aus und ich musste gerade erstmal viele neue Begriffe ergooglen.

Ich denke, dass ich zumindest die Idee hinter dem Code verstehe.

Zum Abrufen könnte ich die Variablen nun mit z.B.:

if (digitalRead(limitSwitch[0]==HIGH){
für den ersten und

if (digitalRead(limitSwitch[7]==HIGH){
für den letzten richtig?

Wenn ich alle gleichzeitig (UND-Verknüfung) abrufen will, kann ich einfach
if (digitalRead(inputs.all==HIGH){
verwenden?

Schön, dass es dir gefällt.

Das wird nix

Du meinst sicherlich:

if (digitalRead(inputs.limitSwitch[0])==HIGH){
// und
if (digitalRead(inputs.limitSwitch[7])==HIGH){

Das wäre schön......
Bedenke: Ich habe eine eigene Variante des pinMode() erfunden, welche Arrays verarbeiten kann, und damit die originale pinMode() überschreiben. Das müsstest du dann auch mit digitalRead tun.
Zudem hats den gleichen Syntax Fehler wie die beiden andern Zeilen.

Es ist also nicht ganz so einfach.

1 Like

nein eher so

if (digitalRead(limitSwitch[0])==HIGH){

auslesen musst imho dennoch über eine for schleife wenn du keine direkten Portzugriff machst (und nein das willst du nicht im Arduino Style).

Wohl wahr!
Und dennoch kann man die Schleife in eine Funktion auslagern, wenn man alle Pins eines PinArrays "anfassen" möchte

Hier mal ein tieferer Blick in meiner Wühlkiste, denn ein klein wenig hatte ich irgendwann mal vorbereitet:


using PinMode  = decltype(INPUT);
using PinValue = decltype(LOW);

// initialisiert alle Pins in dem Array mit Mode
template<size_t N> void pinMode(const byte (&pins)[N], const PinMode mode)
{
  for(const byte &pin : pins)  
    pinMode(pin, mode);
}

// schreibt value in alle Pins
template<size_t N> void digitalWrite(const byte (&pins)[N], const PinValue value)
{
  for(const byte &pin : pins)  
    digitalWrite(pin, value);
}

// testet ob irgendeiner der Pins High oder Low ist
template<size_t N> bool digitalIsAny(const byte (&pins)[N], const PinValue value)
{
  for(const byte &pin : pins)
    if(value == digitalRead(pin)) 
      return true;
  return false;
}

// zaehlt alle High oder Low
template<size_t N> size_t digitalCount(const byte (&pins)[N], const int &value)
{
  size_t result = 0;
  for(const byte &pin : pins) 
    result += value == digitalRead(pin);
  return result;
}


template<unsigned i, unsigned j> struct Inputs
{
  union
  {
    struct
    {
      byte limitSwitch[i];
      byte limitSensor[j];
    };
    byte all[i + j];
  };
};

constexpr Inputs<8, 8> inputs{{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}};

//const byte outputs[] {18,19,20};
constexpr byte outputs[] {18, 19, 20};



void setup()
{
  Serial.begin(9600);
  pinMode(inputs.all, INPUT_PULLUP); //alle inputs konfigurieren
  // pinMode(inputs.all,INPUT); //alle inputs konfigurieren
  
  pinMode(outputs, OUTPUT); // alle outputs konfigurieren
  digitalWrite(outputs, LOW); // alle outputs vorbesetzen
  
  // bool merker = digitalRead(inputs.limitSwitch[3]); // einzelnen Pin lesen
  // bool merker = digitalRead(inputs.all[11]); // einzelnen Pin lesen
}

void loop()
{
  Serial.println(" -----loop-------.");
  
  Serial.println(" ------digitalIsAny von inputs.all------.");
  if(digitalIsAny(inputs.all, LOW)) Serial.println("Mindestens 1 Pin ist Low");
    else Serial.println("kein Pin ist Low");
    
  Serial.println(" ------digitalIsAny von inputs.limitSwitch------.");
  if(digitalIsAny(inputs.limitSwitch, HIGH)) Serial.println("Mindestens 1 Pin ist High");
    else Serial.println("kein Pin ist High");
    
  Serial.println(" ------digitalcount------.");
  Serial.print("Es sind ");
  Serial.print(digitalCount(inputs.all, HIGH));
  Serial.println(" Pins High.");
  Serial.println();

  delay(1000); // provisorisch
}

Wobei, ich glaube, dass auch dieses an einer echten Lösung vorbei geht.
Bisher sehe ich nur einen Teil einer Idee...
Kann also nur zeigen "was geht"

Solange das Gesamtproblem, welches gelöst werden soll, geheim ist, solange wirds auch keine echte/angemessene Lösung geben.

PS:
Das Programm wirft übrigens eine Warnung, wenn man den Compiler ganz pedantisch einstellt:

 warning: ISO C++ prohibits anonymous structs [-Wpedantic]
   43 |     {
      |     ^

Das ist solange kein Drama, wie man den GCC nutzt. Und das dürfte in allen Arduino Programmen, egal für welchen µC, der Fall sein.