İçindekiler:

Arduino'da Bir Menü ve Butonların Kullanımı: 10 Adım (Resimlerle)
Arduino'da Bir Menü ve Butonların Kullanımı: 10 Adım (Resimlerle)

Video: Arduino'da Bir Menü ve Butonların Kullanımı: 10 Adım (Resimlerle)

Video: Arduino'da Bir Menü ve Butonların Kullanımı: 10 Adım (Resimlerle)
Video: TİKTOK DİLENCİLERİ PART 1 DAHA NELER DEDİRTEN Video #tiktok #tiktokvideo #tiktokvideo 2024, Kasım
Anonim
Arduino'da Bir Menü ve Düğmelerin Kullanımı
Arduino'da Bir Menü ve Düğmelerin Kullanımı

Arduino 101 eğitimimde, ortamınızı Tinkercad'de nasıl kuracağınız öğretilecek. Tinkercad'i öğrencilere devre inşa etmek için çeşitli beceriler göstermeme izin veren oldukça güçlü bir çevrimiçi platform olduğu için kullanıyorum. Arduino IDE ve gerçek bir Arduino kullanarak tüm eğitimlerimi oluşturmaktan çekinmeyin!

Bu eğitimde, düğmeler hakkında bilgi edineceğiz! Bilmeye ihtiyacımız var:

  • onları nasıl bağlarım
  • Değerlerini okumak
  • Geri dönme ve neden önemli
  • Pratik bir uygulama (menü oluşturma)

Çoğu insan bir düğmeyle yapılacak en pratik şeyin bir ışığı açıp kapatmak olduğunu düşünür. Yapacağız, burada değil! Bir menü oluşturmak ve Arduino'da bazı seçenekleri ayarlamak için bizimkini kullanacağız.

Hazır? Başlayalım!

Adım 1: Kartı Kurun

Kurulu Kur
Kurulu Kur
Kurulu Kur
Kurulu Kur

İlk adım, prototipleme alanına bir Arduino ve Breadboard Small yerleştirmektir. Güç raylarının nasıl bağlanacağını görmek için yukarıdaki resimleri kontrol edin.

Bir Breadboard Mini, üstte ve altta iki güç rayına sahiptir. Bunları Arduino'ya bağlarız, böylece daha fazla bileşene güç sağlayabiliriz. Bu öğreticide daha sonra 3 düğme kullanacağız, bu nedenle daha fazla güce ihtiyacımız olacak. Unutulmaması gereken şey, küçük bir devre tahtasında, güç raylarının tahta boyunca yatay olarak geçmesidir. Bu, ortadaki ana prototipleme alanındaki sütunlardan farklıdır; bunlar dikey olarak çalışır. Ortadaki ana alanda herhangi bir sütuna güç sağlamak için güç pimlerinden herhangi birini kullanabilirsiniz.

Güç eklediğinizde, sırasıyla negatif ve pozitif için siyah ve kırmızı kabloları kullanın. Kartın diğer tarafına güç sağlayan kabloları uca ekleyin. O tarafı kullanmayacağız, ama bu iyi bir uygulama.

Adım 2: Düğmeyi ve Direnci Ekleyin

Düğmeyi ve Direnci ekleyin
Düğmeyi ve Direnci ekleyin
Düğmeyi ve Direnci ekleyin
Düğmeyi ve Direnci ekleyin
Düğmeyi ve Direnci ekleyin
Düğmeyi ve Direnci ekleyin

Bileşenler tepsisinden küçük bir düğme ekleyin. Resimdeki gibi görünmelidir. Bunun bir anahtar olmadığından emin olun! Bir direnç de ekleyin. Tıklayın ve değerini 10kΩ olarak ayarlayın. Bu, bağlı olmadığında pimi aşağı çekmek için yeterlidir, bu kodda daha sonra çok önemlidir.

Bileşeni devre tahtasının ortasına yerleştirin. Bir düğmenin çalışma şekli şudur:

  • Köşeden köşeye, düğme bağlı değil. Düğmeye basmak kontakları kapatır ve köşeleri birleştirir.
  • Düğmenin yanları birbirine bağlıdır. Sol üste ve sol alta bir kablo bağlarsanız devre kapanır.

