HSES-LCD24に文字を表示させるプログラム(3)

160810a6現在、梱包上の問題でスイッチサイエンスでのHSES-LCD24の販売が停止されています。対策の目途は立っていますので、お盆明けぐらいには再開できると思います。

さて、HSES-LCD24に文字を表示させるプログラムですが、前回紹介したサンプルプログラムESP8266WebServer/HelloServerをベースに簡単に作ってみました。ソースは、この記事の最後に置いておきます。

拡張性を考え、/printというパスに、文字表示のハンドラを設定しました。パラメータで表示にひつような情報を渡します。現在有効なパラメータを以下に示します。

text:    // 表示する文字列
clear:   // 画面クリアの有無、 1:全クリア、 2: x0,y0,x1,y1で指定した領域のみクリア
size:    // 文字サイズ 
rotation: // 描画座標の向き、デフォルト3
x,y:      // 文字描画の位置
color:    // 文字描画色、 #rrggbb または white, black, red, green, blueなど
bg:       // クリアに使用する背景色
x0,y0,x1,y1:  // 部分クリアの領域指定

動作確認はブラウザで行えます。プログラムを書き込み、WiFiと接続できると、表示は次のようになります。

160810a1

HSES-LCD24に割り当てられたIPアドレスが 192.168.0.104だったとして、ブラウザで

http://192.168.0.104/print?clear=1&size=3&text=Hello

にアクセスすると、次の写真のように表示されます。

160810a3

与えるパラメータの値を変えることで、表示をコントロールできます。

PC側のプログラムから表示を行うこともできます。
下のプログラムはPython3のプログラムで、1秒ごとに時刻を表示させています。

import urllib.request
import time
from datetime import datetime

ip_addr = '192.168.0.104'
url_date = "http://%s/print?clear=1&color=%%238080ff&x=21&y=80&size=3&text=%s"
url_time = 'http://%s/print?x=10&y=120&color=green&size=6&text=%s'

while(1):
    s = datetime.now().strftime("%Y/%m/%d(%a)")
    req = urllib.request.Request(url_date % (ip_addr,s));
    the_page = urllib.request.urlopen(req).read()
    
    s = datetime.now().strftime("%H:%M:%S")
    req = urllib.request.Request(url_time % (ip_addr,s));
    the_page = urllib.request.urlopen(req).read()
    time.sleep(1)

時刻を表示させる前に画面クリアをしていますので、多少ちらついて見えます。この辺は今後改良していきたいところです。

最後に、HSES-LCD24側のプログラムを以下に掲載します。

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

#define TFT_DC 15
#define TFT_CS 2
#define TFT_RST -1

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

const char* ssid = "ssid-name";      // 接続するWiFiのssidを設定
const char* password = "password";   // 接続するWiFiのパスワードを設定

ESP8266WebServer server(80);

typedef const struct {
  const char *name;
  uint16_t value;
} color_name_t;

color_name_t color_names[] = {
  {"BLACK",	  ILI9341_BLACK},
  {"LIGHTGREY",	  ILI9341_LIGHTGREY},
  {"DARKGREY",	  ILI9341_DARKGREY},
  {"BLUE",	  ILI9341_BLUE},
  {"GREEN",	  ILI9341_GREEN},
  {"RED",	  ILI9341_RED},
  {"YELLOW",	  ILI9341_YELLOW},
  {"WHITE",	  ILI9341_WHITE},
  {"PINK",	  ILI9341_PINK},
  {NULL, 0},
};

struct {
  int16_t x0;
  int16_t y0;
  int16_t x1;
  int16_t y1;
  uint16_t bg_color;
} lcd_cont = { 0, 0, 320, 240, ILI9341_BLACK};

void handleRoot() {
  server.send(200, "text/plain", "NetLCD server");
}

static boolean getHex(const char *s, int *pVal)
{
  int i,vv=0;

  for(i=0; i<2; i++){
    int v;
    if(!isxdigit(s[i]))
      return false;
    if(s[i] > 'f') return false;
    else if(s[i] >= 'a') v = s[i] - 'a' + 10;
    else if(s[i] > 'F') return false;
    else if(s[i] >= 'A') v = s[i] - 'A' + 10;
    else if(s[i] > '9') return false;
    else if(s[i] >= '0') v = s[i] - '0';
    else return false;
    vv = vv * 16 + v;
  }
  *pVal = vv;
  return true;
}

static boolean getColor( const char *str, uint16_t *pColor)
{
  if(*str == '#'){
    int r,g,b;
    if(getHex(str+1, &r) && getHex(str+3, &g) && getHex(str+5, &b)) {
      *pColor = tft.color565(r,g,b);
      return true;
    }
    Serial.print("Bad color:\"");
    Serial.print(str);
    Serial.println("\" found.");
    return false;
  }
  else {
    color_name_t *p;
    for(p=color_names; p->name; p++){
      if(stricmp(str, p->name)==0){
	*pColor = p->value;
	return true;
      }
    }

    Serial.print("Undefned color name:\"");
    Serial.print(str);
    Serial.println("\" found.");
    return false;
  }
}

void handlePrint() {
  for(int i=0; i<server.args(); i++){
    String name  = server.argName(i);
    String value = server.arg(i);
    if(name == "text")
      tft.print(value.c_str());
    else if(name == "clear") {
      if(value == "1"){
	tft.fillScreen(lcd_cont.bg_color);
	tft.setCursor(0,16);
      }
      else if(value == "2"){
	tft.fillRect(lcd_cont.x0, lcd_cont.y0, lcd_cont.x1, lcd_cont.y1,
		     lcd_cont.bg_color);
      }
    }
    else if(name == "size")
      tft.setTextSize(value.toInt());
    else if(name == "rotation")
      tft.setRotation(value.toInt());
    else if(name == "x") 
      tft.setCursor( value.toInt(), tft.getCursorY());
    else if(name == "y")
      tft.setCursor( tft.getCursorX(), value.toInt());
    else if(name == "color") {
      uint16_t color;
      if(getColor(value.c_str(), &color))
	tft.setTextColor(color);
    }
    else if(name == "bg") {
      getColor(value.c_str(), &lcd_cont.bg_color );
    }
    else if(name == "x0") 
      lcd_cont.x0 = value.toInt();
    else if(name == "y0") 
      lcd_cont.y0 = value.toInt();
    else if(name == "x1") 
      lcd_cont.x1 = value.toInt();
    else if(name == "y1") 
      lcd_cont.y1 = value.toInt();
    else {
      Serial.print("param:");
      Serial.print(name.c_str());
      Serial.print(" not defined.");
      Serial.println();
    }
  }
  server.send(200, "text/plain", "Ok");
}

void handleNotFound(){
  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);
}

void setup(void){
  Serial.begin(115200);
  tft.begin();
  tft.setTextSize(2);
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLACK);

  tft.setCursor(2, 16);
  tft.println("Initialize");
  
  WiFi.begin(ssid, password);
  Serial.println("");
  tft.print("connecting");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    tft.print(".");
  }
  Serial.println();
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  tft.println();
  tft.print("connected to ");
  tft.setTextColor(ILI9341_GREEN);
  tft.println(WiFi.localIP());
  tft.setTextColor(ILI9341_WHITE);

  server.on("/", handleRoot);
  server.on("/print", handlePrint);
  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
  tft.println("start");
}

void loop(void){
  server.handleClient();
}

今後、このプログラムに、もう少し機能を追加していく予定です。

Leave a Reply

メールアドレスが公開されることはありません。