본문 바로가기

ESP32

ESP32: Bluetooth를 사용하여 WiFi 연결 설정

반응형

 

 

ESP32: Bluetooth를 사용하여 WiFi 연결 설정

작성자 Majid Merati

 

 

소개

 

ESP32 마이크로컨트롤러의 끝없는 기능을 탐색하고 싶다면 올바른 곳에 왔습니다. 모든 ESP32 기반 보드에는 내장 WiFi와 Bluetooth가 제공됩니다. WiFi를 사용하면 ESP32가 인터넷에 연결하여 다른 장치와 통신할 수 있고 Bluetooth는 ESP32와 다른 Bluetooth 지원 장치 간의 무선 통신을 용이하게 합니다.

 

이 단계별 자습서에서는 Bluetooth를 사용하여 ESP32에서 WiFi를 구성하는 방법을 알아봅니다. 초보자이든 경험이 많든 이 자습서를 읽은 후에는 ESP32를 인터넷에 손쉽게 연결하여 모든 잠재력을 활용할 수 있습니다.

 

 

학습할 내용

  • ESP32의 내장 Bluetooth를 사용한 데이터 전송.
  • WiFi 구성을 위한 Bluetooth 데이터 사용.

 

Bluetooth를 사용하여 ESP32 WiFi를 구성하는 이점

 

여러 이점이 있습니다. 첫째, 초기 WiFi 구성을 위해 ESP32를 컴퓨터에 물리적으로 연결할 필요가 없습니다. (이 기능은 특히 ESP32가 장치에 내장되어 있거나 도달할 방법이 없는 경우에 유용합니다.) 또한 WiFi 설정을 수정할 때 ESP32를 다시 프로그래밍할 필요가 없습니다.

 

이러한 유연성은 특히 WiFi 네트워크가 크게 변경되는 환경에서 매우 중요합니다.

 

필요한 자료

 

하드웨어 구성 요소

ESP32-WROOM × 1

Android 휴대전화 × 1

 

소프트웨어 앱

 

Arduino IDE

Serial Bluetooth Terminal(Android)

 

Bluetooth로 ESP32 WiFi 제어

 

1단계: "Serial Bluetooth Terminal" 앱 설치

 

먼저 Google Play에서 Serial Bluetooth Terminal을 설치해야 합니다.

 

 

2단계: ESP32에 코드 업로드

 

먼저 Arduino IDE에 ESP32 애드온 라이브러리를 설치합니다. 그런 다음 아래 코드를 ESP32에 업로드합니다.

 

#include "BluetoothSerial.h"
#include <WiFi.h>

//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below
const char *pin = "1218"; // Change this to more secure PIN.

String device_name = "ESP32-BT-WIFI-CONTROLLER";
BluetoothSerial SerialBT;

int i = 0;
String incoming_char;
String SSIDIN;
String PASSIN;
String header;
String ssids_array[50];
String network_string;
String connected_string;

int startchar;
int endchar;

long start_wifi_millis;
long wifi_timeout = 10000;

void setup() {
 	//pinMode(LED_BUILTIN, OUTPUT);
 	Serial.begin(115200);
	// Initialize the output variables as outputs

	SerialBT.begin(device_name); //Bluetooth device name
	Serial.printf("Device name: \"%s\"\n", device_name.c_str());
 	//Serial.printf("The device with name \"%s\" and MAC address %s is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str(), SerialBT.getMacString()); // Use this after the MAC method is implemented
 	/*#ifdef USE_PIN
 	SerialBT.setPin(pin);
 	Serial.println("Using PIN");
 	#endif*/
 	while (!(SerialBT.available()));
 	SerialBT.println("Scanning Wi-Fi networks");
 	Serial.println("Scanning Wi-Fi networks");
 

 	scan_wifi_networks();
A:
 	SerialBT.println("Please enter the name of your WiFi.");
 	while (!(SerialBT.available()));
 	while (SerialBT.available()) {
 	char c = SerialBT.read();
 	incoming_char += c;
 	Serial.write(c);
 	}
 	if (incoming_char.indexOf("ssid:") >= 0)
 	{
 		startchar = incoming_char.indexOf('<') + 1;
 		endchar = incoming_char.indexOf('>', startchar);
 		for (int i = startchar; i < endchar; i++)
 			SSIDIN += incoming_char[i];
 		Serial.println(SSIDIN);
 	}
 	else
 	{
 		SerialBT.println("Error:Enter SSID with following format -> ssid:...");
 		goto A;
 	}
 	incoming_char = "";
 	SerialBT.println("Please enter the password of your WiFi.");
 	while (!(SerialBT.available()));
 	while (SerialBT.available()) {
 	char c = SerialBT.read();
 	incoming_char += c;
 	Serial.write(c);
 	}
 	if (incoming_char.indexOf("pass:") >= 0)
 	{
 		int startchar2 = incoming_char.indexOf('<') + 1;
 		int endchar2 = incoming_char.indexOf('>', startchar2);
 		for (int i = startchar2; i < endchar2; i++)
 			PASSIN += incoming_char[i];
 		Serial.println(PASSIN);
 	}
 	else
 	{
 		SerialBT.println("Error:Enter Pass with following format -> pass:...");
 		goto A;
 	}
 	delay(500);

 	SerialBT.println("Please wait for Wi-Fi connection...");
 	Serial.println("Please wait for Wi_Fi connection...");
 	//disconnect_bluetooth();

 	start_wifi_millis = millis();
 	const char* ssid = SSIDIN.c_str();
 	const char* password = PASSIN.c_str();
 	WiFi.begin(ssid, password);
 	while (WiFi.status() != WL_CONNECTED) {
 		delay(500);
 		Serial.print(".");
 		if (millis() - start_wifi_millis > wifi_timeout) {
 			WiFi.disconnect(true, true);
 			SerialBT.println("Could't connect to Wi-Fi...");
 			Serial.println("Could't connect to Wi-Fi...");
 		}
 	}
 	SerialBT.println("Connected");
 	Serial.println("Connected");

 	SerialBT.print("ESP32 IP: ");
 	SerialBT.println(WiFi.localIP());
 	Serial.print("ESP32 IP: ");
 	Serial.println(WiFi.localIP());

 	incoming_char = "";
 	SSIDIN = "";
 	PASSIN = "";
 	//while (1);
}

