グラフィック液晶SSD1306
キャラクター液晶はドットで文字などを表示を行う。
グラフィック液晶は一文字ごとのドットのエリアに距離が無く、円や四角形を画面全体に表示できる。
秋月電子さんでは500円位で販売しているが、梱包手数料が必要になる。
中華ショップは値段の変動があり、送料等確認してから購入すればよい。
128×64ドットなのでキャラクター液晶と合わせてサブ画面で使うのも面白いと思う。
接続はI2C規格なので下記の通りで。
液晶モジュール Arduino UNO
GND → GND
VCC → 5V
SCA → A4
SCL → A5
同じくI2C接続のRTCモジュールを忘れずに。
RTCの時計の時刻書込みは以前の記事を参照。
僕はDS3231を使用した。
スケッチではライブラリは「RTClib」を使用しているが動作するので問題ない(と思う)。
ネットの作例はデモ画面ばかり
グラフィック液晶なのに文字を表示するだけではもったいない。
アナログ時計の表示は三角関数でドットを描画しているので、ゲージ風表示などで応用が利きそうなので試してみた。
ライブラリはAdafruit社の提供のものを使用する。
Adafruit_GFX Library
Adafruit_SSD1306
この二つをArduino IDEで
スケッチメニュー>>ライブラリをインクルード>>ライブラリを管理
を選択するとライブラリマネージャーが開く。
ライブラリーマネージャーの検索窓で上記二個のライブラリをインストールする。
とは言ってもコードはネットで捜したもの
Youtubeの外国の方の動画で以前見付けた。借用いたします。改編もしました。公開者の方、ありがとうございます。
文字盤が小さいので大きくした。
文字盤の文字は端折った。
/***************************************************************OLED Analogue Clock using Adafruit GFX and OLED librariesby Chris Rouse Oct 2014visit https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examplesfor the OLED libraries and instructions on their use.Note:: Sketch uses 51% of program storage space,Global variables use 90% of dyamic memory,leaving 187 bytes for local variables.Using a IIC 128x64 OLED with SSD1306 chipRTC DS1307Optional Temperature Sensor TMP 36Wire RTC:VCC +5vGND GNDSDA Analog pin 4SCL Analog pin 5Wire OLED:VCC +5vGND GNDSDA Analog pin 4SCL Analog pin 5Wire TMP36:VCC +3.3vGND GNDOut Analog pin 1Connect ARef to 3.3v on Arduino***************************************************************/// Add libraries// #include <SPI.h>#include <Wire.h>#include "RTClib.h"#include <Adafruit_GFX.h>#include <Adafruit_SSD1306.h>//// setup OLED display#define OLED_RESET 4Adafruit_SSD1306 display(OLED_RESET);#if (SSD1306_LCDHEIGHT != 64)#error("Height incorrect, please fix Adafruit_SSD1306.h!");#endif//// Setup RTCRTC_DS1307 RTC;void setup() {Serial.begin(9600);// If you want to set the aref to something other than 5vanalogReference(EXTERNAL);Wire.begin();RTC.begin();if (! RTC.isrunning()) {Serial.println("RTC is NOT running!");// following line sets the RTC to the date & time this sketch was compiledRTC.adjust(DateTime(__DATE__, __TIME__));}// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)// Use I2C Scanner to check the address, if necessary change the 0x3C in the line belowdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)// init done// set font sizedisplay.setTextSize(1); // small font sizedisplay.setTextColor(WHITE);display.clearDisplay();}void loop() {//***** RTC **********DateTime now = RTC.now();//// Now draw the clock facedisplay.drawCircle(display.width()/2, display.height()/2, 30, WHITE);display.drawCircle(display.width()/2, display.height()/2, 26, WHITE);////hour ticksfor( int z=0; z < 360;z= z + 30 ){//Begin at 0° and stop at 360°float angle = z ;angle=(angle/57.29577951) ; //Convert degrees to radiansint x2=(64+(sin(angle)*26));int y2=(32-(cos(angle)*26));int x3=(64+(sin(angle)*(26-4)));int y3=(32-(cos(angle)*(26-4)));display.drawLine(x2,y2,x3,y3,WHITE);}// display second handfloat angle = now.second()*6 ;angle=(angle/57.29577951) ; //Convert degrees to radiansint x3=(64+(sin(angle)*(20-3)));int y3=(32-(cos(angle)*(20-3)));display.drawLine(64,32,x3,y3,WHITE);//// display minute handangle = now.minute() * 6 ;angle=(angle/57.29577951) ; //Convert degrees to radiansx3=(64+(sin(angle)*(20-3)));y3=(32-(cos(angle)*(20-3)));display.drawLine(64,32,x3,y3,WHITE);//// display hour handangle = now.hour() * 30 + int((now.minute() / 12) * 6 ) ;angle=(angle/57.29577951) ; //Convert degrees to radiansx3=(64+(sin(angle)*(20-11)));y3=(32-(cos(angle)*(20-11)));display.drawLine(64,32,x3,y3,WHITE);//// now add temperature if needed// update display with all datadisplay.display();//delay(1000);//if (now.second()==0)display.clearDisplay();}// **************** End Main Loop *****************void printDigits(int digits){// utility function for digital clock display: prints preceding colon and leading 0display.print(":");if(digits < 10)display.print('0');display.print(digits);}
思いの外地味で、僕みたいに目が弱った人間には見づらい。
この画面にデジタル時計の表示をしても本末転倒である。
針だけでは地味なので、文字盤の外周を塗りつぶしていくようにした。
0秒の時点で塗りつぶしを消している。
/***************************************************************OLED Analogue Clock using Adafruit GFX and OLED librariesby Chris Rouse Oct 2014visit https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examplesfor the OLED libraries and instructions on their use.Note:: Sketch uses 51% of program storage space,Global variables use 90% of dyamic memory,leaving 187 bytes for local variables.Using a IIC 128x64 OLED with SSD1306 chipRTC DS1307Optional Temperature Sensor TMP 36Wire RTC:VCC +5vGND GNDSDA Analog pin 4SCL Analog pin 5Wire OLED:VCC +5vGND GNDSDA Analog pin 4SCL Analog pin 5Wire TMP36:VCC +3.3vGND GNDOut Analog pin 1Connect ARef to 3.3v on Arduino***************************************************************/// Add libraries#include <SPI.h>#include <Wire.h>#include "RTClib.h"#include <Adafruit_GFX.h>#include <Adafruit_SSD1306.h>//// setup OLED display#define OLED_RESET 4Adafruit_SSD1306 display(OLED_RESET);#if (SSD1306_LCDHEIGHT != 64)#error("Height incorrect, please fix Adafruit_SSD1306.h!");#endif//// Setup RTCRTC_DS1307 RTC;void setup() {Serial.begin(9600);// If you want to set the aref to something other than 5vanalogReference(EXTERNAL);Wire.begin();RTC.begin();if (! RTC.isrunning()) {Serial.println("RTC is NOT running!");// following line sets the RTC to the date & time this sketch was compiledRTC.adjust(DateTime(__DATE__, __TIME__));}// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)// Use I2C Scanner to check the address, if necessary change the 0x3C in the line belowdisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)// init done// set font sizedisplay.setTextSize(1); // small font sizedisplay.setTextColor(WHITE);display.clearDisplay();}void loop() {//***** RTC **********DateTime now = RTC.now();//// Now draw the clock facedisplay.drawCircle(display.width()/2, display.height()/2, 30, WHITE);display.drawCircle(display.width()/2, display.height()/2, 26, WHITE);////hour ticksfor( int z=0; z < 360;z= z + 30 ){//Begin at 0° and stop at 360°float angle = z ;angle=(angle/57.29577951) ; //Convert degrees to radiansint x2=(64+(sin(angle)*26));int y2=(32-(cos(angle)*26));int x3=(64+(sin(angle)*(26-4)));int y3=(32-(cos(angle)*(26-4)));display.drawLine(x2,y2,x3,y3,WHITE);}// display second handfloat angle = now.second()*6 ;angle=(angle/57.29577951) ; //Convert degrees to radiansint x3=(64+(sin(angle)*(28)));int y3=(32-(cos(angle)*(28)));display.fillCircle(x3,y3,2,WHITE);//// display minute handangle = now.minute() * 6 ;angle=(angle/57.29577951) ; //Convert degrees to radiansx3=(64+(sin(angle)*(20-3)));y3=(32-(cos(angle)*(20-3)));display.drawLine(64,32,x3,y3,WHITE);//// display hour handangle = now.hour() * 30 + int((now.minute() / 12) * 6 ) ;angle=(angle/57.29577951) ; //Convert degrees to radiansx3=(64+(sin(angle)*(20-11)));y3=(32-(cos(angle)*(20-11)));display.drawLine(64,32,x3,y3,WHITE);//// now add temperature if needed// update display with all datadisplay.display();delay(100);if (now.second()==0)display.clearDisplay();}// **************** End Main Loop *****************void printDigits(int digits){// utility function for digital clock display: prints preceding colon and leading 0display.print(":");if(digits < 10)display.print('0');display.print(digits);}
ライブラリには画面のテキストを表示する以外は、円、三角、四角、角にRをとった四角、線を引く、点を打つが基本である。
三角形は三点の座標を指定して塗りつぶしができるが、四角形は始点と高さと幅で指定である。
ゲージの表示など凝った画面を作ろうかと思えば、三角形を描画して塗りつぶした後に円や四角で消すとかが必要かと。
それかひたすらドットで描画するか。
次回
今回はRTCの時刻から表示しているが、次回は外部からの入力をグラフィック液晶に表示しようと思う。
おまけ
半年以上休職して病気療養中である。結構しんどいが、
癌治療中の現在の様子はこちら。




