Thay thế một số chân pinMode () và digitalWrite () bằng một mảng


7

Tôi muốn 'dọn sạch' một số mã liên quan đến một số pinMode()digitalWrite()các dòng bằng cách sử dụng một dòng duy nhất của một mảng. Tôi rất mới với cả hai mảng nên tôi hơi bối rối. Các ví dụ sau đây là các phần từ mã điều khiển đèn LED 4 chữ số, 7 đoạn.

// 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;

Xác định chân:

Tôi khá chắc chắn mã dưới đây là cách chính xác để lưu trữ các chân như một mảng (nhưng vui lòng sửa lại cho tôi nếu tôi sai).

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

pinMode():

Tôi hiểu rằng tôi có thể sử dụng vòng lặp for để đặt chế độ pin nhưng có cách nào đơn giản hơn không? Có công việc nào như vầy không?

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

digitalWrite():

Tôi có thể truy cập mã pin thích hợp từ mảng để sử dụng digitalWrite()như mã bên dưới nhưng điều đó sẽ dẫn đến cùng một số dòng mã (và thậm chí còn khó hiểu hơn). Có lựa chọn nào khác không?

digitalWrite(segPins[1], HIGH);


1
Vì đây là màn hình 4 chữ số, 7 chữ số, nên câu hỏi phù hợp nhất có lẽ là: Làm thế nào để sử dụng màn hình 7 cực, 4 chữ số anode chung? .
Edgar Bonet

Câu trả lời:


7

cách chính xác để lưu trữ các chân như một mảng

Công cụ khởi tạo mảng của bạn gần như đúng; bạn chỉ cần tách các giá trị bằng dấu phẩy:

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

Bạn sẽ cần gọi pinMode () trong một vòng lặp; nó không chấp nhận mảng như là đối số.

Làm thế nào về kỹ thuật sốWrite () trong đó sự pha trộn giữa CAO và THẤP?

Có (ít nhất) hai cách: Tạo các mảng có giá trị CAO và THẤP, khớp với các mảng DigitPins [] và segPins [] tương ứng với từng mảng một. Hoặc để bảo trì dễ dàng hơn, hãy khai báo cấu trúc dữ liệu ( struct) của pin # và giá trị; tạo một mảng của những cái đó Nó phức tạp hơn một chút nhưng cũng hữu dụng hơn. Ví dụ:

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:
}

structlà viết tắt của "cấu trúc dữ liệu"; nó cho phép bạn kết hợp dữ liệu của các loại khác nhau thành một đơn vị có tên và địa chỉ. typedefkhai báo một loại dữ liệu mới và nói "Đừng phân bổ bất kỳ bộ nhớ nào ngay bây giờ; cái này (pinInit) chỉ là một mô tả. Tôi sẽ sử dụng nó sau này." Nó làm cho pinInit một kiểu dữ liệu được đặt tên, có thể sử dụng bất cứ nơi nào bạn có thể sử dụng kiểu dữ liệu gốc VÀ một kiểu dữ liệu đa giá trị (như một mảng) được cho phép.

Vì vậy, chúng ta có thể tạo một mảng các pinInitcặp s (pin- # / boolean-value) chỉ bằng cách sử dụng tên của loại mới.

Sau đó, mã khởi tạo của bạn có thể trông như sau:

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);
}

Biểu thức sizeof(digitPins)/sizeof(pinInit)ước tính số lượng bộ khởi tạo (# byte trong mảng / # byte trong một thành viên mảng).

Biểu thức digitPins[i].pinNumcó nghĩa là: "trong mảng DigitInin, lấy phần tử thứ i ..." (hãy nhớ, đây là một cặp giá trị), "... và lấy giá trị của thành viên" pinNum ". , lần đầu tiên chúng ta nghĩ về nó, nhưng hãy xem mảng đó đọc dễ dàng như thế nào. Và một gợi ý về việc đọc biểu thức đó: Tôi đọc ngược lại: "thành viên pinNum của phần tử thứ i của mảng DigitPins."

Ngày mai, hoặc tháng tới, khi chúng ta cần một mã pin khác, không cần cập nhật 2 mảng (tất nhiên là nhớ, để giữ chúng theo thứ tự với nhau!); chỉ cần thêm một phần tử có giá trị 2 khác vào mảng một DigitPins [].


3

[MÃ BỔ SUNG VÀ KHAI THÁC CỦA MÃ]

Đây là chức năng được sử dụng trong liên kết được đăng trong các bình luận:

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
  }
}

