Bu makalede, Wio Terminal, sıradan bir Ultrasonik mesafe sensörü ve üzerine ekleyeceğimiz özel Derin Öğrenme sosu kullanarak bir insan sayma sistemi oluşturacağız ve bunun gerçekten çalışmasını sağlayacağız.
Ayrıca, oda doluluk verilerini bulutta depolamak ve PC’de görselleştirmek için Microsoft Azure IoT Central hizmetini kullanacağız.

Daha fazla detay ve video eğitimi için ilgili videoyu izleyin!
Veri ile tanışın
Öncelikle, Ultrasonik sensörden alabileceğimiz verileri ve bunları nesnelerin yönünü belirlemek için nasıl kullanabileceğimizi anlayalım. Bu basit betiği, Grove Ultrasonik Ranger’a bağlı Wio Terminal’e yükleyebiliriz ve ardından odaya girip çıkabiliriz.
#include "Ultrasonic.h"
#define INTERVAL_MS 50
Ultrasonic ultrasonic(0);
void setup() {
Serial.begin(115200);
}
void loop() {
static unsigned long last_interval_ms = 0;
float distance;
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
distance = ultrasonic.MeasureInCentimeters();
if (distance < 200.0) {
Serial.println(distance);
}
else
Serial.println(-1);
//Serial.print('\t');
}
}
Yürüdüğümüzde, ilk olarak nesneden uzaklıkla ilgili oldukça yüksek değerler alıyoruz, ardından bu değerler azalıyor. Odanın dışına çıkarken ise tamamen zıt bir sinyal alıyoruz.

Teorik olarak, yönü belirleyebilecek bir algoritmayı kendimiz yazabiliriz, ancak gerçek yaşam durumları karmaşık – hızlı yürüyen (daha kısa eğri uzunluğu) ve yavaş yürüyen (daha uzun eğri uzunluğu) insanlar var, ince insanlar ve o kadar ince olmayan insanlar var ve daha fazlası. Bu nedenle, el yazısı algoritmamız tüm bunları dikkate almak zorunda kalacak, bu da kaçınılmaz olarak karmaşık ve karmaşık hale getirecektir. Bir çıkarım sinyal işleme ve önemli varyasyonlara sahip gürültülü verilerle ilgili bir görevimiz var… Ve çözüm – Derin Öğrenme. Ya da Sherlock Holmes.

Ben Derin Öğrenmeyi seçeceğim.
Verileri toplayın
Şimdi Edge Impulse Dashboard’da yeni bir proje oluşturalım ve verileri toplamaya hazırlanalım. Verileri toplamak için, çok yüksek bir örnekleme frekansına ihtiyacımız olmadığından, edge-impulse-cli’den veri iletim aracını kullanabiliriz. ei_people_counter_data_collection.ino betiğini (yukarıda yapıştırılan tam aynı betik) Wio Terminal’e yükleyin – edge-impulse-cli ve veri iletim protokolünü nasıl kuracağınızı öğrenmek için TinyML serisinin ilk videosunu izleyin.
Bu özel betikte, 200 cm’den büyük tüm değerleri filtreliyoruz ve bunları -1 olarak ayarlıyoruz.
if (distance < 200.0) {
Serial.println(distance);
}
else
Serial.println(-1);
Uygulamanız için, kurulumunuza bağlı olarak bu değeri daha düşük veya daha yüksek ayarlamanız gerekebilir. Ardından yürümeye başlayın.

Her sınıf için 1 dakika 30 saniye veri kaydettim, her seferinde 5000 ms örnek kaydettim ve ardından bunları 1500 ms örnekler elde etmek için kırptım – veri setinde çeşitliliğin çok önemli olduğunu unutmayın, bu nedenle hızlı, yavaş, koşan vb. yürüyen örnekleriniz olduğundan emin olun. Cihazın önünde kimsenin olmadığı örnekler dışında “hiç kimse” kategorisi için, cihazın hemen yakınında duran ve yanından yürüyen bir kişinin olduğu örnekleri dahil etmek iyi bir fikirdir, böylece herhangi bir hareketin yanlış bir şekilde içeri veya dışarı olarak sınıflandırılmasını önleyebilirsiniz.
Doğru işleme bloğunu ve ağ mimarisini bulun
Veri toplama işlemi tamamlandığında, impulsunuzu oluşturun – pencere uzunluğunu 1500 ms ve pencere boyutunu 500 ms olarak ayarladım.

1500 ms, bir kişinin kapıdan içeri girmesi veya dışarı çıkması için ihtiyaç duyduğu süreyi kapsamak için yeterlidir, çok yavaş hareket etmediği sürece. İşleme blokları için, bu sefer denemek için yalnızca iki bloğumuz var – Ham veri veya Spektral analiz. Düzleştirme bloğu, verilerden tüm zaman alanı bilgilerini silerek yönü belirlemede tamamen işe yaramaz hale getirecektir, bu nedenle bunu kullanmayacağız. Spektral analiz bloğu, veri örneklerine Hızlı Fourier dönüşümü uygular ve sinyali zaman alanından frekans alanına dönüştürür. FFT, sesler veya ivmeölçer verileri gibi diğer sinyal türleri için çalışabilirken, bizim durumumuzda sinyalin frekansı da çok önemli değildir, çünkü bir kişinin odaya girip girmediğini frekansa dayanarak yargılayamayız. Spektral analiz bloğundan sonra veri görselleştirmesine baktığınızda, içeri ve dışarı veri örneklerini ayırmanın zor olduğu açıktır.

İşlem bloğunu spektrograma değiştirmek gerçekten sorunu hafifletmiyor ve sonuçta elde edilen doğruluk oldukça düşük kalıyor – elde edebildiğim en yüksek değer %79.6, iç ve dış sınıflar arasında çok fazla karışıklık var. Ve bir kez daha kazanan, Ham veri (ölçekleme ile) + 1D Konvolüsyonel ağ. Ağı biraz ayarlayarak %92 doğruluk elde ettim, bunun için “uzman” moduna geçmem gerekti ve MaxPool1D adımlarını 1, havuz boyutunu ise 4 olarak değiştirdim.

%92 doğruluk ne kadar iyi ve bunu artırmak için ne yapılabilir?
%92, bir kavram kanıtı veya prototip için oldukça iyi, ancak üretim modeli için korkunç. Üretimde, durum değişebilir – eğer uygulamanız kritikse ve bir şekilde otomatik kontrol ve karar verme süreçlerinde kullanılıyorsa, %98 – %99’un altında bir şey istemezsiniz ve hatta bu bile düşük olabilir, ödeme veya kimlik doğrulama için bir yüz tanıma sistemi gibi düşünün. Bu sistemin doğruluğunu artırmanın yolları var mı?
- Ultrasonik sensör ucuz ve yaygın bir sensördür, ancak nispeten yavaş ve çok hassas değildir. Daha iyi veriler elde etmek için Grove TF Mini LiDAR Modülü‘nü kullanabiliriz.
- Daha fazla veri elde edin ve sensörü normal insan bel seviyesine daha aşağı yerleştirin. Ben 181 cm boyundayım ve sensörü göğüs seviyeme yerleştirdim, ancak daha kısa ve ince meslektaşlarımı kaçırdığını fark ettim.
- İki, birden iyidir – iki sensörün biraz farklı yerlerde ölçüm yapması çok fazla veri eklemeyecek (her örnekte yalnızca 31 veri noktası var), ancak doğruluğu artırabilir. Daha ilginç fikirleri keşfetmek için, Wio Terminal uygun bir şekilde yerleştirilirse yerleşik bir ışık sensörü kullanılabilir.
Sürekli çıkarım
Model eğitildikten sonra cihazdan gelen verilerle canlı sınıflandırma yapabiliriz – burada 500 ms’lik pencere boyutunun aslında o kadar iyi çalışmadığını ve daha fazla yanlış pozitif ürettiğini buldum, bu yüzden bir sonraki adımda, cihazda dağıtım yaparken bu değeri 750 ms’ye artırdım. Modeli Wio Terminal’a dağıtmak için dağıtım sekmesine gidin, Arduino kütüphanesini seçin, indirin, arşivi çıkarın ve Arduino kütüphanelerinizin klasörüne koyun.
Bu sefer sürekli çıkarım örneğini kullanacağız, böylece önemli verileri kaçırmadığımızdan emin olacağız. Seeed studio örnek şemalar deposunu klonlayın ve Arduino IDE ile people_counting_continious.ino şemasını açın, Edge Impulse kütüphanesinin adını projenizle eşleşecek şekilde değiştirin, Wio Terminal’ı kartınız olarak seçin, Grove Ultrasonik sensör kütüphanesini yükleyin ve şemayı yükleyin.
Serinin ilk videosunda hatırlarsanız, çıkarım için örnekteki tüm veri noktalarını toplar, çıkarım yapar ve ardından örneklemeye geri dönerdik – bu, verileri sinir ağına beslerken veri toplama işlemini durduracağımız ve bazı verileri kaybedeceğimiz anlamına geliyordu.

