2.4" 240x320 color LCD と Arduino nano で、小さなターミナルを自作してみました。

2.4" 240x320 color LCD と Arduino nano で、小さなターミナルを自作してみました。
写真中央のArduino-NANOをコントローラとして、手前の黒いコネクタはマイコン用のUART、左上は電源コネクタ、右上はキーボード用のPS2コネクタ、その他はArguino互換のピン配置で、LCDモジュール用のコネクタだ。

実験なので、Arduino互換ピン配置のユニバーサルボードを使って、ラッピングで配線をした。

 液晶モジュールを載せたところ。

 キーボードと電源をつないで、ハイこの通り。
 画面の向き、文字の大きさ・色、UARTの通信速度等が設定できるように作ってみた。

チャレンジしてみたい方、お気軽にご連絡ください。

お問い合わせ






参考までに、Arduino-NANOのCodeです。
是非、コメントをお寄せください。

/* By T.Kasahara May-26 '17 CHUM_Terminal Ver1.0
 *PS2Keyboard Japanese Keyboard Layout  
  Color TFTLCD Adafruit library 
  PS2 Key board
  Charactor Terminal
F1 :Help
F5 :Save Setting
F6 :Local Echo
F7 :Board Rate
F8 :Reverse Color
F9 :Back color
F10:Font color
F11:Rotation
F12:Font Size

-ESC- for Exit from Settings
 
*/

//#define DEBUG //Debug mode

#ifdef DEBUG
 #define DEBUG_PRINTLN(x)  Serial.println (x)
 #define DEBUG_PRINT(x)  Serial.print (x)
 #define DEBUG_FPRINT(x,y)  Serial.print (x,y)
#else
 #define DEBUG_PRINTLN(x)
 #define DEBUG_PRINT(x)
 #define DEBUG_FPRINT(x,y)
#endif

#include    // Core graphics library
#include // Hardware-specific library
#include

#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin

#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0

CHUM_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD);

#define T_Wrap HIGH //Text Wrap around ON:HIGH,OFF:LOW
#define blink_speed 1000
#define D_Width 240 //Display Width size Pixel
#define D_Hight 320 //Display Hight size Pixel
#define Wait_setup 2000

// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#include
#define EE_boardrate 1023
#define EE_F_color 1022
#define EE_B_color 1021
#define EE_rotation 1020
#define EE_C_Size 1019
#define EE_Echo 1018

#include //code modified for Japanese Key board
const int DataPin = 18;
const int IRQpin =  2;
PS2Keyboard keyboard;

int color[]={BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE};
int C_Size = 2; //Charactor Mag.
#define C_Max 4
long rate[]={9600,19200,38400,57600,74880,115200,230400,250000};
int boardrate = 0;
int rotation = 0; //Display rotation 0&2:H,1&3:V
int F_color = 0;
int B_color = 0;
int echo = 0;

int End_Line ;
int C_Line = 0;
boolean toggle = 0;
int ii,jj;
char cc;
uint8_t c;
int count;
unsigned long c_time;

