Arduino seri porttan komut okuma, Serial.available() ile veriyi kontrol edip readStringUntil('n') gibi bir sınırla metni almak, trim() ile temizlemek ve yalnızca tanımlı komutları işlemektir. Verinin mevcut olup olmadığını kontrol et, tamamlanmış komutu uygun sınırda oku, metni temizle, yalnızca izin verilen komutlarla karşılaştır ve geçersiz girdide güvenli varsayılan davranışı uygula.
Seri porttan veri okumak ile seri port komutunu güvenli biçimde yorumlamak aynı işlem değildir. Serial.available() bir veya daha fazla baytın alındığını gösterebilir, ancak tam komutun geldiğini göstermez; mesaj sınırı ayrıca belirlenmelidir.
Güvenli seri komut akışı hangi adımlardan oluşur?
Serial.available() yalnızca giriş tamponunda okunabilecek bayt olup olmadığını kontrol eder. Arduino API'sinde bu işlevin dönüş değeri, okunmaya hazır bayt sayısıdır. Bu nedenle available() > 0 sonucu, komutun tamamlandığı anlamına gelmez. Örneğin LED_ON komutunun yalnızca ilk birkaç karakteri alınmış olabilir.
- Veriyi kontrol et: Tamponda veri varsa okumayı başlat.
- Sınırı belirle: Bu yazıda komut sonunu
nile tanımla ve metni bu sınıra kadar oku. - Metni temizle: Satır sonundan gelebilecek
rve baştaki veya sondaki boşlukları kaldır. - İzin verilen komutlarla karşılaştır: Yalnızca
LED_ONveLED_OFFgibi açıkça tanımlanan değerleri kabul et. - Geçersiz girdiyi etkisiz bırak: Bilinmeyen komutta mevcut çıkış durumunu değiştirme.
Aşağıdaki iskelet, fiziksel pin seçmeden bu akışı gösterir:
bool ledOn = false;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('n');
command.trim();
if (command == "LED_ON") {
ledOn = true;
Serial.println("LED_ON accepted");
} else if (command == "LED_OFF") {
ledOn = false;
Serial.println("LED_OFF accepted");
} else {
Serial.println("UNKNOWN_COMMAND");
}
}
}
LED_ON gönderildiğinde beklenen çıktı LED_ON accepted, LED_OFF gönderildiğinde LED_OFF accepted olur. Başka bir metin UNKNOWN_COMMAND üretir ve ledOn değerini değiştirmez. readStringUntil('n') sınırı bulamazsa ayarlanmış zaman aşımına kadar bekleyebilir; bu süre Serial.setTimeout() ile değiştirilebilir.
Baud hızı, satır sonu ve trim birlikte nasıl çalışır?

