Bài 11: Mảng trong lập trình arduino

     Bài hôm nay tôi sẽ hướng dẫn cho các bạn một chủ đề mới trong lập trình là mảng trong arduino. Nói đến khái niệm mảng thì các bạn nghĩ ngay đến nhiều phần tử, nhưng những phần tử này sẽ có mối liên quan với nhau và được xử lý giống nhau trong cùng một thời điểm.

     Mảng trong Arduino thì hầu như giống mảng của ngôn ngữ C, C++ thuần, chỉ khác nhau về câu lệnh, còn thuật toán hoàn toàn giống nhau. Để các bạn có thể hiểu được toàn bộ mảng của arduino, trước hết tôi sẽ hướng dẫn cho các bạn cách thực hiện câu lệnh của Arduino cho mảng. Phần thứ 2 tôi mới viết cho các bạn về ví dụ ứng dụng của mảng trong lập trình thực tế arduino.

  NỘI DUNG BÀI VIẾT  

  • Định nghĩa và khai báo mảng
  • Cách nhập dữ liệu cho mảng
  • Cách in dữ liệu lên màn hình Serial
  • Kết hợp mảng và chương trình con

  1.  ĐỊNH NGHĨA VÀ KHAI BÁO MẢNG  

     Trước hết bạn phải hiểu mảng là gì: Mảng là tập hợp các phần tử có cùng kiểu dữ liệu, các kiểu dữ liệu đó có thể là int, float, char

     Cách khai báo mảng 

     <Kiểu dữ liệu>   <Tên mảng>[<Số phần tử>];

     <Kiểu dữ liệu>   < Tên mảng>[]={<Giá trị 1>, <Giá trị 2>, <Giá trị 3>,…};

     Ví dụ: int A[10];  //Khai báo mảng có kiểu int có tối đa 5 phần tử.

                int B[]={1, 2 , 3 ,10} ;  //Khai báo mảng có kiểu int chứa 4 phần tử và giá trị được khởi tạo khi vừa khai báo.

     Khi bạn tiến hành khai báo một mảng, thì chương trình sẽ tạo ra một vùng nhớ, vùng nhớ đó có tên với tên bạn khai báo và số ô nhớ cung cấp cho bạn đủ với số lượng phần tử mà bạn khai báo. Trong cú pháp khai báo trên thì chương trình sẽ tạo ra một vùng nhớ có tên là A, và số phần tử của mảng là 10.

     Giả sử, tôi có 1 mảng A[5], và các phần tử nhập theo thứ tự 15, 2, 10, 5, 4. Thì cấu trúc của mảng được mô tả như hình dưới.

     Các phần tử được sắp xếp thứ tự với nhau, mỗi vị trí đều có chỉ số đánh dấu, chỉ số được đánh bắt đầu từ 0 đến hết mảng. Nếu mảng chúng ta khai báo là 5 phần tử, thì chỉ số sẽ được bắt đầu từ 0 đến 4. Chúng ta muốn thao tác đến phần tử nào thì cần phải cho chương trình biết tên của mảng và chỉ số của nó thì chương trình mới lấy chính xác vị trí đó cho bạn.

    int A[]={15, 2, 10, 5, 4};

    Chương trình thực hiện khởi tạo vùng nhớ như sau

A

15

2

10

5

4

\n

i

i=0

i=1

i=2

i=3

i=4

i=5

       Chương trình sẽ tạo ra vùng nhớ có 5 ô nhớ, mỗi ô là 2 byte (vì khai báo kiểu int). Riêng ô nhớ cuối cùng sẽ chứa ký tự đánh dấu kết thúc mảng. Ký tự này được chương trình tự tạo ra để biết mảng kết thúc ở vị trí nào.

      Khi truy xuất đến từng phần tử của mảng chúng ta cần phải biết chỉ số của phần tử đó.

  • Ví dụ:            A[0] = 15;
  •                       A[1] = 2;
  •                       A[2] = 10;
  •                       A[3] = 5;
  •                      A[4] = 4;
  •                      A[5]=NULL;  // Giá trị này chỉ có ý nghĩa kết thúc, không sử dụng cho việc truy xuất

  2.  CÁCH NHẬP DỮ LIỆU CHO MẢNG  

     Vì mảng là tập hợp nhiều phần tử nên chúng ta phải sử dụng vòng lặp để nhập dữ liệu.

     Cú pháp:

 int A[10];