void setup() {
// Restore settings
  boardrate = EEPROM.read(EE_boardrate);
  F_color = EEPROM.read(EE_F_color);
  B_color = EEPROM.read(EE_B_color);
  rotation = EEPROM.read(EE_rotation);
  C_Size = EEPROM.read(EE_C_Size);
  if(C_Size == 0) C_Size = 1;
  echo = EEPROM.read(EE_Echo);

//Keyboard Serial Begin
  keyboard.begin(DataPin, IRQpin, PS2Keymap_Japanese);
  Serial.begin(rate[boardrate]);
  DEBUG_PRINTLN(F("CHUM_Terminal V0.1"));

// TFTLCD Initialize
  tft.reset();
  uint16_t identifier = tft.readID();
  tft.begin(identifier);

  refresh(); //Refresh display
  tft.print(F("F1 for Setting"));
  refresh(); //Refresh display
  tft.print(F("F1 for Setting"));

// Setting
  if (keyboard.available()) {
    c = cc = keyboard.read();
    DEBUG_FPRINT(c,HEX);
    DEBUG_PRINT(" ");

    if(c == 0xc2){
      while(c != 0x1B) { // Wait ESC
        switch(c){
          case 0x81:  // F1 Help
            tft.fillScreen(color[B_color]); // Screen clear
            tft.setTextWrap(T_Wrap); //Set Text Wrap around
            tft.setCursor(0,0);
            DEBUG_PRINTLN(F("F1 :Help"));
            tft.println(F("F1 :Help"));
            tft.println(F("F5 :Save EEPROM"));
            tft.println(F("F6 :Local Echo"));
            tft.println(F("F7 :Board Rate"));
            tft.println(F("F8 :Reverse Color"));
            tft.println(F("F9 :Back color"));
            tft.println(F("F10:Font color"));
            tft.println(F("F11:Rotation"));
            tft.println(F("F12:Font Size"));
            tft.println();
            tft.println(F("-ESC- for Exit from Help"));
          break;

          case 0x85:  // F5 Save Settings to EEPROM
            F5_Set_EEPROM();
          break;
     
          case 0x86:  // F6 Local Echo On/Off
            F6_sw_echo();
          break;

          case 0x87:  // F7 BoardRte
            F7_BoardRate();
          break;
     
          case 0x88:  // F8 Reverse color
            jj = B_color;
            B_color = F_color;
            F_color = jj;
            refresh();        
          break;
     
          case 0x89:  // F9 Back ground color KCMYGBR
            B_color += 1;
            if( B_color >7) B_color =0;
            refresh();
          break;
     
          case 0x8A:  // F10 Font Color WRGBMYC
            F_color -= 1;
            if( F_color < 0) F_color =7;
            refresh();
          break;
     
          case 0x8B:  // F11 Rotation 0,1,2,3
            rotation +=1;
            if(rotation > 3) rotation=0;
            refresh();
          break;
     
          case 0x8C:  // F12 Zoom 1,2,3,4
            C_Size +=1;
            if(C_Size > C_Max) C_Size=1;
            refresh();
          break;
             
          default:
            ;
          break;

        }
        while (!keyboard.available()) ;
        cc = keyboard.read();
        c = cc;
        DEBUG_FPRINT(c,HEX);
        DEBUG_PRINT(" ");
      }
      refresh();
    }
  }
  refresh();
  c_time = millis();
}

//************************************************//
void loop() {
    C_Line = tft.getCursorY();

// Keyboard
    if (keyboard.available()) {
      off_Cursor();
      c = cc = keyboard.read();
      DEBUG_FPRINT(c,HEX);
      DEBUG_PRINT(" ");

      switch(c){
        case 0x0d:  //CR
          if ( echo != 0) New_Line();
          Serial.println();
        break;

        case 0x0a:  //LF
          if ( echo != 0) New_Line();
          Serial.println();
        break;

        case 0x08:  //Back Space or Left arrow
          if ( echo != 0) Back_Space(1);
          Serial.print(cc);
        break;

        case 0x7F:  //Delete
          if ( echo != 0) Delete_Space();
          Serial.print(cc);
        break;
     
        case 0x8d:  // Up
          Serial.write(0x1b);Serial.write(0x5b);
          Serial.write(0x41);
        break;

        case 0x8e:  // Down
          Serial.write(0x1b);Serial.write(0x5b);
          Serial.write(0x42);
        break;

        case 0x8f:  // Right
          Serial.write(0x1b);Serial.write(0x5b);
          Serial.write(0x43);
        break;

        case 0x90:  // Left
          Serial.write(0x1b);Serial.write(0x5b);
          Serial.write(0x44);
        break;

        default:
          if ( echo != 0){
            tft.print(cc);
            New_Line();
          }
          Serial.write(c);
        break;
      }
    }

//Serial
    if(Serial.available()){
      off_Cursor();
      c = cc = Serial.read();

      switch(c){
        case 0x0d:  //CR
          tft.setCursor( 0, tft.getCursorY());
//          New_Line();
        break;

        case 0x0a:  //LF
          tft.println();
          New_Line();
        break;

        case 0x08:  //Back Space
          Back_Space(1);
        break;
     
        case 0x7F:  //Delete
          Delete_Space();
        break;

        case 0x1b:  //ESC Sequence
          while(!Serial.available());
          c = cc = Serial.read();
          if(c != 0x5b ) break;
          count = 0;
          do{
            while(!Serial.available());
            c = cc = Serial.read();
            if( c == 0x4b ){  //delete line
              Clear_line(tft.getCursorX(),tft.getCursorY());
              break;
            }else if(c == 0x44){ //Number
              if(count == 0) count = 1;
              Back_Space(count);
              break;
            }else if( (c >= 0x30) && (c <= 0x39)){ //Number
              count = count*10 + (c -0x30);
            }else {
              break;
            }
          }while(1);
        break;

        default:
          tft.print(cc);
          New_Line();
        break;
      }
    }
  if ( (millis()-c_time) > blink_speed ){
    if(toggle){
      tft.setTextColor(color[F_color]);
      tft.print("_");
    }else{
      tft.setTextColor(color[B_color]);
      tft.print("_");
    }
    Back_Space(1);
    tft.setTextColor(color[F_color],color[B_color]);
    toggle = !toggle;
    c_time = millis();
  }
}

