esp32 + oled 보드에 한글과 web을 올리고 free rtos 를 사용했다.

 

컴파일을 하기위헤서는 라이브러리를 링크 해야 한다.

 

 

 

 

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

 

#include <Wire.h>
#include <SPI.h>

 

#include "ASCFont.h"
#include "KSFont.h"

 

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

 

#define OLED_PCLK     18
#define OLED_PDATA    23
#define OLED_PRESET   17
#define OLED_PCMD     16
#define OLED_PCS     5

#define LED 2

 

//----- Graphic define
#define NUMFLAKES 10
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };


byte HANFontImage[32] = {0, };

 

//HW SPI
Adafruit_SSD1306 display(OLED_PCMD, OLED_PRESET, OLED_PCS); //DC, RST, CS
String inputString;

 

//----- FreeRtos
QueueHandle_t queue;
int queueSize = 10;

 

QueueHandle_t xQueue;

 

typedef struct{
  int sender;
  int counter;
}Data;

 

// 세마포어 핸들을 선언합니다.->선언될때만 TASK 실행
SemaphoreHandle_t sem;


//------ Web define
const char *ssid =  "ssid";     // replace with your wifi ssid and wpa2 key
const char *pass =  "pass";

 

WiFiClient client;

WiFiServer server(80);

 

//The setup function is called once at startup of the sketch
void setup()
{
 // Add your initialization code here
 pinMode(LED, OUTPUT);

 Serial.begin(115200);
 delay(10);

 

    //--------------------------------
    //OLED OUTPUT

    display.begin(SSD1306_SWITCHCAPVCC); //SPI


    display.display();  //diplay output
    delay(2000);
    display.clearDisplay(); // Clear the buffer.

 

    inputString="*--동작 시작--*" ;

    char paramChar[inputString.length()+1];
    inputString.toCharArray(paramChar,inputString.length()+1);
    matrixPrint(0,0,paramChar);
    display.display();  //diplay output

    //--------------------------------

    //Web init
    WiFi.begin(ssid, pass);

    while (WiFi.status() != WL_CONNECTED)
    {
      delay(500);
      Serial.print(".");
    }


    Serial.println("WiFi connected");

    Serial.print("MAC: ");
    Serial.println(WiFi.macAddress());

 

    // Start the server
    server.begin();
    Serial.println("Server started");

 

    // Print the IP address
    Serial.print("Use this URL to connect: ");
    Serial.print("http://");
    Serial.print(WiFi.localIP());
    Serial.println("/");

 

    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0,18);
    display.print("http://");
    display.print(WiFi.localIP());
    display.println("/");
    display.display();  //diplay output

 

    //---------------------------------
    Serial.println("Start..");

 

   //Free Rtos Q Set
   queue = xQueueCreate( queueSize, sizeof( int ) );
   if(queue == NULL){
     Serial.println("Error creating the queue");
   }

 

   xQueue = xQueueCreate(5, sizeof(Data));
   if(xQueue == NULL){
     Serial.println("Error creating the queue");
   }

 

   //세마포어를 초기화 합니다. 세마포어는 동시에 1개만 생성됩니다.
   sem = xSemaphoreCreateCounting(1, 0);


 //Free Rtos Task Set
 xTaskCreate(
     taskOne,          /* Task function. */
     "TaskOne",        /* String with name of task. */
     1024,            /* Stack size in words. 10000->1024*/
     NULL,             /* Parameter passed as input of the task */
     1,                /* Priority of the task. */
     NULL);            /* Task handle. */

 

 xTaskCreate(
     taskTwo,          /* Task function. */
     "TaskTwo",        /* String with name of task. */
     1024,            /* Stack size in words. */
     NULL,             /* Parameter passed as input of the task */
     1,                /* Priority of the task. */
     NULL);            /* Task handle. */

 

 xTaskCreate(
     taskWeb,          /* Task function. */
     "TaskWeb",        /* String with name of task. */
     1024,            /* Stack size in words. */
     NULL,             /* Parameter passed as input of the task */
     1,                /* Priority of the task. */
     NULL);            /* Task handle. */

 

 xTaskCreate(
     taskSAM,          /* Task function. */
     "taskSAM",        /* String with name of task. */
     1024,            /* Stack size in words. */
     NULL,             /* Parameter passed as input of the task */
     1,                /* Priority of the task. */
     NULL);            /* Task handle. */

}

 

