Ví dụ: if(A > 50) { Thực hiện một nhiệm vụ nào đó; } Chương trình sẽ kiểm tra xem giá trị A nào đó có lớn hơn 50 không, nếu có thì nhiệm vụ bên trong cấu trúc if sẽ được thực hiện, nói cách khác, nếu biểu thức điều kiện đúng thì khối lệnh bên trong hai dấu ngoặc nhọn sẽ được thực hiện, còn nếu không thì chương trình sẽ bỏ qua các câu lệnh này. Trong một số trường hợp thì hai dấu ngoặc nhọn có thể bỏ đi, nếu biểu thức điểu kiện đúng thì câu lệnh ngay sau if sẽ được thực hiện, câu lệnh này định nghĩa bằng dấu chấm phẩy, và nó chỉ thực hiện một câu lệnh duy nhất này. Ví dụ: if ( x >120 ) digitalWrite(LEDpin,HIGH); Một số toán tử so sánh thường được dùng trong cấu trúc if: x == y (giá trị của x bằng giá trị của y) x != y (giá trị của x khác giá trị của y) x < y (giá trị của x nhỏ hơn giá trị của y) x > y (giá trị của x lớn hơn giá trị của y) x=y (giá trị của x lớn hơn hoặc bằng giá trị của y) Lưu ý khi sử dụng if với toán tử so sánh bằng ( == ), nếu bạn chỉ sử dụng một dấu bằng cho cấu trúc if, ví dụ if (x = 10) thì khi đó dấu bằng đơn này sẽ được hiểu là phép gán giá trị chứ không phải là toán tử so sánh nữa, khi đó giá trị 10 sẽ được gán cho biến x, có nghĩa là khi cấu trúc if hoạt động thì sẽ luôn ra kết quá là TRUE, và khi đó cấu trúc if của chúng ta sẽ bị hoạt động sai. - Cấu trúc if/else: Cấu trúc if/else là một cấu trúc điều khiển rẽ nhánh cao cấp hơn là cấu trúc if, nếu như cấu trúc if được gọi là cấu trúc if dạng thiếu thì cấu trúc if/else còn được gọi là cấu trúc if dạng đủ. Cấu trúc if / else giải quyết bài toán linh hoạt hơn là cấu trúc if. Cấu trúc if/else cho phép ta kiểm tra nhiều toán từ so sánh hơn.
Trang 1ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
ARDUINO MEGA 2560
Hà Nội - 2016
Trang 2LỜI NÓI ĐẦU
Hiện nay với việc sự phát triển của khoa học công nghệ thì những ứng dụng của vi điều khiển trong cuộc sống ngày càng nhiều, trên thị trường hiện nay có rất nhiều dòng vi điều khiển khác nhau, nhưng hầu hết các dòng vi điều khiển này đều khá khó để lập trình
và yêu cầu người lập trình phải có một lượng kiến thức sâu để có thể lập trình được chúng, và điều đó gây khó khăn cho những người mới tiếp xúc với lĩnh vực này Dựa trên những yếu tố đó, Arduino đã ra đời để khắc phục các yếu tố trên, Arduino là một loai kit phát triển dựa trên các dòng vi điều khiển có sẵn trên thị trường, nhưng được nhà sản xuất tích hợp sẵn các chức năng,được giới thiệu vào năm 2005, những nhà thiết kế của Arduino cố gắng mang đến một phương thức dễ dàng, không tốn kém cho những người yêu thích, sinh viên, và giới chuyên nghiệp để tạo ra các thiết bị có khả năng tương tác với môi trường thông qua các cảm biến và các cơ cấu chấp hành, những ví dụ phổ biến cho người yêu thích mới bắt đầu bao gốm các robot đơn giản, điều khiển nhiệt độ và phát hiện chuyển động…… vì vậy khi làm việc với arduino thì các bạn không cần lo lằng và suy nghĩ nhiều về phần cứng, đặc biệt hơn là arduino rất dễ lập trình, với trình dịch dễ sử dụng, ngôn ngữ lập trình đơn giản, chính vì vậy arduino là một sự lựa chọn đúng đắn cho những người mới tiếp xúc với lính vực lập trình vi điểu khiển Dựa trên các yếu tố đó thì chúng tôi viết ra cuốn sách này với mục địch đưa người đọc đến với Arduino một cách dễ dàng nhất Nội dung cuốn sách sẽ tổng hợp các kiến thức cơ bản nhất về lĩnh vực lập trình Từ các cấu trúc và các lệnh cơ bản của ngôn ngữ lập trình C, lưu đồ thuật toán đến việc sử dụng các cấu trúc đó vào trong lập trình Arduino, cách cài đặt trình dịch, driver, nạp code và mô phỏng trên phần mềm mô phỏng Proteus Cuốn sách này sẽ tập trung vào giới thiệu về các khối cơ bản nhất của Arduino đó là khối vào ra số (digital) và khối vào
ra tương tự (analog), các bài ví dụ sẽ được trình bày theo một trình tự và các bước rõ ràng, từ việc phân tích đề bài, xây dừng mạch mô phỏng, đến việc lập trình, giải thích code và chạy thử, để người đọc có thể dễ dàng hiểu và tự mình xây dựng được cho mình một chương trình điều khiển với Arduino Trong cuốn sách sẽ có những sai sót ko đáng
có, vì vậy các chúng tôi mong sẽ nhận được góp ý của người đọc để cuốn sách được hoàn thiện hơn
Trang 3Chương I: Kiến thức cơ bản về ngôn ngữ lập trình C
- Ngôn ngữ C là một ngôn ngữ lập trình bậc cao khá thông dụng hiện nay, vì đặc trưng
dễ hiểu dễ lập trình và dễ sử dụng nên C được dùng nhiều trong các lĩnh vực lập trình khác nhau
- Trong lĩnh vực lập trình vi điều khiển thì ngôn ngữ C là ngôn ngữ phổ biến nhất, hầu hết các loại vi điều khiển trên thị trường đều có thế sử dụng ngôn ngữ C để lập trình, và arduino cũng vậy
- Vì vậy để có thể lập trình tốt trên Arduino thì mình xin giới thiệu một chút về các thành phần và các lệnh cơ bản trong lập trình bằng ngôn ngữ C
1.1.Lưu đồ thuật toán:
Lưu đồ thuật toán là một biểu đồ thế hiện trình tự và các bước để tạo ra một chương trình
cụ thể, bảng 1 đưa ra các hình dạng và ý nghĩa của các thành phần trong lưu đồ thuật toán
Gọi chương trình con, hàm
Bắt đầu, kết thúc (Begin, end)
Điểm kết nối
Bảng 1.1 Hình dạng và ý nghĩa của các thành phần trong lưu đồ thuật toán
Trang 41.2 Cấu trúc
1.2.1 Cấu trúc điều khiển
** Cấu trúc điều khiển là các cấu trúc dùng để điều khiển chương trình theo các hướng
khác nhau, vì thế các cấu trúc này còn được gọi là cấu trúc điều khiển rẽ nhánh
Trang 5Hình 1.3.1 Lưu đồ thuật toán của cấu trúc if
Trong một số trường hợp thì hai dấu ngoặc nhọn có thể bỏ đi, nếu biểu thức điểu kiện đúng thì câu lệnh ngay sau if sẽ được thực hiện, câu lệnh này định nghĩa bằng dấu chấm phẩy, và nó chỉ thực hiện một câu lệnh duy nhất này Ví dụ:
if ( x >120 ) digitalWrite(LEDpin,HIGH);
Một số toán tử so sánh thường được dùng trong cấu trúc if:
x == y (giá trị của x bằng giá trị của y)
x != y (giá trị của x khác giá trị của y)
x < y (giá trị của x nhỏ hơn giá trị của y)
x > y (giá trị của x lớn hơn giá trị của y)
x<=y (giá trị của x nhỏ hơn hoặc bằng giá trị của y)
x>=y (giá trị của x lớn hơn hoặc bằng giá trị của y)
Lưu ý khi sử dụng if với toán tử so sánh bằng ( == ), nếu bạn chỉ sử dụng một dấu bằng cho cấu trúc if, ví dụ if (x = 10) thì khi đó dấu bằng đơn này sẽ được hiểu là phép gán giá trị chứ không phải là toán tử so sánh nữa, khi đó giá trị 10 sẽ được gán cho biến x, có nghĩa là khi cấu trúc if hoạt động thì sẽ luôn ra kết quá là TRUE, và khi đó cấu trúc if của chúng ta sẽ bị hoạt động sai
- Cấu trúc if/else:
Cấu trúc if/else là một cấu trúc điều khiển rẽ nhánh cao cấp hơn là cấu trúc if, nếu như cấu trúc if được gọi là cấu trúc if dạng thiếu thì cấu trúc if/else còn được gọi là cấu trúc if dạng đủ Cấu trúc if / else giải quyết bài toán linh hoạt hơn là cấu trúc if Cấu trúc if/else cho phép ta kiểm tra nhiều toán từ so sánh hơn
Cấu trúc:
if( <điều kiện )
Trang 6Lưu đồ thuật toán:
Hình 1.2.2 Lưu đồ thuật toán của cấu trúc if else
Trang 7A có giá trị bằng 500 hoặc nhỏ hơn 500
Việc kiểm tra tính đúng sai của biểu thức trong cấu trúc if else được thực hiện liên tục cho đến khi nó tìm được một toán tử so sánh đúng, khi đó câu lệnh tương ứng sẽ được thực hiện, và chương trình sẽ thoát khỏi cấu trúc if else này
Ngoài việc sử dụng cấu trúc if else như bình thường, ta còn có thế sử dụng cấu trúc này theo một cách khác, ví dụ:
Với cách này, ta có thế kiểm tra nhiều toán tử so sánh khác nhau, ứng với mỗi toán tử đó
sẽ là một nhiệm vụ khác nhau, như vậy cấu trúc này sẽ điều khiển linh hoạt hơn rất nhiều
so với cấu trúc if bình thường
- Cấu trúc for:
Cấu trúc for là cấu trúc sử dụng để lặp lại một khối lệnh nào đó dựa theo một điều kiện
cụ thể, cấu trúc này thường được sử dụng cho các câu lệnh với tính chật lặp lại nhiều lần Trong mỗi cấu trúc lặp for có 3 phần:
Trang 8for( khởi tạo; điều kiện ; biến gia tăng )
Lưu đồ thuật toán:
Hình 1.2.3 Lưu đồ thuật toán của cấu trúc for
Ví dụ về một vòng lặp for trong arduino:
for( int i = 0; i <255; i ++ )
Trang 9- Cấu trúc switch case:
Giống như cấu trúc if hay if else thì switch case cũng là một cấu trúc rẽ nhánh, nó điều khiển chương trình dựa vào việc thực hiện các lệnh khác nhau tùy thuộc vào từng điều kiện khác nhau, nói một cách cụ thể thì với 1 biểu thức ở trong switch thì ta sẽ có thể có nhiều kết quả, mỗi kết quả sẽ ứng với một case, khi chương trình kiểm tra giá trị cuả biểu thức, giá trị đó bằng với giá trị của case nào thì các khối lệnh trong case đó sẽ được thực hiện
Trang 10Hình 1.2.4 Lưu đồ thuật toán của lệnh switch
Từ khóa break trong cấu trúc switch case rất quan trọng, nó xuất hiện trong mỗi giá trị của case, nếu không có từ khóa break thì cấu truc switch case sẽ tiếp tục thực hiện biểu thức tiếp theo cho đến khi gặp break hoặc cho đến khi kết thúc cấu trúc swith case
- Cấu trúc while:
while là một vòng lặp liên tiếp, nó sẽ thực hiện việc lặp lại cho đến khi nào biểu thức bên trong dấu ngoặc đơn của nó trở nên sai
Cấu trúc:
Trang 11while( <biểu thức>)
{
Khối lệnh thực hiện;
}
Lưu đồ thuật toán:
Hình 1.2.5 Lưu đồ thuật toán của lệnh while
- Cấu trúc do while:
Trang 12Cấu trúc do while cũng là một cấu trúc lặp giống như while nhưng có một sự khác biệt
là điều kiện kiểm tra để tiếp tục vòng lặp sẽ được thực hiên ở cuối cùng của vòng lặp, điều này có nghĩa là dù khối lệnh bên trong do sẽ được thực hiện ít nhất là một lần Cấu trúc:
Lưu đồ thuật toán:
Hình 1.2.6 Lưu đồ thuật toán của lệnh do … while
Khi chương trình bắt đầu được chạy thì việc đầu tiên là khối lệnh sẽ được thực hiên trước tiên, cho dù điều kiện trong while có đúng hay sai, sau khi thực hiện xong khối lệnh này thì chương trình mới đi đến để kiểm tra biểu thức, nếu biểu thức này đúng thì chương
Trang 13trình lại lặp lại thực hiện khối lệnh, còn ngược lại nếu biểu thức sai thì chương trình sẽ thoát khỏi cấu trúc do while
Trang 14Khi hàm này được gọi, tùy vào giá trị của biến a mà hàm này sẽ có giá trị khác nhau, nếu
a =1 thì khi đó hàm Giatri nay sẽ được trả về giá trị 1, tức là hàm này có giá trị bằng 1, và nếu a không băng 1 tức là hàm này được trả về giá trị bằng 0
Trang 15Chương trình này có thể được hiểu như sau, trong vòng lặp vô hạn void loop, nếu kiểm
tra điều kiện a == 100 đúng thì nhảy đến thực hiện hàm có tên Ham1()
Trang 16- Dấu ngoặc nhọn {}
Dấu ngoặc nhọn là một thành phần của ngôn ngữ lạp trình C, chúng được sử dụng cho nhiều cấu trúc khác nhau, và điều này sẽ dễ gây ra nhầm lần cho những người mới tiếp xúc với lĩnh vực này
Khi trong chương trình xuất hiện một dấu ngoặc mở { thì chắc chắn sẽ phải có một dấu ngoặc đóng đi theo Đó là một quy định bắt buộc Trong trình dịch Arduino IDE thì có những chức năng để kiểm tra việc đã đủ các dấu ngoặc nhọn này chưa, khi t click chọn vào một dấu ngoặc bất kì ( hoặc dấu đóng hoặc dấu mở) thì dấu ngoặc tương ứng với nó
sẽ được làm nỗi bật lên
- Dấu chú thích đơn ( // ) và chú thích nhiều dòng ( /* … */)
Trong một chương trình lập trình thì chú thích là những dòng quan trong không kém so với những dòng lệnh,chú thích dùng để chỉ ra cho chính người lập trình hoặc những người đọc chương trình cách mà chương trình hoạt động hoặc ý đồ của người viết
chương trình, những dòng chú thích sẽ được chương trình biên dịch bỏ qua,
- Cấu trúc #define
#define là một cấu trúc dùng để định nghĩa, nó cho phép chương tình gán một tên cho một giá trị hằng số nào đó trong chương trình
Cấu trúc:
Trang 17Cấu trúc:
#include < tên thư viện.h>
Chú ý là cũng giống như với #define thì #include cũng không có dấu chấm phẩy khi kết thúc, chương trình biên dịch sẽ bào lỗi nếu bạn thêm chấm phẩy vào phía sau của cấu trúc này
1.2.3 Các toán tử thuật toán
- Các phép toán ( Cộng +, Trừ -, Nhân * và Chia / )
Là các phép toán trả về giá trị Tổng, Hiệu, Tích, Thương của hai số.Kết quả của các phép tính này sẽ trả về kiểu giá trị là kiểu giá trị của toán hạng đó, điều nãy cũng có nghĩa là hiện tượng tràn giá trị có thể xẩy ra nếu kết quá của phép tính lớn hơn miền giá trị của kiểu dữ liệu đó, khi đó một kiểu dữ liệu rộng hơn sẽ được sử dụng đẻ chứa kết quá của phép tính này
Cấu trúc:
Kết quả = Giá trị 1 + Giá trị 2;
Kết quả = Giá trị 1 - Giá trị 2;
Trang 18Kết quả = Giá trị 1 * Giá trị 2;
Kết quả = Giá trị 1 / Giá trị 2;
- Phép chia lấy phần dư ( % )
Là phép toán sử dụng để lấy phần dư của phép chia một số nguyên cho một số nguyên khác
X >Y ( X có giá trị lớn hơn Y)
X <= Y ( X có giá trị nhỏ hơn hoặc bằng Y)
X >= Y ( X có giá trị lớn hơn hoặc bằng Y)
1.2.5 Các toán tử logic
- Toán tử logic and ( && )
Toán tử logic and là toán tử chỉ trả về giá trị đúng khi cả hai toán hạng đều đúng
Trang 19- Toán tử logic not ( ! )
Toán từ logic not là toán từ trả về giá trị đúng nếu toán hạng sai
1.2.6 Các toán tử logic theo bit
- Toán tử logic ANDtheo bit
Toán tử logic and theo bit được biểu diễn bằng một dấu &, toàn tử này hoạt động với nguyên tắc: nếu cả bits input có giá trị bằng 1 thì bits output sẽ có giá trị bằng 1 còn nếu không thì bits output có giá trị bằng 0;
Có thể biểu diễn toán tử này như sau:
Bảng 1.2.1 Toán tử logic AND theo bit
- Toán tử logic OR theo bit
Toán tử logic or theo bit được biểu diễn bằng 1 dấu | , toán tử này hoạt động với nguyên tắc: bit output sẽ có giá trị bằng 1 nếu một trong hai bit input có giá trị bằng 1 hoặc cả hai cùng có giá trị bằng 1
Có thể biểu diễn toán tử này như sau:
Trang 20Bit 1 input 0 0 1 1
Bảng 1.2.2 Toán tử logic OR theo bit
- Toán tử logic XOR ( ^ )
Toán từ XOR được biểu diễn bằng 1 dấu ^, nó hoạt động với một nguyên tắc là bit output
sẽ có giá trị bằng 0 nếu hai bit đầu vào có giá trị giống nhau và bằng 1 nếu hai bit input
có giá trị khác nhau
Có thể biểu diễn toán tử này như sau:
Bảng 1.2.3 Toán tử logic XOR theo bit
- Toán tử NOT ( ~ ) theo bit:
Toán từ NOT theo bit được biểu diễn bằng 1 dấu ~, Khác với toán tử & hay | thì NOT được sử dụng đối với 1 bit đầu vào, Toán tử này thay đổi 1 thành 0 và 0 thành 1
Có thể biểu diễn toán tử này như sau:
- Toán tử dịch bit ( dịch trái << , dịch phải >> ):
Toán tử dịch bit được biểu diễn bằng hai dấu << nếu là dịch trái và dấu >> nếu là dịch phải toán tử dịch bit hoạt động theo nguyên tắc di chuyển các bit về một phía ( trái hoặc phải ) và dịch một khoảng bằng số ở phía sau của dấu << hoặc >>
- Toán tử tăng và giảm ( ++ và )
Là phép dùng để tăng hoặc giảm giá trị của một biến
Ví dụ:
X ++; // tăng X lên một đơn vị và trả về giá trị thay thế cho giá trị của của X cũ
Trang 21X ; // giảm X đi một đơn vịvà trả về giá trị thay thế cho giá trị của của X cũ
X /= Y; // là cách viết tắt thay thế X = X /Y;
X %= Y; // là cách viết tắt thay thế X = X %Y;
x &= y; // là cách viết tắt thay thế x = x &y;
x |= y; // là cách viết tắt thay thế x = x |y;
1.3 Biến
1.3.2 Kiểu dữ liệu
- void : từ khóa void chỉ được sử dụng trong việc khai báo các hàm, với việc khai báo
hàm bằng từ khóa void thfi khi chúng ta gọi hàm thì hàm này sẽ không trả về bất kì giá trị nào Hàm sử dụng void được sử dụng rất nhiều trong quá trình lập trình
- boolean : boolean chứ hai giá trị, một là đúng ( true ) hai là sai ( false ), mối một biến
được khai báo kiểu boolean sẽ chiếm 1 byte trong bộ nhớ
Cấu trúc:
boolean < tên biến >;
hoặc
boolean < tên biến > = <true>;
boolean < tên biến > = <false>;
Trang 22- char : char là kiểu dữ liệu khá phổ biến trong lập trình bằng ngôn ngữ C, nó chiếm 1
byte trong bộ nhớ dữ liệu của chip và nó chứa các giá trị dạng kí tự ( A , B , C ….)
char là một kiểu dữ liệu dạng signed, có nghĩa là nó sẽ mã hóa các số từ -128 đến 127 Cấu trúc:
char < tên biến >;
- unsigned char : unsigned char là kiểu dữ liệu cũng chiếm 1 byte dữ liệu trong bộ nhớ
unsigned char < tên biến > = < giá trị >;
- byte : byte là kiểu dữ liệu chứa 1 số dương 8 bit, có miền giá trị từ 0 đến 255
Cấu trúc:
byte < tên biến >;
- int : int là một kiểu dữ liệu chiếm 2 byte trong bộ nhớ chương trình, miền giá trị của
kiểu int từ -32768 đến 32767
Cấu trúc:
int < tên biến >;
hoặc
int < tên biến > = < giá trị >;
- unsigned int : unsigned int là kiểu dữ liệu cũng chiếm 2 byte trong bộ nhớ dữ liệu
giống như int, chỉ có điều unsigned int mã hóa các số từ 0 đến 65535
Cấu trúc:
unsigned int < tên biến >;
hoặc
unsigned int < tên biến > = < giá trị >;
- word : word là một kiểu dữ liệu rất lớn, trên arduino UNO hoặc các board mạch phát
triển dựa trên ATMEGA khác thì word chứa dữ liệu 16 bits còn trên Arduino Due thì giá trị này là 32 bits
Trang 23Cấu trúc:
word < tên biến> ;
Hoặc
word <tên biến> = < giá trị >;
- long : long là kiểu giá trị lưu trữ tới 4 byte, 32bits, từ -2,147,483,648 to
unsigned long < tên biến>;
- short : là một kiểu dữ liệu 16 bits,
Trên tất cả các board Arduino thì kiểu dữ liệu short lưu trữ giá trị dữ liệu 16 bits
Cấu trúc:
short < tên biến>;
Hoặc
short < tên biến> = < giá trị >;
- float : float là kiểu dữ liệu thực, kiểu dữ liệu này chiếm 4 bytes trong bộ nhớ chương
trình, , nó dùng để lưu trữ các số thực, các số thập phân …
Cấu trúc:
foat < tên biến >;
Hoặc
float <tên biến> = <giá trị>;
-double : là kiểu dữ liệu chiếm 4 byte trong bộ nhớ chương trình, kiểu dữ liệu này sẽ thể
hiện chính xác giá trị của biểu thưc với ít sai lệch
Cấu trúc khai báo:
double < tên biến>;
Hoặc
double < tên biến> = < giá trí >;
Trang 24- string : string là kiểu dữ liêu chuỗi kí tự, có thể sử dụng kiểu string này với kiểu dữ liệu
char
Một số cách khai báo dữ liệu kiể string:
char Str1[15];
char Str2[8] = { ‘a’ , ‘r’ , ‘d’ , ‘u’ , ‘i’ ,’ n’’ ,’ o ‘};
char Str3[8] = { ‘a’ , ‘r’ , ‘d’ , ‘u’ , ‘i’ ,’ n’’ ,’ o ‘ , ‘ \0’};
char Str4[] = {“arduino”};
char Str1[8] = “arduino”;
char Str1[15] = “arduino”;
- array : là kiểu dữ liệu mảng, một mảng là một tập hợp của các giá trị với các chỉ số,
mảng là kiểu dữ liệu được dùng khá nhiều trong quá trình lập trình
Một số kiểu khai báo mảng:
int myArr[8];
int myArr[] ={ 2,4,6,8};
int myArr[8] = {1,3,6,5,6};
char message[6] = “hello”;
1.3.3 Các phép biến đổi kiểu dữ liệu
- char() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu char
Cú pháp:
char(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
- byte() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu byte
Cú pháp:
byte(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
- int() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu int
Cú pháp:
int(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
- word() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu word
Cú pháp:
word(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
- long() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu long
Trang 25Cú pháp:
long(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
- float() : chuyển đổi một giá trị của một kiểu dữ liệu bất kì về kiểu dữ liệu float
Cú pháp:
float(x); trong đó x là một giá trị thuộc 1 kiểu dữ liệu bất kì
1.3.3 Phạm vi của biến trong chương trình và Qualifiers
- Phạm vi của biến trong chương trình:
Trong một chương trình lập trình bằng ngôn ngữ C sẽ có 2 loại biến khác nhau, biến toàn cục và biến cục bộ
Biến toàn cục là biến có thể được sử dụng ở tất cả các hàm trong chương trình, nói cách khác là biến này có giá trị trong toàn chương trình
Biến cục bộ là biến được khai báo ở một hàm cụ thể nào đó và biến này chỉ có giá trị trong hàm mà nó khai bảo
Trong một chương trình lớn và phức tạp thì việc sử dụng 2 loại biến này sẽ là điều rất cần thiết để khiến cho chương trình chặt chẽ và dễ dàng hơn trong việc lập trình
- kiểu khai báo biến Static:
Static là từ khóa để tạo ra giá trị chỉ được sử dụng trong một hàm, tuy nhiên khác với biến cục bộ ở chỗ, nếu như biến cục bộ bị xóa đi sau khi hàm được gọi thì kiểu static cho phép lưu trữ giá trị của biến sau mỗi lần gọi hàm, biến được khai báo kiểu static sẽ có giá trị vĩnh viễn trong chương trình
Cấu trúc khai báo:
static < kiểu dữ liệu><tên biến> ;
- volatile : volatile được xem là một kiểu khai báo để giới hạn giá trị của dữ liệu, nó
thường được sử dụng để khai báo cho các biến có giá trị thay đối một cách ko báo trước Đối với arduino thì chỉ có một trường hợp duy nhất mà trường hợp này có thể xảy ra là trong các biến khi sử dụng ngắt
Cách khai báo biến với volatile:
volatile < tên kiểu dữ liệu>< tên biến> ;
Trang 26Hoặc
volatile < tên kiểu dữ liệu>< tên biến> = < giá trị >;
- const : const là từ viết tắt của constant có nghĩa là hằng số, const là một kiểu dữ liệu
giới hạn giá trị của biến, khi một biến được khai báo với kiểu const tức là nó sẽ được hiểu như là một biến chỉ có thể đọc ( read –only ), có nghĩa là biến này sẽ không thế thay đổi
về giá trị, nếu bạn cố tính thay đổi giá trị của nó thì khi đó trình dịch sẽ báo lỗi
Chương II Giới thiệu sơ lược về Arduino Mega 2560
2.1 Giới thiệu chung
- Board Arduino Mega2560 là một Kit phát triển dựa trên chip ATmega2560 của dòng AVR
- Trên Kit có 54 chân In Out (Digital) trong đó có 15 chân là chân PWM output, 16 chân đầu vào analog, 4 kênh USART, tích hợp thạch anh 16MHz
Trên Kit còn tích hợp kết nối USB, Jack cắm nguồn…
- Một số thông tin về arduino mega2560:
Trang 27Hình 2.1 Các thông số cảu arduino mega 2560
Hình 2.2 Hình ảnh thực tế của arduino mega2560
- Một số lưu ý khi sử dụng Kit Arduino Mega2560: Có
- Nguồn vào cho Jack cắm là 7 -12 V, trên board ko có điot chống ngược nên bạn cần phải cắm đúng chiều âm dương nếu ko muốn board bị hỏng
Bạn nên sử dụng nguồn từ máy tính thông qua kết nối USB để an toàn hơn
Trang 28- Các khối trên phần cứng của Arduino mega 2560:
+ Số 1: Jack cắm USB để nạp chương trình cho arduino
+ Số 8: Jack cắm nguồn ngoài cho Arduino
+ Số 2: Các chân PWM của Arduino
+ Số 3: Các chân giao tiếp UART của Arduino
+ Số 4: Các chân digital của Arduino
+ Số 5: Các chân Analog In phục vụ việc đọc giá trị analog
+ Số 6: Các chân lấy nguồn, cấp nguồn và reset
Hình 2.3 Các khối trên mạch Arduino mega2560
2.2 Phần mềm biên dịch
2.2.1 Cài đặt
- Arduino sử dụng phần mềm biên dịch là Arduino IDE Bạn có thể download trình biên dịch tại trang web của arduino : https://www.arduino.cc/en/Main/Software Đối với hệ điều hành Windown thì sẽ có hai lựa chọn là phiên bản cần cài đặt và bản Zip ko cần cài đặt, bạn có thể download 1 trong hai bản về máy của mình, đối với bản cài đặt thì bạn chỉ cần chạy file setup bình thường, còn đối với bản không cần cài đặt thì bạn chỉ cần giải nén là có thể sử dụng
- Một điều cũng rất quan trong nếu muốn sử dụng được arduino đó là cài driver Đối với bản cài đặt arduino của windown thì Driver sẽ được tự động cài đặt cùng với chương trình, còn với bản Zip, để cài Driver thì chúng ta làm như sau:
+ Bước 1: Mở file chứa arduino lên
Trang 29Hình 2.4 Mở file chứa arduino
+ Bước 2: chọn vào thư mục Driver Sau đó chạy 1 trong 2 file như hình ở dưới tùy thuộc vào win mà bạn sử dụng, với win 64 bit thì bạn chạy file dpinst-amd64, còn với win 32 bit thì bạn chạy file dpinst-x86
Hình 2.5 Chọn file cài đặt arduino tương thích Windows + Bước 3: Bạn chọn next cho đến khi cài đặt xong Driver
Trang 30Hình 2.5 Kết thức cài đặt Driver cho arduino
- Giao diện của phần mềm Arduino IDE sau khi cài :
Hình2.6 Giao diện của Arduino IDE
Trang 312.2.2 Thanh Toolbar của Arduino IDE
Hình 2.9.Thanh Toolbar của Arduino IDE
Trong đó:
Button dùng để biên dịch chương trình, kiểm tra lỗi của chương trình
Button dùng để nạp chương trình vào Board Arduino
Các Button dùng để mở file mới (new), mở chương trình có sẵn (open), và lưu chương trình (save)
Button dùng để mở cổng Monitor (COM) của arduino
2.2.3 Arduino IDE menu gồm các tùy chọn
Hình 2.9.Menu của Arduino IDE
a Trong menufile gồm các tùy chọn
Hình 2.10.MenuFile Arduino IDE
Trang 32Trong đó ta quan tâm tới tùy chọn Example, trong tùy chọn này chứa các bài ví dụ đã được viết sẵn về các khối của arduino để chúng ta có thế tham khảo, ví dụ như các khối digital hay analog, communocation……
Hình 2.11.Tùy chọn Example
b Trong menuedit
Trong menu edit là các công cụ soạn thảo thông dụng nhất mà trong bất kỳ phần mềm soạn thảo nào cũng có Kèm theo đó là một số chức năng hỗi trợ soạn thảo cơ bản của ngôn ngữ lập trình C
Trang 33Hình 2.12.MenuEdit Arduino IDE
c Trong menu sketch
Trong menusketch, verifly dùng để kiểm tra lỗi của chương trình, upload để nạp chương trình và board Arduino,include Library dùng để thêm thư viện cho arduino…
Hình 2.13.MenuSketch Arduino IDE
d Trong menu tools
Trong tools menu, Serial Monitor dùng để mở cổng COM kết nối giữa máy tính và arduino, Lệnh Board dùng để chọn board arduino tương ứng, ví dụ như ở đây board đang được chọn là arduino mega 2560, chúng ta sử dụng nạp chương trình cho board nào thì phải chọn đúng board đó
Trang 34Hình 2.13.MenuTools Arduino IDE
2.2.4 Cấu trúc
Một chương trình của Arduino nhất thiết phải có hai phần:
setup() :là hàm sử dụng đề cài đặt các thông số cho chương trình,ví dụ như cấu hình chân, tốc độ baud …
Loop(): là vòng lặp vô hạn của chương trình, đây là phần chương trình chính, nhất thiết phải có trong chương trình
2.2.5 Các biến hằng số
Là các biến có giá trị ko thay đổi, những giá trị đã được quy định trước
Trong Arduino các biến này được chia thành 4 nhóm:
+ Nhóm 1: Các biến được định nghĩa theo mức logic, hay được gọi là hằng số logic,
gồm có true và false
Đây là hai hằng số dùng để đại diện cho đúng và sai trong ngôn ngữ lập trình Arduino false : được định nghĩa là số 0, sử dụng để đại diện cho Sai
true : được định nghĩa là số 1, sử dụng để đại diện cho Đúng
Chú ý: true và false được viết dưới dạng chữ thường
+ Nhóm 2: Các biến được định nghĩa theo mức logic của các chân của Arduino, gồm có
HIGH và LOW
HIGH : HIGH sẽ có nghĩa khác nhau một chút tùy thuộc vào trường hợp chân đó được cài đặt là chân đầu ra hay đầu vào, nếu là đầu vào (INPUT) thì sẽ được định hình bằng pinMode(), và được đọc bằng hàm digitalRead(), khi đó Arduino sẽ trả về giá trị HIGH khi:
* Đối với board 5V thì điện áp trên chân đó phải lớn hơn 3V
Trang 35* Đối với board 3.3V thì điện áp trên chân đó phải lớn hơn 2V
Còn nếu là đầu ra (OUTPUT) thì sẽ được định hình bằng hàm pinMode() và được set bằng hàm digitalWrite(), khi đó Arduino sẽ trả về giá trị HIGH khi:
* Đối với board 5V thì điện áp trên chân đó phải là 5V
* Đối với board 3.3V thì điện áp trên chân đó phải là 3.3V
LOW : cũng giống như với HIGH thì LOW cũng được định nghĩa khác nhau với trường hợp nếu chân đó là đầu ra hoặc đầu vào Nếu chân đó là đầu vào INPUT thì arduino sẽ trả
về giá trị LOW khi:
* Đối với board 5V thì điện áp trên chân đó phải nhỏ hơn 3V
* Đối với board 3.3V thì điện áp trên chân đó phải nhỏ hơn 2V
Còn nếu chân đó là đầu ra OUTPUT thì Arduino sẽ trả về giá trị LOW khi
* Đối với board 5V thì điện áp trên chân đó bằng 0
* Đối với board 3.3V thì điện áp trên chân đó bằng 0
+ Nhóm 3: Các biến được định nghĩa bằng chế độ hoạt động của một chân nào đó của
Arduino, gồm có INPUT, INPUT_PULLUP và OUTPUT
Một chân vào ra số bất kì của Arduino có thể được sử dụng với chức năng là chân đầu vào ( INPUT), đầu ra (OUTPUT) , hoặc đầu vào có điện trở kéo lên (INPUT_PULLUP) INPUT: một chân của Arduino được cấu hình là iNPUT với hàm pinMode(), nếu một chân của Arduino được cấu hình là INPUT và được sử dụng để đọc một nút bấm, khi nút bấm đó ở trạng thái mở thì khi đó đầu vào của chân sẽ ở trạng thái thay đổi, không thể dự đoán trước được kết quả, vì vậy người ta sẽ sử dụng một điện ở kéo lên hoặc kéo xuống
để biết được trạng thái của chân đó khi nút bấm chưa được bấm, thường thì điện trở được chọn là 10K ohm
Nếu điện trở kéo xuống được sử dụng, thì khi nút bấm chưa được bấm thì đầu vào của chân sẽ ở mức thấp ( LOW), và khi nút bấm được bấm thì trạng thái của chân sẽ được đẩy lên mức cao ( HIGH) và điều này ngược lại với việc sử dụng điện trở kéo lên
INPUT_PULLUP : Trong Arduino có một điện trở kéo lên được thiết kế ở trong
Arduino, vì vậy bạn có thể truy cập vào các điện trở này, nếu bạn muốn sử dụng các điện trở này thay vì sử dụng điện trở kéo bên ngoài thì bạn có thể sử dụng INPUT_PULLUP với hàm pinMode()
OUTPUT: Khi một chân của Arduino được cấu hình là đầu ra với hàm pinMode(), điều này có nghĩa là nó có thể cung cấp một giá trị dòng điện ra ngoài hoặc đến một mạch khác Giá trị của dòng điện này thường rơi vào khoảng 40mA, với dòng điện này chúng
ta có thẻ sử dung để cấp trực tiếp cho LED vì LED sử dụng dòng nhỏ hơn 40mA, với các
Trang 36mạch yêu cầu dòng điện lớn hơn, ví dụ như động cơ thì cần có các transistor hoặc các mạch công suất khác
+ Nhóm 4: LED_BUILTIN
Hầu hết các Arduino đều có một chân kết nối với một LED ở trên board mạch, khi đó hằng số LED_BUILTIN sẽ được định nghĩa chính là chân có gắn con led đó, thường thì con led này sẽ được gắn vào chân số 13
2.2.6 Digital I/O
- pinMode() : pinMode là hàm dùng để định nghĩa cấu hình của các chân cho arduino là
đầu ra hay đầu vào Thường được sử dùng trong phần setup()
Cú pháp:
pinMode( < tên chân >, OUTPUT);
pinMode( < tên chân >, INPUT);
- digitalWrite() : Khi một chân bất kì nào đó của Arduino được cấu hình là đầu ra bằng
hàm pinMode() thì khi đó ta có thể sử dụng hàm digitalWrite() để xuất tín hiệu ra theo mức cao HIGH hoặc mức thấp LOW
Cú pháp:
digitalWrite( < tên chân>, HIGH);
digitalWrite( < tên chân>, LOW);
- digitalRead() : Khi một chân bât kì của Arduino được cấu hình là đầu vào INPUT bằng
hàm pinMode() thì khi đó ta có thể sử dùng hàm digitalRead() để đọc trạng thái của chân
đó, trạng thaasi này có thể xẩy ra 2 giá trị đó là HIGH hoặc LOW
Digital ( Analog to Digital Convert), tùy vào mục địch sử dụng mà người lập trình chọn mức điện áp tham chiếu phù hớp cho vi điều khiển Đối với Arduino thì có các cách chọn mức điện áp tham chiếu như sau:
- DEFAUT : Mức điện áp tham chiếu khi chọn DEFAUT là 5V đối với board Arduino 5V hoặc 3.3V đối với board mạch 3.3V
- INTERNAL : mức điện áp tham chiếu sẽ được chọn là 1.1V đối với các board có sử dụng Atmega328 hoặc 2.56V đối với Atmega8
Trang 37-INTERNAL1V1 : Mức điện áp được chọn là 1.1V ( chỉ với Arduino mega 2560)
- INTERNAL2V56 : mức điện áp được chọn là 2.56V ( chỉ với Arduino mega 2560)
- EXTERNAL : mức điện áp được chọn sẽ là mức điện áp được đặt vào trên chân AREF của Arduino
Cấu trúc để khai báo hàm analogReference():
analogReference( type);
Trong đó type là một trong các kiểu chọn mức điện áp đã nêu ở trên
- analogRead() :
Hàm analogRead() là một hàm được sử dụng để đọc tín hiệu từ một chân Analog In batas
kì nào của Arduino Trên mỗi Board Arduino có ít nhất là 6 chân sử dụng cho Analog In, với độ phân giải 10- bits, điều này có nghĩa là giá trị mức điện áp từ 0V đến 5V sẽ được chia đều thành các số nguyên từ 0 đến 1023, và khi sử dụng analogRead() để đọc giá trị analog trên 1 chân bất kì sẽ thu được kết quả nằm trong khoảng từ 0 đến 1023
Arduino sẽ mất 100 micro giây để đọc 1 lần giá trị analog In, vì thế tốc độ đọc tối đa của Arduino sẽ là 10000 lần đọc 1 giây
- analogWrite() :
Hàm analogWrite() là hàm sử dụng để xuất một tín hiệu analog xuống một chân nào đó của Arduino Tín hiệu này là một xung PWM, vì vậy nó có thể sử dụng để điều khiển độ sáng của led hay điều khiển tốc độ của động cơ
Tần số của xung PWM khi xuất ra bằng hàm analogWrite() tùy thuôc vào các chân của Arduino, thường thì tần số này sẽ là 490 Hz, hoặc ở trên chân 5 và 6 của Arduino UNO
và một số Board khác thì giá trị tần số này là 980 Hz
Trên hầu hết các board Arduino thì hàm này sẽ hoạt động trên các chân như 3,5,6,9,10 … Lưu ý khi sử dụng hàm này thì chân xuất tín hiệu phải được cài đặt cấu hình chân là OUTPUT với hàm pinMode();
Cú pháp:
analogWrite(<tên chân>, < giá trị >);
Giá trị ở đây có giá trị từ 0 đến 255, trong đó 0 là luôn tắt còn 255 là luôn mở
Trang 38Cú pháp:
shifftOut( dataPin,clockPin,bitOrder,value);
Trong đó:
dataPin là chân xuất dữ liệu ra
clockPin là chân tạo xung cho quá trình
bitOrder lầ một trong hai gia trị MSBFIRST hoặc LSBFIRST, tức là bit chuyển đi đầu tiên sẽ là bit ở bên phải nhất hay ở bên trái nhất
value là giá trị cần chuyển
Chú ý là shiftOut chỉ chuyển được dữ liệu 8 bits Nếu bạn muốn chuyên giá trị lớn hơn thì có thể shiftOut nhiều lần, mỗi lần 8 bits
Trang 39clockPin là chân tạo xung cho quá trình
bitOrder lầ một trong hai gia trị MSBFIRST hoặc LSBFIRST, tức là bit chuyển đi đầu tiên sẽ là bit ở bên phải nhất hay ở bên trái nhất
Hàm shiftIn trả về giá trị dữ liệu nhận được theo byte
- pulseIn():
Hàm pulseIn(): là hàm đọc tín hiệu từ một chân của Arduino và trả về giá trị của thời gian thay đổi trạng thái của chân đó, ví dụ nếu giá trị ta cần đọc là HIGH thì chương trình sẽ đợi cho đến khi chân đó lên mức cao HIGH và bắt đầu tính thời gian, cho đến khi chân
đó chuyển từ mức cao xuống mức thấp, khi đó quá trình đếm thời gian sẽ kết thúc và giá trị của thời gian đó sẽ được trả về với giá trị của hàm pulseIn(): theo đơn vị là micro giây
Cú pháp:
pulseIn(< tên chân>, <value>);
pulseIn(< tên chân>, <value>, <time out>);
trong đó
value là trạng thái của chân Arduino ( HIGH hoặc LOW)
time out là thời gian chờ, nếu như chân đó luôn ở mức cao hoặc luôn ở mức thấp thì sau một khoảng thời gian là time out thì chương trình sẽ dừng việc đếm thời gian lại và trả về giá trị 0 cho hàm pulseIn();
10 thì có nghĩa chương trình của bạn đã chạy được 40 microgiây Tương tự, trên mạch 8Mhz (ví dụ LilyPad), hàm này có giá trị tương đương 8 micro giây
Hàm micros sẽ trả về giá trị kiểu unsigned long kể từ khi Arduino bắt đầu hoạt động
- delay()
Hàm delay() là hàm chờ, khi gặp hàm delay thì Arduino sẽ không làm gì và chờ cho đến khi hết thời gian delay thì lại tiếp tục hoạt động đơn vị của hàm delay() là mili giây (ms)
Trang 40hàm min() trả về giá trị của số nhỏ hơn
- max() : là hàm dùng để tính giá trị lớn hơn gữa 2 số
Cú pháp:
max(x ,y);
Trong đó x là số thứ nhất và y là số thứ 2
Hàm max() sẽ trả về giá trị của số lớn hơn
- abs() là hàm dùng để tính giá trị tuyệt đối của một số
Cú pháp:
abs(x);
Hàm abs() sẽ trả về giá trị bằng x nếu x lớn hơn 0 và bằng –x nếu x nhỏ hơn 0
- constrain() : là hàm dùng để giới hạn, bắt buộc một gia trị nằm trong một giới hạn cho