ESP8266 ile Access Point (Erişim Noktası) oluşturma

👤 Yazar: ozcan 📅 Tarih: 20.05.2026 13:05 👁️ Görüntüleme: 32

Esp8266 ile wifi alanınızı genişletebilirsiniz. bu oldukça basit. Githubda 2 tane yöntem buldum. ilki Arduino ile 2. firmware yükleyerek. İki konuyu da ele alacağız. Öncelikle Arduino ide ile nasıl yapılır onu göreceğiz.

esp8266 wifi genişletici

Arduino'da yeni proje oluşturalım ve aşağıdaki kodu yazalım

/* 
 *  Yazar: Pius Onyema Ndukwu
 *  Lisans: MIT Lisansı
 *  GitHub: https://github.com/Pius171/esp8266-wifi-extender
 *  Düzenleme: www.yenidir.com
 */

#include "WM.h"
// Değişkenler
bool RepeaterIsWorking = true;
int ledState = LOW; 
unsigned long previousMillis = 0;
long delay_time = 0; // Yanıp sönme arasındaki süre (milisaniye)
// Yönlendiriciye (router) bağlıysa her 200 ms'de bir yanıp söner
// Web sunucusu aktifse her 1 saniyede bir yanıp söner
// Menzil genişleticide (repeater) hata varsa LED söner
// Yönlendiriciye bağlanmaya çalışırken LED sürekli yanık kalır


/* İstediğiniz kimlik bilgilerini buraya ayarlayın. */

#if LWIP_FEATURES && !LWIP_IPV6

#define HAVE_NETDUMP 0
#include <lwip/napt.h>
#include <lwip/dns.h>
#include <LwipDhcpServer.h>


#define NAPT 1000
#define NAPT_PORT 10

#if HAVE_NETDUMP

#include <NetDump.h>


void dump(int netif_idx, const char* data, size_t len, int out, int success) {
  (void)success;
  Serial.print(out ? F("çıkış ") : F(" giriş "));
  Serial.printf("%d ", netif_idx);

  // İsteğe bağlı filtre örneği: if (netDump_is_ARP(data))
  {
    netDump(Serial, data, len);
    //netDumpHex(Serial, data, len);
  }
}
#endif






WM my_wifi;


void setup() {
  delay(1000);
 pinMode(0,INPUT_PULLUP);
 pinMode(LED_BUILTIN,OUTPUT);
 digitalWrite(LED_BUILTIN,1); // Aktif düşük (Active Low) led kapalı başlar
  Serial.begin(115200);

  Serial.println();

  if (!LittleFS.begin()) {
    Serial.println("LittleFS dosya sistemi yüklenemedi");
    return;
  }

  Serial.printf("\n\nNAPT Menzil Genişletici\n");
  Serial.printf("Başlangıçtaki boş bellek (Heap): %d\n", ESP.getFreeHeap());

#if HAVE_NETDUMP
  phy_capture = dump;
#endif

  // İlk olarak, düzgün bir yerel DNS sunucusu alabilmek için STA modunda bağlanıyoruz


  String ssid = my_wifi.get_credentials(0); // Dosya mevcut değilse fonksiyon her zaman null döner
  String pass = my_wifi.get_credentials(1);
  String ap= my_wifi.get_credentials(2);

  if (ssid == "null") { // Dosya mevcut değilse ssid "null" olacaktır
start_webserver:
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("Erişim Noktası (AP) IP adresi: ");
    Serial.println(myIP);
    WiFi.softAP("yenidir.com");
    Serial.printf("AP IP: %s\n", WiFi.softAPIP().toString().c_str());
    my_wifi.create_server();
    //server.begin();
    my_wifi.begin_server();
    Serial.println("HTTP sunucu başladı");
    delay_time=1000; // Web sunucusu aktifse her saniye yanıp sön
  }
  else {
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, pass); // Fonksiyonu anlamak için kontrol edin
    int timeout_counter=0;
    while (WiFi.status() != WL_CONNECTED) {
      if(timeout_counter>=120){
        goto start_webserver; // Bağlantı başarısız olursa web sunucusunu başlat
      }

      Serial.print('.');
      timeout_counter++;
      digitalWrite(LED_BUILTIN,0);// Bağlanmaya çalışırken LED'i açık bırak
      delay(500);
    }



    Serial.printf("\nSTA Bağlantısı Kuruldu: %s (dns: %s / %s)\n",
                  WiFi.localIP().toString().c_str(),
                  WiFi.dnsIP(0).toString().c_str(),
                  WiFi.dnsIP(1).toString().c_str());

    // DNS sunucularını AP (Erişim Noktası) tarafına aktar
    dhcpSoftAP.dhcps_set_dns(0, WiFi.dnsIP(0));
    dhcpSoftAP.dhcps_set_dns(1, WiFi.dnsIP(1));

    WiFi.softAPConfig(  // Android uyumlu google alanı ile AP'yi etkinleştir
      IPAddress(172, 217, 28, 254),
      IPAddress(172, 217, 28, 254),
      IPAddress(255, 255, 255, 0));
    WiFi.softAP(ap, pass);
    Serial.printf("AP IP: %s\n", WiFi.softAPIP().toString().c_str());

    Serial.printf("NAPT öncesi boş bellek: %d\n", ESP.getFreeHeap());
    err_t ret = ip_napt_init(NAPT, NAPT_PORT);
    Serial.printf("ip_napt_init(%d,%d): dönüş değeri=%d (OK=%d)\n", NAPT, NAPT_PORT, (int)ret, (int)ERR_OK);
    if (ret == ERR_OK) {
      ret = ip_napt_enable_no(SOFTAP_IF, 1);
      Serial.printf("ip_napt_enable_no(SOFTAP_IF): dönüş değeri=%d (OK=%d)\n", (int)ret, (int)ERR_OK);
      if (ret == ERR_OK) {
        Serial.printf("'%s' WiFi Ağına aynı şifre ile başarıyla NAT yapıldı (köprü kuruldu)", ssid.c_str());
      }
    }
    Serial.printf("NAPT kurulumu sonrası boş bellek: %d\n", ESP.getFreeHeap());
    if (ret != ERR_OK) {
      Serial.printf("NAPT kurulumu başarısız\n");
    }
    delay_time=200; // Bağlantı başarılıysa LED'i hızlıca (200ms) yakıp söndür
  }
  RepeaterIsWorking=true;
}

