Ersetzen mehrerer pinMode () - und digitalWrite () -Pins durch ein Array


7

Ich möchte ‚aufzuräumen‘ einige Code, der mehrere beinhaltet pinMode()und digitalWrite()unter Verwendung einer einzelnen Zeile eines Arrays Linien. Ich bin sehr neu in beiden Arrays, daher bin ich etwas verwirrt. Die folgenden Beispiele sind Abschnitte aus Code, der eine 4-stellige 7-Segment-LED steuert.

// Define display pins
// Digit pins (common cathode)
int digit1 = 13; //Display pin 1
int digit2 = 12; //Display pin 2
int digit3 = 11; //Display pin 6
int digit4 = 10; //Display pin 8
// Segment pins
int segA = 2; //Display pin 14
int segB = 3; //Display pin 16
int segC = 4; //Display pin 13
int segD = 5; //Display pin 3
int segE = 6; //Display pin 5
int segF = 7; //Display pin 11
int segG = 8; //Display pin 15

void setup() {                
  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
}

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (numberToDisplay){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

Stifte definieren:

Ich bin mir ziemlich sicher, dass der folgende Code die richtige Art ist, die Pins als Array zu speichern (aber bitte korrigieren Sie mich, wenn ich falsch liege).

digitPins[] = {13 12 11 10};
segPins[] = {2 3 4 5 6 7 8};

pinMode():

Ich verstehe, dass ich eine for-Schleife verwenden könnte, um die Pin-Modi einzustellen, aber gibt es einen noch einfacheren Weg? Würde so etwas funktionieren?

pinMode(digitPins[], OUTPUT);
pinMode(segPins[], OUTPUT);

digitalWrite():

Ich könnte auf den entsprechenden Pin aus dem Array zugreifen, um ihn digitalWrite()wie den folgenden Code zu verwenden, aber das würde zu der gleichen Anzahl von Codezeilen führen (und noch verwirrender sein). Gibt es eine andere Option?

digitalWrite(segPins[1], HIGH);


1
Da es sich um eine 4-stellige 7-Segment-Anzeige handelt, ist die wahrscheinlich zu prüfende Frage wahrscheinlich: Wie wird eine 4-stellige 7-Segment-Anzeige mit gemeinsamer Anode verwendet? .
Edgar Bonet

Antworten:


7

die richtige Art, die Pins als Array zu speichern

Ihre Array-Initialisierer sind fast richtig; Sie müssen die Werte nur durch Kommas trennen:

digitPins[] = {13, 12, 11, 10};
segPins[] = {2, 3, 4, 5, 6, 7, 8};

Sie müssen pinMode () in einer Schleife aufrufen. Arrays werden nicht als Argumente akzeptiert.

Wie wäre es mit digitalWrite (), wo es eine Mischung aus HIGH und LOW ist?

Es gibt (mindestens) zwei Möglichkeiten: Erstellen Sie Arrays mit HIGH- und LOW-Werten, die eins zu eins mit den Arrays digitPins [] und segPins [] übereinstimmen. Oder deklarieren Sie zur einfacheren Wartung eine Datenstruktur ( struct) einer Pin-Nr. Und eines Werts. machen Sie eine Reihe von denen. Es ist etwas komplexer, aber auch nützlicher. Also zum Beispiel:

typedef struct {
    uint8_t pinNum;
    bool pinVal;
} pinInit_t;

pinInit_t digitPins[] {
    {13, HIGH},
    {12, LOW},
    {11, LOW},
    {10, HIGH}
};

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

structist die Abkürzung für "Datenstruktur"; Damit können Sie Daten verschiedener Typen zu einer einzigen benannten und adressierbaren Einheit kombinieren. typedefdeklariert einen neuen Datentyp und sagt: "Weisen Sie gerade keinen Speicher zu. Dies (pinInit) ist nur eine Beschreibung. Ich werde ihn später verwenden." Dadurch wird pinInit zu einem benannten Datentyp, der überall dort verwendet werden kann, wo Sie einen nativen Datentyp verwenden können UND ein mehrwertiger Datentyp (z. B. ein Array) zulässig ist.

Somit können wir ein Array von pinInits (Pin- # / Boolesche-Wert-Paare) erstellen, indem wir einfach den Namen des neuen Typs verwenden.

Dann könnte Ihr Initialisierungscode folgendermaßen aussehen:

uint8_t i;
for( i = 0; i < sizeof(digitPins)/sizeof(pinInit_t); ++i ){
   pinMode(digitPins[i].pinNum, OUTPUT);
   digitalWrite(digitPins[i].pinNum, digitPins[i].pinVal);
}

Der Ausdruck sizeof(digitPins)/sizeof(pinInit)ergibt die Anzahl der Initialisierer (Anzahl der Bytes im Array / Anzahl der Bytes in einem Array-Mitglied).

Der Ausdruck digitPins[i].pinNumbedeutet: "Holen Sie sich im PinInit-Array digitPins das i-te Element ..." (denken Sie daran, dies ist ein Wertepaar), "... und nehmen Sie den Wert des Elements" pinNum ". Etwas komplexer , das erste Mal, wenn wir darüber nachdenken, aber schauen Sie sich an, wie leicht das Array gelesen werden kann. Und ein Hinweis zum Lesen dieses Ausdrucks: Ich lese es rückwärts: "Das pinNum-Mitglied des i-ten Elements des digitPins-Arrays."

Morgen oder im nächsten Monat, wenn wir einen weiteren Pin benötigen, müssen keine zwei Arrays aktualisiert werden (denken Sie natürlich daran, sie in der Reihenfolge miteinander zu halten!). Fügen Sie einfach ein weiteres 2-wertiges Element zum Array digitPins [] hinzu.


3

[ZUSÄTZLICHER CODE und ERKLÄRUNG DES CODES]

Dies ist die Funktion, die in dem in den Kommentaren veröffentlichten Link verwendet wird:

void number(int num)                        //num is the number to display
{
  for(int i=0; i<7; i++)                    //going through the 7-segments (7 leds)
  {
    digitalWrite(segment[i], nums[num][i]); //tell the arduino to turn on or off which led
  }
}

Es ist großartig, weil Sie es verwenden können, indem Sie anrufen:

number(/*the number you want to display*/);

Durch die Verwendung einer for-Schleife wird vermieden, dass eine Menge Dinge kopiert und eingefügt werden. Sie können damit auch viel Speicherplatz sparen.

Um einen kleinen 0-9-Timer anzuzeigen, können Sie Folgendes tun:

for(int i=0; i<10; i++)
{
  number(i);            //display the number
  delay(1000);          //wait 1sec
}

[ORIGINAL ANWSER]

Verwenden Sie ein Array und eine for-Schleife.

int segments = {2,3,4,5,6,7,8}; //declaring the pins

void setup() {
  for(int i=0;i<8;i++)
  {
    pinMode(segments[i], OUTPUT); //declaring them as outputs
  }
}

Es ist sehr nützlich. Machen Sie dasselbe auch für die Ziffern.

Diese Methode funktioniert in vielen Fällen:

  • viele Sensoren, Schalter
  • viele Ausgänge wie LEDs, Relais, Transistoren

1
Wie wäre es mit digitalWrite (), wo es eine Mischung aus HIGH und LOW ist?
Zdub

@zdub, was die Sache zwar komplizierter macht, aber wenn Sie eine gute Lösung für das suchen, wonach Sie wahrscheinlich suchen, sollten Sie Ihre Frage so bearbeiten, dass mehr als eine Möglichkeit zum Schreiben der Daten angezeigt wird .
Chris Stratton

Hier ist ein Beitrag, den ich vor einiger
Dat Ha

1
Für eine Mischung aus HIGH und LOW haben Sie auch die Liste von HIGH und LOW in einem Array. Stellen Sie übrigens sicher, dass Sie das Array erstellen constund, noch besser, auch anordnen PROGMEM, obwohl dies Auswirkungen auf die Leistung hat.
Majenko

@canadiancyborg 2D Arrays !! Ich wusste nicht, dass dies eine Option ist, aber ich denke, es wird funktionieren. Warum muss sich dieses digitalWrite (Segment [i], nums [num] [i]) in einer for-Schleife befinden? Warum kann 'i' nicht einfach eine Variable sein und der Code funktioniert ohne die for-Schleife?
Zdub

0

Benutzerdefinierte Methodenverwendung

Verwendete Referenz: https://stackoverflow.com/a/33235154/5500092

Sie können eine benutzerdefinierte Methode wie die folgende verwenden:

template<size_t size>
void pinMode(const uint8_t (&pin)[size], uint8_t mode) {
    for (size_t i = 0; i < size; ++i) {
        pinMode(pin[i], mode);
    }
}

template<size_t size>
void digitalWrite(const uint8_t (&pin)[size], uint8_t val) {
    for (size_t i = 0; i < size; ++i) {
        digitalWrite(pin[i], val);
    }
}

Dann definieren Sie ein Array mit den Pins:

uint8_t displayPins[4] = {13, 12, 11, 10};
uint8_t segmentPins[7] = {2, 3, 4, 5, 6, 7, 8};

Und schließlich in Ihrem Setup verwenden:

void setup() {                
    pinMode(displayPins, OUTPUT);
    pinMode(segmentPins, OUTPUT);
}

void loop() {
    // Your logic with digitalWrite.
}

Deine Logik

PS: Für Ihre Logik können Sie sogar Folgendes verwenden:

template<size_t size>
void digitalWrite(const uint8_t (&pin)[size], const uint8_t (&val)[size]) {
    for (size_t i = 0; i < size; ++i) {
        digitalWrite(pin[i], val[i]);
    }
}

Und definieren Sie für jede Segmentnummer ein benutzerdefiniertes Wertearray.

uint8_t zero[7] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW};
...

Oder auch:

uint8_t segment[][7] = {{HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW }, // 0
                        {____, ____, ____, ____, ____, ____, ____}, // 1
                        {____, ____, ____, ____, ____, ____, ____}, // 2
                        ...
                        {____, ____, ____, ____, ____, ____, ____}}; // F

Und benutze:

digitalWrite(segmentPins, segment[5]); // print 5

-4
func(){ 
   boolean pins[] ={ 1,1,1,1,1,1,0};
   for(int i=0; i<7;i++)`
   digitalWrite(segPins[i], pins[i]);
}

das ist alles :)


Bitte fügen Sie eine Textbeschreibung hinzu, warum Ihre vorgeschlagene Lösung die Antwort ist. Formatieren Sie Ihren Code auch korrekt. Bitte lesen Sie, wie ich eine gute Antwort schreibe . Wenn Sie eine gut präsentierte Antwort geben, erhalten Sie nicht so viele Abstimmungen.
Greenonline

1. Das hilft nicht, da Sie für jede der zehn Ziffern eine solche Funktion benötigen würden. 2. Es wird nicht kompiliert.
Edgar Bonet
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.