본문 바로가기
하드웨어/아두이노

[아두이노] ESP32 블루투스로 SSID 업데이트하기(EEPROM 이용)

by 만들오 2021. 5. 23.
728x90

1. 서론

  지난 글에서 EEPROM을 이용해 기록하는 방법을 알아보았습니다.

2021.05.22 - [아두이노] - [아두이노] ESP 보드 EEPROM 사용하기

 

[아두이노] ESP 보드 EEPROM 사용하기

1. 서론 ESP계열 보드의 EEPROM이란, 하드디스크처럼 저장할 수 있는 공간을 말합니다. 전원을 끄거나 스케치를 바꿔도 남아있기 때문에 중요한 정보를 기록할 수 있습니다. 저는 Wifi에 접속하기 위

mandloh.tistory.com

 

오늘은 ESP32의 Bluetooth 기능을 이용해 SSID와 비밀번호를 업데이트하는 코드를 공유합니다.


2. 본론

  사용한 MCU는 WEMOS D1 MINI ESP32 보드 입니다.

WEMOS D1 MINI ESP32 보드

#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "EEPROM.h"
#include "BluetoothSerial.h"

BluetoothSerial SerialBT;
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<html>

<head>
    <title>WebRTC with fabric.js</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tweakpane@2.3.0/dist/tweakpane.min.js"></script>

<body>
    <video id="video" width="640" height="480" style="display:none"></video>
    <canvas id="canvas" width="640" height="480"></canvas>
    <div id="container" style="float:left; width:300px"></div>
    <script>
        //Fixed video & canvas size to 640x480.
        let stream;
        const videoElement = document.getElementById('video');
        const video = new fabric.Image(videoElement, { objectCaching: false });
        const canvas = new fabric.Canvas('canvas');
        canvas.selection = false;
        fabric.util.requestAnimFrame(function render() {
            canvas.renderAll();
            fabric.util.requestAnimFrame(render);
        });

        const stopRtc = () => { if (stream) stream.getTracks().forEach(track => track.stop()) }
        const runRtc = (constraints) => {
            stopRtc();
            navigator.mediaDevices.getUserMedia(constraints)
                .then(mediaStream => {
                    stream = window.stream = mediaStream;
                    videoElement.srcObject = mediaStream;
                    videoElement.play();
                    canvas.setBackgroundImage(video);
                })
                .catch(e => console.log(e));
        }
        const setConstraints = (w, h, camera_dir) => {
            const constraints = {
                audio: false,
                video: {
                    facingMode: { exact: camera_dir },
                    width: { exact: w },
                    height: { exact: h },
                }
            };
            return constraints;
        }

        const pane = new Tweakpane({container: document.getElementById("container")});
        const params = {
            rtcCamera: "",
            imgSrc: "http://192.168.0.10:4747/video",
        };
        const videoFolder = pane.addFolder({ title: "Video Setting" });
        const rtcFolder = videoFolder.addFolder({ title: "WebRTC" });
        rtcFolder.addInput(params, "rtcCamera", {
            label: "Camera",
            options: {
                Front: "user",
                Rear: "environment",
            }
        });
        rtcFolder.addButton({ title: "Start Streaming" }).on("click", () => {
            setSrc("");
            runRtc(setConstraints(640, 480, params.rtcCamera));
        });
        rtcFolder.addButton({ title: "Stop Streaming" }).on("click", () => stopRtc());
        const setSrc = (src) => {
            canvas.setBackgroundImage(src, canvas.renderAll.bind(canvas));
        }
        const tagFolder = videoFolder.addFolder({title: "Html Tag Streaming"});
        tagFolder.addInput(params, "imgSrc");
        tagFolder.addButton({title: "Start Streaming"}).on("click", () => {
            stopRtc();
            setSrc(params.imgSrc);
        });
        tagFolder.addButton({title: "Stop Streaming"}).on("click", () => setSrc(""));
    </script>
</body>