Serial.begin(9600) içindeki 9600, bu örnekte seçilmiş bir yapılandırma değeridir, zorunlu bir Arduino standardı değildir. Klasik seri bağlantıda Seri Monitör'de de aynı baud değeri seçilmelidir. Bazı yerel USB CDC bağlantılarında Serial.begin() içindeki baud değeri fiziksel USB aktarım hızını belirlemeyebilir; bu durumda hedef kartın seri arayüz belgesi esas alınır.
Seri Monitör'deki satır sonu seçimi, komutun ne zaman tamamlandığını belirler:
No line ending: Yalnızca komut metni gönderilir, sonuna karakter eklenmez. Komutla birliktengelmediği içinreadStringUntil('n')sınır bulamaz ve zaman aşımı davranışı devreye girer.Newline: Metnin sonunan, yani LF eklenir. Bu seçim,readStringUntil('n')için doğrudan sınır sağlar.Carriage return: Metnin sonunareklenir. Kod yalnızcanbekliyorsa bu karakter tek başına okuma sınırı değildir.Both NL & CR: CR ve LF birlikte gönderilir.nokumayı bitirir,rise dönen metnin sonunda kalabilir.
command.trim(), String nesnesinin başındaki ve sonundaki boşluk karakterlerini yerinde temizler. Böylece LED_ONr değeri LED_ON ile karşılaştırılabilir; metnin ortasındaki boşluklar silinmez. USB kablosuyla açılan seri portun yerel USB arayüzü mü, USB-UART köprüsü mü kullandığı ve donanımsal UART pinlerinin hangi seri nesneye bağlı olduğu karttan karta değişebilir. Serial, Serial1 ve pin eşlemesini hedef kartın resmi belgelerine göre seç.
readStringUntil mı, karakter bazlı okuma mı?
readStringUntil satır temelli, karakter bazlı okuma ise bayt bazlıdır. Serial.readStringUntil('n') karakterleri bir String içinde toplar ve ayırıcıyı sonuçtan çıkarır. Ayırıcı gelmezse çağrı, Serial.setTimeout(...) ile milisaniye cinsinden belirlenen süre boyunca bekleyebilir. Serial.read() tek bayt okur, int döndürür ve veri yoksa -1 verir; Serial.available() yalnızca alınmış baytları bildirir.
n seçtiysen gönderici bu karakteri yollamalıdır. Seri Monitör'de satır sonunu Newline ya da Both NL & CR olarak ayarlayabilirsin. CRLF içindeki r, trim() ile temizlenebilir; manuel ayrıştırmada doğrudan yok sayılabilir. Satır sonu gönderilmezse readStringUntil() zaman aşımına kadar bekleyebilir.
| yaklaşım | mesaj sınırı | bekleme davranışı | uzunluk denetimi | uygun kullanım bağlamı |
|---|---|---|---|---|
readStringUntil('n') |
n veya zaman aşımı |
Satır sonu yoksa bekler | String için ayrıca üst sınır koymalısın |
Kısa, satır tabanlı komutlar |
Serial.read() ve tampon |
Ayrıştırıcı n ve r politikasını belirler |
Yalnızca mevcut baytlar işlenir | Sabit kapasite ve taşmada ret uygulanır | Döngünün bloklanmaması gereken akışlar |
Mutlak bir üstünlük yoktur. Satır sonu güvenilir, komutlar kısa ve bekleme kabul edilebilirse readStringUntil() daha sade kalır. Döngünün başka işleri de sürdürmesi, sabit tampon kullanımı veya katı uzunluk denetimi gerekiyorsa karakter bazlı yaklaşım daha uygundur.
- Mevcut baytları
Serial.read()ile al ve negatif sonucu atla. rkarakterini yönet,nkarakterini komut sonu kabul et.index < MAX_COMMAND_LENGTH - 1olduğu sürece karakteri tampona ekle.- Taşmada kalan baytları sonraki
nkarakterine kadar tüket, komutu reddet, hata ver ve tamponu sıfırla.
LED_ON ve LED_OFF komut işleyicisi nasıl kurulur?

