본문 바로가기
...

[ESP-8266 가지고 놀기 Ep.4] 7세그먼트 + WiFi WebServer

by GGoris 2022. 3. 29.
반응형

 

https://wowan.tistory.com/166

 

[ESP-8266 가지고 놀기 Ep.3] 7세그먼트 컨트롤

브레드보드에 ESP8266과 7세그먼트를 위 그림처럼 연결해주고 아래와 같이 코드를 작성 const long interval = 10000; bool isSleep=false; const int SegmentPin[]={14,16,4,0,2,12,13,5}; const int PinData[11..

wowan.tistory.com

보드연결 방식은 앞서 해보았던 그대로를 사용했다.

다만 기존코드를 약간 수정하고 웹페이지를 컨트롤 가능하게끔 변경시켜주었다.

 

아래는 완전한 코드.

 

Web_7segment_Ctrl.ino

#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <Arduino.h>
#include <datas.h>

#define PORT 8266                    //외부접속을 위한 포트
IPAddress local_IP(192, 168, 0, ***); //고정 IP를 위한 ip값
IPAddress gateway(192, 168, 1, 1);   //게이트웨이
IPAddress subnet(255, 255, 0, 0);    //넷마스크

int i = 0;
const char *ssid = "your-wifi-ssid";          //와이파이 이름
const char *password = "your-wifi-password"; // 비밀번호

AsyncWebServer server(PORT);

const long interval = 10000; // 10초. milliseconds
unsigned long previousMillis = 0; // 시간차이 계산을 위한 변수
bool isSleep = false;  // 10초 미입력 flag.

bool isLEDOn = true;  // LED On/Off flag.
const int SegmentPin[] = {14, 16, 4, 0, 2, 12, 13, 5}; // 각 세그먼트에 매칭되는 GPIO핀번호
const int PinData[11][8] = {
    {1, 1, 1, 1, 1, 1, 0, 1},
    {0, 1, 1, 0, 0, 0, 0, 0},
    {1, 1, 0, 1, 1, 0, 1, 1},
    {1, 1, 1, 1, 0, 0, 1, 0},
    {0, 1, 1, 0, 0, 1, 1, 1},
    {1, 0, 1, 1, 0, 1, 1, 0},
    {1, 0, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 0, 0, 1, 0, 0},
    {1, 1, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 1, 0, 1, 1, 0},
    {0, 0, 0, 0, 0, 0, 1, 1}}; // 숫자를 출력하기위한 세그먼트의 값들

String inputMessage = "-1"; // 숫자를 저장하기위한변수
void setSegment(int num)
{
    if (isLEDOn)
    {
        if (num < 0 || num > 9)
        {
            for (int i = 0; i < 9; i++)
            {
                digitalWrite(SegmentPin[i], LOW);
            }
            return;
        }
        int data[8] = {};
        for (int i = 0; i < 9; i++)
        {
            digitalWrite(SegmentPin[i], PinData[num][i] == 1 ? LOW : HIGH);
        }
    }
}
void notFound(AsyncWebServerRequest *request)
{
    request->send(404, "text/plain", "Not found");
}

void aWake()
{
    previousMillis = millis();
    isSleep = false;
}

//기본 초기화 함수
void setup()
{
    Serial.begin(9600);
    Serial.println("Start Setup");
    for (int i = 0; i < 9; i++)
    {
        pinMode(SegmentPin[i], OUTPUT);
    }

    for (int i = 0; i < 9; i++)
    {
        digitalWrite(SegmentPin[i], LOW);
    }

    if (!WiFi.config(local_IP, gateway, subnet))
    {
        Serial.println("STA Failed to configure");
    }

    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    server.on("/", [](AsyncWebServerRequest *request)
              {
    aWake();
    Serial.println("You called root page");
    request->send_P(200, "text/html", index_html); });

    server.on("/ledOn", [](AsyncWebServerRequest *request)
              {
    aWake();
    isLEDOn=true;
    setSegment(inputMessage.toInt());
    Serial.println("LED on page");
    request->send_P(200, "text/html", "ON"); });

    server.on("/ledOff", [](AsyncWebServerRequest *request)
              {
    aWake();
    for(int i=0; i<9; i++){
      digitalWrite(SegmentPin[i], HIGH);  
    }
    isLEDOn=false;
    Serial.println("LED off page");
    request->send_P(200, "text/html", "OFF"); });

    server.on("/NumPad", HTTP_GET, [](AsyncWebServerRequest *request)
              {
    aWake();
    Serial.print("Numpad Clicked : ");
    
    String inputParam;
    if (request->hasParam("num")) {
      inputMessage = request->getParam("num")->value();
      inputParam = "num";
    }else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    setSegment(inputMessage.toInt());
    request->send(200, "text/html", inputMessage); });

    server.onNotFound(notFound);
    server.begin();
}
//기본 루핑 함수
void loop()
{
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval)
    {
        previousMillis = currentMillis;
        isSleep = true;
    }
    if (isSleep && isLEDOn)
    {
        int num = (((currentMillis - previousMillis) / 1000) % 10);
        inputMessage = String(num);
        setSegment(num);
    }
}