#else

void setup() {
  Serial.begin(115200);
  Serial.printf("\n\nNAPT bu donanım/yazılım yapılandırmasında desteklenmiyor.\n");
  RepeaterIsWorking= false;
  digitalWrite(LED_BUILTIN,1); // LED kapalı kalır
}

#endif

void loop() {
  // GÜVENLİ SIFIRLAMA: Parazit korumalı buton kontrolü
  if(digitalRead(0) == LOW){
    delay(100); // Filtre gecikmesi
    int basili_tutma_sayaci = 0;
    
    while(digitalRead(0) == LOW) {
      delay(100);
      basili_tutma_sayaci++;
      
      // Eğer buton aralıksız 3 saniye boyunca (30 * 100ms) basılı kaldıysa sil
      if(basili_tutma_sayaci > 30) { 
        Serial.println("Sıfırlama istendi: Hafıza temizleniyor...");
        LittleFS.format();
        delay(500);
        ESP.restart();
      }
    }
  }

  // LED Yanıp Sönme Rutini
  while(RepeaterIsWorking){
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= delay_time) {
      previousMillis = currentMillis;
      ledState = (ledState == LOW) ? HIGH : LOW;
      digitalWrite(LED_BUILTIN, ledState);
    }
    break;
  }
}

Daha sonra soldaki üç noktadan iki adet sekme daha ekleyelim adlarını da WM.cpp ve WM.h yapalım.

WM.h içine :

#ifndef WM_H
#define WM_H

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <FS.h>
#include <LittleFS.h>
//
//AsyncWebServer server(80);
//DynamicJsonDocument Config(2048);


#if (ARDDUINO >=100)
  #include "Arduino.h"
#endif

class WM {
  public:
  
//  JsonObject obj = Config.as<JsonObject>();
  void listDir(const char * dirname);
  void begin_server();
  void create_server();
  String get_credentials(int a);
  
};

#endif
WM.cpp içinede :

#include "WM.h"