Bu kod örneği Arduino UNO R3 içindir. Kartın pinout'unda LED_BUILTIN, D13/PB5 olarak ve D13 dijital/GPIO olarak gösterilir. UNO örneğinde etkin seviye HIGH, devre dışı seviye LOW kullanılır. Farklı mantık kullanan bir karta geçerken iki seviye sabitini kart belgelerine göre değiştir.
const int LED_PIN = LED_BUILTIN;
const int LED_ON_LEVEL = HIGH; // UNO R3 örneği
const int LED_OFF_LEVEL = LOW;
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LED_OFF_LEVEL);
Serial.begin(9600);
Serial.println("READY");
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('n');
command.trim();
if (command == "LED_ON") {
digitalWrite(LED_PIN, LED_ON_LEVEL);
Serial.println("OK: LED_ON");
} else if (command == "LED_OFF") {
digitalWrite(LED_PIN, LED_OFF_LEVEL);
Serial.println("OK: LED_OFF");
} else {
Serial.print("ERROR: UNKNOWN_COMMAND: ");
Serial.println(command);
}
}
}
LED_ON ve LED_OFF yalnızca tam eşleşen dallarda digitalWrite çağırır. Bilinmeyen komut dalında çıkışa yazılmaz; böylece LED'in önceki geçerli durumu korunur. Seri Monitör'de başlangıçta READY, ardından geçerli komutlarda OK: LED_ON veya OK: LED_OFF görürsün. BLINK gibi bir komut ise ERROR: UNKNOWN_COMMAND: BLINK yanıtını üretir.
USB ile test ederken veri taşıyan USB kablosu, doğru port ve 9600 baud ayarı gerekir. Seri arayüzün fiziksel karşılığı karta göre değişir: UNO R4 WiFi'de USB bağlantısı için Serial, D0 ve D1 üzerindeki donanımsal UART için Serial1 kullanılır. UNO R3'te D0 ve D1, USB seri köprüsüyle paylaşılan tek seri yolun parçasıdır. Harici UART kullanırken kartın pinout'undaki seri nesneyi ve lojik seviyelerini esas al.
Harici LED bağlayacaksan LED_BUILTIN yerine kart belgelerinde dijital çıkış olarak gösterilen bir pin seç, LED'i seri dirençle bağla ve pin akımı ile besleme gerilimi sınırlarını aşma. Arduino'nun UNO örneğinde LED, GND'ye 220 ohm seri direnç üzerinden bağlanır; bu değer her kart için otomatik bir kural değildir.
Komut işleyicisi hangi senaryolarla sınanmalı?
Komut işleyicisini yalnızca doğru komutlarla değil, hatalı ve biçimi bozuk girdilerle de sınamak gerekir. Aşağıdaki akışta yanıt sözleşmesi READY, OK: ... ve ERROR: UNKNOWN_COMMAND biçimindedir. Bilinmeyen komut çıkış durumunu değiştirmeyecek.
- Başlangıç: Seri Monitör'ü açıp kartı sıfırla. Gönderilen metin: yok. Beklenen seri yanıt:
READY. Beklenen çıkış: örnekte LED kapalı. - LED'i açma: Gönderilen metin:
LED_ON. Beklenen seri yanıt:OK: LED_ON. Beklenen çıkış: LED açık. - Bilinmeyen komut: Gönderilen metin:
LED_ON_EXTRA. Beklenen seri yanıt:ERROR: UNKNOWN_COMMAND. Beklenen çıkış: LED açık kalır. - LED'i kapatma: Gönderilen metin:
LED_OFF. Beklenen seri yanıt:OK: LED_OFF. Beklenen çıkış: LED kapalı. - Başta boşluk: Başında iki boşluk bulunan
LED_ONgönder. Beklenen seri yanıt:OK: LED_ON. Beklenen çıkış: LED açık. - Sonda boşluk: Sonunda iki boşluk bulunan
LED_OFFgönder. Beklenen seri yanıt:OK: LED_OFF. Beklenen çıkış: LED kapalı. - Büyük ve küçük harf: Gönderilen metin:
led_on. Harf dönüşümü yapılmayan tam eşitlik kontrolünde beklenen seri yanıt:ERROR: UNKNOWN_COMMAND. Beklenen çıkış: LED kapalı kalır.
Başta ve sonda boşluk bulunan komutların kabul edilmesi, karşılaştırmadan önce trim() çağrıldığını gösterir; bu işlev metnin iki ucundaki boşluk karakterlerini temizler.
command == "LED_ON" tam eşitlik kontrolüdür. LED_ON_EXTRA aynı metinle başlasa da ek karakter içerdiği için koşul sağlanmaz. startsWith() veya indexOf() ile yalnızca parçayı aramak, istemeden çıkış değiştirilmesine yol açabilir.
Bu test sırası, komutları koşullarla eşleştirme becerisini de pekiştirir. Benzer karar yapılarını algoritmik düşünme bilgi testi ile farklı örnekler üzerinden çalışabilirsin.
Seri komut çalışmıyorsa sorun nasıl teşhis edilir?
Teşhisi bağlantıdan komut mantığına doğru sırala ve her adımda tek bir değişkeni kontrol et.
- READY: Kartı sıfırladığında
READYgörünmüyorsa önce seri bağlantıyı, portu ve başlangıç kodunu kontrol et. - Port ve bağlantı: Veri aktarabilen USB bağlantısını ve doğru portu seç. IDE'de kart adı yerine
Unknowngörünebilir; bağlantıyı çıkarıp takarak değişen portu karşılaştır. - Baud ve satır sonu:
Serial.begin()değeri ile Seri Monitör değeri eşleşsin.readStringUntil('n')içinNewlineseç;No line endingayırıcı göndermez.Both NL & CRseçilirsermetne eklenebilir, bu nedenletrim()veya iki sonlandırıcıyı ele alan bir mantık gerekir. - Ham metin: Gelen veriyi geçici olarak sınır işaretleri ve uzunluğuyla yazdır.
- Eşleşme: Boşluk, alt çizgi ve büyük veya küçük harf farklarını kontrol et. Bilinmeyen komutta çıkış değişmemeli.
- Çıkış devresi: Koddaki LED pini
OUTPUTolarak ayarlı mı, kullandığın devrede etkin seviyeHIGHmıLOWmu kontrol et.
String command = Serial.readStringUntil('n');
Serial.print("<");
Serial.print(command);
Serial.print("> len=");
Serial.println(command.length());
Bu geçici çıktıyı trim() çağrısından önce al. Temiz bir LED_ON girdisi için beklenen sonuç <LED_ON> len=6 olur; fazladan boşluk veya r uzunluk değerini değiştirir.
USB üzerinden açılan seri bağlantı ile donanımsal UART aynı şey değildir. USB dönüştürücüsü, yerleşik USB veya ayrı UART düzenleri karttan karta değişebilir. UART pinleri başka işlevlerle paylaşılabildiği için Serial nesnesinin fiziksel yolunu resmi pinout'tan doğrula. Pinler USB köprüsüyle paylaşılmışsa USB trafiği ile harici UART trafiğini aynı anda kullanma; mantık seviyesi ve elektriksel sınırlar uygun değilse TX ve RX bağlantısı yapma.
Ayırıcı gelmiyorsa veya veri parçalıysa
Serial.available() > 0 yalnızca o anda en az bir bayt okunabildiğini gösterir, tamamlanmış komutu değil. Veri parça parça gelirse readStringUntil('n') satır sonunu bekler; ayırıcı hiç gelmezse zaman aşımına kadar bekliyormuş gibi görünür.
Komut fazla uzunsa veya tampon taşarsa
Fazla uzun komut için bir üst sınır belirle; sınır aşılırsa satır sonuna kadar gelenleri tüketip komutu reddet. Karakter tamponuna yazarken kapasite kontrolü yap. Her iki durumda da LED çıkışını değiştirme.
Komutlar art arda gelirse
LED_ONnLED_OFFn gibi iki satırı tek komut sanma. Her satır ayrı işlenmeli, yanıtlar sırayla OK: LED_ON ve OK: LED_OFF gelmeli, son çıkış LED kapalı olmalıdır.
Sık Sorulan Sorular
Serial.available() değeri sıfırdan büyükse komutun tamamı gelmiş sayılır mı?
Serial.available() > 0, komutun tamamının geldiği anlamına gelmez. Değer, o anda okunabilir baytları gösterir. Komutun tamamlanması için satır sonu veya belirlediğin başka bir protokol sınırı gerekir.
Serial.readStringUntil('n') neden bazen bekliyormuş gibi görünür?
Fonksiyon n karakterini bekler. Bu karakter gönderilmezse veya veri henüz parçalıysa, zaman aşımına kadar bekler ve ardından elindeki metni döndürür.
Seri Monitör'de hangi satır sonu seçeneği kullanılmalıdır?
Kod readStringUntil('n') kullanıyorsa Newline seç. Kod r bekliyorsa Carriage return kullan. Both NL & CR seçeneğini ancak iki karakteri de yöneten bir kodun varsa tercih et.
String yerine karakter tamponu ne zaman tercih edilmelidir?
Kısa ve düşük hızlı komutlarda String daha okunaklı olabilir. Komut uzunluğunu kesin sınırlamak, bellek kullanımını öngörülebilir tutmak veya sürekli veri almak gerektiğinde karakter tamponu tercih edilebilir. Her yazmada sınır kontrolü yap.
Seri komutlarda güvenilirlik, doğru yanıt kadar hatalı girdide çıkışın korunmasına ve veri sınırlarının açıkça tanımlanmasına bağlıdır.