웹페이지 소스는 datas.h로 헤더파일을 만들어 따로 만들어주었다.

 

datas.h

#ifndef datas_H
#define datas_H

//웹페이지 소스
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
  <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
  .button { background-color: #195B6A; border: none; color: white; padding: 8px 20px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
  .button2 { background-color: #77878A; border: none; color: white; padding: 8px 20px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
  .wrapper{
    display: grid;
    grid-template-columns: 50px 50px 50px;
    grid-template-rows: 50px 50px 50px;
    font-size: 30px;
    width:150px;
    height:190px;
    margin: 0px auto;
  }
  .g1{
    background-color: #eeeeee;
  }
  .g0{
    grid-column-start: 1;
    grid-column-end: 4;
    background-color: #eeeeee;
  }</style>
   
  <body>
    <center>
      <h1>WiFi LED ON/OFF with 7Segments</h1><br>
      <p><button id="b2" onClick="b2()" class="button" hidden> ON</button></p>
      <p><button id="b1" onClick="b1()" class="button2" > OFF</button></p>
      <div><p>LED Status : <iframe id="StatusFrame" name="StatusFrame" width="50" height="25" frameBorder="0" scrolling="no" ></iframe></p>
      <p>NumPad Status : <iframe id="NumPadFrame" name="NumPadFrame" width="50" height="25" frameBorder="0" scrolling="no" ></iframe></p></div>
      <p><div class="wrapper">
        <button class="g1" id="num1" onClick="numpad(1)">1</button>
        <button class="g1" id="num2" onClick="numpad(2)">2</button>
        <button class="g1" id="num3" onClick="numpad(3)">3</button>
        <button class="g1" id="num4" onClick="numpad(4)">4</button>
        <button class="g1" id="num5" onClick="numpad(5)">5</button>
        <button class="g1" id="num6" onClick="numpad(6)">6</button>
        <button class="g1" id="num7" onClick="numpad(7)">7</button>
        <button class="g1" id="num8" onClick="numpad(8)">8</button>
        <button class="g1" id="num9" onClick="numpad(9)">9</button>
        <button class="g0" id="num0" onClick="numpad(0)">0</button>
      </div></p>
     <script>
		
		var StatusFrame=document.getElementById("StatusFrame");
		var NumPadFrame=document.getElementById("NumPadFrame");
		StatusFrame.contentWindow.document.open();
		StatusFrame.contentWindow.document.write('<body>OFF</body>');
		StatusFrame.contentWindow.document.close();
		
		NumPadFrame.contentWindow.document.open();
		NumPadFrame.contentWindow.document.write('<body>-</body>');
		NumPadFrame.contentWindow.document.close();
		
		function b1() {
		  document.getElementById("b1").hidden = true;
		  document.getElementById("b2").hidden = false;
		  StatusFrame.src = "/ledOff";
		}
		function b2() {
		  document.getElementById("b1").hidden = false;
		  document.getElementById("b2").hidden = true;
		  StatusFrame.src = "/ledOn";
		}
		function numpad(i){
		  NumPadFrame.src = "/NumPad?num="+i;
		}
	</script>
      <hr>
      <a href="https://wowan.tistory.com">wowan.tistory.com</a>
    </center>
  </body>
</html>)rawliteral";

#endif

 

이제 업로드를 해주면...

 

7Segment web ctrl with esp8266 2배속영상.

숫자를 누르면 표기가 되고 On/Off를 통해 세그먼트 전체를 껏다켯다한다.

inputMessage변수를 통해 입력받은 값을 유지한다.

 

 

성공!

 

 

 

 

 

반응형

댓글