Bu yüzden bileşeni ortadaki boşluğa yerleştirdik. Köşelerin panodaki pinlerin altına bağlanmamasını sağlar.

Bir sonraki adım, bu noktaları gösteren birkaç resim sağlar.

Direnci sağ alt pimden sütunlara yerleştirin, böylece yatay olarak oturur.

Adım 3: Düğme Bağlantıları

Düğme Bağlantıları
Düğme Bağlantıları
Düğme Bağlantıları
Düğme Bağlantıları

Yukarıdaki resimler, düğmelerin nasıl bağlandığını oldukça net bir şekilde ortaya koymaktadır. Bir şeyin tamamen iyi olduğunu ve işe yaramadığını düşündüğünüzde her zaman bir kafa karışıklığı olmuştur!

Şimdi telleri ekleyelim.

  • Pozitif güç piminden düğmedeki sağ alt pimle aynı sütuna kırmızı bir uç yerleştirin
  • Negatif güç piminden dirençle aynı sütuna siyah bir kurşun yerleştirin.
  • Arduino'da sol üst pimden Dijital Pim 2'ye renkli bir kablo (kırmızı/siyah değil) yerleştirin

Kablolamanızın doğru olduğundan emin olmak için yukarıdaki resimleri kontrol edin.

Adım 4: Kod…

Kod…
Kod…
Kod…
Kod…

Temel bir düğmenin koduna bir göz atalım.

Kod düzenleyiciyi açın ve Bloklardan Metin'e değiştirin. Gelen uyarıyı silin. Metinden memnunuz!

Temel kurulumu biliyorsunuz, bu yüzden düğmeyi tanımlayalım ve temel bir okuma yapalım. Çıktıyı Seri olarak yazdıracağız.

Aşağıdaki koda fazladan birkaç yorum ekledim ki görselden daha kolay okunsun.

// Sabitleri tanımla

#define düğmesi 2 void setup() { pinMode(button, INPUT); Seri.başla(9600); } void loop() { // Düğmenin durumunu kontrol etmek için dijital pini okuyun int basıldı = digitalRead(düğme); // Düğmeye basılırsa HIGH döner, değilse LOW döner if(basıldı == HIGH){ Serial.println("Basıldı!"); } }

Tamam, işe yarıyor!

Esasen, tek yaptığımız, kod her döndüğünde dijital pinin durumunu kontrol etmektir. Simülasyonu Başlat'a tıklar ve düğmesine basarsanız, Seri Monitörün (kodun altındaki düğmeyi tıklayın) "Basıldı!" defalarca.

Yukarıdaki kodda göreceğiniz bir özellik, if() koşul değerlendirmesinin gerçekleşmesidir. Bu durumda, kodun tek yaptığı bir soru sormak ve bunun doğru olup olmadığını değerlendirmektir. Değişkenin değerinin belirli bir değere eşit olup olmadığını kontrol etmek için eşittir (çift eşittir: ==) işaretini kullanırız. Bir digitalRead() YÜKSEK veya DÜŞÜK döndürür.

if() else if / else kullanarak birçok koşulu veya tüm koşulları kontrol edebiliriz ve Arduino Temellerine geri dönerseniz, yapabileceğiniz bazı karşılaştırmaları göreceksiniz.

Şimdi… Kodumuz tamamlanmış görünebilir… Ama bir sorunumuz var.

Bak, simülatördeyken bu gerçekten iyi çalışıyor. Ancak gerçek elektriğin gürültüsü vardır, özellikle DC elektroniği. Bu yüzden düğmemiz bazen yanlış bir okuma döndürebilir. Ve bu bir sorun çünkü projeniz kullanıcı için doğru şekilde yanıt vermeyebilir.

Hadi düzeltelim!

Adım 5: Biraz Geri Dönme

Biraz Geri Dönme
Biraz Geri Dönme

Düğme sorunumuzun üstesinden gelmek için debounce adlı bir prosedür kullanıyoruz. Bu, esasen, düğmeye basıldığı zaman ile aslında basmaya yanıt verdiği zaman arasında belirli bir süre bekler. Yine de kullanıcıya doğal geliyor (süreyi çok uzun tutmadığınız sürece). Ayrıca, her seferinde farklı yanıt verebilmeniz için basış süresini kontrol etmek için de kullanabilirsiniz. Herhangi bir kablolamayı değiştirmenize gerek yok!