void scan_wifi_networks()
{
 	WiFi.mode(WIFI_STA);
 	// WiFi.scanNetworks will return the number of networks found
 	int n = WiFi.scanNetworks();
 	if (n == 0) {
 		SerialBT.println("no networks found");
 	} 
    else 
    {
 		SerialBT.println();
 		SerialBT.print(n);
 		SerialBT.println(" networks found");
 		delay(1000);
 		for (int i = 0; i < n; ++i) {
 			ssids_array[i + 1] = WiFi.SSID(i);
 			Serial.print(i + 1);
 			Serial.print(": ");
 			Serial.println(ssids_array[i + 1]);
 			network_string = i + 1;
 			network_string = network_string + ": " + WiFi.SSID(i) + " (Strength:" + WiFi.RSSI(i) + ")";
 			SerialBT.println(network_string);
 		}
 	}
}

void disconnect_bluetooth()
{
 	delay(1000);
 	Serial.println("BT stopping");
 	SerialBT.println("Bluetooth disconnecting...");
 	delay(1000);
 	SerialBT.flush();
 	SerialBT.disconnect();
 	SerialBT.end();
 	Serial.println("BT stopped");
 	delay(1000);
}

void loop() {
 	delay(1000);
}

 

간단히 말해서 코드:

 

• ESP32와 Android 스마트폰 간에 양방향 Bluetooth 통신을 설정합니다.

• ESP32 Bluetooth에 연결된 사용자에게 SSID와 WiFi 비밀번호를 입력하라는 메시지를 표시합니다.

• ESP32에서 Bluetooth에서 수신한 데이터를 처리합니다.

• WiFi를 구성하고 연결합니다.

 

코드 크래킹

 

먼저 ESP32 Bluetooth 및 WiFi에 설치된 라이브러리를 포함합니다.

 

#include "BluetoothSerial.h"
#include <WiFi.h>

 

다음으로 Bluetooth(ESP32에서 생성)의 이름을 선택한 후 해당 Bluetooth의 "인스턴스"를 정의합니다.

 

String device_name = "ESP32-BT-WIFI-CONTROLLER";
BluetoothSerial SerialBT;

 

이 함수는 먼저 115200의 전송 속도로 직렬 통신을 설정합니다.

 

Serial.begin(115200);

 

다음으로 ESP32 Bluetooth를 활성화합니다.

 

SerialBT.begin(device_name);

 

이제 WiFi를 설정하고 주변 네트워크를 스캔하여 SSID 이름과 신호 강도를 직렬 모니터에 표시하고 Bluetooth 모듈에 연결된 기기로 전송합니다.

 

scan_wifi_networks(); 

 

위 함수의 코드는 다음과 같습니다.

 