</html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32");
  EEPROM.begin(100);
  String EEPROM_SSID = EEPROM.readString(0);
  String EEPROM_PWD = EEPROM.readString(20);
  EEPROM_SSID.trim();
  EEPROM_PWD.trim();
  const char* ssid = EEPROM_SSID.c_str();
  const char* password = EEPROM_PWD.c_str();
  
  Serial.print("SSID: ");
  Serial.println(ssid);
  Serial.print("Password: ");
  Serial.println(password);
  
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  server.begin();
}

void loop() {
  if (SerialBT.available()) {
    String msg = SerialBT.readStringUntil('\n');
    int index = msg.indexOf(",");
    if (index > 0) {
      String ssid = msg.substring(0, index);
      String pwd = msg.substring(index+1, msg.length());
      EEPROM.writeString(0, ssid);
      EEPROM.writeString(20, pwd);
      EEPROM.commit();
      Serial.print("New SSID: ");
      Serial.println(ssid);
      Serial.print("New Password: ");
      Serial.println(pwd);
    }
  }
  delay(5000);
}

 

주요코드에 대한 설명을 주석으로 남겼습니다.

#include "EEPROM.h" //EEPROM 라이브러리 호출
#include "BluetoothSerial.h" //블루투스 클래식 라이브러리 호출
BluetoothSerial SerialBT; //블루투스 시리얼 선언
SerialBT.begin("ESP32"); //블루투스 이름을 ESP32로 설정
EEPROM.begin(100); //EEPROM의 메모리 주소 중 100까지 사용
String EEPROM_SSID = EEPROM.readString(0); //EEPROM 주소 0부터 SSID를 읽기
String EEPROM_PWD = EEPROM.readString(20); //EEPROM 주소 20부터 저장된 비밀번호 읽기
EEPROM_SSID.trim(); //혹시라도 있을 공백을 제거
EEPROM_PWD.trim();
const char* ssid = EEPROM_SSID.c_str(); //String 타입을 char*로 변경
const char* password = EEPROM_PWD.c_str();

//읽어온 SSID와 비밀번호를 출력
Serial.print("SSID: "); 
Serial.println(ssid);
Serial.print("Password: ");
Serial.println(password);
if (SerialBT.available()) {
    String msg = SerialBT.readStringUntil('\n'); //블루투스 시리얼 읽기
    int index = msg.indexOf(","); // 쉼포(,)로 분리
    if (index > 0) {
      String ssid = msg.substring(0, index); //쉼표의 앞부분을 ssid로 저장
      String pwd = msg.substring(index+1, msg.length()); //쉼표의 뒷부분을 비밀번호로 저장
      EEPROM.writeString(0, ssid);
      EEPROM.writeString(20, pwd);
      EEPROM.commit();
      Serial.print("New SSID: ");
      Serial.println(ssid);
      Serial.print("New Password: ");
      Serial.println(pwd);
    }
  }

블루투스 시리얼로 SSID와 비밀번호 업데이트 예

  • SSID : MANDLOH
  • PASSWORD : 123456
  • 적용 예 : MANDLOH,123456

업데이트 한 후 재부팅하면, 저장된 내용으로 적용이 됩니다.


3. 결론

  WEMOS D1 MINI ESP32 보드의 블루투스 기능으로, EEPROM에 SSID와 비밀번호를 변경 적용하는 코드를 공유했습니다. 이 보드는 USB 포트가 있기 때문에 쉽게 코드를 업데이트 할 수 있지만,

ESP32-CAM 보드는 별도의 FTDI가 있어야 하기 때문에 이 기능을 적용하려 했습니다. 하지만 동영상 스트리밍 서버를 구동하며 블루투스 기능을 켜니 제대로 작동하지 않는 문제가 있어 다른 방법을 찾아야 하겠습니다.

ESP32-CAM에 적용하시려는 분들은 이 내용을 참고해 주시기 바랍니다.

[끝].

댓글