// Cú pháp nhập
 for (int i=0; i< 10; i++)
  {
    Serial.println("Nhap phan tu thu: ” );
    while (Serial.available() == 0) {} //Chờ nhập dữ liệu
    A[i]=Serial.pasteInt();
  }

    Giải thích đoạn code trên:

     Khi i = 0

  • Lệnh Serial.println dùng để xuất thông báo nhập phần tử.
  • Vòng lặp while được sử dụng để chờ người dùng nhập dữ liệu từ bàn phím.
  • Sử dụng lệnh Serial.pasteInt() để đọc dữ liệu từ bàn phím gán cho phần tử thứ 0 của mảng.

     Tiếp theo biến i được tăng lên 1

  • Lệnh Serial.println dùng để xuất thông báo nhập phần tử.
  • Vòng lặp while được sử dụng để chờ người dùng nhập dữ liệu từ bàn phím.
  • Sử dụng lệnh Serial.pasteInt() để đọc dữ liệu từ bàn phím gán cho phần tử thứ 1 của mảng.

      Cứ như vậy chương trình sẽ lần lượt nhập các phần tử cho mảng.

  3. CÁCH IN DỮ LIỆU TRÊN MÀN HÌNH Serial  

     Vì mảng là tập hợp nhiều phần tử nên khi chúng ta cần in dữ liệu ra màn hình chúng ta cũng phải sử dụng vòng lặp để quét từng phần tử của mảng.

    Cú pháp in dữ liệu lên màn hình Serial.

for(int i=0; i< 10; i++)
 {
   Serial.print("Phan tu thu: ");
   Serial.println(A[i]);
  }

      Tương tự như đoạn code nhập dữ liệu, vòng lặp for sẽ lần lượt quét qua các ô nhớ của mảng và xuất ra dữ liệu lên màn hình.

      Như vậy, chúng ta có thể thực hiện toàn bộ đoạn code trong IDE của arduino một cách dễ dàng. Bây giờ chúng ta tiến hành viết ví dụ tạo ra một mảng 10 phần tử, tiến hành nhập và in 10 phần tử đó lên màn hình serial nhé.

 int A[10];
 int i;
void setup()
 {
 Serial.begin(9600);
 }

void loop(){
 for(i=0; i<10; i++)
  {
  Serial.print(“Nhap phan tu: ”);
  While (Serial.available()==0) {} // Chờ người dùng nhập dữ liệu vào
  A[i] = Serial.parseInt();
  Serial.println(A[i]);
  }

 //In dữ liệu mảng lên màn hình
  Serial.println(“Toan bo mang da nhap: ”);
  for(i=0; i<10; i++)
   {
    Serial.println(A[i]);
    }
}

      Như vậy, đến thời điểm này các bạn có thể hiểu được cách thức được tạo ra, và cấu trúc của mảng rồi chứ. Phần tiếp theo tôi sẽ hướng dẫn các bạn viết một ứng dụng thực tế có sử dụng mảng, và từ đó các bạn có thể sử dụng rộng rãi trong ứng dụng thực tế.

  4. KẾT HỢP MẢNG VÀ CHƯƠNG TRÌNH CON  

    Trong bài viết này tôi sẽ hướng dẫn cho các bạn thực hiện chương trình con kết hợp với mảng. Việc thực hiện chương trình con sẽ giúp cho câu lệnh trong vòng lặp loop đơn giản và dễ dàng quản lý hơn.

    Khi chúng ta thực hiện các lệnh với mảng, thì hầu như với 1 yêu cầu sẽ có nhiều câu lệnh. Chẳng hạn, với yêu cầu nhập dữ liệu vào mảng chúng ta cũng cần phải có ít nhất 4 câu lệnh, với việc in dữ liệu lên màn hình Serial chúng ta cũng cần ít nhất 3 câu lệnh. Do đó, để đơn giản hóa cho công việc, chúng ta nên viết bằng chương trình con những yêu cầu riêng biệt, còn trong vòng lặp loop chúng ta chỉ thực hiện những công việc chính.

   Giờ tôi sẽ viết cho các bạn chương trình nhập mảng bằng chương trình con. Giả sử chúng ta đã khai báo mảng kiểu nguyên A[10].

void nhapmang() {
  for(int i=0; i<10; i++)
   {
    Serial.print(“Nhap phan tu: ”);
    While (Serial.available()==0) {}
    A[i] = Serial.parseInt();
    Serial.println(A[i]);
    }
 }

    Tương tự, chúng ta có chương trình con inmang

void inmang(){
  for(int i=0; i<10; i++)
   {
   Serial.println(A[i]);
   }
}

     Và sau khi đã sử dụng chương trình con, thì code trong vòng lặp loop đơn giản hơn rất nhiều. Sau đây là chương trình đầy đủ

int A[10];
void setup()
 {
 Serial.begin(9600);
 }

void loop()
 {
 nhapmang();  //gọi chương trình con nhập mảng
 Serial.println(“Mang da nhap: ”);
 inmang();  //gọi chương trình con in mảng
 }

// Viết chương trình con nhập mảng
void nhapmang()
 {
   for(int i=0; i<10; i++)
   {
   Serial.print(“Nhap phan tu: ”);
   While (Serial.available()==0) {}
   A[i] = Serial.parseInt();
   Serial.println(A[i]);
   }
 }

// Viết chương trình con in mảng
 void inmang() {
  for(int i=0; i<10; i++)
   {
   Serial.println(A[i]);
   }
 }

     Các bạn thấy rõ ràng đoạn code trong vòng lặp rất đơn giản, các bạn chỉ cần gọi những chương trình con theo chức năng là chương trình sẽ tự động thực hiện chương trình con cho các bạn.

     Lưu ý trong ví dụ này, tôi đã khai báo toàn bộ biến là biến toàn cục nên tất cả các chương trình con đều sử dụng chung những biến này. Các bạn có thể xem lại bài viết về biến trong ngôn ngữ Arduino để có thể hiểu rõ hơn nhé.

     Các bạn hãy thử thực hiện chương trình con với yêu cầu tìm phần tử có giá trị lớn nhất trong mảng bằng chương trình con nhé. Tôi sẽ viết bài này đầy đủ cho các bạn tham khảo, tuy nhiên các bạn nên tự viết lại nhé, việc viết code sẽ giúp cho các bạn kỹ năng sửa lỗi.

int A[10];
int Max;

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

void loop() {
 nhapmang();  //gọi chương trình con nhập mảng
 Serial.println(“Mang da nhap: ”);
 inmang();  //gọi chương trình con in mảng
 Serial.print(“Gia tri lon nhat trong mang: ”);
 TimGTLN();
 }

// Viết chương trình con nhập mảng
void nhapmang() {
  for(int i=0; i<10; i++)
 {
  Serial.print(“Nhap phan tu: ”);
  While (Serial.available()==0) {}
  A[i] = Serial.parseInt();
  Serial.println(A[i]);
 }
}

// Viết chương trình con in mảng
void inmang(){
 for(int i=0; i<10; i++)
  Serial.println(A[i]);
 }

// Viết chương trình con tìm giá trị lớn nhất trong mảng
void TimGTLN() {
  Max = A[0];
  for (int i=1; i< 10; i++)
   {
    if (Max < A[i])
      Max= A[i];
   }
  Serial.println(Max);
}

    Tổng kết: với cách kết hợp mảng với chương trình con các bạn sẽ đơn giản hơn chương trình chính, và cũng từ đó bạn dễ dàng hiểu được code bạn đang sử dụng với mục đích gì, nhanh chóng đọc và hiểu code, từ đó rất dễ đưa ra phương án chỉnh sửa code.

   Và bây giờ các bạn thử thực hiện code nhập vào 1 mảng số nguyên, hãy tính giá trị trung bình, tìm giá trị lớn nhất, đếm bao nhiêu số chẵn, bao nhiêu số lẻ,…

 

 


Categories:

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *