Projenin en kritik Ar-Ge süreçlerinden biri, alıcı ve verici sistemlerin farklı mimarilerde paralel olarak kodlanmasıydı. Sistem iki farklı versiyon üzerinden çalıştırılmıştır: Biri STM32 tabanlı, kendi kapalı kütüphanesini kullanan yerli Alacakart (PPM sinyalleri üzerinden otonom/manuel haberleşme); diğeri ise açık kaynak kütüphanelerle desteklenen Arduino Mega/Nano mimarisi (Serial/UART haberleşme).
Yazılım mimarisi kurgulanırken C ve C++ dilleri kullanılmış olup, nesne tabanlı programlamaya (OOP) giriş yapılarak kodların daha yönetilebilir olması sağlanmıştır. Modülerliği artırmak amacıyla, verici ve alıcı taraflarındaki temel işlevler kendi özel header kütüphanelerine ayrılmıştır.
1. Alacakart (PPM Modülasyonu) Yazılım Paketi
Alıcı ve verici kodları kendi içlerinde modüler (header kütüphanesi ve asıl kütüphane) olarak ayrılmıştır. Verici tarafında havadaki veri paketlerinin çevresel gürültülerden dolayı bozulmasını engellemek için, gönderilmeden hemen önce paket içerisindeki değerler toplanarak bir doğrulama baytı (Check-Sum) oluşturulur. Alıcı tarafında ise bu paket çözülerek eşleşme durumuna göre PPM sinyali (1000-2000 arası) oluşturulur. 2 saniye sinyal kesildiğinde ise sistem Fail-Safe moduna geçerek aracı güvene alır.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define JOY_X A1
#define JOY_Y A0
#define POT A2
#define SWITCH 6
struct KumandaVerisi {
int8_t ileri_Geri; // Joystick Y ekseni (ileri/geri)
int8_t donus; // Joystick X ekseni (dönüş)
int8_t hiz; // Pot ile belirlenen hız
bool mod; // Mod seçimi (toggle switch)
};
KumandaVerisi veri;
RF24 radio(9, 10);
const byte adres[5] = {'0', 'I', 'K', 'A', '0'}; //Adres adı
unsigned long onceki_Zaman = 0;
const unsigned long gonderim_Araligi = 20; // 20 ms yani 50 HZ.
void loop() {
unsigned long simdi = millis();
if (simdi - sonDonguZamani > 20) { // ~50 Hz
/* --------- RF24 veri kontrolü --------- */
if (radio.available()) { // Yeni paket?
radio.read(&rxData, sizeof(rxData));
sonVeriZamani = simdi;
Structtan_ppmKanali();
}
/* --------- Failsafe --------- */
else if (simdi - sonVeriZamani > 2000) { // 2 s veri yoksa
kanal[4] = 2000; // Failsafe kanalı yüksek
}
kanallariYolla();
sonDonguZamani = simdi;
}
}
void Structtan_ppmKanali() {
/* Struct alanlarını PPM kanallarına dönüştür */
kanal[0] = constrain(map(rxData.ileri_Geri, -127, 127, 1000, 2000), 1000, 2000); // İLERİ-GERİ
kanal[1] = constrain(map(rxData.donus, -127, 127, 1000, 2000), 1000, 2000); // DÖNÜŞ
kanal[2] = constrain(map(rxData.hiz, 0, 255, 1000, 2000), 1000, 2000); // HIZ
kanal[3] = rxData.mod ? 2000 : 1000; // Anahtar açık/kapalı
kanal[4] = 1500; // Yedek
}
2. Arduino Mega Versiyonu (Serial Haberleşme)
Sistemin yedek veya test mimarisi olarak Arduino Mega ve Nano üzerinden çalışan versiyonunda, modüller arası iletişim UART (Hardware/Software Serial) üzerinden sağlanmaktadır. Arduino IDE ortamında C ve C++ dilleriyle geliştirilen bu yapıda da benzer bir Fail-Safe algoritması uygulanmış, bağlantı koptuğunda (300ms zaman aşımı) röle ve fren pinleri üzerinden aracın fiziksel kontrolü kesilmiştir.
/* ---------- Failsafe ---------- */
void failsafe() {
analogWrite(PIN_PWM, 0); // gaz kapalı
digitalWrite(PIN_BRK, HIGH); // fren çekili
digitalWrite(ROLE, ROLE_IDLE); // ileri
}
void loop() {
/* ---------- Paket al ---------- */
if (link.available() >= PKT_LEN + 1) {
if (link.read() == HEADER) {
link.readBytes(reinterpret_cast<uint8_t*>(&rx), PKT_LEN);
lastPkt = millis();
}
}
/* ---------- Failsafe ---------- */
if (millis() - lastPkt > FS_TIMEOUT) { failsafe(); return; }
/* ---------- Gaz ---------- */
analogWrite(PIN_PWM, map(rx.hiz, 0, 255, PWM_MIN, PWM_MAX));
}