Kişisel Sayfaları
İlgi Alanları
İş Tecrubesi
Eğitim Geçmişi
Sertifikalar & Başarılar
Kullanıcıya ait test sonucu bulunmamaktadır.
Dil Becerileri
Son Forum Aktiviteleri
230PAYLAŞIM - ARDUINO EEPROM Okuma ve Yazma Teknikleri
Her tip ARDUINO işlemcisinin içinde değişik ebatlarda EEPROM tipi bellek vardır. Bu belleğin özelliği ARDUINO kapatıldığı zaman bellek içeriklerinin silinmemesidir. Yazdığınız kodlarda bir çalışma devresinden ötekine veri kaydetmek ve yeni devrede bu değerleri kullanmak gerekiyorsa EEPROM işinize yarayabilir.
EEPROM fonksiyonarını kullanabilmek için önce EEPROM.h kütüphanesini programınıza eklemeniz gerekir. Bunu yapar yapmaz bir takım EEPROM işlevlerine ulaşma imkanını elde edersiniz. Bunlardan en basiti bize EEPROM belleğini boyutunu bildiren EEPROM.length() işlevidir:
int eepromBellek = EEPROM.length();
kodu eepromBellek değişkenine kullandığımız ARDUINO modelinin EEPROM boyutunu atar.
Burada dikkat etmemiz gereken bir nokta aldığımız değerin nasıl kullanılacağıdır. EEPROM adresleri sıfır (0) dan başladığı için geri gelen veri değeri adres olarak kullanıldığında sıfır ile eepromBellek - 1 arası olmalıdır. Örneğin: ARDUINO UNO da EEPROM boyutu 1024 dür. Buna göre addres olarak kullandığımızda bu deger 0 - 1023 arasında olmalıdır. Değişik modellerin boyutları değişiktir !
Bu değeri elde ettikten sonra hemen belleği temizlemek için basit bir döngü ile kullanabiliriz:
#include <EEPROM.h>
void setup()
{int eepromBellek = EEPROM.length();
for (int i = 0 ; i < eepromBellek ; i++) {EEPROM.write(i, '\0');}
}
Bu kodda sıfırdan başlayarak bütün bellek adreslerine NUL ( '\0' ) değerini yazıyoruz. Bunu yaparken EEPROM.write() işlevini kullanıyoruz. Burada belleğe yazdığımız değer tamamen bize kalmış bir seçenektir. NUL (\0), SIFIR (0), BOŞLUK ( ), vs gibi herhangi uygun değer kullanılabilir.
EEPROM a yazıp okuma işlemleri üç tip işlevle sağlanır:
- EEPROM.read() ve EEPROM.write() : karakter veya bayt olarak okuyup yazma
- EEPROM.get() ve EEPROM.put() : dizgi veya özel / değişik veri yapılarına göre okuyup yazma
- EEPROM.update() : Eğer veri bellektekinden değişikse yaz
EEPROM.read() ve EEPROM.write() işlevleri verileri belleğe tek bayt olarak okuyup yazarlar. Yani okunacak veya yazılacak değerlerin 0 - 255 arası bir değer olması gerekir. Kodlamada kullanabileceğimiz veri tipleri char ve byte dır.
EEPROM.get() ve EEPROM.put() işlevleri ise belleğe bir bayttan daha fazla veya uzunlukta veri kaydetmek istediğimiz zaman kullanılır. Örneğin float tipi veriler dört (4) bayt olduğundan bu işlevle kaydedilmesi gerekir. Eğer uzunca bir dizgi veya dizi kaydetmek isterseniz (örneğin: "dosyaadı.txt") bu işlevleri kullanmanız gerekir. Burada dikkat edilecek nokta, dizi veya dizgi yazıp okurken bir seçeneğin döngü ile aynı işlemi yapmaktır. Yani get() veya put() kullanacağımıza bir döngü ile dizi veya dizgi harflerini teker teker read() veya write() kullanarak da yazıp okuyabiliriz. Tabi ki get() ve put() çok daha kolay bir uygulamadır.
Fakat bu iki teknik arasında önemli bir fark vardır: dizi ve dizgi uygulamalarında char[ ] tipi ARRAY veriler bilgisayar belleğinde genelde otomatikman bir NUL karakter ile sonuçlandırıldığından get() ve put() işlevleri yazma ve okuma işlemlerini bu noktaya kadar yaparlar. Yani bir NUL bulunca okuma ve yazma durur. Eğer bu sizin işinize göre değilse, o zaman write() veya read() kullanmanız daha uygun olabilir. Mühim olan işlevlerin nasıl çalıştığı ve sizin ne yapmak istediğiniz !
EEPROM ın kullanılma limiti bellek başına 100.000 yazma devresi olduğundan bu tip belleğe devamlı veya sonsuz bir döngüde işlem yapmak doğru değildir. Yani ARDUINOnun LOOP() kısmına bu tip kodları yazarken dikkatli olun. Bu problemi yok edebilmek için EEPROM.update() işlevi vardır.
EEPROM.update() işlevi yazılacak veriyi yazmak istediğimiz adresteki değer ile karşılaştırır ve yalnız aynı değilse yazma işlemini tamamlar. Böylece lüzumsuz yazma işlemleri engellenmiş olur. Dikkat edilecek nokta bu işlemin yanlız bayt veya karakter modunda çalıştığıdır. Yani bir dizi, dizgi, veya bir bayt tan uzun veri tipleri yazdığımızda bu tekniği bir döngü içinde uygulamamız gerekir.
Yukarıda anlatılan teknikleri uygulayan bir ARDUINO programına şu linkten ulaşabilrsiniz:
https://drive.google.com/open?id=1sLhuDjaDT43f6bToC7eFoSqulz8Z5qRa
Program detayları içinde yazılıdır.
Bununla oynayarak EEPROM detaylarının ustası olmanızı dilerim.
İyi çalışmalar.
PAYLAŞIM - ARDUINO KESME (INTERRUPT) Uygulama Tekniği
ÖRNEK KESME PROGRAMI LİNKİ:
https://drive.google.com/open?id=13JQrjacp2bJGCdS-fAEfLQIi8Gn71384
ARDUINO genelde teker işlem yaparak çalışır. Fakat içerdiği iki KESME pinlerini kullanarak veTIMER yardımı ile ona iki işi aşağı yukarı gerçek zamanda yaptırmak mümkündür.
Ekteki örnek program bu tekniği uygulayarak D2 ve D3 pinlerini KESME olarak tanımlıyor.
Bağlantılar:
D2 ------------- GND
D3 ------------- GND
D2 KESME bu pinin HIGH olduğu zaman ateşlemesine ve intRtn_H() işlemini yapmasına ayarlı.
D3 KESME bu pinin CHANGE olduğu zaman ateşlemesine ve intRtn_C() işlemini yapmasına ayarlı.
Bunlara göre test için:
D2 kablosunu GND den ayırdığınız zaman pin HIGH olup intRtn_H() rutinini çalıştıracaktır.
Seri Monitör de buna uyan mesajları yazacaktır.
D3 kablosunu GND den ayırdığınız zaman pin CHANGE olup intRtn_C() rutinini çalıştıracaktır.
SERI Monitör de buna uyan mesajları yazacaktır.
Kabloları geri taktığınızda da standard SERI mesajları her iki portun durumunu yazacaktır.
KESME kullanırken dikkat edilecek noktalar:
DELAY() kullanılmaz
MILLIS() artmaz
SERIAL veri okuma düzenli olmayabilir
KESME uuygulanabilecek PIN ler ARDUINO modellerine göre değişir. Her zaman referans sayfasını kontrol edin:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
Bu örnek programda göreceğiniz bir başka teknik de DELAY() yerine kullanılabilecek intDELAY() fonksiyonudur.
Bu fonksiyon MICROS() komutu kullanarak yukarıdaki problemi elimine ediyor.
Gördüğünüz gibi her iki ISR rutini de bu intDelay() kullanarak istenen yavaşlatmayı uyguluyor.
KESME olaylarını halleden rutinlerin çok çabuk çalışması ve fazla lüzümsuz işleri yapmaması gerektiğinden, her iki ISR rutinde de birer FLAG (bayrak) kullanılmıştır.
Bu teknik, KESME olayını tanımlayıp bu veriyi ana LOOP() kısmına iletmekte kullanılır. Böylece KESME ye ait mesajlar vs KESME ISR rutini dışında halledilir.
Umarım bu örnek program KESME ile çalışmaya başlayan arkadaşlara yardımcı olur.
İyi çalışmalar.
PAYLAŞIM - MILLIS kullanarak Çoklu Görev (MultiTasking)
ARDUINO programlarında birden fazla işlemi değişik zamanlayıcı kontrolleri altında yapabilmek için aşağıdaki uygulamayı sunuyorum. Umarım yardımcı olur.
Örnekte 3 değişik işlem değişik zaman ayarları ile programlanmıştır. Daha fazlası gerektiğinde aynı yöntem kullanılarak arttırılabilir.
Her işlem için iki değişken tanımlanması gerekir:
unsigned long ISR1_Zaman = 5000; //ms
unsigned long ISR1_evvelkiMILLIS = 0;
ISRnZaman işlemlerin hangi süre ayarı ile gerçekleşmesi gerektiğini ayarlar. Yukarıdaki örnek ayar işlemin her 5 saniyede bir yapılacağını tanımlar.
ISR1_evvelkiMILLIS ise işlemler arası geçen zamanı kontrolde kullanılır.
Bu ayarlardan sonra, LOOP() içinde her işlemin zaman ayarı kontrol edilerek gereken rutin çalıştırılır.
MILLIS() fonksiyonu ARDUINO programı çalışmaya başladığından beri geçen zamanı döndürür. Bu değişkeni arzuladığımız işlemimizin zaman ayarına karşılaştırarak işlemin yapılması gereken zamanı tespit etmiş oluruz.
Bu tekniğin en önemli kısmı ARDUINO nun DELAY() fonksiyonunun kullanılmamasıdır.
DELAY() kumandası çalışırken ARDUINO programındaki başka bütün işlemler çalışmaz. Bundan dolayı birden fazla işlem kontrolü gerektiğinde DELAY() kullanmak doğru değildir.
DELAY yerine MILLIS() fonksiyonunu kullanarak programı durdurmadan istediğimiz kadar işlemi 'gerçek zaman' da çalıştırabiliriz.
İyi Çalışmalar.
ÖRNEK:
Program 3 tane işlem tanımlar.
Her 5 saniyede ekrana bir mesaj yaz.
Her 1 saniyede LED13 ü yak.
LED13 ü 3 saniye yandıktan sonra söndür.
Programın çalışmasını takip için #1 deki MESAJ haricinde öteki işlemler de seri monitöre mesajlar yollamaktadırlar.
ARDUINO LED13 ü izlediğinizde, her 1 saniyede yandığını ve 3 saniye yanık kaldıktan sonra söndüğünü göreceksiniz.
Ayrıca her 5 saniyede seri monitöre
****** ZAMANLAYICI_1: Message @ nnnn
yazılacaktır.
// MILLIS kullanarak Çoklu Görev (MultiTasking)
const int LEDPin= 13; //LED13 kullan
//GÖREV değişkenleri
unsigned long ISR1_Zaman = 5000; //ms
unsigned long ISR2_Zaman = 1000; //ms
unsigned long ISR3_Zaman = 3000; //ms
unsigned long ISR1_evvelkiMILLIS = 0;
unsigned long ISR2_evvelkiMILLIS = 0;
unsigned long ISR3_evvelkiMILLIS = 0;
void setup() {
Serial.begin(115200); //Seri Monitör hız ayarı
pinMode(LEDPin, OUTPUT); //LED13 ü çıkış olarak ayarla
}
void loop() {
unsigned long currentMillis = millis(); // zamanlayıcıyı oku
//ZAMANI gelen işi yap:
// ----- TASK#1:
if (currentMillis - ISR1_evvelkiMILLIS >= ISR1_Zaman)
{
ISR1_evvelkiMILLIS = currentMillis;
ISR_1();
}
// ----- TASK#2:
if (currentMillis - ISR2_evvelkiMILLIS >= ISR2_Zaman)
{
ISR2_evvelkiMILLIS = currentMillis;
ISR_2();
}
// ----- TASK#3:
if (currentMillis - ISR3_evvelkiMILLIS >= ISR3_Zaman)
{
ISR3_evvelkiMILLIS = currentMillis;
ISR_3();
}
}
void ISR_1() {
// Seri monitöre mesaj yazdır
Serial.print("****** ZAMANLAYICI_1: Message @ ");
Serial.println(ISR1_evvelkiMILLIS);
}
void ISR_2() {
// LED13 ü yak
LEDon();
Serial.print("DIAGS - ZAMANLAYICI_2: LEDon @ ");
Serial.println(ISR2_evvelkiMILLIS);
}
void ISR_3() {
// LED 13ü söndür
Serial.print("DIAGS - ZAMANLAYICI_3: LEDoff @ ");
Serial.println(ISR3_evvelkiMILLIS);
LEDoff();
}
void LEDon() {
digitalWrite (LEDPin, HIGH);
}
void LEDoff() {
digitalWrite (LEDPin, LOW);
}
Sketch, program depolama alanının 2690 baytını (%8) kullanır. Maksimum 32256 bayttır. Global değişkenler 28 bayt (%1) dinamik bellek kullanır ve yerel değişkenler için 2020 bayt kalır. Maksimum 2048 bayttır.
Bu hata mesajı değil, derleme sonundaki stat ler.
Sketch uses 198834 bytes (15%) of program storage space. Maximum is 1310720 bytes.
Global variables use 13248 bytes (4%) of dynamic memory, leaving 314432 bytes for local variables. Maximum is 327680 bytes.
Eğer checkmark üzerine tıkladysanız, yalnız derleme yapılır ve bu mesaj çıkar.
Programınızı derleyip sonra da Arduino ya yükleyip çalıştırmak isterseniz, checkmark a değil menudeki SAĞ OK a tıklayın.
Mesajdan sonra çalışır.
TG
Arduino da birden çok begin oluşturma
HC-05 da Parmak izi sensörü de seri bağlantı ile çalışır.
Arduino da birden fazla seri iletişim yapmak biraz zor olabiliir, ama SoftwareSerial kitaplığı ile mümkün; bazı püf noktalara dikkat etmek gerekiyor.
Projenizin nasıl çalışması gerektiğini yazmadığınız için tam bir yöntem sunmak zor.
Fakat şöyle bir çalışma farz ederek bir opsiyon sunayım:
* Pamak izi okuyarak bir güvenlik safhasından geçeceksiniz.
* Eğer güvenlik onaylandıysa, o zaman BT üzerinden bir iletişim ile bazı işlemleri yapacaksınız.
SoftwareSerial ile çalışırken en önemli şey, birden fazla tanımladığınız portları teker teker çalıştırmanız. Bunun sebebi Arduino nun yeteri kadar güçlü olmaması ve softserial kodunun işlemciyi baya meşgul tutması.
İki SoftSerial yerine bir tane normal Seri port artı bir tane de SoftSerial port kombinasyonu da olabilir. Burada tek problem, programınızı geliştiriken USB bağlantınız hardware seri portu ( D0 ve D1) kullanacağı için, devamlı kablo takıp çıkarmanız gerekecek.
İlk denemenizde önce parmak izi sensörünü okuyarak, güvenlik işlemleri tamamlandıktan sonra da BT ye atanmış seri portu devreye sokarak iletişim işlerinizi yapın.
Elinizdeki sensör hızlarının SoftSerial kodunun hız limitlerine uygun olarak ayarlanması gerekir. Örnek: ikisi de 9600 olarak ayarlanmalı. Veya biri fazla yüksek hız gerektiriyorsa, ötekini azaltmanız gerekebilir. Bence 38400 üzeri jızlarda çalışabileceğinizi sanmıyorum.
Eğer softserial uygulaması başarılı olmadıysa, o zaman birden fazla hardware seri portu olan işlemciler seçmeniz gerekecektir: MEGA da üç port var. Veya da Arduino ya bağlı kalmak istemezseniz Raspberry Pico gayet uygun olabilir.
https://docs.arduino.cc/learn/built-in-libraries/software-serial
İyi çalışmalar.
Seri port ekranında hiçbir şey gözükmüyor acaba bir şeyi eksik mi yaptım
Serial Monitor a çıktı yapabilmek için önce:
* programınızın SETUP kısmında portu açmanız gerekir::
Serial.begin(115200);
Sürat seçimi size göre, ama programdaki ve seri monitor un altındaki süratin aynı olması gerekir.
* Sonra, programın SETUP veya LOOP kısmında porta yazmak için:
Serial.print(), Serial.println(), veya Serial.write() fonksiyonlarından birini kullanarak değer yazmalısınız.
İyi çalışmalar.
expected initializer before 'Servo' hatası
int v
satırının sonunda ; (noktalı virgül) yok.
Belli bir arazide yanılma payı olmadan yer tespiti nasıl yapılır?
RFID araştırın. Ağaçları bunlarla tanımlayıp cep telefonla yanına geldığınızde posıtıf tanıma yapabilirsiniz.
Biraz daha komplike bir uygulama ise, yerel bir WFI ağı oluşturmak ve bunu GPS ile bağdaştırarak daha yüksek konum çözünürlüğüne ulaşmak. Fakat bu tıp bir uygulama açık tabıat ortamından dolayı zorluk çıkarablir.
Yine ESP32 veya ESP8266 bazlı araçlarla bir HTTP server ortamı kurulabilir. ağaçlara bahsettiğiniz gibi sayısal tanılama ile çevrimiçi bir veri tabanından geçmişlerine cep telefon uygulaması ıle ulaşılabilir.
İyi çalışmalar.