Bu optimal değil ve bu sorunu çözmek için DMA (Doğrudan Bellek Erişimi), iş parçacığı veya çoklu işlem kullanabiliriz.

Wio Terminal MCU (Cortex M4F çekirdeği) yalnızca bir çekirdeğe sahiptir, bu nedenle çoklu işlem seçeneği yoktur – bu nedenle bu durumda FreeRTOS ve iş parçacıkları kullanacağız. Olacak olan, çıkarım süreci sırasında FreeRTOS’un çıkarımı kısa bir süre durdurması, veri örneğini toplaması ve ardından çıkarıma geri dönmesidir.

Bu şekilde gerçek çıkarım biraz daha uzun sürecek, ancak bu belirli kullanım durumu için fark önemsizdir. Her 500 ms’de bir çıkarım yapıyoruz, bu nedenle zaman diliminin her 500 ms’lik diliminde 3 kez çıkarım yapılacak. Ardından, 3 çıkarım arasında en yüksek güvene sahip sonucu alıyoruz – örneğin, “dışarı” etiketinde 2 kez en yüksek güvene sahipken, “hiçbiri” etiketinde bir kez en yüksek güvene sahip olduğumuzda, sonuç “dışarı” olarak sınıflandırılmalıdır. Testi basitleştirmek için, bir kişinin odaya girdiğinde Wio Terminal ekranını açan ve bir kişi çıktığında kapatan satırları ekledim.

Azure IoT Central Entegrasyonu
Peki, model çalışıyor, ama yine de kendi başına gerçek dünyada uygulanabilir değil. Bunu tam teşekküllü bir uygulama haline getirmek için iki unsur ekleyelim – bir basit GUI ve buluta veri yükleme ile güzel grafikler. Grafik kullanıcı arayüzü oluşturmak için LVGL kütüphanesini ve verileri göndermek ve görselleştirmek için Microsoft Azure IoT Central hizmetini kullanacağız. Ortaya çıkan şema 693 satır uzunluğunda ve RTOS’ta 3 eşzamanlı iş parçacığı çalışıyor. Bu projenin ML kısmında yaklaşık 2 gün çalıştım ve GUI, Azure ve Edge Impulse’un birlikte çalışmasını sağlamak için 2 gün daha harcadım. Hepsi oldukça eğlenceliydi. İşte IoT central ile çalıştırmak için yapmanız gereken adımların hızlı bir özeti.
Azure IoT central bağlantısı için kod, Seeed Japan Github‘dan alınan şemanın değiştirilmiş bir versiyonudur, bu da Benjamin Kabe’nin orijinal çalışmasına dayanmaktadır ve resmi Azure SDK’sını C dilinden Wio Terminal’a taşımaktadır. Hem Benjamin hem de Seeed Japon ofisi Platform.io’yu Visual Studio Code ile kullanmışlardır – bu harika bir çerçeve, çok fazla kolaylık sağlıyor, ancak benim eğitimlerim Arduino IDE’ye dayandığı için sadece bir proje için IDE’yi değiştirmek istemedim. VS Code’dan Arduino IDE’ye kod taşımak aslında oldukça basittir:
- main.cpp dosyasını sketch.ino olarak yeniden adlandırdım ve include klasöründeki başlık dosyalarını kaynak dosyalarla birlikte sketch klasörüne koydum.
- azure-sdk-for-c klasörü Arduino kütüphanelerinin klasörüne yerleştirilmelidir ve bir dizi kütüphaneyi manuel olarak yüklemeniz gerekecek.
- Son olarak, Signature.cpp dosyasındaki bu satırları değiştirin.
#include <mbedtls/base64.h>
#include <mbedtls/md.h>
#include <mbedtls/sha256.h>
Şuna dönüştürmek için
#include "Seeed_mbedtls.h"
Gerekli kütüphaneleri yükleyin:
https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi#v1.0.2
=https://github.com/Seeed-Studio/Seeed_Arduino_rpcUnified#v2.1.1
https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls#dev
https://github.com/Seeed-Studio/Seeed_Arduino_FS
https://github.com/Seeed-Studio/Seeed_Arduino_SFUD
https://github.com/sstaub/NTP
PubSubClient
https://github.com/lovyan03/LovyanGFX#0.3.4
https://github.com/ciniml/ExtFlashLoader
https://github.com/Seeed-Studio/Seeed_Arduino_LIS3DHTR
https://github.com/bxparks/AceButton
MsgPack
Ve normal bir Arduino IDE projesi olarak derlenecektir. Bunu bu GitHub deposunda, WioTerminal_Azure_Central.ino adı altında bulabilirsiniz, tüm değişiklikler zaten yapılmıştır. Şema yüklendikten sonra, Wio Terminal’ın üstündeki üç düğmeye basarak yapılandırma moduna girin ve cihazı sıfırlayın. “Yapılandırma modunda” ifadesi cihaz ekranında görüntülenecektir. Cihazla Seri monitör (baud hızı 115200, carriage return) ile bağlanın ve WiFi SSID, şifre ve Azure IoT Central kimlik bilgilerini ayarlayın (aşağıdaki formatta set_az_iotc your_ID_scope your_primary_key your_device_ID), bunları elde etmek için şu adımları izleyebilirsiniz:
- https://apps.azureiotcentral.com/ adresine gidin.
- Eğer henüz bir Microsoft hesabınız yoksa, bir tane kaydedin.
- Build -> Custom app bölümüne gidin. Uygulama adını ve benzersiz URL’yi (uygulama adıyla benzer olabilir) girin. Ücretsiz planı seçin.
- Bir uygulama oluşturduktan sonra, Device Templates bölümüne gidin. IoT cihaz türünde yeni bir şablon oluşturun. Özel modeli seçin, aşağıdaki ekran görüntüsünde olduğu gibi üç yetenek ekleyin ve iki arayüz ekleyin (Views -> Cihazı Görselleştirme üzerine tıklayın). Bunu tamamladıktan ve her şeyin doğru olduğundan emin olduktan sonra, şablonu yayınlayın.
- Devices bölümüne giderek şablondan yeni bir cihaz oluşturun ve yeniye tıklamayı unutmayın, az önce oluşturup yayınladığınız şablonu seçtiğinizden emin olun!
- Administration -> Device connection bölümünden ID scope’u alın, Administration -> Device connection -> SAS-IoT-Devices bölümünden birincil anahtarı ve Cihazlar sekmesinden cihaz ID’sini alın, burada 5. Adımda cihazınızı oluşturmuştunuz.

