ESP32 DEVKIT V1 보드를 사놓은지 몇 년이 지났지만 삶이 바빠 처음 왔을 때만큼 확인을 못했다.

간간히 온도센서를 연결하고 라즈베리 파이에 온습도를 올려놓은 용도로 몇일사용해 본것이 전부다.

 

그러다 우연히 ESP32가 2개의 core를 가졌다는 것을 알게되었고 그래서 정보를 찾아 적용하게 되었다.

이번 코드는 2개의 Core중 첫번째 Core에는 WebServer를 돌리고 두번째 Core에서는 GPIO를 담당하게

했다.

이유는 첫번째 Core가 WiFi에 두번째 Core는 application에 우선순위를 두고 동작하기 때문이라고 해서

그렇게 정했다.

 

코드는 간단하게 WebServer를 구축하고 Web에 나오는 'here'를 눌러 보드의 LED를 On/Off 시키는

간단한 동작을 하는 것이다.

Arduino IDE의 시리얼 모니터를 켜면 보이는 IP를 Web browser 주소창에 넣으면 동작한다.

 

코드는 웹상에 있는 것을 그대로 실행했다가 에러가 너무 많아서 ESP32기본 WebServer를 기반으로

다시 재구성한 것이다.

 

 

/*
 * ESP32 DEVKIT V1
 * 
 * select -> Tools -> ESP32 Arduino -> DOIT ESP32 DEVKIT V1
 */
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const char* ssid = ".....";         // 사용하고 있는 공유기의 ssid를 넣는다.
const char* password = ".....";     // 사용하고 있는 공요기의 암호를 넣는다.
const int led = LED_BUILTIN;        // 보드에 있는 기본 LED

int led_value = 0;                  // LED 끄고(0), 켜기(1)
bool bCheck = false;                // LED 켜고끄는 동작이 제어

TaskHandle_t task0;                 // Core0번 핸들러
TaskHandle_t task1;                 // Core1번 핸들러
static uint8_t taskCoreZero = 0;    // Core0번 지정
static uint8_t taskCoreOne  = 1;    // Core1번 지정

WebServer server (80);              // 웹서버 port 80번으로 열기

void setup ()
{
  Serial.begin (115200);

  // prepare LED
  pinMode (led, OUTPUT);
  digitalWrite (led, 0);

  xTaskCreatePinnedToCore (
    work_wifi,     // 태스크 함수
    "Task0",       // 태스크 이름
    8192,          // 스택 크기(워드단위)
    NULL,          // 태스크 파라미터
    1,             // 태스크 우선순위 (0 a N)
    &task0,        // 태스크 핸들
    taskCoreZero); // 실행될 코어 (PRO_CORE for WIFI)

  xTaskCreatePinnedToCore (
    work_sensor,   // 태스크 함수
    "Task1",       // 태스크 이름
    8192,          // 스택 크기(워드단위)
    NULL,          // 태스크 파라미터
    1,             // 태스크 우선순위 (0 a N)
    &task1,        // 태스크 핸들
    taskCoreOne);  // 실행될 코어 (APP_CORE for application)
}

void loop ()
{
  // loop는 사용하지 않는다.
}

// web의 index.html과 같은 함수
void handleRoot ()
{
  char temp [512];

  snprintf(temp, 512, "<html>\
  <head>\
    <meta charset='UTF-8'>\
    <title>ESP32 Demo</title>\
    <style>\
      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
    </style>\
  </head>\
  <body>\
    <h1>Hello from ESP32!</h1>\
    <br /><br />\
    Click <a href='/gpio/on'>here</a> to switch LED GPIO on, or\
    <a href='/gpio/off'>here</a> to switch LED GPIO off.\
  </body>\
</html>");
  server.send(200, "text/html", temp);
}

// '/gpio/on' 을 눌렀을 때 대응하는 함수
void handleLedOn ()
{
  led_value = 1;      // LED 켜짐
  bCheck = true;      // LED 바꾸도록 설정
  Serial.println (F ("LED ON"));
  handleRoot ();
}

// '/gpio/off'를 눌렀을 때 대응하는 함수
void handleLedOff ()
{
  led_value = 0;      // LED 꺼짐
  bCheck = true;      // LED 바꾸도록 설정
  Serial.println (F ("LED OFF"));
  handleRoot ();
}

// 존재하지 않는 페이지를 선택했을 때 대응하는 함수
void handleNotFound()
{
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }

  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

// Core0용 함수
void work_wifi (void *parameter)
{
  // Connect to WiFi network
  Serial.println ();
  Serial.println ();
  Serial.print (F ("Connecting to "));
  Serial.println (ssid);

  WiFi.mode (WIFI_STA);
  WiFi.begin (ssid, password);

  // AP에 연결되길 기다림
  while (WiFi.status () != WL_CONNECTED)
  {
    delay (500);
    Serial.print (F ("."));
  }
  Serial.println ();
  Serial.println (F ("WiFi connected"));

  // Start the server
  server.on ("/", handleRoot);             // index.html
  server.on ("/gpio/on", handleLedOn);     // LED on을 선택했을 때 함수 지정
  server.on ("/gpio/off", handleLedOff);   // LED off를 선택했을 때 함수 지정
  server.onNotFound (handleNotFound);      // 없는 페이지 함수 지정
  server.begin ();
  Serial.println (F ("Server started!"));

  // Print the IP address
  Serial.println (WiFi.localIP ());

  while (1)
  {
    // Check if a client has connected
    server.handleClient();                 // client가 들어오는 것을 확인하기 위해서
    delay (10);
  }
}

void work_sensor (void *parameter)
{
  while (1)
  {
    // LED 값을 바꿨다면
    if (bCheck == true)
    {
      bCheck = false;                 // LED 바꿈 동작 중지 (한번만 하면 된다.)
      digitalWrite (led, led_value);  // LED 껴거나 끄기
      Serial.print (F ("LED : "));
      Serial.println (led_value);
    }
    delay (10);
  }
}

 

 

'ESP32' 카테고리의 다른 글

ESP32 and ST7789V2  (0) 2023.09.24
사용할 수 있는 PIN  (0) 2022.05.10
ESP32-CAM에서 카메라를 찾을 수 없을 때.  (0) 2021.12.30
Posted by codebank
,