// The loop function is called in an endless loop
void loop()
{
 delay(1000);

}


void taskOne( void * parameter )
{
  /* keep the status of sending data */
 BaseType_t xStatus;
 /* time to block the task until the queue has free space */
 const TickType_t xTicksToWait = pdMS_TO_TICKS(100);

 /* create data to send */
 Data data;

 /* sender 1 has id is 1 */
 data.sender = 1;
 data.counter = 1;

 for(;;){
  for( int i = 0;i<10;i++ ){

   Serial.println("Hello from task 1");
   digitalWrite(LED, 1);
   //digitalWrite(LED, 0);

   xQueueSend(queue, &i, portMAX_DELAY);

      xStatus = xQueueSendToFront( xQueue, &data, xTicksToWait );
      /* check whether sending is ok or not */
      if( xStatus == pdPASS ) {
        /* increase counter of sender 1 */
        data.counter = data.counter + 1;
      }

   delay(1000);
  }
 }
    Serial.println("Ending task 1");
    vTaskDelete( NULL );

}

 

 

void taskTwo( void * parameter)
{
 /* keep the status of receiving data */
 BaseType_t xStatus;
 /* time to block the task until data is available */
 const TickType_t xTicksToWait = pdMS_TO_TICKS(100);
 Data data;

 int element;

 for(;;){
  for( int i = 0;i<10;i++ ){

   xQueueReceive(queue, &element, portMAX_DELAY);
   Serial.print(element);
   Serial.print(" -> ");

      /* receive data from the queue */
      xStatus = xQueueReceive( xQueue, &data, xTicksToWait );
      /* check whether receiving is ok or not */
      if(xStatus == pdPASS){
        /* print the data to terminal */
        Serial.print("receiveTask got data: ");
        Serial.print("sender = ");
        Serial.print(data.sender);
        Serial.print(" counter = ");
        Serial.println(data.counter);
      }

   Serial.println("Hello from task 2");
   delay(1000);


  }
 }
    Serial.println("Ending task 2");
    vTaskDelete( NULL );

}

 

 

void taskWeb( void * parameter)
{
 for(;;){

  WiFiClient client = server.available();
  if (client)
  {
      Serial.println("new client");
      while(!client.available()){
      delay(1);
      }
      //요청을 읽는다.
      String request = client.readStringUntil('\r');
      Serial.println(request);
      client.flush();

      //사용자가 접속한 URL읽어서 판별
      if (request.indexOf("/ON") > 0) { //1이면
        Serial.println("LED ON");
        digitalWrite(LED, LOW);
      }
      if (request.indexOf("/OFF") > 0) { //0이면
        Serial.println("LED OFF");
        digitalWrite(LED, HIGH);
      }

      // Match the request
      int val1 = digitalRead(LED);;

      // Prepare the response
      //int sensorReading = analogRead(ANALOG_IN);
      int sensorReading = 100;

      String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n ";
      s += "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">";     //한글출력
      s += "<body>";
      s += "<h1>LED is now = ";
      s += (val1)?"OFF<p>":"ON<p>";
      s += "Analog Value is now = ";
      s += (sensorReading);
      s += "</h1><p>";

      // Send the response to the client
      client.print(s);

      //-----
      client.println("<svg height='210' width='300'>");
      int val = analogRead(A0)/5;
      int y1 = 200-val;
      for(int i=1;i<300;i++){
        // 아나로그입력 생성(0-1023):1023=3.3V
        int x1 = (i-1);
        int x2 = i;
        int val = analogRead(A0)/5;
        int y2 = 200-val;
        client.println("<line x1='");

        client.println(x1);
        client.println("' y1='");
        client.println(y1);
        client.println("' x2='");
        client.println(x2);
        client.println("' y2='");
        client.println(y2);
        client.println("'");
        client.println("' style='stroke:rgb(255,0,0);stroke-width:2' />");
        client.println("Sorry, your browser does not support inline SVG.");
        y1 = y2;
      }

      client.println("</svg>");
      client.println("  </body>");

      client.println("<br><br>");
      client.println("<a href=\"/ON\"\"><button>LED 점등 </button></a>");
      client.println("<a href=\"/OFF\"\"><button>LED 소등 </button></a><br />");

      client.println("<br><br>");
      client.println("<a href=\"/reflsh\"\"><button>Data Refresh </button></a><br />");
      client.println("</html>");
      delay(1);

      Serial.println("Client disonnected");

      //세마포어를 전달합니다.
      xSemaphoreGive(sem);

  }

 }

    Serial.println("Ending task Web");
    vTaskDelete( NULL );
}

 

 