void off_Cursor(){
  tft.setTextColor(color[B_color]);
  tft.print("_");
  Back_Space(1);
  tft.setTextColor(color[F_color],color[B_color]);
}

void Delete_Space(){
      tft.print(" ");
      jj = tft.getCursorX() - 12 * C_Size;
      if( jj < 0) jj=0;
      tft.setCursor( jj, tft.getCursorY());
}

void Back_Space(int pp){
      jj = tft.getCursorX() - 6 * C_Size * pp;
      if( jj < 0) jj=0;
      tft.setCursor( jj, tft.getCursorY());
}

void  New_Line(){
      jj = tft.getCursorY();
      if( C_Line < jj ){
        if(jj >= End_Line){
          tft.setCursor(0, 0);
          jj = 0;
        }
//        DEBUG_PRINT(" Y=");
//        DEBUG_PRINTLN(jj);
        C_Line = jj;
        Clear_line(tft.getCursorX(),jj);
      }
}

void Clear_line(int xx, int yy){
        tft.setTextWrap(LOW);
        tft.print(F("                                                       "));
        tft.setCursor(xx,yy);
        tft.setTextWrap(T_Wrap);
}

void  F6_sw_echo(){
          tft.fillScreen(color[B_color]); // Screen clear
          tft.setCursor(0,0);
          DEBUG_PRINTLN(F("F6 :Local Echo ON/Off"));
          if( echo == 0) {
            tft.println(F("Local Echo OFF"));
          }else{
            tft.println(F("Local Echo ON "));
          }
          tft.println();
          tft.println(F("ESC->Exit"));
          while(c != 0x1B) { // Wait ESC
            while(!keyboard.available()) ; // wait key
            c = keyboard.read();
            tft.setCursor(0,0);
            tft.println();
            if(keyboard.available()) c = keyboard.read();
            if(c != 0x1B) echo ^= 0x0001 ;
            if( echo == 0) {
              tft.println(F("Local Echo OFF"));
            }else{
              tft.println(F("Local Echo ON "));
            }
          }
          refresh();
}

void  F7_BoardRate(){
          tft.fillScreen(color[B_color]); // Screen clear
          tft.setCursor(0,0);
          DEBUG_PRINTLN(F("F2 :BoardRate"));
          Serial.end();
          tft.println("        ");
          tft.println("bps");
          tft.println();
          tft.println(F("ESC->Exit"));
          while(c != 0x1B) { // Wait ESC
            tft.setCursor(0,0);
            tft.print(rate[boardrate]);
            tft.println("      ");
            while(!keyboard.available()) ; // wait key
            c = keyboard.read();
            if(keyboard.available()) c = keyboard.read();
            if(c != 0x1B) boardrate += 1;
            if(boardrate > 7) boardrate = 0;
          }
          Serial.begin(rate[boardrate]);
          refresh();
}

void   F5_Set_EEPROM(){
          EEPROM.write(EE_boardrate,boardrate);
          EEPROM.write(EE_F_color,F_color);
          EEPROM.write(EE_B_color,B_color);
          EEPROM.write(EE_rotation,rotation);
          EEPROM.write(EE_C_Size,C_Size);
          refresh();
}

void F1_Help(){
          tft.fillScreen(color[B_color]); // Screen clear
          tft.setTextWrap(T_Wrap); //Set Text Wrap around
          tft.setCursor(0,0);
          DEBUG_PRINTLN(F("F1 :Help"));
       
          tft.println(F("F1 :Help"));
          tft.println(F("F5 :Save EEPROM"));
          tft.println(F("F7 :Board Rate"));
          tft.println(F("F8 :Reverse Color"));
          tft.println(F("F9 :Back color"));
          tft.println(F("F10:Font color"));
          tft.println(F("F11:Rotation"));
          tft.println(F("F12:Font Size"));
          tft.println();
          tft.println(F("-ESC- for Exit from Help"));
          while(c != 0x1B) { // Wait ESC
            c = keyboard.read();
            delay(200);
          }
          refresh();
}

void refresh(){
  tft.fillScreen(color[B_color]); // Screen clear
  tft.setTextWrap(T_Wrap); //Set Text Wrap around
  tft.setRotation(rotation);
  tft.setCursor(0,0);
  tft.setTextColor(color[F_color],color[B_color]);  tft.setTextSize(C_Size);
  tft.println(F("CHUM_Terminal V0.1"));
  if(rotation == 0 || rotation == 2 ){
    End_Line = D_Hight;
  }else{
    End_Line = D_Width;
  }
}