AsyncWebServer server(80);
DynamicJsonDocument Config(2048);
JsonObject obj = Config.as<JsonObject>();

    void WM::begin_server(){
      server.begin();
    }
    void WM::listDir(const char * dirname) {
      Serial.printf("Dizin listeleniyor: %s\n", dirname);
      Dir root = LittleFS.openDir(dirname);
      while (root.next()) {
        File file = root.openFile("r");
        Serial.print("  DOSYA: ");
        Serial.print(root.fileName());
        Serial.print("  BOYUT: ");
        Serial.print(file.size());
        file.close();
      }
    }

    void WM::create_server() {
      server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
        String network_html = "";
        int n = WiFi.scanComplete();
        if (n == -2) {
          WiFi.scanNetworks(true);
        } else if (n) {
          for (int i = 0; i < n; ++i) {
            String router = WiFi.SSID(i);
            network_html += "<input type=\"radio\" id=\"#radiobuttonex\" name=\"ssid\" value=\"" + router + "\" required ><label for=\"html\">" + router + "</label><br>";
          }
          WiFi.scanDelete();
          if (WiFi.scanComplete() == -2) {
            WiFi.scanNetworks(true);
          }
        }

        String html = "<!DOCTYPE html><html lang=\"tr\">";
        html+= "<head><meta charset=\"UTF-8\"><link rel=\"stylesheet\" href=\"styles.css\"></head>";
        html+= "<body><div>";
        html+= "<h1>yenidir.com Menzil Genişletici Ayar Sayfası</h1>";
        html+= "<button onclick=\"window.location.href='/';\">Ağları Tara</button>";
        html+= "<p>Bulunan ağlar:</p>";
        html+= "<form action=\"/credentials\">";
        html+= "<p>Lütfen bir WiFi ağı seçin:</p>" + network_html;
        html+= "<input type=\"password\" id=\"pass\" name=\"pass\" value=\"\" required ><label for=\"pass\">Şifre</label><br><br>";
        html+= "<input type=\"text\" id=\"ap\" name=\"ap\" value=\"\" required ><label for=\"ap\">Yeni Erişim Noktası (A.P.) Adı:</label><br>";
        html+= "<input type=\"submit\" value=\"Kaydet ve Başlat\">";
        html+= "</form></body></html></div>";

        request->send(200, "text/html; charset=utf-8", html);
      });

      server.on("/styles.css", HTTP_GET, [](AsyncWebServerRequest * request) {
        String style = "#radiobuttonex{border: 2px solid rgb(255,1,199); text-align: center; font-family: sans serif; width: 305px; background: rgb(50,50,100); border-radius: 40px;}";
        request->send(200, "text/css", style);
      });

      // YENİ AYARLARI KAYDETME VE YENİDEN BAŞLATMA ALANI
      server.on("/credentials", HTTP_GET, [] (AsyncWebServerRequest * request) {
        String param = "ssid";
        if (request->hasParam(param)) { Config["ssid"] = request->getParam(param)->value(); }
        
        param = "pass";
        if (request->hasParam(param)) { Config["pass"] = request->getParam(param)->value(); }

        param = "ap";
        if (request->hasParam(param)) { Config["ap"] = request->getParam(param)->value(); }
        
        String output;
        serializeJson(Config, output);
        String path = "/config.json";

        File file = LittleFS.open(path, "w");
        if (!file) {
          Serial.println("Dosya yazma amacıyla açılamadı!");
          request->send(500, "text/plain", "Hata: Ayarlar kaydedilemedi.");
          return; // Hatalı return "null" kaldırıldı, fonksiyon güvenli bitiyor
        }
        
        if (file.print(output)) {
          Serial.println("Ayarlar başarıyla kaydedildi. Cihaz yeniden başlatılıyor...");
          // Kullanıcıya başarılı mesajı gönderiyoruz
          request->send(200, "text/html; charset=utf-8", "<h2>Ayarlar Kaydedildi!</h2><p>Cihaz 2 saniye icinde yeniden baslayacak ve yeni aga baglanacak.</p>");
          file.close();
          
          // Sunucunun yanıtı göndermesine zaman tanımak için 2 saniye sonra reset atıyoruz
          delay(2000);
          ESP.restart();
        } else {
          Serial.println("Yazma hatası!");
          request->send(500, "text/plain", "Yazma hatasi olustu.");
          file.close();
        }
      });
    }

    String WM::get_credentials(int a) {
      String path = "/config.json";
      String credentials = "";
      
      if (!LittleFS.exists(path)) {
        return "null";
      }

      File file = LittleFS.open(path, "r");
      if (!file) {
        return "null";
      }

      while (file.available()) {
        credentials += file.readString();
      }
      file.close();
      
      deserializeJson(Config, credentials);
      String credential_array [3] = {Config["ssid"], Config["pass"], Config["ap"]};
      return credential_array[a];
    }

Yazdıktan sonra projemizi derleyip esp8266 ya yükleyelim.

İlk çalıştığında AP yenidir.com a bağlanıp tarayıcıdan http://192.168.4.1/ adresine giriyoruz. Ağları taratıp bağlanacağımız ağı seçip şifresini ve AP adını yazarak kaydet e başlat butonuna basalım. Birkaç saniye sonra AP'miz aktifleşecek şifre bağlandığımız AP şifresi ile aynı olacak. Yaklaşık 4-5 Mbps hızında bir tekrarlayıcımız olacak. Fazla özelliği olmayan basit bir AP ama avantajı Arduino'dan kendi kodumuzu da ekleyebilmemiz. Bu sayede oldukça esnek bir AP yapmış olacağız.

İkinci yöntem olan firmware ile olanı bu konu çok uzun olduğundan  yeni bir konuda anlatacağım.

Zipli dosyalar:

wifi_extender.zip

💬 Yorumlar

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bir Yorum Bırakın

Güvenlik Kontrolü:

Yenidir.com
Sayfa Başı
Yenidir CMS V0.1