Yapılandırma başarılı olduktan sonra, Wio Terminal’i yeniden başlatın ve Azure IoT Central’a bağlanmaya başlayacaktır, Serial Terminal’da ayrıntılı ilerleme geri bildirimini izleyebilirsiniz. Daha sonra a) Gösterge panelindeki Cihaz durumu Provisioned olarak değişti b) Cihaz -> Ham verilerde İvmeölçer sensöründen telemetri verilerini görebileceksiniz.

Daha sonra Edge Impulse model çıkarımı, iş parçacığı yönetimi için gerekli parçaları ekliyoruz ve telemetri gönderme fonksiyonunu, odaya giren kişi sayısı, çıkan kişiler ve odadaki toplam kişi sayısı için değerleri gönderecek şekilde değiştiriyoruz. Ayrıca, bilgi güncellemelerini gösteren üç düğme ve bir metin alanından oluşan basit bir GUI ekliyoruz – sonuçta oluşan taslağı WioTerminal_EI_People_Counting_Azure_Central_LVGL.ino dosyasını açarak görebilirsiniz.

En zor kısım, her bir ayrı iş parçacığında her şeyin normal çalıştığından emin olmak ve diğer iş parçacıklarını etkilememesini sağlamaktı. Kodu fazla karmaşık hale getirmeden bunu sağlamak için bazı fedakarlıklar yapıldı, örneğin LVGL görev güncelleme fonksiyonunu arayüz güncellemelerinin hemen ardından yerleştirmek ve periyodik olarak çalışmasına izin vermemek birçok baş ağrısını önledi.
Bugün Wio Terminal ile yaptığımız uygulama, üretime hazır olmasa da, biraz ek çalışma ile odaların doluluk oranını ölçmek ve kontrol etmek için kullanılabilir. Kendiniz deneyin ve sonuçları görün! Umarım makaleyi ve videoyu beğenirsiniz, TinyML serisindeki bir sonraki makale için takipte kalın.