void scan_wifi_networks()
{
 	WiFi.mode(WIFI_STA);
 	// WiFi.scanNetworks will return the number of networks found
 	int n = WiFi.scanNetworks();
 	if (n == 0) {
 	SerialBT.println("no networks found");
 	} 
    else 
    {
 		SerialBT.println();
 		SerialBT.print(n);
 		SerialBT.println(" networks found");
 		delay(1000);
 		for (int i = 0; i < n; ++i) {
 			ssids_array[i + 1] = WiFi.SSID(i);
 			Serial.print(i + 1);
 			Serial.print(": ");
 			Serial.println(ssids_array[i + 1]);
 			network_string = i + 1;
 			network_string = network_string + ": " + WiFi.SSID(i) + " (Strength:" + WiFi.RSSI(i) + ")";
 			SerialBT.println(network_string);
 		}
 	}
}

 

여기서 ESP32 WiFi의 작동 모드가 선택되었으며 여기에는 다음이 포함됩니다.

 

• Station: ESP32가 액세스 포인트(예: 라우터)에 연결됩니다.

• Access Point(핫스팟): 다른 기기가 WiFi를 통해 ESP32에 연결할 수 있습니다.

• Access Point & Station: ESP32는 액세스 포인트 역할을 하면서 다른 액세스 포인트에 Station으로 연결합니다.

 

Station 모드를 사용하여 ESP32 보드를 인터넷에 연결하여 로컬 네트워크를 통해 액세스할 수 있습니다. 이 모드에서 라우터는 액세스 포인트 역할을 하고 ESP32는 Station 역할을 합니다.

 

마지막으로 "scan-wifi_networks" 함수는 검색된 WiFi 네트워크 수와 해당 사양(SSID 및 신호 강도)을 직렬 모니터에 인쇄합니다.

 

다음으로, Bluetooth를 통해 사용자에게 WiFi 네트워크의 SSID를 입력하라는 메시지를 보냅니다.

 

SerialBT.print(""WiFi 이름을 입력하세요." "); 

 

여기서 ESP32를 사용하여 SSID와 PASS가 포함된 문자열을 수신한 다음 "incoming_char" 문자열에 저장합니다.

 

while (SerialBT.available()) {
    char c = SerialBT.read();
    incoming_char += c;
    Serial.write(c);
  }

 

 

그런 다음 "incoming_char" 문자열이 올바르게 포맷되었는지 확인합니다.

 

if (incoming_char.indexOf("ssid:") >= 0)
 {
 startchar = incoming_char.indexOf('<') + 1;
 endchar = incoming_char.indexOf('>', startchar);
 for (int i = startchar; i < endchar; i++)
 SSIDIN += incoming_char[i];
 Serial.println(SSIDIN);
 }

 

Bluetooth 메시지에 "SSID:"라는 단어가 포함되어 있으면 '<'와 '>' 문자 사이에 있는 WiFi 네트워크 이름을 추출하여 SSIDIN 문자열에 저장합니다.

 

전송된 텍스트에 "SSID"가 포함되어 있지 않으면 사용자에게 데이터 전송 형식을 따르도록 요청하고 프로그램을 지점 A로 반환하여 해당 줄에서 반복합니다.

 

else
 {
 SerialBT.println("Enter SSID with following format -> ssid:...");
 goto A;
 }

 

지점 A는 Wi-Fi 사양을 수신하기 시작하는 곳입니다.

 

그런 다음 Bluetooth 포트에 다음 문장을 인쇄하여 사용자에게 원하는 Wi-Fi 비밀번호를 입력하도록 요청합니다.

 

SerialBT.println("WiFi 비밀번호를 입력하세요."); 

 

SSID에서 한 것과 동일한 작업을 PASS에 대해서도 수행합니다.

 

if (incoming_char.indexOf("pass:") >= 0)
 {
 int startchar2 = incoming_char.indexOf('<') + 1;
 int endchar2 = incoming_char.indexOf('>', startchar2);
 for (int i = startchar2; i < endchar2; i++)
 PASSIN += incoming_char[i];
 Serial.println(PASSIN);
 }
 else
 {
 SerialBT.println("Enter Pass with following format -> pass:...");
 goto A;
 }

 

이제 Bluetooth를 통해 수신된 데이터에 따라 ESP32 WiFi 네트워크를 구성할 시간입니다.

 

WiFi.begin(ssid, password);

 

그런 다음 코드는 10초 동안 연결 상태를 확인합니다. ESP32가 인터넷에 연결하지 못하면 오류 메시지가 직렬 모니터에 인쇄된 다음 Bluetooth 모듈에 연결된 장치로 전송됩니다.

 

while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 if (millis() - start_wifi_millis > wifi_timeout) {
 WiFi.disconnect(true, true);
 SerialBT.println("Could't connect to Wi-Fi...");
 Serial.println("Could't connect to Wi-Fi...");
 }
 }

 

Arduino 연결이 성공적으로 이루어지면 "Connected"라는 단어가 인쇄됩니다.

 

SerialBT.println("Connected");

Serial.println("Connected");

 

