M5 ATOM Lite LovyanGFX 基本図形描画
<コード>
#include <M5Atom.h>
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <Wire.h>
//グローバル変数********************************************************
uint colorNumber=0;//RGBLEDの色配列指定
int color[3]={0xFF0000,0x008000, 0x0000FF};//RGBLED Red(8),Green(8),Blue(8)
uint state=0;
int32_t t=0;
// コンストラクタを作成し、ここで各種設定を行います。
class LGFX_SSD1306 : public lgfx::LGFX_Device
{
lgfx::Panel_SSD1306 _panel_instance; // SSD1306構造体のインスタンス
lgfx::Bus_I2C _bus_instance; // バス設定用の構造体を取得します。
// コンストラクタ
public:
LGFX_SSD1306()
{
{ //I2Cバスクラスの構造体に設定。
auto cfg = _bus_instance.config(); // I2Cバス構造体インスタンスの取得
cfg.i2c_port = 1; // 使用するI2Cポートを選択 (0 or 1)Wire0, Wire1の選択
cfg.freq_write = 400000; // 送信時のクロック クロック周波数
cfg.freq_read = 400000; // 受信時のクロック クロック周波数
cfg.pin_sda = 25; // SDAを接続しているピン番号 SDAピン
cfg.pin_scl = 21; // SCLを接続しているピン番号 SCLピン
cfg.i2c_addr = 0x3C; // I2Cデバイスのアドレス スレーブアドレス
_bus_instance.config(cfg); //設定値をバスに反映します。
_panel_instance.setBus(&_bus_instance); //バスをパネルにセットします。
}
{ // 表示パネル制御の設定を行います。
auto cfg = _panel_instance.config();
// 以下はST7735やILI9163のようにピクセル数が可変のドライバで表示がずれる場合にのみ設定してください。
//cfg.memory_width = 128; // ドライバICがサポートしている最大の幅
//cfg.memory_height = 64; // ドライバICがサポートしている最大の高さ
cfg.offset_rotation = 2; //回転方向のオフセット 0~7 (4~7は上下反転)
_panel_instance.config(cfg); //再設定
}
setPanel(&_panel_instance); // 使用するパネルをセットします。
}
};
//LovyanGFXインスタンス*************************************************
static LGFX_SSD1306 lcd;
static LGFX_Sprite canvas(&lcd); //スプライトバッファ
//setup****************************************************************
void setup()
{
int i;
//ATOM初期化---------------------------------------------------------
M5.begin(true, false, true); //初期化(UART, I2C wire0 , LED)
//ATOM RGBLED点滅----------------------------------------------------
for(i=0; i<=3; i++)
{
M5.dis.drawpix(0, 0x000FFF000);
delay(300);
M5.dis.drawpix(0, 0x000000);
delay(300);
}
//SSD1306初期化 LovyanGFX--------------------------------------------
lcd.init();
canvas.createSprite(lcd.width(), lcd.height());
canvas.setTextWrap(false); //自動折返し:無し
canvas.fillScreen(TFT_BLACK); //背景塗り潰し
canvas.setTextColor(TFT_WHITE); //文字色
t=0;
//グローバル変数 カウント値初期化-------------------------------------
state=17;
}
int tw=0;
int sign=1;
int repeat;
//メインルーチン********************************************************
void loop()
{
uint8_t err;
int x0,x1,x2,x3;
int y0,y1,y2,y3;
//RGBLED-------------------------------------
M5.dis.drawpix(0,color[colorNumber++]);
if(colorNumber==3)
{
colorNumber=0;
}
//SSD1306 表示---------------------------------
canvas.beginTransaction();/// 通信トランザクションを開始する。(ペリフェラルを占有する);
switch(state)
{
case 0:
//drawFastVLine ( x, y , h , color); // 垂直線
canvas.drawFastVLine ( 3+10*t, 0 , 60 , TFT_WHITE); // 垂直線
t++;
if(t==15)
{
t=0;
state=1;
}
break;
case 1:
//drawFastHLine ( x, y, w , color); // 水平線
canvas.drawFastHLine ( 0, 0+10*t, 128 , TFT_WHITE); // 水平線
t++;
if(t==7)
{
t=0;
state=2;
}
break;
case 2:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=3;
break;
case 3:
//drawRect ( x, y, w, h , color); // 矩形の外周
canvas.drawRect( 3+t*10, 3+t*10, 17, 17,TFT_WHITE); // 矩形の外周
canvas.drawRect( 50+t*10, 3+t*10, 17, 17,TFT_WHITE); // 矩形の外周
t++;
if(t==5)
{
t=0;
state=4;
}
break;
case 4:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=5;
break;
case 5:
//fillRect ( x, y, w, h , color); // 矩形の塗り
canvas.fillRect(3+t*17, 5+t*17, 17, 17,TFT_WHITE); // 矩形の塗り
canvas.fillRect(70+t*17, 5+t*17, 17, 17,TFT_WHITE); // 矩形の塗り
t++;
if(t==3)
{
t=0;
state=6;
}
break;
case 6:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=7;
break;
case 7:
//drawRoundRect ( x, y, w, h, r, color); // 角丸の矩形の外周
canvas.drawRoundRect (5+t*40, 20, 30, 30, 5, TFT_WHITE); // 角丸の矩形の外周
t++;
if(t==3)
{
t=0;
state=8;
}
break;
case 8:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=9;
break;
case 9:
//fillRoundRect ( x, y, w, h, r, color); // 角丸の矩形の塗り
canvas.fillRoundRect(5+t*40, 20, 30, 30, 5, TFT_WHITE); // 角丸の矩形の塗り
t++;
if(t==3)
{
t=0;
state=10;
}
break;
case 10:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=11;
break;
case 11:
//drawCircle ( x, y , r, color); // 円の外周
canvas.drawCircle(3+t*13, 3+t*13, 9, TFT_WHITE); // 円の外周
canvas.fillCircle(50+t*18, 3+t*13, 9, TFT_WHITE); // 円の塗り
t++;
if(t==5)
{
t=0;
state=12;
}
break;
case 12:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=13;
break;
case 13:
//drawEllipse ( x, y, rx, ry , color); // 楕円の外周
canvas.drawEllipse(3+t*18, 3+t*18, 10, 5 , TFT_WHITE); // 楕円の外周
//fillEllipse ( x, y, rx, ry , color); // 楕円の塗り
canvas.fillEllipse(50+t*18, 3+t*18, 10, 5 , TFT_WHITE); // 楕円の塗り
t++;
if(t==5)
{
t=0;
state=14;
}
break;
case 14:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=15;
break;
case 15:
x0=10+tw; x1=x0+10; x2=x0+20; y0=30; y1=0; y2=60, y3=30;
//drawTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の外周
canvas.drawTriangle( x0, y0, x1, y1, x2, y0, TFT_WHITE); // 3点間の三角形の外周
//fillTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の塗り
canvas.fillTriangle( x0, y2, x1, y3, x2, y2, TFT_WHITE); // 3点間の三角形の塗り
tw+=25;
if(tw==125)
{
tw=0;
state=16;
}
break;
case 16:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=17;
break;
case 17:
canvas.fillScreen(TFT_BLACK);
//drawBezier ( x0, y0, x1, y1, x2, y2, color); // 3点間のベジエ曲線
canvas.drawTriangle(10, 60, 50, 0+t, 120, 60, TFT_WHITE); // 3点間の三角形の外周
canvas.drawBezier(10, 60, 50, 0+t, 120, 60, TFT_WHITE); // 3点間のベジエ曲線
t+=5;
if(t==50)
{
t=0;
state=18;
}
break;
case 18:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=19;
break;
case 19:
canvas.fillScreen(TFT_BLACK);
canvas.drawRect(10, 5, 100, 55,TFT_WHITE); // 矩形の塗り
//drawBezier ( x0, y0, x1, y1, x2, y2, x3, y3, color); // 4点間のベジエ曲線
x0=10; y0=60; x1=10+t; y1=60; x2=10+t; y2=5; x3=110; y3=5;
canvas.drawBezier(x0, y0, x1, y1, x2, y2, x3, y3, TFT_WHITE);
t+=10;
if(t==100)
{
t=0;
state=20;
}
break;
case 20:
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=21;
sign=1;
repeat=0;
break;
case 21:
canvas.fillScreen(TFT_BLACK);
canvas.drawString("0",55,50);
canvas.drawString("50%",17,30);
canvas.drawString("100%",80,15);
//drawArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の外周
canvas.drawArc( 60, 40, 25, 15, 120,320, TFT_WHITE); // 円弧の外周
canvas.fillArc( 60, 40, 25, 15, 120,120+t, TFT_WHITE); // 円弧の塗り
//Serial.printf("angle1=%d t=%d sign=%d \r",120+t, t, sign);
if(sign>=0)
t+=10;
if(sign<0)
t-=10;
if(t==200)
{
sign=-1;
}
if(t==-10)
{
t=0;
sign=1;
repeat++;
if(repeat==4)
{
repeat=0;
t=0;
state=22;
Serial.printf("State=%d\r",state);
}
}
break;
case 22:
sign=1;
delay(1000);
canvas.fillScreen(TFT_BLACK);
state=0;
break;
}
canvas.pushSprite(0,0);
canvas.endTransaction();/// 通信トランザクションを終了する。(ペリフェラルの占有を終了する);
switch(state)
{
case 0:
delay(100);
break;
case 1:
delay(100);
break;
case 3:
delay(200);
break;
case 5:
delay(400);
break;
case 7:
delay(400);
break;
case 9:
delay(400);
break;
case 11:
delay(400);
break;
case 13:
delay(400);
break;
case 15:
delay(400);
break;
case 17:
delay(700);
break;
case 19:
delay(500);
break;
case 21:
delay(50);
break;
}
}
<LovyanGFX カラーコード>
static constexpr int TFT_BLACK = 0x0000; /* 0, 0, 0 */
static constexpr int TFT_NAVY = 0x000F; /* 0, 0, 128 */
static constexpr int TFT_DARKGREEN = 0x03E0; /* 0, 128, 0 */
static constexpr int TFT_DARKCYAN = 0x03EF; /* 0, 128, 128 */
static constexpr int TFT_MAROON = 0x7800; /* 128, 0, 0 */
static constexpr int TFT_PURPLE = 0x780F; /* 128, 0, 128 */
static constexpr int TFT_OLIVE = 0x7BE0; /* 128, 128, 0 */
static constexpr int TFT_LIGHTGREY = 0xD69A; /* 211, 211, 211 */
static constexpr int TFT_LIGHTGRAY = 0xD69A; /* 211, 211, 211 */
static constexpr int TFT_DARKGREY = 0x7BEF; /* 128, 128, 128 */
static constexpr int TFT_DARKGRAY = 0x7BEF; /* 128, 128, 128 */
static constexpr int TFT_BLUE = 0x001F; /* 0, 0, 255 */
static constexpr int TFT_GREEN = 0x07E0; /* 0, 255, 0 */
static constexpr int TFT_CYAN = 0x07FF; /* 0, 255, 255 */
static constexpr int TFT_RED = 0xF800; /* 255, 0, 0 */
static constexpr int TFT_MAGENTA = 0xF81F; /* 255, 0, 255 */
static constexpr int TFT_YELLOW = 0xFFE0; /* 255, 255, 0 */
static constexpr int TFT_WHITE = 0xFFFF; /* 255, 255, 255 */
static constexpr int TFT_ORANGE = 0xFDA0; /* 255, 180, 0 */
static constexpr int TFT_GREENYELLOW = 0xB7E0; /* 180, 255, 0 */
static constexpr int TFT_PINK = 0xFE19; /* 255, 192, 203 */ //Lighter pink, was 0xFC9F
static constexpr int TFT_BROWN = 0x9A60; /* 150, 75, 0 */
static constexpr int TFT_GOLD = 0xFEA0; /* 255, 215, 0 */
static constexpr int TFT_SILVER = 0xC618; /* 192, 192, 192 */
static constexpr int TFT_SKYBLUE = 0x867D; /* 135, 206, 235 */
static constexpr int TFT_VIOLET = 0x915C; /* 180, 46, 226 */
static constexpr int TFT_TRANSPARENT = 0x0120;
<constexpr について>
C++の「constexpr」というキーワードは、変数や関数を定義する際に使います。constant expressionの略です。
constexprを使うことで、関数をコンパイル時に計算して値を得ることも、実行時に求めることもできます。
ex)
constexpr int square(int x)
{
return x * x;
}
main()
{
constexpr int ans = square(3); //コンパイル時に計算されます。
int exeAns = square(5): //実行時に計算されます。
}
<LovyanGFX 基本的な図形の描画関数>
fillScreen ( color); // 画面全体の塗り潰し
drawPixel ( x, y , color); // 点
drawFastVLine ( x, y , h , color); // 垂直線
drawFastHLine ( x, y, w , color); // 水平線
drawRect ( x, y, w, h , color); // 矩形の外周
fillRect ( x, y, w, h , color); // 矩形の塗り
drawRoundRect ( x, y, w, h, r, color); // 角丸の矩形の外周
fillRoundRect ( x, y, w, h, r, color); // 角丸の矩形の塗り
drawCircle ( x, y , r, color); // 円の外周
fillCircle ( x, y , r, color); // 円の塗り
drawEllipse ( x, y, rx, ry , color); // 楕円の外周
fillEllipse ( x, y, rx, ry , color); // 楕円の塗り
drawLine ( x0, y0, x1, y1 , color); // 2点間の直線
drawTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の外周
fillTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の塗り
drawBezier ( x0, y0, x1, y1, x2, y2, color); // 3点間のベジエ曲線
drawBezier ( x0, y0, x1, y1, x2, y2, x3, y3, color); // 4点間のベジエ曲線
drawArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の外周
fillArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の塗り