void taskSAM( void * parameter)
{
   while (1) {

     //세마포어를 받을때까지 스레드는 계속 기다리게 됩니다.
     xSemaphoreTake(sem, portMAX_DELAY);

     Serial.println(">>> Semaphore Run!");

   }

}

 

 

//한글 라이브러리 처리
void matrixPrint(int XPOS,int YPOS,char *pChar){
  //byte rg = 3;   //<b1> red, <b0> green
  byte *pFs;
  //byte i, b;
  byte c, c2, c3;

  while(*pChar){
    c = *(byte*)pChar++;

    //---------- �ѱ� ---------
    if(c >= 0x80){
      c2 = *(byte*)pChar++;
      c3 = *(byte*)pChar++;
      //Serial.print(c,DEC);
      //Serial.print(c2,DEC);
      //Serial.print(c3,DEC);
      pFs = getHAN_font(c, c2, c3);
      display.drawBitmap(XPOS, YPOS,  pFs, 16, 16, 1);
      XPOS = XPOS+16;
      if(XPOS > 128){
        XPOS = 0;
        YPOS = YPOS+16;
      }
    }
    //---------- ASCII ---------
    else{
      pFs = (byte*)ASCfontSet + ((byte)c - 0x20) * 16;
      display.drawBitmap(XPOS, YPOS,  pFs, 8, 16, 1);
      XPOS = XPOS+8;
      if(XPOS > 128){
        XPOS = 0;
        YPOS = YPOS+16;
      }
    }
  }
}


/*=============================================================================
한글 font 처리부분  "주의 : 파일 형식을 UTF-8 로 꼭 사용해야 한다.
  =============================================================================*/
uint16_t utf16_d;