마지막으로 ESP32 모듈의 IP가 사용자에게 표시됩니다.

 

SerialBT.print("ESP32 IP: ");
  SerialBT.println(WiFi.localIP());
  Serial.print("ESP32 IP: ");
  Serial.println(WiFi.localIP());

 

팁:

 

ESP32 기반 모듈에서는 Bluetooth와 WiFi 무선 시스템을 공유하므로 두 연결을 동시에 활성화하면 오작동이 발생할 수 있습니다. Wi-Fi를 통해 데이터(예: 이미지)를 보내려면 Wi-Fi 네트워크에 연결한 후 Bluetooth 연결을 끊습니다. Bluetooth를 끊으려면 코드의 88번째 줄의 주석 처리를 제거합니다.

 

//disconnect_bluetooth();

 

아래 함수를 사용하여 먼저 ESP32 보드와 사용자 간의 Bluetooth 통신을 끊은 다음 Bluetooth 모듈과의 Bluetooth 통신을 끊습니다.

 

void disconnect_bluetooth()
{
  delay(1000);
  Serial.println("BT stopping");
  SerialBT.println("Bluetooth disconnecting...");
  delay(1000);
  SerialBT.flush();
  SerialBT.disconnect();
  SerialBT.end();
  Serial.println("BT stopped");
  delay(1000);
}

 

3단계: 실행해 보겠습니다!

 

ESP32에 앱을 업로드한 후 휴대전화에서 Bluetooth를 켜고 ESP32-BT-Slave에 연결합니다. 주석 처리되지 않은 4번째 줄이 있는 경우 코드를 입력하라는 메시지가 표시되고, 연결을 설정하려면 1218이라는 숫자를 입력해야 합니다. 이제 Serial Bluetooth Terminal 앱을 실행할 차례입니다. 아래에 표시된 순서대로 1~3까지의 숫자를 탭하기만 하면 됩니다. ESP32 Bluetooth에 성공적으로 연결되면 섹션 4에 텍스트가 표시됩니다.

 

 

"Connected"라는 단어가 표시되면 ESP32에 문자를 보냅니다. 앱에 주변의 활성 WiFi 네트워크가 표시됩니다.

 

 

이제 사용 가능한 네트워크 중 하나를 선택하고 다음 형식으로 SSID와 비밀번호를 별도로 입력합니다.

 

ssid:<여기에 ssid를 입력하세요>

 

pass:<여기에 비밀번호를 입력하세요>

 

모든 단계를 올바르게 수행했다면 ESP32가 WiFi 네트워크에 연결되고 직렬 포트와 Bluetooth를 통해 IP 주소가 표시됩니다.

 

 

 

 

팁:

 

WiFi와 Bluetooth 신호는 서로 간섭할 수 있습니다. 따라서 ESP32를 강력한 WiFi 또는 Bluetooth 신호를 방출하는 기기에서 멀리하는 것이 가장 좋습니다.

 

다음은 무엇일까요?

 

이 튜토리얼에서는 ESP32와 통신하고 Bluetooth를 통해 데이터를 송수신하는 과정과 초기 WiFi 설정을 구성하는 방법을 다루었습니다.

 

이 튜토리얼과 약간의 창의성을 활용하면 다음 기능으로 프로젝트를 개선할 수 있습니다.

 

1. 암호화 또는 인증과 같은 보안 통신 프로토콜을 구현하여 WiFi 구성 정보를 보호합니다.

2. 도구 또는 자동화 스크립트를 활용하여 WiFi 구성 프로세스를 자동화합니다.

3. WiFi 구성 코드에서 오류 처리 및 복구를 위한 메커니즘을 구현합니다.

 

이러한 팁을 사용하면 ESP32에서 WiFi 구성 프로세스를 최적화할 수 있습니다.

 

또한 액세스 포인트 및 액세스 포인트 및 스테이션과 같은 ESP32의 다른 WiFi 모드를 살펴볼 수 있습니다. 액세스 포인트 모드를 사용하면 ESP32를 라우터로 전환하고 다른 ESP32 또는 Android 휴대전화와 같은 기기에서 Bluetooth를 통해 SSID와 비밀번호를 구성할 수 있습니다.

 

또는 Bluetooth와 결합된 Access Point & Station 모드를 사용하면 Bluetooth를 통해 광범위하고 구성 가능한 WiFi 네트워크를 만들 수 있습니다.

 

세 가지 모드 모두에서 서버를 설정하고 다양한 모듈을 ESP32 보드에 연결하여 원하는 데이터를 업로드하고 원격으로 볼 수 있습니다. 

 

이 문서의 원문을 보시려면 언제나 그렇듯이 다름 링크를 따라가세요. 배움을 멈추지 마세요.

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^