Mục lục:
- Bước 1: Thiết lập Hội đồng quản trị
- Bước 2: Thêm nút và điện trở
- Bước 3: Kết nối nút
- Bước 4: Mã…
- Bước 5: Một chút Debounce
- Bước 6: Tạo thực đơn
- Bước 7: Phân tích mã - Toàn cầu
- Bước 8: Phân tích mã - Thiết lập và chức năng tùy chỉnh
- Bước 9: Vòng lặp…
- Bước 10: Khối mã cuối cùng
Video: Menu trong Arduino và cách sử dụng các nút: 10 bước (có hình ảnh)
2024 Tác giả: John Day | [email protected]. Sửa đổi lần cuối: 2024-01-30 13:33
Trong hướng dẫn Arduino 101 của tôi, bạn sẽ được dạy cách thiết lập môi trường của mình trong Tinkercad. Tôi sử dụng Tinkercad vì nó là một nền tảng trực tuyến khá mạnh mẽ cho phép tôi chứng minh một loạt các kỹ năng xây dựng mạch cho sinh viên. Hãy thoải mái xây dựng tất cả các hướng dẫn của tôi bằng cách sử dụng Arduino IDE và Arduino thực sự!
Trong hướng dẫn này, chúng ta sẽ tìm hiểu về các nút! Chúng ta cần biết:
- Làm thế nào để kết nối chúng
- Đọc giá trị của họ
- Debounce và tại sao nó quan trọng
- Một ứng dụng thực tế (tạo menu)
Hầu hết mọi người nghĩ rằng điều thiết thực nhất để làm với một nút là bật và tắt đèn. Chúng tôi sẽ, không ở đây! Chúng tôi sẽ sử dụng của chúng tôi để tạo menu và thiết lập một số tùy chọn trên Arduino.
Sẵn sàng? Bắt đầu nào!
Bước 1: Thiết lập Hội đồng quản trị
Bước đầu tiên là đặt Arduino và Breadboard Small vào khu vực tạo mẫu. Kiểm tra các hình ảnh ở trên để biết cách đấu dây vào ray điện.
Một Breadboard Mini có hai đường ray điện trên và dưới. Chúng tôi kết nối những thứ này với Arduino để chúng tôi có thể cung cấp năng lượng cho nhiều thành phần hơn. Phần sau của hướng dẫn này, chúng tôi sẽ sử dụng 3 nút nên chúng tôi sẽ cần nhiều năng lượng hơn. Điều cần lưu ý là trên bảng mạch nhỏ, các đường ray điện chạy ngang bảng, theo chiều ngang. Điều này khác với các cột trong khu vực tạo mẫu chính ở giữa; chúng chạy theo chiều dọc. Bạn có thể sử dụng bất kỳ chân nguồn nào để cung cấp điện cho bất kỳ cột nào trong khu vực chính ở giữa.
Khi bạn thêm điện, sử dụng dây màu đen và màu đỏ cho cực âm và dương tương ứng. Thêm dây vào cuối chạy điện cho phía bên kia của bảng. Chúng tôi sẽ không sử dụng mặt đó, nhưng đó là một thực tiễn tốt.
Bước 2: Thêm nút và điện trở
Thêm một nút ấn nhỏ từ khay linh kiện. Nó sẽ giống như trong hình ảnh. Hãy chắc chắn rằng nó không phải là một công tắc! Thêm một điện trở, quá. Nhấp vào nó và đặt giá trị của nó thành 10kΩ. Như vậy là đủ để kéo chân cắm xuống thấp khi nó không được kết nối, điều này rất quan trọng sau này trong mã.
Đặt thành phần ở giữa breadboard. Cách thức hoạt động của một nút là:
- Góc này sang góc khác, nút không được kết nối. Nhấn nút sẽ đóng các địa chỉ liên lạc và kết nối các góc.
- Các mặt của nút được kết nối. Nếu bạn kết nối một dây ở phía trên bên trái và phía dưới bên trái, mạch sẽ bị đóng.
Đây là lý do tại sao chúng tôi đặt thành phần trên khoảng trống ở giữa. Nó đảm bảo các góc không được kết nối dưới các chân cắm trong bảng.
Bước tiếp theo cung cấp một vài hình ảnh minh họa những điểm này.
Đặt điện trở từ chốt dưới cùng bên phải qua các cột, để nó nằm ngang.
Bước 3: Kết nối nút
Các hình ảnh trên cho thấy khá rõ ràng cách các nút kết nối. Luôn luôn là một điểm bối rối khi bạn nghĩ rằng một cái gì đó là tốt và nó không hoạt động!
Bây giờ, hãy thêm dây.
- Đặt dây dẫn màu đỏ từ chốt nguồn dương vào cùng cột với chốt phía dưới bên phải trên nút
- Đặt một dây dẫn màu đen từ chân nguồn âm vào cùng cột với điện trở.
- Đặt một dây màu (không phải màu đỏ / đen) từ chân trên cùng bên trái đến Chân số 2 trên Arduino
Kiểm tra các hình ảnh ở trên để đảm bảo hệ thống dây điện của bạn là chính xác.
Bước 4: Mã…
Hãy xem mã cho một nút cơ bản.
Mở trình chỉnh sửa mã và thay đổi từ Khối thành Văn bản. Xóa cảnh báo xuất hiện. Chúng tôi hài lòng với văn bản!
Bạn biết thiết lập cơ bản, vì vậy hãy xác định nút và đọc cơ bản. Chúng tôi sẽ in đầu ra thành Serial.
Tôi đặt thêm một vài nhận xét vào đoạn mã bên dưới để nó dễ đọc hơn hình ảnh.
// Định nghĩa hằng số
#define button 2 void setup () {pinMode (button, INPUT); Serial.begin (9600); } void loop () {// Đọc ghim kỹ thuật số để kiểm tra trạng thái của button int press = digitalRead (button); // Nút trả về CAO nếu được nhấn, THẤP nếu không nếu (nhấn == CAO) {Serial.println ("Đã nhấn!"); }}
Ok, tốt mà hoạt động!
Về cơ bản, tất cả những gì chúng tôi đang làm là kiểm tra trạng thái của pin kỹ thuật số mỗi khi mã lặp lại. Nếu bạn nhấp vào Bắt đầu mô phỏng và nhấn nút, bạn sẽ thấy Màn hình nối tiếp (nhấp vào nút bên dưới mã) hiển thị "Đã nhấn!" nhiều lần.
Một tính năng bạn sẽ thấy trong đoạn mã trên là đánh giá điều kiện if () đang diễn ra. Tất cả những gì đoạn mã đang làm là đặt một câu hỏi và đánh giá xem nó có đúng không, trong trường hợp này. Chúng tôi sử dụng is bằng (dấu bằng kép, như thế này: ==) để kiểm tra xem giá trị của biến có bằng một giá trị nào đó hay không. Một digitalRead () trả về HIGH hoặc LOW.
Sử dụng if () else if / else, chúng tôi có thể kiểm tra nhiều điều kiện hoặc tất cả các điều kiện và nếu bạn quay lại Kiến thức cơ bản về Arduino, bạn sẽ thấy một số so sánh mà bạn có thể thực hiện.
Bây giờ… Mã của chúng tôi có thể đã hoàn chỉnh… Nhưng chúng tôi gặp sự cố.
Thấy chưa, điều đó thực sự hoạt động tốt khi ở trong trình mô phỏng. Nhưng điện thực có nhiễu, đặc biệt là điện tử một chiều. Vì vậy, nút của chúng tôi đôi khi có thể trả về kết quả đọc sai. Và đó là một vấn đề, bởi vì dự án của bạn có thể không phản hồi đúng cách cho người dùng.
Hãy sửa chữa nó!
Bước 5: Một chút Debounce
Chúng tôi sử dụng một quy trình có tên là debounce để khắc phục sự cố nút của chúng tôi. Về cơ bản, điều này sẽ đợi một khoảng thời gian cụ thể từ khi nhấn nút đến khi thực sự phản hồi lại thao tác nhấn. Nó vẫn tạo cảm giác tự nhiên cho người dùng (trừ khi bạn đặt thời gian quá lâu). Bạn cũng có thể sử dụng nó để kiểm tra độ dài của báo chí, vì vậy bạn có thể phản hồi khác nhau mỗi lần. Bạn không cần phải thay đổi bất kỳ hệ thống dây điện nào!
Hãy xem mã:
#define button 2 # define debounceTimeout 100
Thay đổi đầu tiên là trên phạm vi toàn cầu. Bạn sẽ nhớ đó là nơi chúng tôi xác định các biến mà nhiều hàm của chúng tôi có thể sử dụng hoặc những biến không thể đặt lại mỗi khi vòng lặp kích hoạt. Vì vậy, chúng tôi đã thêm debounceTimeout vào các hằng số đã xác định. Chúng tôi đã thực hiện 100 này (sau này sẽ dịch thành 100ms), nhưng nó có thể ngắn hơn. Lâu hơn và nó sẽ cảm thấy không tự nhiên.
long int lastDebounceTime;
Biến này được khai báo bên dưới hằng số. Đây là kiểu int dài, về cơ bản cho phép chúng ta lưu trữ các số dài trong bộ nhớ. Chúng tôi đã gọi nó là LastDebounceTime.
Chúng ta không cần thay đổi bất cứ điều gì trong hàm void setup (). Bỏ cái đó đi.
void loop () {// Đọc ghim kỹ thuật số để kiểm tra trạng thái của button int press = digitalRead (button); long int currentTime = millis (); // Mã nút}
Thay đổi đầu tiên mà chúng tôi thực hiện trong hàm loop () nằm dưới lệnh gọi để đọc nút. Chúng ta cần theo dõi thời gian hiện tại. Hàm millis () trả về thời gian hiện tại của đồng hồ kể từ khi Arduino khởi động tính bằng mili giây. Chúng ta cần lưu trữ điều này trong một biến kiểu int dài.
Bây giờ, chúng tôi cần đảm bảo rằng chúng tôi biết thời gian kể từ khi nút được nhấn, vì vậy chúng tôi đặt lại bộ đếm thời gian khi nó không được nhấn. Hãy xem:
void loop () {// Đọc ghim kỹ thuật số để kiểm tra trạng thái của button int press = digitalRead (button); long int currentTime = millis (); if (nhấn == LOW) {// Đặt lại thời gian đếm khi không nhấn nút lastDebounceTime = currentTime; } // Mã nút}
Thuật toán if (được nhấn == LOW) kiểm tra xem nút không được nhấn. Nếu không, thì mã lưu trữ thời gian hiện tại kể từ lần gỡ lỗi cuối cùng. Bằng cách đó, mỗi lần nhấn nút, chúng ta có một thời điểm mà từ đó chúng ta có thể kiểm tra thời điểm nút được nhấn. Sau đó, chúng tôi có thể thực hiện một phép tính toán học nhanh để xem nút được nhấn trong bao lâu và phản hồi chính xác. Hãy xem phần còn lại của đoạn mã:
void loop () {// Đọc ghim kỹ thuật số để kiểm tra trạng thái của button int press = digitalRead (button); long int currentTime = millis (); if (nhấn == LOW) {// Đặt lại thời gian đếm khi không nhấn nút lastDebounceTime = currentTime; } // Nút đã được nhấn trong một thời gian nhất định if (((currentTime - lastDebounceTime)> debounceTimeout)) {// Nếu hết thời gian, hãy nhấn nút! Serial.println ("Đã ép!"); }}
Khối mã cuối cùng lấy thời gian hiện tại, trừ đi thời gian gỡ lỗi cuối cùng và so sánh nó với thời gian chờ mà chúng tôi đã đặt. Nếu nó lớn hơn, mã giả định rằng nút đã được nhấn trong thời gian đó và phản hồi. Gọn gàng!
Chạy mã của bạn và kiểm tra xem nó hoạt động. Nếu bạn có lỗi, hãy kiểm tra mã của bạn!
Bây giờ, chúng ta hãy xem xét một ví dụ thực tế.
Bước 6: Tạo thực đơn
Các nút rất thú vị, vì có rất nhiều khả năng với chúng! Trong ví dụ này, chúng ta sẽ tạo một menu. Giả sử bạn đã tạo ra thiết bị thực sự tuyệt vời này và cần người dùng có thể thay đổi các tùy chọn để bật hoặc tắt một số thứ nhất định hoặc đặt một giá trị cụ thể cho một cài đặt. Thiết kế ba nút này có thể làm được điều đó!
Vì vậy, đối với dự án này, chúng tôi cần:
- Ba nút
- Ba điện trở được đặt thành 10kΩ
Chúng tôi đã có một trong những cái này, chúng tôi chỉ cần hai cái còn lại. Vì vậy, hãy thêm chúng vào bảng. Việc nối dây phức tạp hơn một chút, nhưng chỉ vì tôi muốn giữ cho nó thực sự nhỏ gọn. Bạn có thể làm theo mẫu tương tự cho nút đầu tiên hoặc làm theo hình trên.
Ba nút là tùy chọn mở / tiếp theo của menu, tùy chọn thay đổi (như trong, thay đổi cài đặt) và nút lưu / đóng menu.
Lên dây, chúng ta hãy nhìn vào mã!
Bước 7: Phân tích mã - Toàn cầu
Ok, đây sẽ là một bước dài, nhưng tôi sẽ đi qua từng phần mã.
Đầu tiên, chúng ta hãy xem xét các biến toàn cục cần thiết.
// Định nghĩa hằng # xác định menuButton 2 #define menu Chọn 3 # định menuSave 4 #define debounceTimeout 50 // Định nghĩa biến int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; long int lastDebounceTime; // Tùy chọn menu char * menuOptions = {"Kiểm tra Nhiệt độ", "Kiểm tra Ánh sáng"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0;
Ba khối này khá giống với những gì chúng ta đã thấy trước đây. Trong phần đầu tiên, tôi đã xác định ba nút và thời gian chờ. Đối với phần này của dự án, tôi đã đặt nó thành 50ms vì vậy cần phải có một lần nhấn cố ý để làm cho nó hoạt động.
Khối thứ hai là tất cả các biến. Chúng ta cần theo dõi buttonPreviousState và chúng ta cần theo dõi LastDebounceTime. Đây là tất cả các biến kiểu int, nhưng biến cuối cùng là kiểu dài vì tôi giả sử chúng ta cần không gian trong bộ nhớ.
Khối tùy chọn menu có một vài tính năng mới. Đầu tiên, ký tự * (vâng, đó là một dấu hoa thị cố ý), là một biến ký tự / chuỗi ký tự. Nó là một con trỏ đến một bộ nhớ tĩnh trong bộ nhớ. Bạn không thể thay đổi nó (chẳng hạn như bạn có thể làm trong Python). Dòng char * menuOptions này tạo ra một mảng các ký tự chuỗi. Bạn có thể thêm bao nhiêu mục menu tùy thích.
Biến bool featureSetting chỉ là một mảng các giá trị đại diện cho mỗi mục menu. Có, bạn có thể lưu trữ bất cứ thứ gì bạn thích, chỉ cần thay đổi kiểu biến (tất cả chúng đều phải cùng một kiểu). Bây giờ, có thể có nhiều cách tốt hơn để quản lý điều này, như từ điển hoặc bộ dữ liệu, nhưng điều này rất đơn giản đối với ứng dụng này. Tôi có thể sẽ tạo một trong những cái sau trong một ứng dụng đã triển khai.
Tôi đã theo dõi MenuMode, vì vậy nếu tôi muốn những thứ khác trên màn hình của mình, tôi có thể làm điều đó. Ngoài ra, nếu tôi có logic cảm biến, tôi có thể tạm dừng điều đó trong quá trình hoạt động của menu, đề phòng có điều gì đó xung đột. Tôi có biến menuNeedsPrint vì tôi muốn in menu vào những thời điểm cụ thể, không chỉ mọi lúc. Cuối cùng, tôi có một biến optionSelected, vì vậy tôi có thể theo dõi tùy chọn đã chọn khi tôi truy cập nó ở một số nơi.
Chúng ta hãy xem xét tập hợp các chức năng tiếp theo.
Bước 8: Phân tích mã - Thiết lập và chức năng tùy chỉnh
Hàm setup () đủ dễ dàng, chỉ cần ba khai báo đầu vào:
void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }
Tiếp theo là ba chức năng tùy chỉnh. Hãy xem xét hai phần đầu tiên, sau đó là phần cuối cùng một cách riêng biệt.
Chúng ta cần hai hàm trả về một số thông tin. Lý do là, chúng tôi muốn đảm bảo rằng đây là loại người có thể đọc được. Nó cũng sẽ giúp gỡ lỗi mã nếu chúng tôi gặp sự cố. Mã số:
// Hàm trả về option đã chọn hiện tạichar * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Return optionSelected return menuOption; } // Hàm trả về trạng thái của tùy chọn được chọn hiện tại char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; }
Hàm char * ReturnOptionSelected () kiểm tra tùy chọn đã chọn (nếu bạn thấy ở trên, chúng tôi đặt một biến để theo dõi điều đó) và kéo chuỗi ký tự từ mảng mà chúng tôi đã tạo trước đó. Sau đó, nó trả về nó dưới dạng một kiểu char. Chúng tôi biết điều này vì hàm chỉ ra kiểu trả về.
Hàm thứ hai, char * ReturnOptionStatus () đọc trạng thái của tùy chọn được lưu trong mảng và trả về một ký tự chuỗi đại diện cho giá trị. Ví dụ: nếu cài đặt chúng tôi đã lưu trữ là sai, tôi sẽ trả về "Sai". Điều này là do chúng tôi hiển thị cho người dùng biến này và tốt hơn là giữ tất cả logic này lại với nhau. Tôi có thể làm điều đó sau, nhưng làm ở đây sẽ có ý nghĩa hơn.
// Hàm chuyển đổi optionbool hiện tại ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; trả về true; }
Hàm bool ToggleOptionSelected () là một hàm tiện lợi để thay đổi giá trị của cài đặt chúng ta đã chọn trong menu. Nó chỉ làm thay đổi giá trị. Nếu bạn có một bộ tùy chọn phức tạp hơn, điều này có thể hoàn toàn khác. Tôi trả về true trong hàm này, vì lệnh gọi lại của tôi (lệnh gọi sau đó trong mã kích hoạt hàm này) mong đợi trả lời đúng / sai. Tôi chắc chắn 100% điều này sẽ hoạt động, vì vậy tôi đã không giải thích nó không hoạt động, nhưng tôi sẽ sử dụng một ứng dụng đã triển khai (đề phòng).
Bước 9: Vòng lặp…
Hàm loop () khá dài, vì vậy chúng ta sẽ thực hiện nó theo từng phần. Bạn có thể giả sử mọi thứ bên dưới là tổ trong chức năng này:
void loop () {
// Làm việc tại đây <-----}
Ok, chúng tôi đã thấy nội dung này trước đây:
// Đọc các nút int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Lấy thời gian hiện tại long int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Đặt lại thời gian đếm khi nút không được nhấn lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; }
Tất cả những gì tôi phải làm ở đây là thêm ba lệnh gọi digitalRead () và đảm bảo rằng tôi đã tính đến thực tế rằng nếu tất cả các nút ở mức thấp, chúng ta nên đặt lại bộ hẹn giờ (lastDebounceTime = currentTime) và đặt tất cả các trạng thái trước đó thành thấp. Tôi cũng lưu trữ mili () trong currentTime.
Phần tiếp theo nằm bên trong dòng
if (((currentTime - lastDebounceTime)> debounceTimeout)) {
// Làm việc tại đây <----}
Có ba phần. Đúng, tôi có thể đã chuyển chúng vào các chức năng của riêng chúng, nhưng vì đơn giản, tôi đã giữ ba thuật toán nút chính ở đây.
if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Cho người dùng biết Serial.println ("Menu đang hoạt động"); } else if (menuMode == true && optionSelected = 1) {// Đặt lại tùy chọn optionSelected = 0; } // In menu menuNeedsPrint = true; // Chuyển đổi nút trước. trạng thái chỉ hiển thị menu // nếu nút được nhả ra và nhấn lại menuButtonPreviousState = menuButtonPressed; // Sẽ CAO}
Cái đầu tiên này xử lý khi menuButtonPressed ở mức CAO hoặc khi nút menu được nhấn. Nó cũng kiểm tra để đảm bảo rằng trạng thái trước đó là THẤP, do đó nút phải được thả ra trước khi nó được nhấn lại, điều này sẽ ngăn chương trình liên tục kích hoạt cùng một sự kiện lặp đi lặp lại.
Sau đó, nó sẽ kiểm tra nếu menu không hoạt động, nó sẽ kích hoạt nó. Nó sẽ in tùy chọn đầu tiên được chọn (theo mặc định là mục đầu tiên trong mảng menuOptions. Nếu bạn nhấn nút lần thứ hai hoặc thứ ba (v.v.), bạn sẽ nhận được tùy chọn tiếp theo trong danh sách. Một số thứ tôi có thể khắc phục là rằng khi đến cuối, nó sẽ quay trở lại từ đầu. Điều này có thể đọc độ dài của mảng và giúp quay lại dễ dàng hơn nếu bạn thay đổi số lượng tùy chọn, nhưng điều này hiện tại rất đơn giản.
Phần nhỏ cuối cùng (// In menu) rõ ràng sẽ in menu, nhưng nó cũng đặt trạng thái trước đó thành CAO để chức năng tương tự sẽ không lặp lại (xem lưu ý của tôi ở trên về việc kiểm tra xem nút trước đó có THẤP không).
// menuSelect được nhấn, cung cấp logicif ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Thay đổi tùy chọn đã chọn // Hiện tại, đây chỉ là true / false // nhưng có thể là bất cứ thứ gì bool toggle = ToggleOptionSelected (); if (chuyển đổi) {menuNeedsPrint = true; } else {Serial.println ("Đã xảy ra lỗi. Vui lòng thử lại"); }} // Chuyển trạng thái thành chỉ chuyển đổi nếu được thả ra và nhấn lại menuSelectPreviousState = menuSelectPressed; }
Đoạn mã này xử lý nút menuSelectPressed theo cách tương tự, ngoại trừ lần này chúng ta chỉ kích hoạt hàm ToggleOptionSelected (). Như tôi đã nói trước đây, bạn có thể thay đổi chức năng này để nó hoạt động nhiều hơn, nhưng đó là tất cả những gì tôi cần nó làm.
Điều chính cần lưu ý là biến chuyển đổi, theo dõi mức độ thành công của lệnh gọi lại và in menu nếu đúng. Nếu nó không trả về gì hoặc sai, nó sẽ in thông báo lỗi. Đây là nơi bạn có thể sử dụng lệnh gọi lại của mình để làm những việc khác.
if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Thoát khỏi menu // Tại đây bạn có thể thực hiện bất kỳ thu dọn nào // hoặc lưu vào EEPROM menuMode = false; Serial.println ("Menu đã thoát"); // Chuyển đổi trạng thái để menu chỉ thoát một lần menuSavePreviousState = menuSavePressed; }}
Chức năng này xử lý nút MenuSave, nút này vừa thoát ra khỏi menu. Đây là nơi bạn có thể có tùy chọn hủy hoặc lưu, có thể thực hiện một số thao tác dọn dẹp hoặc lưu vào EEPROM. Tôi chỉ in "Menu đã thoát" và đặt trạng thái nút thành CAO để nó không lặp lại.
if (menuMode && menuNeedsPrint) {// Chúng tôi đã in menu, vì vậy, trừ khi // có điều gì đó xảy ra, không cần in lại menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Đã chọn:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }
Đây là thuật toán menuPrint, thuật toán này chỉ kích hoạt khi menu đang hoạt động và khi biến menuNeedsPrint được đặt thành true.
Điều này chắc chắn có thể được chuyển sang chức năng riêng của nó, nhưng vì mục đích đơn giản..!
Vâng, đó là nó! Xem bước tiếp theo cho toàn bộ khối mã.
Bước 10: Khối mã cuối cùng
// Định nghĩa hằng số
#define menuButton 2 #define menuChọn 3 #define menuSave 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = LOW; int menuSavePreviousState = LOW; // Định nghĩa biến long int lastDebounceTime; bool lightSensor = true; bool tempSensor = true; // Tùy chọn menu char * menuOptions = {"Kiểm tra Nhiệt độ", "Kiểm tra Ánh sáng"}; bool featureSetting = {false, false}; bool menuMode = false; bool menuNeedsPrint = false; int optionSelected = 0; // Chức năng thiết lập
void setup () {pinMode (menuSelect, INPUT); pinMode (menuSave, INPUT); pinMode (menuSelect, INPUT); Serial.begin (9600); }
// Hàm trả về tùy chọn đã chọn hiện tại char * ReturnOptionSelected () {char * menuOption = menuOptions [optionSelected]; // Return optionSelected return menuOption; } // Hàm trả về trạng thái của tùy chọn được chọn hiện tại char * ReturnOptionStatus () {bool optionSetting = featureSetting [optionSelected]; char * optionSettingVal; if (optionSetting == false) {optionSettingVal = "False"; } else {optionSettingVal = "True"; } // Return optionSetting return optionSettingVal; } // Hàm chuyển đổi tùy chọn hiện tại bool ToggleOptionSelected () {featureSetting [optionSelected] =! FeatureSetting [optionSelected]; trả về true; } // Vòng lặp chính
void loop () {// Đọc các nút int menuButtonPressed = digitalRead (menuButton); int menuSelectPressed = digitalRead (menuSelect); int menuSavePressed = digitalRead (menuSave); // Lấy thời gian hiện tại long int currentTime = millis (); if (menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW) {// Đặt lại thời gian đếm khi nút không được nhấn lastDebounceTime = currentTime; menuButtonPreviousState = LOW; menuSelectPreviousState = LOW; menuSavePreviousState = LOW; } if (((currentTime - lastDebounceTime)> debounceTimeout)) {// Nếu hết thời gian chờ, hãy nhấn nút!
// menuButton được nhấn, cung cấp logic
// Chỉ kích hoạt khi nút đã được phát hành trước đó if ((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)) {if (menuMode == false) {menuMode = true; // Cho người dùng biết Serial.println ("Menu đang hoạt động"); } else if (menuMode == true && optionSelected = 1) {// Đặt lại tùy chọn optionSelected = 0; } // In menu menuNeedsPrint = true; // Chuyển đổi nút trước. trạng thái chỉ hiển thị menu // nếu nút được nhả ra và nhấn lại menuButtonPreviousState = menuButtonPressed; // Sẽ là CAO} // menuSelect được nhấn, cung cấp logic if ((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)) {if (menuMode) {// Thay đổi tùy chọn đã chọn // Hiện tại, đây là chỉ đúng / sai // nhưng có thể là bất kỳ thứ gì bool toggle = ToggleOptionSelected (); if (chuyển đổi) {menuNeedsPrint = true; } else {Serial.print ("Đã xảy ra lỗi. Vui lòng thử lại"); }} // Chuyển trạng thái thành chỉ chuyển đổi nếu được thả ra và nhấn lại menuSelectPreviousState = menuSelectPressed; } if ((menuSavePressed == HIGH) && (menuSavePreviousState == LOW)) {// Thoát khỏi menu // Tại đây bạn có thể thu dọn // hoặc lưu vào EEPROM menuMode = false; Serial.println ("Menu đã thoát"); // Chuyển đổi trạng thái để menu chỉ thoát một lần menuSavePreviousState = menuSavePressed; }} // In tùy chọn menu hiện tại đang hoạt động, nhưng chỉ in nó một lần nếu (menuMode && menuNeedsPrint) {// Chúng tôi đã in menu, vì vậy, trừ khi có điều gì đó // xảy ra, không cần in lại menuNeedsPrint = false; char * optionActive = ReturnOptionSelected (); char * optionStatus = ReturnOptionStatus (); Serial.print ("Đã chọn:"); Serial.print (optionActive); Serial.print (":"); Serial.print (optionStatus); Serial.println (); }}}
Mạch có sẵn trên trang Tinkercad. Mình cũng đã nhúng mạch bên dưới cho các bạn xem!
Như mọi khi, nếu bạn có thắc mắc hoặc vấn đề, vui lòng cho tôi biết!
Đề xuất:
Các cách hay để tái sử dụng các bộ phận máy tính cũ: 7 bước (có hình ảnh)
Những cách hay để tái sử dụng các bộ phận máy tính cũ: Trong phần hướng dẫn này, tôi sẽ ngắn gọn cung cấp cho bạn một số ý tưởng về cách tái sử dụng một số bộ phận của máy tính cũ mà mọi người đang vứt bỏ. Bạn sẽ không tin, nhưng những chiếc máy tính cũ này có nhiều bộ phận thú vị bên trong. sẽ không cung cấp đầy đủ
Đầu vào cảm ứng điện dung ESP32 sử dụng "Phích cắm lỗ kim loại" cho các nút: 5 bước (có hình ảnh)
Đầu vào cảm ứng điện dung ESP32 sử dụng "Phích cắm lỗ kim loại" cho các nút: Khi tôi đang hoàn thiện các quyết định thiết kế cho dự án dựa trên ESP32 WiFi Kit 32 sắp tới yêu cầu đầu vào ba nút, một vấn đề đáng chú ý là Bộ WiFi 32 không sở hữu một nút bấm cơ học duy nhất, nhưng chỉ có ba nút cơ học, f
Sử dụng Ngưỡng cường độ thang màu xám thay đổi để hình dung và xác định các điểm bất thường trong hình ảnh chụp X quang: 9 bước
Sử dụng Ngưỡng cường độ thang màu xám thay đổi để hình dung và xác định các bất thường trong hình ảnh chụp X quang: Mục đích của dự án này là xác định và sử dụng một tham số để xử lý hình ảnh chụp X quang quang tuyến xám của các phân loại mô nền khác nhau: Béo, Béo tuyến, & Mô dày đặc. Phân loại này được sử dụng khi bác sĩ X quang phân tích
Cách áp dụng các họa tiết trên các bề mặt đối tượng riêng lẻ trong đời thứ hai: 7 bước
Cách áp dụng họa tiết trên các bề mặt đối tượng riêng lẻ trong Đời sống thứ hai: Trong Đời sống thứ hai, bạn có khả năng áp dụng nhiều kết cấu cho một đối tượng duy nhất. Quá trình này rất đơn giản và có thể cải thiện đáng kể sự xuất hiện của các công trình xây dựng của bạn
Bộ pin di động nút cho các thí nghiệm hoặc các ứng dụng nhỏ.: 5 bước
Bộ pin di động nút dành cho Thử nghiệm hoặc Ứng dụng Nhỏ: Xin chào mọi người! Hãy học cách tạo một bộ pin! Thực sự đơn giản, dễ dàng và rẻ. Đây là những ứng dụng tuyệt vời cho các thí nghiệm và thử nghiệm hoặc các ứng dụng nhỏ yêu cầu 3.0 - 4.5 volt