TFT液晶グラフィックモジュール

 

僕が購入したのは8・9年前で同じSPI通信のマイクロSDが裏面についていて、Arduino UNOにデータの読み書きの機能が追加される。

 

ST7735というチップでコントロールしているグラフィック液晶モニターです。

Arduino UNOはクロック周波数が遅いので、書き換えが遅くその際もチカチカする感じです。

 

  文字だけ表示やライブラリのデモの下りは端折ります

雑ですみません。

基本的にAdafruitのライブラリを使用します。

 

  ライブラリをインストール

グラフィック液晶なのに文字を表示するだけではもったいない。

アナログ時計の表示は三角関数でドットを描画しているので、ゲージ風表示などで応用が利きそうなので試してみた。

 

ライブラリはAdafruit社の提供のものを使用する。

Adafruit_GFX Library

 

これに加えてライブラリーマネージャー(ライブラリを管理)の検索窓で7735で検索してライブラリをインストール。

 

ライブラリの内容はSSD1306とほぼ同じで色が増えただけ。(と思います)

 

 

  RTCモジュールも使用して時計表示

RTCモジュールはDS3231を使用。

RTCモジュールの接続方法など使い方はこちらを参照。

 

 

  TFT液晶モジュールの接続

 

 

  液晶モジュール    Arduino UNO

                 GND      →  GND

                 VCC   →  5V

      SCL  →   13

      SDA  →       11

      DC   →        8

      RES   →       9

      CS   →        10

 

  時計のスケッチ