Thật tuyệt vời vì bạn có thể sử dụng nó bằng cách gọi:

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

Sử dụng vòng lặp for sẽ tránh sao chép và dán một loạt các thứ. Nó cũng cho phép bạn tiết kiệm rất nhiều bộ nhớ.

Sau đó, để hiển thị một bộ đếm thời gian 0-9 nhỏ, bạn có thể làm điều này:

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

[NGUỒN GỐC]

Sử dụng một mảng và một vòng lặp for.

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
  }
}

Nó rất hữu ích. Làm tương tự cho các chữ số quá.

Phương pháp này hoạt động trong nhiều trường hợp:

  • nhiều cảm biến, công tắc
  • nhiều đầu ra như đèn led, rơle, bóng bán dẫn

1
Làm thế nào về kỹ thuật sốWrite () trong đó sự pha trộn giữa CAO và THẤP?
zdub

@zdub điều đó thực sự sẽ khiến mọi thứ trở nên phức tạp hơn, nhưng nếu bạn muốn một giải pháp tốt cho những gì bạn có thể đang tìm kiếm, bạn nên chỉnh sửa câu hỏi của mình để hiển thị nhiều hơn một khả năng cho dữ liệu được viết.
Chris Stratton

đây là một bài đăng tôi đã đăng cách đây khá lâu về 7-seg: arduino.stackexchange.com/questions/30031/ gợi
Đạt Hà

1
Đối với sự pha trộn giữa CAO và THẤP, chỉ cần có danh sách CAO và THẤP trong một mảng là tốt. Nhân tiện, hãy chắc chắn để tạo ra mảng constvà, thậm chí tốt hơn, sắp xếp nó PROGMEMlà tốt, mặc dù điều đó có ý nghĩa hiệu suất.
Majenko

@canadiancyborg mảng 2D !! Không biết đây là một lựa chọn nhưng tôi nghĩ nó sẽ hoạt động. Tại sao DigitalWrite này (đoạn [i], nums [num] [i]) phải nằm trong một vòng lặp for? Tại sao không thể là một biến và mã hoạt động mà không có vòng lặp for.
zdub

0

Sử dụng phương pháp tùy chỉnh

Tài liệu tham khảo được sử dụng: https://stackoverflow.com/a/33235154/5500092

Bạn có thể sử dụng một phương thức tùy chỉnh như thế này:

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);
    }
}

Sau đó, bạn xác định một mảng với các chân:

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

Và cuối cùng trong thiết lập của bạn sử dụng:

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

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

Logic của bạn

PS: Đối với logic của bạn, bạn thậm chí có thể sử dụng:

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]);
    }
}

Và xác định cho mỗi số phân đoạn một mảng giá trị tùy chỉnh.

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

Hoặc thậm chí:

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

Và sử dụng:

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]);
}

đó là tất cả :)


Vui lòng thêm một mô tả văn bản tại sao giải pháp đề xuất của bạn là câu trả lời. Cũng định dạng chính xác mã của bạn. Xin vui lòng đọc Làm thế nào để tôi viết một câu trả lời tốt . Nếu bạn đưa ra một câu trả lời được trình bày tốt, bạn sẽ không nhận được quá nhiều lượt tải xuống.
Greenonline

1. Điều đó không có ích, vì bạn sẽ cần một hàm như vậy cho mỗi mười chữ số. 2. Nó không biên dịch.
Edgar Bonet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.