byte *getHAN_font(byte HAN1, byte HAN2, byte HAN3)
{

  const byte cho[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 1, 2, 4, 4, 4, 2, 1, 3, 0 };
  const byte cho2[] = { 0, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 6, 6, 7, 7, 7, 6, 6, 7, 5 };
  const byte jong[] = { 0, 0, 2, 0, 2, 1, 2, 1, 2, 3, 0, 2, 1, 3, 3, 1, 2, 1, 3, 3, 1, 1 };


  byte first, mid, lastcode;
  byte firstType, midType;
  byte last_Type = 0 ;
  byte i;
  byte *pB, *pF;

  /*------------------------------
    UTF-8 -> UTF-16 change
    UTF-8 1110xxxx 10xxxxxx 10xxxxxx
  */------------------------------

  utf16_d = (uint16_t)((HAN1 & 0x0f) << 12) | (uint16_t)((HAN2 & 0x3f) << 6) | (uint16_t)(HAN3 & 0x3f);

  /*------------------------------
    초,중,종성 코드를 분리해 낸다.

    unicode = {[(초성 * 21) + 중성] * 28}+ 종성 + 0xAC00

          0   1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
    초성 ㄱ   ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ
    중성 ㅏ   ㅐ ㅑ ㅒ ㅓ ㅔ ㅕ ㅖ ㅗ ㅘ ㅙ ㅚ ㅛ ㅜ ㅝ ㅞ ㅟ ㅠ ㅡ ㅢ ㅣ
    종성 없음 ㄱ ㄲ ㄳ ㄴ ㄵ ㄶ ㄷ ㄹ ㄺ ㄻ ㄼ ㄽ ㄾ ㄿ ㅀ ㅁ ㅂ ㅄ ㅅ ㅆ ㅇ ㅈ ㅊ ㅋ ㅌ ㅍ ㅎ
  ------------------------------*/
  utf16_d -= 0xac00;
  lastcode = utf16_d % 28;
  utf16_d /= 28;
  mid = utf16_d % 21;
  first = utf16_d / 21;

  first++;
  mid++;

  /*------------------------------
    초,중,종성 해당 폰트 타입(벌)을 결정한다.
  ------------------------------*/

  /*
   초성 19자:ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ
   중성 21자:ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ
   종성 27자:ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅆㅇㅈㅊㅋㅌㅍㅎ

   초성
      초성 1벌 : 받침없는 'ㅏㅐㅑㅒㅓㅔㅕㅖㅣ' 와 결합
      초성 2벌 : 받침없는 'ㅗㅛㅡ'
      초성 3벌 : 받침없는 'ㅜㅠ'
      초성 4벌 : 받침없는 'ㅘㅙㅚㅢ'
      초성 5벌 : 받침없는 'ㅝㅞㅟ'
      초성 6벌 : 받침있는 'ㅏㅐㅑㅒㅓㅔㅕㅖㅣ' 와 결합
      초성 7벌 : 받침있는 'ㅗㅛㅜㅠㅡ'
      초성 8벌 : 받침있는 'ㅘㅙㅚㅢㅝㅞㅟ'

   중성
      중성 1벌 : 받침없는 'ㄱㅋ' 와 결합
      중성 2벌 : 받침없는 'ㄱㅋ' 이외의 자음
      중성 3벌 : 받침있는 'ㄱㅋ' 와 결합
      중성 4벌 : 받침있는 'ㄱㅋ' 이외의 자음

   종성
      종성 1벌 : 중성 'ㅏㅑㅘ' 와 결합
      종성 2벌 : 중성 'ㅓㅕㅚㅝㅟㅢㅣ'
      종성 3벌 : 중성 'ㅐㅒㅔㅖㅙㅞ'
      종성 4벌 : 중성 'ㅗㅛㅜㅠㅡ'

  */
  if(!lastcode){  //��ħ ���� ���
    firstType = cho[mid];
    if(first == 1 || first == 24) midType = 0;
    else midType = 1;
  }
  else{       //��ħ �ִ� ���
    firstType = cho2[mid];
    if(first == 1 || first == 24) midType = 2;
    else midType = 3;
    last_Type = jong[mid];
  }
  memset(HANFontImage, 0, 32);

  //�ʼ�
  pB = HANFontImage;
  pF = (byte*)KSFont + (firstType*20 + first)*32;
  i = 32;
  while(i--) *pB++ = pgm_read_byte(pF++);

  //�߼�
  pB = HANFontImage;
  pF = (byte*)KSFont + (8*20 + midType*22 + mid)*32;
  i = 32;
  while(i--) *pB++ |= pgm_read_byte(pF++);

  //����
  if(lastcode){
    pB = HANFontImage;
    pF = ((byte*)KSFont) + ((8*20) + (4*22) + (last_Type*28) + lastcode)*32;
    i = 32;
    while(i--) *pB++ |= pgm_read_byte(pF++);
  }

  return HANFontImage;
}


static byte c1;  // Last character buffer
byte utf8ascii(byte ascii) {
    if ( ascii<128 )   // Standard ASCII-set 0..0x7F handling
    {   c1=0;
        return( ascii );
    }

    // get previous input
    byte last = c1;   // get last char
    c1=ascii;         // remember actual character

    switch (last)     // conversion depnding on first UTF8-character
    {   case 0xC2: return  (ascii);  break;
        case 0xC3: return  (ascii | 0xC0);  break;
        case 0x82: if(ascii==0xAC) return(0x80);       // special case Euro-symbol
    }

    return  (0);                                     // otherwise: return zero, if character has to be ignored
}

String utf8ascii(String s)
{
        String r="";
        char c;
        for (int i=0; i<s.length(); i++)
        {
                c = utf8ascii(s.charAt(i));
                if (c!=0) r+=c;
        }
        return r;
}
void utf8ascii(char* s)
{
        int k=0;
        char c;
        for (int i=0; i<strlen(s); i++)
        {
                c = utf8ascii(s[i]);
                if (c!=0)
                        s[k++]=c;
        }
        s[k]=0;
}

 

 

 

 

      

 

'공부 > arduino' 카테고리의 다른 글

ESP32 DAC를 이용한 사운드 출력  (0) 2019.06.25
esp32 ble test  (0) 2018.04.12
esp32 free rtos 사용  (0) 2018.04.12
esp32 oled 한글 올리기  (0) 2018.04.12
esp32 아두이노 라이브러리 업그레이드  (0) 2018.04.12

+ Recent posts