基本的にSSD1306でやった時計表示と同じ。

 

  1.  
  2. #include <Adafruit_GFX.h> // Core graphics library
  3. #include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
  4. #include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
  5. #include <SPI.h>
  6. #include <DS3232RTC.h>
  7. #if defined(ARDUINO_FEATHER_ESP32) // Feather Huzzah32
  8. #define TFT_CS 14
  9. #define TFT_RST 15
  10. #define TFT_DC 32
  11.  
  12. #elif defined(ESP8266)
  13. #define TFT_CS 4
  14. #define TFT_RST 16
  15. #define TFT_DC 5
  16.  
  17. #else
  18. // For the breakout board, you can use any 2 or 3 pins.
  19. // These pins will also work for the 1.8" TFT shield.
  20. #define TFT_CS 10
  21. #define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
  22. #define TFT_DC 8
  23. #endif
  24. DS3232RTC RTC;
  25.  
  26. // OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
  27. // to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
  28. // SCLK = pin 13. This is the fastest mode of operation and is required if
  29. // using the breakout board's microSD card.
  30.  
  31. // For 1.44" and 1.8" TFT with ST7735 use:
  32. Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
  33.  
  34. // For 1.14", 1.3", 1.54", 1.69", and 2.0" TFT with ST7789:
  35. //Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
  36.  
  37.  
  38. // OPTION 2 lets you interface the tft using ANY TWO or THREE PINS,
  39. // tradeoff being that performance is not as fast as hardware SPI above.
  40. //#define TFT_MOSI 11 // Data out
  41. //#define TFT_SCLK 13 // Clock out
  42.  
  43. // For ST7735-based tfts, we will use this call
  44. //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
  45.  
  46. // OR for the ST7789-based tfts, we will use this call
  47. //Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
  48.  
  49.  
  50. float p = 3.1415926;
  51.  
  52. void setup(void) {
  53.   Serial.begin(9600);
  54.   Serial.print(F("Hello! ST77xx TFT Test"));
  55.   Serial.begin(9600);
  56.   // If you want to set the aref to something other than 5v
  57.   analogReference(EXTERNAL);
  58.   Wire.begin();
  59.   RTC.begin();
  60.   setSyncProvider(RTC.get); // the function to get the time from the RTC
  61.   if (timeStatus() != timeSet)
  62.     Serial.println("Unable to sync with the RTC");
  63.   else
  64.     Serial.println("RTC has set the system time");
  65.  
  66.   // Use this initializer if using a 1.8" TFT screen:
  67.   tft.initR(INITR_BLACKTAB); // Init ST7735S chip, black tab
  68.  
  69.   // OR use this initializer if using a 1.8" TFT screen with offset such as WaveShare:
  70.   // tft.initR(INITR_GREENTAB); // Init ST7735S chip, green tab
  71.  
  72.   // OR use this initializer (uncomment) if using a 1.44" TFT:
  73.   //tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab
  74.  
  75.   // OR use this initializer (uncomment) if using a 0.96" 160x80 TFT:
  76.   //tft.initR(INITR_MINI160x80); // Init ST7735S mini tft
  77.   // OR use this initializer (uncomment) if using a 0.96" 160x80 TFT with
  78.   // plug-in FPC (if you see the tft is inverted!)
  79.   //tft.initR(INITR_MINI160x80_PLUGIN); // Init ST7735S mini tft
  80.  
  81.   // OR use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT:
  82.   //tft.init(240, 240); // Init ST7789 240x240
  83.  
  84.   // OR use this initializer (uncomment) if using a 1.69" 280x240 TFT:
  85.   //tft.init(240, 280); // Init ST7789 280x240
  86.  
  87.   // OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
  88.   //tft.init(240, 320); // Init ST7789 320x240
  89.  
  90.   // OR use this initializer (uncomment) if using a 1.14" 240x135 TFT:
  91.   //tft.init(135, 240); // Init ST7789 240x135
  92.  
  93.   // OR use this initializer (uncomment) if using a 1.47" 172x320 TFT:
  94.   //tft.init(172, 320); // Init ST7789 172x320
  95.  
  96.   // SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
  97.   // Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
  98.   // may end up with a black screen some times, or all the time.
  99.   //tft.setSPISpeed(40000000);
  100.  
  101.   //Serial.println(F("Initialized"));
  102.   Serial.begin(9600);
  103.   // If you want to set the aref to something other than 5v
  104.   analogReference(EXTERNAL);
  105.   Wire.begin();
  106.  
  107.  
  108.   uint16_t time = millis();
  109.  
  110.   time = millis() - time;
  111.  
  112.   Serial.println(time, DEC);
  113.   //delay(500);
  114.  
  115.   // large block of text
  116.   //tft.fillScreen(ST77XX_BLACK);
  117.   //testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
  118.   //delay(1000);
  119.  
  120.   // tft print function!
  121.   //tftPrintTest();
  122.   //delay(4000);
  123.  
  124.   // a single pixel
  125.   //tft.drawPixel(tft.width() / 2, tft.height() / 2, ST77XX_GREEN);
  126.   //delay(500);
  127.  
  128.   // line draw test
  129.   //testlines(ST77XX_YELLOW);
  130.   //delay(500);
  131.  
  132.   // optimized lines
  133.   //testfastlines(ST77XX_RED, ST77XX_BLUE);
  134.   //delay(500);
  135.  
  136.   //testdrawrects(ST77XX_GREEN);
  137.   //delay(500);
  138.  
  139.   //testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
  140.   //delay(500);
  141.  
  142.   tft.fillScreen(ST77XX_BLACK);
  143.   tft.fillCircle(tft.width() / 2, tft.height() / 2, 60, ST77XX_RED);
  144.  
  145. }
  146.  
  147. void loop() {
  148.   //DateTime now = RTC.now();
  149.   // Now draw the clock face
  150.   //tft.fillCircle(tft.width() / 2, tft.height() / 2, 60, ST77XX_RED);
  151.   tft.fillCircle(tft.width() / 2, tft.height() / 2, 50, ST77XX_BLACK);
  152.   //
  153.   //hour ticks
  154.   for ( int z = 0; z < 360; z = z + 30 ) {
  155.     //Begin at 0° and stop at 360°
  156.     float angle = z ;
  157.     angle = (angle / 57.29577951) ; //Convert degrees to radians
  158.     int x2 = (tft.width() / 2 + (sin(angle) * 58));
  159.     int y2 = (tft.height() / 2 - (cos(angle) * 58));
  160.     int x3 = (tft.width() / 2 + (sin(angle) * (58 - 5)));
  161.     int y3 = (tft.height() / 2 - (cos(angle) * (58 - 5)));
  162.     tft.drawLine(x2, y2, x3, y3, ST77XX_WHITE);
  163.   }
  164.   // tft second hand
  165.   float angle = second() * 6 ;
  166.   angle = (angle / 57.29577951) ; //Convert degrees to radians
  167.   int x3 = (tft.width() / 2 + (sin(angle+1.570796) * (50)));//ラジアン表示は時計の3時がスタート地点なので90度(π/4)ずれてる分単純に1.570796足す
  168.   int y3 = (tft.height() / 2 - (cos(angle+1.570796) * (50)));
  169.   //tft.drawLine(tft.width() / 2, tft.height() / 2, x3, y3, ST77XX_ORANGE);
  170.   //
  171.   // tft second hand
  172.   //float angle = now.second() * 6 ;
  173.   //angle = (angle / 57.29577951) ; //Convert degrees to radians
  174.   int x4 = (tft.width() / 2 + (sin(angle + 0.3+1.570796) * (-10)));
  175.   int y4 = (tft.height() / 2 - (cos(angle + 0.3+1.570796) * (-10)));
  176.   int x5 = (tft.width() / 2 + (sin(angle - 0.3+1.570796) * (-10)));
  177.   int y5 = (tft.height() / 2 - (cos(angle - 0.3+1.570796) * (-10)));
  178.  
  179.   //tft.drawLine(tft.width() / 2, tft.height() / 2, x4, y4, ST77XX_ORANGE);
  180.   //tft.drawLine(tft.width() / 2, tft.height() / 2, x5, y5, ST77XX_ORANGE);
  181.   tft.fillTriangle(x3, y3 , x4, y4, x5, y5, ST77XX_ORANGE);
  182.  
  183.   //
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.   // tft minute hand
  192.   angle = minute() * 6 ;
  193.   angle = (angle / 57.29577951) ; //Convert degrees to radians
  194.   x3 = (tft.width() / 2 + (sin(angle+1.570796) * (50 - 3)));
  195.   y3 = (tft.height() / 2 - (cos(angle+1.570796) * (50 - 3)));
  196.   tft.drawLine(tft.width() / 2, tft.height() / 2, x3, y3, ST77XX_GREEN);
  197.   //
  198.   // tft hour hand
  199.   Serial.print(hour());
  200.   angle = hour() * 30 + int((minute() / 12) * 6 ) ;
  201.   angle = (angle / 57.29577951) ; //Convert degrees to radians
  202.   x3 = (tft.width() / 2 + (sin(angle+1.570796) * (50 - 20)));
  203.   y3 = (tft.height() / 2 - (cos(angle+1.570796) * (50 - 20)));
  204.   tft.drawLine(tft.width() / 2, tft.height() / 2, x3, y3, ST77XX_BLUE);
  205.   //
  206.   //Serial.print(hour());
  207.   Serial.print(minute());
  208.   Serial.print(second());
  209.   Serial.print(' ');
  210.   Serial.print(day());
  211.   Serial.print(' ');
  212.   Serial.print(month());
  213.   Serial.print(' ');
  214.   Serial.print(year());
  215.   Serial.println();
  216.  
  217.   delay(1000);
  218. }
  219.  
  220.  
  221.  
  222.  
  223.  
  224. void testfastlines(uint16_t color1, uint16_t color2) {
  225.   tft.fillScreen(ST77XX_BLACK);
  226.   for (int16_t y = 0; y < tft.height(); y += 5) {
  227.     tft.drawFastHLine(0, y, tft.width(), color1);
  228.   }
  229.   for (int16_t x = 0; x < tft.width(); x += 5) {
  230.     tft.drawFastVLine(x, 0, tft.height(), color2);
  231.   }
  232. }
  233.  
  234. void testdrawrects(uint16_t color) {
  235.   tft.fillScreen(ST77XX_BLACK);
  236.   for (int16_t x = 0; x < tft.width(); x += 6) {
  237.     tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color);
  238.   }
  239. }
  240.  
  241. void testfillrects(uint16_t color1, uint16_t color2) {
  242.   tft.fillScreen(ST77XX_BLACK);
  243.   for (int16_t x = tft.width() - 1; x > 6; x -= 6) {
  244.     tft.fillRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color1);
  245.     tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color2);
  246.   }
  247. }
  248.  
  249. void testfillcircles(uint8_t radius, uint16_t color) {
  250.   for (int16_t x = radius; x < tft.width(); x += radius * 2) {
  251.     for (int16_t y = radius; y < tft.height(); y += radius * 2) {
  252.       tft.fillCircle(x, y, radius, color);
  253.     }
  254.   }
  255. }
  256.  
  257. void testdrawcircles(uint8_t radius, uint16_t color) {
  258.   for (int16_t x = 0; x < tft.width() + radius; x += radius * 2) {
  259.     for (int16_t y = 0; y < tft.height() + radius; y += radius * 2) {
  260.       tft.drawCircle(x, y, radius, color);
  261.     }
  262.   }
  263. }
  264.  
  265. void testtriangles() {
  266.   tft.fillScreen(ST77XX_BLACK);
  267.   uint16_t color = 0xF800;
  268.   int t;
  269.   int w = tft.width() / 2;
  270.   int x = tft.height() - 1;
  271.   int y = 0;
  272.   int z = tft.width();
  273.   for (t = 0 ; t <= 15; t++) {
  274.     tft.drawTriangle(w, y, y, x, z, x, color);
  275.     x -= 4;
  276.     y += 4;
  277.     z -= 4;
  278.     color += 100;
  279.   }
  280. }
  281.  
  282. void testroundrects() {
  283.   tft.fillScreen(ST77XX_BLACK);
  284.   uint16_t color = 100;
  285.   int i;
  286.   int t;
  287.   for (t = 0 ; t <= 4; t += 1) {
  288.     int x = 0;
  289.     int y = 0;
  290.     int w = tft.width() - 2;
  291.     int h = tft.height() - 2;
  292.     for (i = 0 ; i <= 16; i += 1) {
  293.       tft.drawRoundRect(x, y, w, h, 5, color);
  294.       x += 2;
  295.       y += 3;
  296.       w -= 4;
  297.       h -= 6;
  298.       color += 1100;
  299.     }
  300.     color += 100;
  301.   }
  302. }

SSD1306の時と同じアナログ時計だが、秒針を細長の三角形にして強調してある。

それと再描画は文字盤の内側の針の部分だけ実施している。

ちなみに縦長方向が標準の向きなので、表示はライブラリの機能で90度回転している。

 

 

  重たいおまけ

抗がん剤と糖尿でインシュリン注射の組み合わせってかなりしんどい。

記憶もほとんどないうちに一か月半経過していた。

抗がん剤治療が半年経ったので手術の予定。

ステージ4なので切ってもどんだけ先があるか。数か月か数年か。

ガン治療の様子はこちら。