Şimdi koda bakalım:

#define düğmesi 2#define debounceTimeout 100

İlk değişiklik küresel kapsamdadır. Bir çok fonksiyonumuzun kullanabileceği veya döngü her başladığında sıfırlanamayan değişkenleri burada tanımladığımızı hatırlayacaksınız. Böylece tanımlanan sabitlere debounceTimeout ekledik. Bu 100'ü yaptık (daha sonra 100ms'ye çevrilecek), ancak daha kısa olabilir. Daha fazla ve daha fazla doğal olmayacak.

long int lastDebounceTime;

Bu değişken sabitlerin altında bildirilir. Bu, temelde uzun sayıları bellekte saklamamıza izin veren uzun bir int türüdür. Biz buna lastDebounceTime adını verdik.

void setup() işlevinde hiçbir şeyi değiştirmemize gerek yok. Bunu bırakalım.

void loop() { // Butonun durumunu kontrol etmek için dijital pini okuyun int basıldı = digitalRead(button); long int currentTime = millis(); // Düğme kodu }

loop() fonksiyonunda yaptığımız ilk değişiklik buton okuma çağrısının altındadır. Şimdiki zamanı takip etmemiz gerekiyor. millis() işlevi, Arduino'nun başlatılmasından bu yana milisaniye cinsinden saatin geçerli zamanını döndürür. Bunu uzun bir int tipi değişkende saklamamız gerekiyor.

Şimdi, düğmeye basıldığından beri geçen sürenin farkında olduğumuzdan emin olmamız gerekiyor, bu yüzden basılmadığında zamanlayıcıyı sıfırlıyoruz. Bir göz at:

void loop() { // Butonun durumunu kontrol etmek için dijital pini okuyun int basıldı = digitalRead(button); long int currentTime = millis(); if(pressed == LOW){ // butona basılmadığında sayma süresini sıfırlayın lastDebounceTime = currentTime; } // Düğme kodu }

if(pressed == LOW) algoritması, düğmeye basılıp basılmadığını kontrol eder. Değilse, kod son geri dönmeden bu yana geçerli zamanı saklar. Bu şekilde, düğmeye her basıldığında, düğmeye ne zaman basıldığını kontrol edebileceğimiz bir zaman noktamız olur. Ardından, düğmeye ne kadar süreyle basıldığını görmek için hızlı bir matematiksel hesaplama yapabilir ve doğru yanıt verebiliriz. Kodun geri kalanına bakalım:

void loop() { // Butonun durumunu kontrol etmek için dijital pini okuyun int basıldı = digitalRead(button); long int currentTime = millis(); if(pressed == LOW){ // butona basılmadığında sayma süresini sıfırlayın lastDebounceTime = currentTime; } // Belirli bir süre butona basıldı if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Zaman aşımına ulaşılırsa butona basılır! Serial.println("Basıldı!"); } }

Son kod bloğu, geçerli zamanı alır, son geri dönme süresini çıkarır ve belirlediğimiz zaman aşımı ile karşılaştırır. Daha büyükse, kod, düğmeye o süre boyunca basıldığını varsayar ve yanıt verir. Düzenli!

Kodunuzu çalıştırın ve çalışıp çalışmadığını kontrol edin. Hatalarınız varsa, kodunuzu kontrol edin!

Şimdi pratik bir örneğe bakalım.

Adım 6: Bir Menünün Hazırlanması

Menü Yapımı
Menü Yapımı

Düğmeler ilginç, çünkü onlarla birlikte pek çok olasılık var! Bu örnekte bir menü yapacağız. Diyelim ki bu gerçekten harika cihazı yarattınız ve kullanıcıların belirli şeyleri açmak veya kapatmak için seçenekleri değiştirmesine veya bir ayar için belirli bir değer belirlemesine ihtiyacınız var. Bu üç düğme tasarımı bunu yapabilir!

Yani, bu proje için ihtiyacımız var:

  • Üç düğme
  • 10kΩ'a ayarlanmış üç direnç

Bunlardan biri zaten elimizde, sadece diğer ikisine ihtiyacımız var. Bu yüzden bunları tahtaya ekleyin. Kablolama biraz daha karmaşık, ancak yalnızca onu gerçekten kompakt tutmak istediğim için. İlk düğme için aynı kalıbı veya yukarıdaki resmi takip edebilirsiniz.

Üç düğme, bir menü açma/sonraki seçeneği, bir değiştirme seçeneği (olduğu gibi, ayarı değiştirme) ve bir kaydet/kapat menü düğmesidir.

Bağlayın, koda bakalım!

7. Adım: Kod Dökümü - Genel

Tamam, bu uzun bir adım olacak, ama ben kodun her bölümünden geçeceğim.

İlk olarak, gereken global değişkenlere bakalım.

// Sabitleri tanımla#define menuButton 2 #define menuSelect3#define menuSave 4 #define debounceTimeout 50 // Değişkenleri tanımla int menuButtonPreviousState = LOW; int menuSelectPreviousState = DÜŞÜK; int menuSavePreviousState = DÜŞÜK; long int lastDebounceTime; // Menü seçenekleri char * menuOptions = {"Sıcaklığı Kontrol Et", "Işığı Kontrol Et"}; bool featureSetting = {false, false}; bool menuMode = yanlış; bool menuNeedsPrint = false; int seçenekSeçili = 0;

Bu üç blok daha önce gördüklerimize oldukça benzer. İlkinde, üç düğmeyi ve zaman aşımını tanımladım. Projenin bu kısmı için 50ms olarak ayarladım, bu yüzden çalışması için bilinçli bir baskı gerekiyor.

İkinci blok tüm değişkenlerdir. buttonPreviousState'i takip etmemiz gerekiyor ve lastDebounceTime'ı takip etmemiz gerekiyor. Bunların hepsi int türü değişkenlerdir, ancak sonuncusu uzun bir türdür çünkü bellekte boş alana ihtiyacımız olduğunu varsayıyorum.

Menü seçenekleri bloğunun birkaç yeni özelliği vardır. İlk olarak, bir karakter/dize değişmez değişkeni olan char * (evet, bu kasıtlı bir yıldız işaretidir). Bellekteki statik bir depolamaya yönelik bir işaretçidir. Bunu değiştiremezsiniz (örneğin Python'da olduğu gibi). Bu char *menuOptions satırı, bir dizi değişmez dize oluşturur. İstediğiniz kadar menü öğesi ekleyebilirsiniz.

bool featureSetting değişkeni, yalnızca her bir menü öğesini temsil eden değerler dizisidir. Evet, istediğiniz her şeyi kaydedebilirsiniz, sadece değişken türünü değiştirin (hepsi aynı türde olmalıdır). Şimdi, bunu yönetmenin sözlükler veya demetler gibi daha iyi yolları olabilir, ancak bu, bu uygulama için basittir. Muhtemelen konuşlandırılmış bir uygulamada ikincisinden birini yaratırdım.

menuMode'un kaydını tuttum, bu yüzden ekranımda başka şeyler istersem bunu yapabilirdim. Ayrıca, sensör mantığım olsaydı, bir şeyin çakışması durumunda menü işlemi sırasında bunu duraklatabilirim. Bir menuNeedsPrint değişkenim var çünkü menüyü her zaman değil, belirli zamanlarda yazdırmak istiyorum. Son olarak, bir optionsSelected değişkenim var, bu yüzden birkaç yerden eriştiğimde seçilen seçeneği takip edebiliyorum.

Bir sonraki fonksiyon grubuna bakalım.

8. Adım: Kod Dökümü - Kurulum ve Özel İşlevler

setup() işlevi yeterince kolaydır, yalnızca üç giriş bildirimi:

void setup() { pinMode(menuSelect, INPUT); pinMode(menuSave, INPUT); pinMode(menuSelect, INPUT); Seri.başla(9600); }

Sonraki üç özel işlevdir. İlk ikisine, sonra sonuncusuna ayrı ayrı bakalım.

Bazı bilgileri döndüren iki işleve ihtiyacımız var. Bunun nedeni, bunun bir tür insan tarafından okunabilir olduğundan emin olmak istiyoruz. Ayrıca, bir sorunumuz varsa kodda hata ayıklamaya da yardımcı olacaktır. Kod:

// Mevcut seçili seçeneği döndürme işlevichar *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // Dönüş seçeneğiSeçili dönüş menüsüSeçenek; } // Geçerli seçili seçeneğin durumunu döndürme işlevi char *ReturnOptionStatus(){ bool optionsSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionsSettingVal = "Yanlış"; }else{ optionsSettingVal = "Doğru"; } // Dönüş seçeneğiAyar dönüş seçeneğiSettingVal; }

char *ReturnOptionSelected() işlevi, seçilen seçeneği kontrol eder (yukarıda görüyorsanız, bunu takip etmek için bir değişken ayarladık) ve daha önce oluşturduğumuz diziden dize değişmezini çeker. Daha sonra onu bir char türü olarak döndürür. Bunu biliyoruz çünkü fonksiyon dönüş tipini gösteriyor.

İkinci işlev olan char *ReturnOptionStatus() diziye kaydedilen seçeneğin durumunu okur ve değeri temsil eden bir dize değişmezi döndürür. Örneğin, kaydettiğimiz ayar false ise, "False" döndürürdüm. Bunun nedeni, kullanıcıya bu değişkeni göstermemizdir ve tüm bu mantığı bir arada tutmak daha iyidir. Daha sonra yapabilirdim ama burada yapmak daha mantıklı.

// Mevcut optionsbool arasında geçiş yapma işlevi ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; true döndür; }

bool ToggleOptionSelected() işlevi, menüde seçtiğimiz ayarın değerini değiştirmek için bir kolaylık işlevidir. Sadece değeri çevirir. Daha karmaşık seçenekleriniz varsa, bu oldukça farklı olabilir. Bu işlevde true değerini döndürürüm, çünkü geri aramam (bu işlevi başlatan kodda daha sonra yapılan arama) bir doğru/yanlış yanıtı bekler. Bunun işe yarayacağından %100 eminim, bu yüzden çalışmadığını hesaba katmadım, ancak konuşlandırılmış bir uygulamada yapardım (her ihtimale karşı).

Adım 9: Döngü…

loop() işlevi oldukça uzundur, bu yüzden bunu parçalar halinde yapacağız. Aşağıdaki her şeyin bu işlev içinde yuvalandığını varsayabilirsiniz:

boşluk döngüsü () {

// Burada çalış <----- }

Tamam, bunu daha önce gördük:

// butonları okuyun int menuButtonPressed = digitalRead(menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Geçerli saati al long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW){ //düğmeye basılmadığında sayım süresini sıfırlayın lastDebounceTime = currentTime; menuButtonÖncekiDurum = DÜŞÜK; menuSelectPreviousState = DÜŞÜK; menuKaydetÖncekiDurum = DÜŞÜK; }

Burada tek yapmam gereken, üç digitalRead() çağrısını eklemek ve tüm düğmeler düşükse, zamanlayıcıyı (lastDebounceTime = currentTime) sıfırlamamız ve önceki tüm durumları düşük olarak ayarlamamız gerektiği gerçeğini hesaba kattığımdan emin olmaktı. Ayrıca millis() öğesini currentTime içinde saklarım.

Sonraki bölüm çizginin içinde yuvalanır

if(((currentTime - lastDebounceTime) > debounceTimeout)){

//Burada çalış <---- }

Üç bölüm var. Evet, onları kendi işlevlerine taşıyabilirdim, ancak basitlik adına üç ana düğme algoritmasını burada tuttum.

if((menuButtonPressed == YÜKSEK) && (menuButtonPreviousState == DÜŞÜK)){ if(menuMode == false){ menuMode = true; // Kullanıcıya Serial.println("Menü aktif"); }else if (menuMode == true && optionsSelected = 1){ // Seçeneği sıfırla optionsSelected = 0; } // Menüyü yazdır menuNeedsPrint = true; // Önceki düğmeyi değiştir. sadece menüyü görüntülemek için durum // düğme bırakılıp tekrar basılırsa menuButtonPreviousState = menuButtonPressed; // YÜKSEK olur }

Bu ilki, menuButtonPressed HIGH olduğunda veya menü düğmesine basıldığında işler. Ayrıca önceki durumun DÜŞÜK olduğundan emin olmak için kontrol eder, böylece tekrar basılmadan önce düğmenin serbest bırakılması gerekir, bu da programın sürekli olarak aynı olayı tekrar tekrar başlatmasını engeller.

Ardından menü aktif değilse, onu etkinleştirdiğini kontrol eder. Seçilen ilk seçeneği yazdıracaktır (varsayılan olarak menuOptions dizisindeki ilk öğedir. Düğmeye ikinci veya üçüncü (vb) kez basarsanız, listedeki bir sonraki seçeneği görürsünüz. Düzeltebileceğim bir şey var. sona geldiğinde başa döner. Bu, dizinin uzunluğunu okuyabilir ve seçeneklerin sayısını değiştirirseniz geri dönmeyi kolaylaştırabilir, ancak bu şimdilik basitti.

Son küçük bölüm (//menüyü yazdırır) açıkça menüyü yazdırır, ancak aynı işlevin döngüye girmemesi için önceki durumu YÜKSEK olarak ayarlar (düğmenin önceden DÜŞÜK olup olmadığını kontrol etmekle ilgili yukarıdaki notuma bakın).

// menuSelect'e basılır, logicif sağlar((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Seçilen seçeneği değiştirin // Şu anda bu sadece doğru/yanlış // ama herhangi bir şey olabilir bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.println("Bir sorun oluştu. Lütfen tekrar deneyiniz"); } } // Yalnızca serbest bırakılıp tekrar basıldığında geçiş yapmak için durumu değiştir menuSelectPreviousState = menuSelectPressed; }

Bu kod parçası menuSelectPressed düğmesini aynı şekilde işler, ancak bu sefer sadece ToggleOptionSelected() işlevini çalıştırmamız yeterlidir. Daha önce de söylediğim gibi, bu işlevi daha fazlasını yapacak şekilde değiştirebilirsiniz, ancak tüm yapmam gereken bu.

Unutulmaması gereken en önemli şey, geri aramanın başarısını izleyen ve doğruysa menüyü yazdıran geçiş değişkenidir. Hiçbir şey veya false döndürmezse, hata mesajını yazdırır. Burası, başka şeyler yapmak için geri aramanızı kullanabileceğiniz yerdir.

if((menuSavePressed == YÜKSEK) && (menuSavePreviousState == DÜŞÜK)){ // Menüden çıkın // Burada herhangi bir düzenleme yapabilirsiniz // veya EEPROM'a kaydedin menuMode = false; Serial.println("Menüden çıkıldı"); // Durumu değiştir, böylece menüden yalnızca bir kez çıkılır menuSavePreviousState = menuSavePressed; } }

Bu işlev, menüden hemen çıkan menuSave düğmesini kullanır. İptal etme veya kaydetme seçeneğine sahip olabileceğiniz yer burasıdır, belki biraz temizlik yapabilir veya EEPROM'a kaydedebilirsiniz. Sadece "Menüden çıktı" yazdırdım ve düğme durumunu YÜKSEK olarak ayarladım, böylece döngü olmaz.

if(menuMode && menuNeedsPrint){ // Menüyü yazdırdık, yani bir şey olmadıkça // tekrar yazdırmaya gerek yok menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Seçili: "); Serial.print(optionActive); Seri.print(": "); Serial.print(optionStatus); Seri.println(); }

Bu, yalnızca menü etkin olduğunda ve menuNeedsPrint değişkeni true olarak ayarlandığında etkinleşen menuPrint algoritmasıdır.

Bu kesinlikle kendi işlevine taşınabilir, ancak basitlik adına..!

İşte bu kadar! Tüm kod bloğu için sonraki adıma bakın.

Adım 10: Son Kod Bloğu

// Sabitleri tanımla

#define menuButton 2 #define menuSelect 3 #define menuKaydet 4 #define debounceTimeout 50 int menuButtonPreviousState = LOW; int menuSelectPreviousState = DÜŞÜK; int menuSavePreviousState = DÜŞÜK; // değişkenleri tanımla long int lastDebounceTime; bool lightSensor = doğru; bool tempSensor = doğru; // Menü seçenekleri char * menuOptions = {"Sıcaklığı Kontrol Et", "Işığı Kontrol Et"}; bool featureSetting = {false, false}; bool menuMode = yanlış; bool menuNeedsPrint = false; int seçenekSeçili = 0; // Kurulum fonksiyonu

void setup() { pinMode(menuSelect, INPUT); pinMode(menuSave, INPUT); pinMode(menuSelect, INPUT); Seri.başla(9600); }

// Geçerli seçili seçeneği döndürme işlevi char *ReturnOptionSelected(){ char *menuOption = menuOptions[optionSelected]; // Dönüş seçeneğiSeçili dönüş menüsüSeçenek; } // Geçerli seçili seçeneğin durumunu döndürme işlevi char *ReturnOptionStatus(){ bool optionsSetting = featureSetting[optionSelected]; char *optionSettingVal; if (optionSetting == false){ optionsSettingVal = "Yanlış"; }else{ optionsSettingVal = "Doğru"; } // Dönüş seçeneğiAyar dönüş seçeneğiSettingVal; } // Geçerli seçeneği değiştirme işlevi bool ToggleOptionSelected(){ featureSetting[optionSelected] = !featureSetting[optionSelected]; true döndür; } // Ana döngü

void loop(){ // Butonları okuyun int menuButtonPressed = digitalRead(menuButton); int menuSelectPressed = digitalRead(menuSelect); int menuSavePressed = digitalRead(menuSave); // Geçerli saati al long int currentTime = millis(); if(menuButtonPressed == LOW && menuSelectPressed == LOW && menuSavePressed == LOW){ //düğmeye basılmadığında sayım süresini sıfırlayın lastDebounceTime = currentTime; menuButtonÖncekiDurum = DÜŞÜK; menuSelectPreviousState = DÜŞÜK; menuKaydetÖncekiDurum = DÜŞÜK; } if(((currentTime - lastDebounceTime) > debounceTimeout)){ // Zaman aşımına ulaşılırsa butona basılır!

// menuButonuna basılır, mantık sağlanır

// Yalnızca düğme daha önce serbest bırakıldığında tetiklenir if((menuButtonPressed == HIGH) && (menuButtonPreviousState == LOW)){ if(menuMode == false){ menuMode = true; // Kullanıcıya Serial.println("Menü aktif"); }else if (menuMode == true && optionsSelected = 1){ // Seçeneği sıfırla optionsSelected = 0; } // Menüyü yazdır menuNeedsPrint = true; // Önceki düğmeyi değiştir. sadece menüyü görüntülemek için durum // düğme bırakılıp tekrar basılırsa menuButtonPreviousState = menuButtonPressed; // YÜKSEK olur } // menuSelect'e basılır, mantık sağlayın if((menuSelectPressed == HIGH) && (menuSelectPreviousState == LOW)){ if(menuMode){ // Seçilen seçeneği değiştirin // Şu anda bu sadece doğru/yanlış // ancak herhangi bir şey olabilir bool toggle = ToggleOptionSelected(); if(toggle){ menuNeedsPrint = true; }else{ Serial.print("Bir sorun oluştu. Lütfen tekrar deneyiniz"); } } // Yalnızca serbest bırakılıp tekrar basıldığında geçiş yapmak için durumu değiştir menuSelectPreviousState = menuSelectPressed; } if((menuSavePressed == YÜKSEK) && (menuSavePreviousState == LOW)){ // Menüden çıkın // Burada herhangi bir düzenleme yapabilirsiniz // veya EEPROM'a kaydedin menuMode = false; Serial.println("Menüden çıkıldı"); // Durumu değiştir, böylece menüden yalnızca bir kez çıkılır menuSavePreviousState = menuSavePressed; } } // Geçerli menü seçeneğini aktif olarak yazdırın, ancak yalnızca bir kez yazdırın if(menuMode && menuNeedsPrint){ // Menüyü yazdırdık, yani bir şey olmadıkça // tekrar yazdırmaya gerek yok menuNeedsPrint = false; char *optionActive = ReturnOptionSelected(); char *optionStatus = ReturnOptionStatus(); Serial.print("Seçili: "); Serial.print(optionActive); Seri.print(": "); Serial.print(optionStatus); Seri.println(); } } }

Devre Tinkercad sitesinde mevcuttur. Aşağıdaki devreyi de görmeniz için yerleştirdim!

Her zaman olduğu gibi, sorularınız veya sorunlarınız varsa lütfen bana bildirin!

Önerilen: