test
This commit is contained in:
335
BackUp/LVGL
Normal file
335
BackUp/LVGL
Normal file
@@ -0,0 +1,335 @@
|
||||
#include <Wire.h>
|
||||
#include <INA226.h>
|
||||
INA226 ina(Wire);
|
||||
|
||||
// #define LGFX_AUTODETECT
|
||||
// #include <LGFX_AUTODETECT.hpp>
|
||||
|
||||
#include <lv_demo.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
/*Change to your screen resolution*/
|
||||
static const uint16_t screenWidth = 320;
|
||||
static const uint16_t screenHeight = 172;
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf[2][screenWidth * 10];
|
||||
|
||||
#include <LovyanGFX.hpp>
|
||||
// ESP32でLovyanGFXを独自設定で利用する場合の設定例
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ST7789 _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
|
||||
lgfx::Light_PWM _light_instance;
|
||||
|
||||
public:
|
||||
// コンストラクタを作成し、ここで各種設定を行います。
|
||||
// クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
|
||||
LGFX(void)
|
||||
{
|
||||
{ // バス制御の設定を行います。
|
||||
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
|
||||
|
||||
// SPIバスの設定
|
||||
cfg.spi_host = SPI2_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
|
||||
cfg.spi_mode = 3; // SPI通信モードを設定 (0 ~ 3)
|
||||
cfg.freq_write = 80000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.freq_read = 16000000; // 受信時のSPIクロック
|
||||
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
|
||||
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
|
||||
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
|
||||
cfg.pin_sclk = 4; // SPIのSCLKピン番号を設定
|
||||
cfg.pin_mosi = 5; // SPIのMOSIピン番号を設定
|
||||
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
|
||||
cfg.pin_dc = 6; // SPIのD/Cピン番号を設定 (-1 = disable)
|
||||
// SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
|
||||
_bus_instance.config(cfg); // 設定値をバスに反映します。
|
||||
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
|
||||
}
|
||||
|
||||
{ // 表示パネル制御の設定を行います。
|
||||
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_cs = 8; // CSが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_rst = 7; // RSTが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
|
||||
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
|
||||
cfg.panel_width = 172; // 実際に表示可能な幅
|
||||
cfg.panel_height = 320; // 実際に表示可能な高さ
|
||||
cfg.offset_x = 34; // パネルのX方向オフセット量
|
||||
cfg.offset_y = 0; // パネルのY方向オフセット量
|
||||
cfg.offset_rotation = 3; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
|
||||
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
|
||||
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
|
||||
cfg.readable = false; // データ読出しが可能な場合 trueに設定
|
||||
cfg.invert = true; // パネルの明暗が反転してしまう場合 trueに設定
|
||||
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
|
||||
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
|
||||
cfg.bus_shared = false; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
|
||||
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
{ // バックライト制御の設定を行います。(必要なければ削除)
|
||||
auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_bl = 10; // バックライトが接続されているピン番号
|
||||
cfg.invert = true; // バックライトの輝度を反転させる場合 true
|
||||
cfg.freq = 44100; // バックライトのPWM周波数
|
||||
cfg.pwm_channel = 1; // 使用するPWMのチャンネル番号
|
||||
|
||||
_light_instance.config(cfg);
|
||||
_panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance); // 使用するパネルをセットします。
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX lcd;
|
||||
// static LGFX_Sprite sprite(&lcd);
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
if (lcd.getStartCount() == 0)
|
||||
{ // Processing if not yet started
|
||||
lcd.startWrite();
|
||||
}
|
||||
lcd.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::swap565_t *)&color_p->full);
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
// void sd_access_sample(void)
|
||||
// {
|
||||
// if (lcd.getStartCount() > 0)
|
||||
// { // Free the bus before accessing the SD card
|
||||
// gfx.endWrite();
|
||||
// }
|
||||
|
||||
// // Something to manipulate the SD card.
|
||||
// auto file = SD.open("/file");
|
||||
// file.close();
|
||||
// }
|
||||
|
||||
/*Read the touchpad*/
|
||||
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
|
||||
{
|
||||
uint16_t touchX, touchY;
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
|
||||
if (lcd.getTouch(&touchX, &touchY))
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touchX;
|
||||
data->point.y = touchY;
|
||||
}
|
||||
}
|
||||
|
||||
void checkConfig()
|
||||
{
|
||||
Serial.print("Mode: ");
|
||||
switch (ina.getMode())
|
||||
{
|
||||
case INA226_MODE_POWER_DOWN:
|
||||
Serial.println("Power-Down");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_TRIG:
|
||||
Serial.println("Shunt Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_BUS_TRIG:
|
||||
Serial.println("Bus Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_TRIG:
|
||||
Serial.println("Shunt and Bus, Triggered");
|
||||
break;
|
||||
case INA226_MODE_ADC_OFF:
|
||||
Serial.println("ADC Off");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_CONT:
|
||||
Serial.println("Shunt Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_BUS_CONT:
|
||||
Serial.println("Bus Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_CONT:
|
||||
Serial.println("Shunt and Bus, Continuous");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Samples average: ");
|
||||
switch (ina.getAverages())
|
||||
{
|
||||
case INA226_AVERAGES_1:
|
||||
Serial.println("1 sample");
|
||||
break;
|
||||
case INA226_AVERAGES_4:
|
||||
Serial.println("4 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_16:
|
||||
Serial.println("16 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_64:
|
||||
Serial.println("64 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_128:
|
||||
Serial.println("128 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_256:
|
||||
Serial.println("256 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_512:
|
||||
Serial.println("512 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_1024:
|
||||
Serial.println("1024 samples");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Bus conversion time: ");
|
||||
switch (ina.getBusConversionTime())
|
||||
{
|
||||
case INA226_BUS_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Shunt conversion time: ");
|
||||
switch (ina.getShuntConversionTime())
|
||||
{
|
||||
case INA226_SHUNT_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Max possible current: ");
|
||||
Serial.print(ina.getMaxPossibleCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max current: ");
|
||||
Serial.print(ina.getMaxCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max shunt voltage: ");
|
||||
Serial.print(ina.getMaxShuntVoltage());
|
||||
Serial.println(" V");
|
||||
|
||||
Serial.print("Max power: ");
|
||||
Serial.print(ina.getMaxPower());
|
||||
Serial.println(" W");
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
lcd.init();
|
||||
// lcd.startWrite();
|
||||
lcd.setBrightness(100);
|
||||
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&draw_buf, buf[0], buf[1], screenWidth * 10);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
/*Change the following line to your display resolution*/
|
||||
disp_drv.hor_res = screenWidth;
|
||||
disp_drv.ver_res = screenHeight;
|
||||
disp_drv.flush_cb = my_disp_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/*Initialize the input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
lv_demo_benchmark();
|
||||
|
||||
Wire.begin(1, 0, 100000);
|
||||
// Default INA226 address is 0x40
|
||||
bool success = ina.begin();
|
||||
// Check if the connection was successful, stop if not
|
||||
if (!success)
|
||||
{
|
||||
Serial.println("Connection error");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
// Configure INA226
|
||||
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
|
||||
// Calibrate INA226. Rshunt = 0.001 ohm, Max excepted current = 4A
|
||||
ina.calibrate(0.001, 40);
|
||||
// Display configuration
|
||||
checkConfig();
|
||||
}
|
||||
int32_t current;
|
||||
int32_t current_buf[322];
|
||||
float t = 0;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
lv_timer_handler(); /* let the GUI do its work */
|
||||
delay(1);
|
||||
}
|
||||
541
BackUp/main copy
Normal file
541
BackUp/main copy
Normal file
@@ -0,0 +1,541 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <LovyanGFX.hpp>
|
||||
|
||||
// ESP32でLovyanGFXを独自設定で利用する場合の設定例
|
||||
|
||||
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
/*
|
||||
クラス名は"LGFX"から別の名前に変更しても構いません。
|
||||
AUTODETECTと併用する場合は"LGFX"は使用されているため、LGFX以外の名前に変更してください。
|
||||
また、複数枚のパネルを同時使用する場合もそれぞれに異なる名前を付けてください。
|
||||
※ クラス名を変更する場合はコンストラクタの名前も併せて同じ名前に変更が必要です。
|
||||
|
||||
名前の付け方は自由に決めて構いませんが、設定が増えた場合を想定し、
|
||||
例えばESP32 DevKit-CでSPI接続のILI9341の設定を行った場合、
|
||||
LGFX_DevKitC_SPI_ILI9341
|
||||
のような名前にし、ファイル名とクラス名を一致させておくことで、利用時に迷いにくくなります。
|
||||
//*/
|
||||
|
||||
// 接続するパネルの型にあったインスタンスを用意します。
|
||||
// lgfx::Panel_GC9A01 _panel_instance;
|
||||
// lgfx::Panel_GDEW0154M09 _panel_instance;
|
||||
// lgfx::Panel_HX8357B _panel_instance;
|
||||
// lgfx::Panel_HX8357D _panel_instance;
|
||||
// lgfx::Panel_ILI9163 _panel_instance;
|
||||
// lgfx::Panel_ILI9341 _panel_instance;
|
||||
// lgfx::Panel_ILI9342 _panel_instance;
|
||||
// lgfx::Panel_ILI9481 _panel_instance;
|
||||
// lgfx::Panel_ILI9486 _panel_instance;
|
||||
// lgfx::Panel_ILI9488 _panel_instance;
|
||||
// lgfx::Panel_IT8951 _panel_instance;
|
||||
// lgfx::Panel_RA8875 _panel_instance;
|
||||
// lgfx::Panel_SH110x _panel_instance; // SH1106, SH1107
|
||||
// lgfx::Panel_SSD1306 _panel_instance;
|
||||
// lgfx::Panel_SSD1327 _panel_instance;
|
||||
// lgfx::Panel_SSD1331 _panel_instance;
|
||||
// lgfx::Panel_SSD1351 _panel_instance; // SSD1351, SSD1357
|
||||
// lgfx::Panel_SSD1963 _panel_instance;
|
||||
// lgfx::Panel_ST7735 _panel_instance;
|
||||
// lgfx::Panel_ST7735S _panel_instance;
|
||||
lgfx::Panel_ST7789 _panel_instance;
|
||||
// lgfx::Panel_ST7796 _panel_instance;
|
||||
|
||||
// パネルを接続するバスの種類にあったインスタンスを用意します。
|
||||
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
|
||||
// lgfx::Bus_I2C _bus_instance; // I2Cバスのインスタンス
|
||||
// lgfx::Bus_Parallel8 _bus_instance; // 8ビットパラレルバスのインスタンス
|
||||
|
||||
// バックライト制御が可能な場合はインスタンスを用意します。(必要なければ削除)
|
||||
// lgfx::Light_PWM _light_instance;
|
||||
|
||||
// タッチスクリーンの型にあったインスタンスを用意します。(必要なければ削除)
|
||||
// lgfx::Touch_CST816S _touch_instance;
|
||||
// lgfx::Touch_FT5x06 _touch_instance; // FT5206, FT5306, FT5406, FT6206, FT6236, FT6336, FT6436
|
||||
// lgfx::Touch_GSL1680E_800x480 _touch_instance; // GSL_1680E, 1688E, 2681B, 2682B
|
||||
// lgfx::Touch_GSL1680F_800x480 _touch_instance;
|
||||
// lgfx::Touch_GSL1680F_480x272 _touch_instance;
|
||||
// lgfx::Touch_GSLx680_320x320 _touch_instance;
|
||||
// lgfx::Touch_GT911 _touch_instance;
|
||||
// lgfx::Touch_STMPE610 _touch_instance;
|
||||
// lgfx::Touch_TT21xxx _touch_instance; // TT21100
|
||||
// lgfx::Touch_XPT2046 _touch_instance;
|
||||
|
||||
public:
|
||||
// コンストラクタを作成し、ここで各種設定を行います。
|
||||
// クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
|
||||
LGFX(void)
|
||||
{
|
||||
{ // バス制御の設定を行います。
|
||||
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
|
||||
|
||||
// SPIバスの設定
|
||||
cfg.spi_host = SPI2_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
|
||||
cfg.spi_mode = 0; // SPI通信モードを設定 (0 ~ 3)
|
||||
cfg.freq_write = 40000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.freq_read = 16000000; // 受信時のSPIクロック
|
||||
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
|
||||
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
|
||||
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
|
||||
cfg.pin_sclk = 2; // SPIのSCLKピン番号を設定
|
||||
cfg.pin_mosi = 3; // SPIのMOSIピン番号を設定
|
||||
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
|
||||
cfg.pin_dc = 8; // SPIのD/Cピン番号を設定 (-1 = disable)
|
||||
// SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
|
||||
//*/
|
||||
/*
|
||||
// I2Cバスの設定
|
||||
cfg.i2c_port = 0; // 使用するI2Cポートを選択 (0 or 1)
|
||||
cfg.freq_write = 400000; // 送信時のクロック
|
||||
cfg.freq_read = 400000; // 受信時のクロック
|
||||
cfg.pin_sda = 21; // SDAを接続しているピン番号
|
||||
cfg.pin_scl = 22; // SCLを接続しているピン番号
|
||||
cfg.i2c_addr = 0x3C; // I2Cデバイスのアドレス
|
||||
//*/
|
||||
/*
|
||||
// 8ビットパラレルバスの設定
|
||||
cfg.i2s_port = I2S_NUM_0; // 使用するI2Sポートを選択 (I2S_NUM_0 or I2S_NUM_1) (ESP32のI2S LCDモードを使用します)
|
||||
cfg.freq_write = 20000000; // 送信クロック (最大20MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.pin_wr = 4; // WR を接続しているピン番号
|
||||
cfg.pin_rd = 2; // RD を接続しているピン番号
|
||||
cfg.pin_rs = 15; // RS(D/C)を接続しているピン番号
|
||||
cfg.pin_d0 = 12; // D0を接続しているピン番号
|
||||
cfg.pin_d1 = 13; // D1を接続しているピン番号
|
||||
cfg.pin_d2 = 26; // D2を接続しているピン番号
|
||||
cfg.pin_d3 = 25; // D3を接続しているピン番号
|
||||
cfg.pin_d4 = 17; // D4を接続しているピン番号
|
||||
cfg.pin_d5 = 16; // D5を接続しているピン番号
|
||||
cfg.pin_d6 = 27; // D6を接続しているピン番号
|
||||
cfg.pin_d7 = 14; // D7を接続しているピン番号
|
||||
//*/
|
||||
|
||||
_bus_instance.config(cfg); // 設定値をバスに反映します。
|
||||
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
|
||||
}
|
||||
|
||||
{ // 表示パネル制御の設定を行います。
|
||||
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_cs = 5; // CSが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_rst = 7; // RSTが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
|
||||
|
||||
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
|
||||
|
||||
cfg.panel_width = 135; // 実際に表示可能な幅
|
||||
cfg.panel_height = 240; // 実際に表示可能な高さ
|
||||
cfg.offset_x = 53; // パネルのX方向オフセット量
|
||||
cfg.offset_y = 40; // パネルのY方向オフセット量
|
||||
cfg.offset_rotation = 0; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
|
||||
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
|
||||
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
|
||||
cfg.readable = true; // データ読出しが可能な場合 trueに設定
|
||||
cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定
|
||||
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
|
||||
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
|
||||
cfg.bus_shared = true; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
|
||||
|
||||
// 以下はST7735やILI9163のようにピクセル数が可変のドライバで表示がずれる場合にのみ設定してください。
|
||||
// cfg.memory_width = 240; // ドライバICがサポートしている最大の幅
|
||||
// cfg.memory_height = 320; // ドライバICがサポートしている最大の高さ
|
||||
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
// //*
|
||||
// { // バックライト制御の設定を行います。(必要なければ削除)
|
||||
// auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
|
||||
|
||||
// cfg.pin_bl = 32; // バックライトが接続されているピン番号
|
||||
// cfg.invert = false; // バックライトの輝度を反転させる場合 true
|
||||
// cfg.freq = 44100; // バックライトのPWM周波数
|
||||
// cfg.pwm_channel = 7; // 使用するPWMのチャンネル番号
|
||||
|
||||
// _light_instance.config(cfg);
|
||||
// _panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
|
||||
// }
|
||||
// //*/
|
||||
|
||||
// //*
|
||||
// { // タッチスクリーン制御の設定を行います。(必要なければ削除)
|
||||
// auto cfg = _touch_instance.config();
|
||||
|
||||
// cfg.x_min = 0; // タッチスクリーンから得られる最小のX値(生の値)
|
||||
// cfg.x_max = 239; // タッチスクリーンから得られる最大のX値(生の値)
|
||||
// cfg.y_min = 0; // タッチスクリーンから得られる最小のY値(生の値)
|
||||
// cfg.y_max = 319; // タッチスクリーンから得られる最大のY値(生の値)
|
||||
// cfg.pin_int = 38; // INTが接続されているピン番号
|
||||
// cfg.bus_shared = true; // 画面と共通のバスを使用している場合 trueを設定
|
||||
// cfg.offset_rotation = 0;// 表示とタッチの向きのが一致しない場合の調整 0~7の値で設定
|
||||
|
||||
// // SPI接続の場合
|
||||
// cfg.spi_host = VSPI_HOST;// 使用するSPIを選択 (HSPI_HOST or VSPI_HOST)
|
||||
// cfg.freq = 1000000; // SPIクロックを設定
|
||||
// cfg.pin_sclk = 18; // SCLKが接続されているピン番号
|
||||
// cfg.pin_mosi = 23; // MOSIが接続されているピン番号
|
||||
// cfg.pin_miso = 19; // MISOが接続されているピン番号
|
||||
// cfg.pin_cs = 5; // CSが接続されているピン番号
|
||||
|
||||
// // I2C接続の場合
|
||||
// cfg.i2c_port = 1; // 使用するI2Cを選択 (0 or 1)
|
||||
// cfg.i2c_addr = 0x38; // I2Cデバイスアドレス番号
|
||||
// cfg.pin_sda = 23; // SDAが接続されているピン番号
|
||||
// cfg.pin_scl = 32; // SCLが接続されているピン番号
|
||||
// cfg.freq = 400000; // I2Cクロックを設定
|
||||
|
||||
// _touch_instance.config(cfg);
|
||||
// _panel_instance.setTouch(&_touch_instance); // タッチスクリーンをパネルにセットします。
|
||||
// }
|
||||
// //*/
|
||||
|
||||
setPanel(&_panel_instance); // 使用するパネルをセットします。
|
||||
}
|
||||
};
|
||||
|
||||
// 準備したクラスのインスタンスを作成します。
|
||||
static LGFX lcd;
|
||||
static LGFX_Sprite sprite(&lcd);
|
||||
// void setup(void)
|
||||
// {
|
||||
// // SPIバスとパネルの初期化を実行すると使用可能になります。
|
||||
// display.init();
|
||||
|
||||
// display.setTextSize((std::max(display.width(), display.height()) + 255) >> 8);
|
||||
|
||||
// // タッチが使用可能な場合のキャリブレーションを行います。(省略可)
|
||||
// if (display.touch())
|
||||
// {
|
||||
// if (display.width() < display.height())
|
||||
// display.setRotation(display.getRotation() ^ 1);
|
||||
|
||||
// // 画面に案内文章を描画します。
|
||||
// display.setTextDatum(textdatum_t::middle_center);
|
||||
// display.drawString("touch the arrow marker.", display.width() >> 1, display.height() >> 1);
|
||||
// display.setTextDatum(textdatum_t::top_left);
|
||||
|
||||
// // タッチを使用する場合、キャリブレーションを行います。画面の四隅に表示される矢印の先端を順にタッチしてください。
|
||||
// std::uint16_t fg = TFT_WHITE;
|
||||
// std::uint16_t bg = TFT_BLACK;
|
||||
// if (display.isEPD())
|
||||
// std::swap(fg, bg);
|
||||
// display.calibrateTouch(nullptr, fg, bg, std::max(display.width(), display.height()) >> 3);
|
||||
// }
|
||||
|
||||
// display.fillScreen(TFT_BLACK);
|
||||
// }
|
||||
|
||||
// uint32_t count = ~0;
|
||||
// void loop(void)
|
||||
// {
|
||||
// display.startWrite();
|
||||
// display.setRotation(++count & 7);
|
||||
// display.setColorDepth((count & 8) ? 16 : 24);
|
||||
|
||||
// display.setTextColor(TFT_WHITE);
|
||||
// display.drawNumber(display.getRotation(), 16, 0);
|
||||
|
||||
// display.setTextColor(0xFF0000U);
|
||||
// display.drawString("R", 30, 16);
|
||||
// display.setTextColor(0x00FF00U);
|
||||
// display.drawString("G", 40, 16);
|
||||
// display.setTextColor(0x0000FFU);
|
||||
// display.drawString("B", 50, 16);
|
||||
|
||||
// display.drawRect(30, 30, display.width() - 60, display.height() - 60, count * 7);
|
||||
// display.drawFastHLine(0, 0, 10);
|
||||
|
||||
// display.endWrite();
|
||||
|
||||
// int32_t x, y;
|
||||
// if (display.getTouch(&x, &y))
|
||||
// {
|
||||
// display.fillRect(x - 2, y - 2, 5, 5, count * 7);
|
||||
// }
|
||||
// }
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
// 最初に初期化関数を呼び出します。
|
||||
lcd.init();
|
||||
|
||||
|
||||
// 回転方向を 0~3 の4方向から設定します。(4~7を使用すると上下反転になります。)
|
||||
lcd.setRotation(1);
|
||||
|
||||
|
||||
// バックライトの輝度を 0~255 の範囲で設定します。
|
||||
lcd.setBrightness(128);
|
||||
|
||||
|
||||
// 必要に応じてカラーモードを設定します。(初期値は16)
|
||||
// 16の方がSPI通信量が少なく高速に動作しますが、赤と青の諧調が5bitになります。
|
||||
// 24の方がSPI通信量が多くなりますが、諧調表現が綺麗になります。
|
||||
//lcd.setColorDepth(16); // RGB565の16ビットに設定
|
||||
lcd.setColorDepth(24); // RGB888の24ビットに設定(表示される色数はパネル性能によりRGB666の18ビットになります)
|
||||
|
||||
|
||||
// 基本的な図形の描画関数は以下の通りです。
|
||||
/*
|
||||
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); // 円弧の塗り
|
||||
*/
|
||||
|
||||
|
||||
// 例えばdrawPixelで点を書く場合は、引数は X座標,Y座標,色 の3つ。
|
||||
lcd.drawPixel(0, 0, 0xFFFF); // 座標0:0に白の点を描画
|
||||
|
||||
|
||||
// カラーコードを生成する関数が用意されており、色の指定に使用できます。
|
||||
// 引数は、赤,緑,青をそれぞれ 0~255で指定します。
|
||||
// 色情報の欠落を防ぐため、color888を使う事を推奨します。
|
||||
lcd.drawFastVLine(2, 0, 100, lcd.color888(255, 0, 0)); // 赤で垂直の線を描画
|
||||
lcd.drawFastVLine(4, 0, 100, lcd.color565( 0, 255, 0)); // 緑で垂直の線を描画
|
||||
lcd.drawFastVLine(6, 0, 100, lcd.color332( 0, 0, 255)); // 青で垂直の線を描画
|
||||
|
||||
|
||||
// カラーコード生成関数を使用しない場合は以下のようになります。
|
||||
// RGB888 24ビットで指定 uint32_t型
|
||||
// RGB565 16ビットで指定 uint16_t型、int32_t型
|
||||
// RGB332 8ビットで指定 uint8_t型
|
||||
|
||||
// uint32_t型を使用すると、RGB888の24ビットとして扱われます。
|
||||
// 16進数2桁で赤緑青の順に記述できます。
|
||||
// uint32_t型の変数を使うか、末尾にUを付けるか、uint32_t型にキャストして使用します。
|
||||
uint32_t red = 0xFF0000;
|
||||
lcd.drawFastHLine(0, 2, 100, red); // 赤で水平の線を描画
|
||||
lcd.drawFastHLine(0, 4, 100, 0x00FF00U); // 緑で水平の線を描画
|
||||
lcd.drawFastHLine(0, 6, 100, (uint32_t)0xFF); // 青で水平の線を描画
|
||||
|
||||
|
||||
// uint16_t型およびint32_t型を使用すると、RGB565の16ビットとして扱われます。
|
||||
// 特別な書き方をしない場合はint32_t型として扱われるので、この方式になります。
|
||||
// (AdafruitGFX や TFT_eSPI との互換性のために、このようにしています。)
|
||||
uint16_t green = 0x07E0;
|
||||
lcd.drawRect(10, 10, 50, 50, 0xF800); // 赤で矩形の外周を描画
|
||||
lcd.drawRect(12, 12, 50, 50, green); // 緑で矩形の外周を描画
|
||||
lcd.drawRect(14, 14, 50, 50, (uint16_t)0x1F); // 青で矩形の外周を描画
|
||||
|
||||
|
||||
// int8_t型、uint8_t型を使用すると、RGB332の8ビットとして扱われます。
|
||||
uint8_t blue = 0x03;
|
||||
lcd.fillRect(20, 20, 20, 20, (uint8_t)0xE0); // 赤で矩形の塗りを描画
|
||||
lcd.fillRect(30, 30, 20, 20, (uint8_t)0x1C); // 緑で矩形の塗りを描画
|
||||
lcd.fillRect(40, 40, 20, 20, blue); // 青で矩形の塗りを描画
|
||||
|
||||
|
||||
// 描画関数の引数の色は省略できます。
|
||||
// 省略した場合、setColor関数で設定した色 または最後に使用した色を描画色として使用します。
|
||||
// 同じ色で繰り返し描画する場合は、省略した方がわずかに速く動作します。
|
||||
lcd.setColor(0xFF0000U); // 描画色に赤色を指定
|
||||
lcd.fillCircle ( 40, 80, 20 ); // 赤色で円の塗り
|
||||
lcd.fillEllipse( 80, 40, 10, 20); // 赤色で楕円の塗り
|
||||
lcd.fillArc ( 80, 80, 20, 10, 0, 90); // 赤色で円弧の塗り
|
||||
lcd.fillTriangle(80, 80, 60, 80, 80, 60); // 赤色で三角の塗り
|
||||
lcd.setColor(0x0000FFU); // 描画色に青色を指定
|
||||
lcd.drawCircle ( 40, 80, 20 ); // 青色で円の外周
|
||||
lcd.drawEllipse( 80, 40, 10, 20); // 青色で楕円の外周
|
||||
lcd.drawArc ( 80, 80, 20, 10, 0, 90); // 青色で円弧の外周
|
||||
lcd.drawTriangle(60, 80, 80, 80, 80, 60); // 青色で三角の外周
|
||||
lcd.setColor(0x00FF00U); // 描画色に緑色を指定
|
||||
lcd.drawBezier( 60, 80, 80, 80, 80, 60); // 緑色で二次ベジエ曲線
|
||||
lcd.drawBezier( 60, 80, 80, 20, 20, 80, 80, 60);// 緑色で三次ベジエ曲線
|
||||
|
||||
// グラデーションの線を描画するdrawGradientLine は色の指定を省略できません。
|
||||
lcd.drawGradientLine( 0, 80, 80, 0, 0xFF0000U, 0x0000FFU);// 赤から青へのグラデーション直線
|
||||
|
||||
delay(1000);
|
||||
|
||||
// clearまたはfillScreenで画面全体を塗り潰せます。
|
||||
// fillScreenはfillRectの画面全体を指定したのと同じで、色の指定は描画色の扱いになります。
|
||||
lcd.fillScreen(0xFFFFFFu); // 白で塗り潰し
|
||||
lcd.setColor(0x00FF00u); // 描画色に緑色を指定
|
||||
lcd.fillScreen(); // 緑で塗り潰し
|
||||
|
||||
// clearは描画系の関数とは別で背景色という扱いで色を保持しています。
|
||||
// 背景色は出番が少ないですが、スクロール機能使用時の隙間を塗る色としても使用されます。
|
||||
lcd.clear(0xFFFFFFu); // 背景色に白を指定して塗り潰し
|
||||
lcd.setBaseColor(0x000000u);// 背景色に黒を指定
|
||||
lcd.clear(); // 黒で塗り潰し
|
||||
|
||||
|
||||
// SPIバスの確保と解放は描画関数を呼び出した時に自動的に行われますが、
|
||||
// 描画スピードを重視する場合は、描画処理の前後に startWriteとendWriteを使用します。
|
||||
// SPIバスの確保と解放が抑制され、速度が向上します。
|
||||
// 電子ペーパー(EPD)の場合、startWrite()以降の描画は、endWrite()を呼ぶ事で画面に反映されます。
|
||||
lcd.drawLine(0, 1, 39, 40, red); // SPIバス確保、線を描画、SPIバス解放
|
||||
lcd.drawLine(1, 0, 40, 39, blue); // SPIバス確保、線を描画、SPIバス解放
|
||||
lcd.startWrite(); // SPIバス確保
|
||||
lcd.drawLine(38, 0, 0, 38, 0xFFFF00U); // 線を描画
|
||||
lcd.drawLine(39, 1, 1, 39, 0xFF00FFU); // 線を描画
|
||||
lcd.drawLine(40, 2, 2, 40, 0x00FFFFU); // 線を描画
|
||||
lcd.endWrite(); // SPIバス解放
|
||||
|
||||
|
||||
// startWriteとendWriteは呼出し回数を内部でカウントしており、
|
||||
// 繰り返し呼び出した場合は最初と最後のみ動作します。
|
||||
// startWriteとendWriteは必ず対になるように使用してください。
|
||||
// (SPIバスを占有して構わない場合は、最初にstartWriteを一度呼び、endWriteしない使い方も可能です。)
|
||||
lcd.startWrite(); // カウント+1、SPIバス確保
|
||||
lcd.startWrite(); // カウント+1
|
||||
lcd.startWrite(); // カウント+1
|
||||
lcd.endWrite(); // カウント-1
|
||||
lcd.endWrite(); // カウント-1
|
||||
lcd.endWrite(); // カウント-1、SPIバス解放
|
||||
lcd.endWrite(); // 何もしない
|
||||
// なお過剰にendWriteを呼び出した場合は何も行わず、カウントがマイナスになることもありません。
|
||||
|
||||
|
||||
// startWriteのカウントの状態に依らず、強制的にSPIバスを解放・確保したい場合は、
|
||||
// endTransaction・beginTransactionを使用します。
|
||||
// カウントはクリアされないので、辻褄が合わなくならないよう注意してください。
|
||||
lcd.startWrite(); // カウント+1、SPIバス確保
|
||||
lcd.startWrite(); // カウント+1
|
||||
lcd.drawPixel(0, 0); // 描画
|
||||
lcd.endTransaction(); // SPIバス解放
|
||||
// ここで他のSPIデバイスの使用が可能
|
||||
// 同じSPIバスの別のデバイス(SDカード等)を使う場合、
|
||||
// 必ずSPIバスが解放された状態で行ってください。
|
||||
lcd.beginTransaction(); // SPIバスの確保
|
||||
lcd.drawPixel(0, 0); // 描画
|
||||
lcd.endWrite(); // カウント-1
|
||||
lcd.endWrite(); // カウント-1、SPIバス解放
|
||||
|
||||
|
||||
|
||||
// drawPixelとは別に、writePixelという点を描画する関数があります。
|
||||
// drawPixelは必要に応じてSPIバスの確保を行うのに対し、
|
||||
// writePixelはSPIバスの状態をチェックしません。
|
||||
lcd.startWrite(); // SPIバス確保
|
||||
for (uint32_t x = 0; x < 128; ++x) {
|
||||
for (uint32_t y = 0; y < 128; ++y) {
|
||||
lcd.writePixel(x, y, lcd.color888( x*2, x + y, y*2));
|
||||
}
|
||||
}
|
||||
lcd.endWrite(); // SPIバス解放
|
||||
// 名前が write~ で始まる関数は全て明示的にstartWriteを呼び出しておく必要があります。
|
||||
// writePixel、writeFastVLine、writeFastHLine、writeFillRect が該当します。
|
||||
|
||||
delay(1000);
|
||||
|
||||
// スプライト(オフスクリーン)への描画も同様の描画関数が使えます。
|
||||
// 最初にスプライトの色深度をsetColorDepthで指定します。(省略した場合は16として扱われます。)
|
||||
//sprite.setColorDepth(1); // 1ビット( 2色)パレットモードに設定
|
||||
//sprite.setColorDepth(2); // 2ビット( 4色)パレットモードに設定
|
||||
//sprite.setColorDepth(4); // 4ビット(16色)パレットモードに設定
|
||||
//sprite.setColorDepth(8); // RGB332の8ビットに設定
|
||||
//sprite.setColorDepth(16); // RGB565の16ビットに設定
|
||||
sprite.setColorDepth(24); // RGB888の24ビットに設定
|
||||
|
||||
|
||||
// ※ setColorDepth(8);を設定後に createPalette()を呼ぶ事で、256色パレットモードになります
|
||||
// sprite.createPalette();
|
||||
|
||||
|
||||
// createSpriteで幅と高さを指定してメモリを確保します。
|
||||
// 消費するメモリは色深度と面積に比例します。大きすぎるとメモリ確保に失敗しますので注意してください。
|
||||
sprite.createSprite(65, 65); // 幅65、高さ65でスプライトを作成。
|
||||
|
||||
for (uint32_t x = 0; x < 64; ++x) {
|
||||
for (uint32_t y = 0; y < 64; ++y) {
|
||||
sprite.drawPixel(x, y, lcd.color888(3 + x*4, (x + y)*2, 3 + y*4)); // スプライトに描画
|
||||
}
|
||||
}
|
||||
sprite.drawRect(0, 0, 65, 65, 0xFFFF);
|
||||
|
||||
// 作成したスプライトはpushSpriteで任意の座標に出力できます。
|
||||
// 出力先はインスタンス作成時に引数で渡したLGFXになります。
|
||||
sprite.pushSprite(64, 0); // lcdの座標64,0にスプライトを描画
|
||||
|
||||
// spriteのインスタンス作成時に描画先のポインタを渡していない場合や、
|
||||
// 複数のLGFXがある場合などは、出力先を第一引数に指定してpushSpriteすることもできます。
|
||||
sprite.pushSprite(&lcd, 0, 64); // lcdの座標0,64にスプライトを描画
|
||||
|
||||
delay(1000);
|
||||
|
||||
// pushRotateZoomでスプライトを回転拡大縮小して描画できます。
|
||||
// setPivotで設定した座標が回転中心として扱われ、描画先の座標に回転中心が位置するように描画されます。
|
||||
sprite.setPivot(32, 32); // 座標32,32を中心として扱う
|
||||
int32_t center_x = lcd.width()/2;
|
||||
int32_t center_y = lcd.height()/2;
|
||||
lcd.startWrite();
|
||||
for (int angle = 0; angle <= 360; ++angle) {
|
||||
sprite.pushRotateZoom(center_x, center_y, angle, 2.5, 3); // 画面中心に角度angle、幅2.5倍、高さ3倍で描画
|
||||
|
||||
if ((angle % 36) == 0) lcd.display(); // 電子ペーパーの場合の表示更新を 36回に一度行う
|
||||
}
|
||||
lcd.endWrite();
|
||||
|
||||
delay(1000);
|
||||
|
||||
// 使用しなくなったスプライトのメモリを解放するには deleteSprite を使用します。
|
||||
sprite.deleteSprite();
|
||||
|
||||
// deleteSprite の後でも、同じインスタンスの再利用が可能です。
|
||||
sprite.setColorDepth(4); // 4ビット(16色)パレットモードに設定
|
||||
sprite.createSprite(65, 65);
|
||||
|
||||
// パレットモードのスプライトでは、描画関数の引数の色をパレット番号として扱います。
|
||||
// pushSprite等で描画する際に、パレットを参照して実際の描画色が決まります。
|
||||
|
||||
// 4ビット(16色)パレットモードの場合、パレット番号は0~15が使用可能です。
|
||||
// パレットの初期色は、0が黒,末尾のパレットが白で、0から末尾にかけてグラデーションになっています。
|
||||
// パレットの色を設定するには setPaletteColor を使用します。
|
||||
sprite.setPaletteColor(1, 0x0000FFU); // パレット1番を青に設定
|
||||
sprite.setPaletteColor(2, 0x00FF00U); // パレット2番を緑に設定
|
||||
sprite.setPaletteColor(3, 0xFF0000U); // パレット3番を赤に設定
|
||||
|
||||
sprite.fillRect(10, 10, 45, 45, 1); // パレット1番で矩形の塗り
|
||||
sprite.fillCircle(32, 32, 22, 2); // パレット2番で円の塗り
|
||||
sprite.fillTriangle(32, 12, 15, 43, 49, 43, 3); // パレット3番で三角の塗り
|
||||
|
||||
// pushSpriteの最後の引数で、描画しない色を指定することができます。
|
||||
sprite.pushSprite( 0, 0, 0); // パレット0を透過扱いでスプライトを描画
|
||||
sprite.pushSprite(65, 0, 1); // パレット1を透過扱いでスプライトを描画
|
||||
sprite.pushSprite( 0, 65, 2); // パレット2を透過扱いでスプライトを描画
|
||||
sprite.pushSprite(65, 65, 3); // パレット3を透過扱いでスプライトを描画
|
||||
|
||||
delay(5000);
|
||||
|
||||
lcd.startWrite(); // ここでstartWrite()することで、SPIバスを占有したままにする。
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
static int count = 0;
|
||||
static int a = 0;
|
||||
static int x = 0;
|
||||
static int y = 0;
|
||||
static float zoom = 3;
|
||||
++count;
|
||||
if ((a += 1) >= 360) a -= 360;
|
||||
if ((x += 2) >= lcd.width()) x -= lcd.width();
|
||||
if ((y += 1) >= lcd.height()) y -= lcd.height();
|
||||
sprite.setPaletteColor(1, lcd.color888( 0, 0, count & 0xFF));
|
||||
sprite.setPaletteColor(2, lcd.color888( 0,~count & 0xFF, 0));
|
||||
sprite.setPaletteColor(3, lcd.color888( count & 0xFF, 0, 0));
|
||||
|
||||
sprite.pushRotateZoom(x, y, a, zoom, zoom, 0);
|
||||
|
||||
if ((count % 100) == 0) lcd.display(); // 電子ペーパーの場合の表示更新を 100回に一度行う
|
||||
}
|
||||
387
BackUp/刷新画线
Normal file
387
BackUp/刷新画线
Normal file
@@ -0,0 +1,387 @@
|
||||
#include <Wire.h>
|
||||
#include <INA226.h>
|
||||
|
||||
INA226 ina(Wire);
|
||||
|
||||
// #include <Arduino.h>
|
||||
// #include "misakiUTF16FontData.h"
|
||||
#include <LovyanGFX.hpp>
|
||||
// ESP32でLovyanGFXを独自設定で利用する場合の設定例
|
||||
|
||||
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ST7789 _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
|
||||
lgfx::Light_PWM _light_instance;
|
||||
|
||||
public:
|
||||
// コンストラクタを作成し、ここで各種設定を行います。
|
||||
// クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
|
||||
LGFX(void)
|
||||
{
|
||||
{ // バス制御の設定を行います。
|
||||
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
|
||||
|
||||
// SPIバスの設定
|
||||
cfg.spi_host = SPI2_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
|
||||
cfg.spi_mode = 3; // SPI通信モードを設定 (0 ~ 3)
|
||||
cfg.freq_write = 80000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.freq_read = 16000000; // 受信時のSPIクロック
|
||||
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
|
||||
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
|
||||
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
|
||||
cfg.pin_sclk = 4; // SPIのSCLKピン番号を設定
|
||||
cfg.pin_mosi = 5; // SPIのMOSIピン番号を設定
|
||||
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
|
||||
cfg.pin_dc = 6; // SPIのD/Cピン番号を設定 (-1 = disable)
|
||||
// SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
|
||||
_bus_instance.config(cfg); // 設定値をバスに反映します。
|
||||
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
|
||||
}
|
||||
|
||||
{ // 表示パネル制御の設定を行います。
|
||||
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_cs = 8; // CSが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_rst = 7; // RSTが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
|
||||
|
||||
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
|
||||
|
||||
cfg.panel_width = 172; // 実際に表示可能な幅
|
||||
cfg.panel_height = 320; // 実際に表示可能な高さ
|
||||
cfg.offset_x = 34; // パネルのX方向オフセット量
|
||||
cfg.offset_y = 0; // パネルのY方向オフセット量
|
||||
cfg.offset_rotation = 3; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
|
||||
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
|
||||
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
|
||||
cfg.readable = true; // データ読出しが可能な場合 trueに設定
|
||||
cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定
|
||||
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
|
||||
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
|
||||
cfg.bus_shared = true; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
|
||||
|
||||
// 以下はST7735やILI9163のようにピクセル数が可変のドライバで表示がずれる場合にのみ設定してください。
|
||||
// cfg.memory_width = 240; // ドライバICがサポートしている最大の幅
|
||||
// cfg.memory_height = 320; // ドライバICがサポートしている最大の高さ
|
||||
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
{ // バックライト制御の設定を行います。(必要なければ削除)
|
||||
auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_bl = 10; // バックライトが接続されているピン番号
|
||||
cfg.invert = true; // バックライトの輝度を反転させる場合 true
|
||||
cfg.freq = 44100; // バックライトのPWM周波数
|
||||
cfg.pwm_channel = 7; // 使用するPWMのチャンネル番号
|
||||
|
||||
_light_instance.config(cfg);
|
||||
_panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance); // 使用するパネルをセットします。
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX lcd;
|
||||
// static LGFX_Sprite sprite(&lcd);
|
||||
|
||||
void drawGradation(void)
|
||||
{
|
||||
// 背景にグラデーションを描画する
|
||||
lcd.startWrite();
|
||||
lcd.setAddrWindow(0, 0, lcd.width(), lcd.height());
|
||||
for (int y = 0; y < lcd.height(); ++y)
|
||||
{
|
||||
for (int x = 0; x < lcd.width(); ++x)
|
||||
{
|
||||
lcd.writeColor(lcd.color888(x >> 1, (x + y) >> 2, y >> 1), 1);
|
||||
}
|
||||
}
|
||||
lcd.endWrite();
|
||||
}
|
||||
|
||||
void checkConfig()
|
||||
{
|
||||
Serial.print("Mode: ");
|
||||
switch (ina.getMode())
|
||||
{
|
||||
case INA226_MODE_POWER_DOWN:
|
||||
Serial.println("Power-Down");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_TRIG:
|
||||
Serial.println("Shunt Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_BUS_TRIG:
|
||||
Serial.println("Bus Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_TRIG:
|
||||
Serial.println("Shunt and Bus, Triggered");
|
||||
break;
|
||||
case INA226_MODE_ADC_OFF:
|
||||
Serial.println("ADC Off");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_CONT:
|
||||
Serial.println("Shunt Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_BUS_CONT:
|
||||
Serial.println("Bus Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_CONT:
|
||||
Serial.println("Shunt and Bus, Continuous");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Samples average: ");
|
||||
switch (ina.getAverages())
|
||||
{
|
||||
case INA226_AVERAGES_1:
|
||||
Serial.println("1 sample");
|
||||
break;
|
||||
case INA226_AVERAGES_4:
|
||||
Serial.println("4 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_16:
|
||||
Serial.println("16 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_64:
|
||||
Serial.println("64 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_128:
|
||||
Serial.println("128 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_256:
|
||||
Serial.println("256 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_512:
|
||||
Serial.println("512 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_1024:
|
||||
Serial.println("1024 samples");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Bus conversion time: ");
|
||||
switch (ina.getBusConversionTime())
|
||||
{
|
||||
case INA226_BUS_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Shunt conversion time: ");
|
||||
switch (ina.getShuntConversionTime())
|
||||
{
|
||||
case INA226_SHUNT_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Max possible current: ");
|
||||
Serial.print(ina.getMaxPossibleCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max current: ");
|
||||
Serial.print(ina.getMaxCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max shunt voltage: ");
|
||||
Serial.print(ina.getMaxShuntVoltage());
|
||||
Serial.println(" V");
|
||||
|
||||
Serial.print("Max power: ");
|
||||
Serial.print(ina.getMaxPower());
|
||||
Serial.println(" W");
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
lcd.init();
|
||||
lcd.fillScreen(0xFFFFFFU);
|
||||
// drawGradation();
|
||||
lcd.setFont(&fonts::Font7);
|
||||
// lcd.setTextDatum(textdatum_t::bottom_right);
|
||||
lcd.setTextDatum(bottom_right);
|
||||
// lcd.setTextColor(0x000000U, 0xFFFFFFU);
|
||||
// lcd.fillScreen(0xFFFFFFU);
|
||||
lcd.setTextColor(0xFFFFFFU, 0x000000U);
|
||||
lcd.fillScreen(0xFFFFFFU);
|
||||
lcd.setBrightness(128);
|
||||
pinMode(10, OUTPUT);
|
||||
digitalWrite(10, 0);
|
||||
|
||||
Wire.begin(1, 0, 100000);
|
||||
// Default INA226 address is 0x40
|
||||
bool success = ina.begin();
|
||||
// Check if the connection was successful, stop if not
|
||||
if (!success)
|
||||
{
|
||||
Serial.println("Connection error");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
// Configure INA226
|
||||
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
|
||||
// Calibrate INA226. Rshunt = 0.001 ohm, Max excepted current = 4A
|
||||
ina.calibrate(0.001, 40);
|
||||
// Display configuration
|
||||
checkConfig();
|
||||
}
|
||||
|
||||
unsigned short int lastX, lastY;
|
||||
unsigned char firstPoint = 1;
|
||||
void drawCurve(short int rawValue)
|
||||
{
|
||||
unsigned short int x, y;
|
||||
y = 120 - rawValue / 280; // data processing code
|
||||
// 这里之所以是120-rawValue/280,与屏幕的扫描方向有关,如果出现上下颠倒的情况,可以改成120 +
|
||||
if (firstPoint) // 如果是第一次画点,则无需连线,直接描点即可
|
||||
{
|
||||
lcd.drawPixel(0, y);
|
||||
lastX = 0;
|
||||
lastY = y;
|
||||
firstPoint = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = lastX + 1;
|
||||
if (x < 320) // 不超过屏幕宽度
|
||||
{
|
||||
lcd.drawLine(lastX, lastY, x, y);
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
else // 超出屏幕宽度,清屏,从第一个点开始绘制,实现动态更新效果
|
||||
{
|
||||
lcd.fillScreen(0xFFFFFFU); // 清屏,白色背景
|
||||
lcd.drawPixel(0, y);
|
||||
lastX = 0;
|
||||
lastY = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// Serial.print("Bus voltage: ");
|
||||
// Serial.print(ina.readBusVoltage(), 5);
|
||||
// Serial.println(" V");
|
||||
|
||||
// Serial.print("Bus power: ");
|
||||
// Serial.print(ina.readBusPower(), 5);
|
||||
// Serial.println(" W");
|
||||
|
||||
// Serial.print("Shunt voltage: ");
|
||||
// Serial.print(ina.readShuntVoltage(), 5);
|
||||
// Serial.println(" V");
|
||||
|
||||
// Serial.print("Shunt current: ");
|
||||
// Serial.print(ina.readShuntCurrent(), 5);
|
||||
// Serial.println(" A");
|
||||
|
||||
// Serial.println("");
|
||||
delay(10);
|
||||
// delay(1000);
|
||||
|
||||
// lcd.setFont(&fonts::Roboto_Thin_24);
|
||||
lcd.setTextColor(0x000000U, 0x000000U);
|
||||
lcd.setFont(&fonts::Font4);
|
||||
lcd.setTextDatum(bottom_center);
|
||||
// lcd.drawString("V", 180, 50);
|
||||
// lcd.drawString("A", 180, 108);
|
||||
// lcd.drawString("W", 180, 166);
|
||||
|
||||
lcd.setTextDatum(top_left);
|
||||
lcd.drawString("Current", 20, 0);
|
||||
|
||||
lcd.setFont(&fonts::Font6);
|
||||
lcd.setTextDatum(bottom_right);
|
||||
// lcd.drawFloat(ina.readBusVoltage(), 4, 160, 58);
|
||||
// lcd.drawFloat(abs(ina.readShuntCurrent()), 4, 160, 116);
|
||||
// lcd.drawFloat(ina.readBusPower(), 4, 160, 174);
|
||||
|
||||
lcd.setTextColor(0xFFFFFFU, 0x000000U);
|
||||
|
||||
short int current = abs(ina.readShuntCurrent()) * 10000;
|
||||
drawCurve(current);
|
||||
|
||||
// lcd.drawNumber(ina.readBusVoltage(), 120, 120);
|
||||
// ※ 名前が"Free"で始まるフォントは 9pt 12pt 18pt 24ptの4種類があります。
|
||||
// drawNumberTest( &fonts::Font0 );
|
||||
// drawNumberTest( &fonts::Font2 );
|
||||
// drawNumberTest( &fonts::Font4 );
|
||||
// drawNumberTest( &fonts::Font6 );
|
||||
// drawNumberTest( &fonts::Font7 );
|
||||
// drawNumberTest( &fonts::Font8 );
|
||||
// drawNumberTest( &fonts::TomThumb );
|
||||
// drawNumberTest( &fonts::FreeMono9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoOblique9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoBoldOblique9pt7b);
|
||||
// drawNumberTest( &fonts::FreeSans9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansOblique9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansBoldOblique9pt7b);
|
||||
// drawNumberTest( &fonts::FreeSerif9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifItalic9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifBoldItalic9pt7b);
|
||||
// drawNumberTest( &fonts::Orbitron_Light_24 );
|
||||
// drawNumberTest( &fonts::Roboto_Thin_24 );
|
||||
// drawNumberTest( &fonts::Satisfy_24 );
|
||||
// drawNumberTest( &fonts::Yellowtail_32 );
|
||||
}
|
||||
369
BackUp/移动波形
Normal file
369
BackUp/移动波形
Normal file
@@ -0,0 +1,369 @@
|
||||
#include <Wire.h>
|
||||
#include <INA226.h>
|
||||
|
||||
INA226 ina(Wire);
|
||||
|
||||
// #include <Arduino.h>
|
||||
// #include "misakiUTF16FontData.h"
|
||||
#include <LovyanGFX.hpp>
|
||||
// ESP32でLovyanGFXを独自設定で利用する場合の設定例
|
||||
|
||||
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ST7789 _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
|
||||
lgfx::Light_PWM _light_instance;
|
||||
|
||||
public:
|
||||
// コンストラクタを作成し、ここで各種設定を行います。
|
||||
// クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
|
||||
LGFX(void)
|
||||
{
|
||||
{ // バス制御の設定を行います。
|
||||
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
|
||||
|
||||
// SPIバスの設定
|
||||
cfg.spi_host = SPI2_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
|
||||
cfg.spi_mode = 3; // SPI通信モードを設定 (0 ~ 3)
|
||||
cfg.freq_write = 40000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.freq_read = 16000000; // 受信時のSPIクロック
|
||||
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
|
||||
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
|
||||
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
|
||||
cfg.pin_sclk = 4; // SPIのSCLKピン番号を設定
|
||||
cfg.pin_mosi = 5; // SPIのMOSIピン番号を設定
|
||||
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
|
||||
cfg.pin_dc = 6; // SPIのD/Cピン番号を設定 (-1 = disable)
|
||||
// SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
|
||||
_bus_instance.config(cfg); // 設定値をバスに反映します。
|
||||
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
|
||||
}
|
||||
|
||||
{ // 表示パネル制御の設定を行います。
|
||||
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_cs = 8; // CSが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_rst = 7; // RSTが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
|
||||
|
||||
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
|
||||
|
||||
cfg.panel_width = 172; // 実際に表示可能な幅
|
||||
cfg.panel_height = 320; // 実際に表示可能な高さ
|
||||
cfg.offset_x = 34; // パネルのX方向オフセット量
|
||||
cfg.offset_y = 0; // パネルのY方向オフセット量
|
||||
cfg.offset_rotation = 3; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
|
||||
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
|
||||
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
|
||||
cfg.readable = true; // データ読出しが可能な場合 trueに設定
|
||||
cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定
|
||||
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
|
||||
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
|
||||
cfg.bus_shared = true; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
|
||||
|
||||
// 以下はST7735やILI9163のようにピクセル数が可変のドライバで表示がずれる場合にのみ設定してください。
|
||||
// cfg.memory_width = 240; // ドライバICがサポートしている最大の幅
|
||||
// cfg.memory_height = 320; // ドライバICがサポートしている最大の高さ
|
||||
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
{ // バックライト制御の設定を行います。(必要なければ削除)
|
||||
auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_bl = 10; // バックライトが接続されているピン番号
|
||||
cfg.invert = true; // バックライトの輝度を反転させる場合 true
|
||||
cfg.freq = 44100; // バックライトのPWM周波数
|
||||
cfg.pwm_channel = 7; // 使用するPWMのチャンネル番号
|
||||
|
||||
_light_instance.config(cfg);
|
||||
_panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance); // 使用するパネルをセットします。
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX lcd;
|
||||
// static LGFX_Sprite sprite(&lcd);
|
||||
|
||||
void drawGradation(void)
|
||||
{
|
||||
// 背景にグラデーションを描画する
|
||||
lcd.startWrite();
|
||||
lcd.setAddrWindow(0, 0, lcd.width(), lcd.height());
|
||||
for (int y = 0; y < lcd.height(); ++y)
|
||||
{
|
||||
for (int x = 0; x < lcd.width(); ++x)
|
||||
{
|
||||
lcd.writeColor(lcd.color888(x >> 1, (x + y) >> 2, y >> 1), 1);
|
||||
}
|
||||
}
|
||||
lcd.endWrite();
|
||||
}
|
||||
|
||||
void checkConfig()
|
||||
{
|
||||
Serial.print("Mode: ");
|
||||
switch (ina.getMode())
|
||||
{
|
||||
case INA226_MODE_POWER_DOWN:
|
||||
Serial.println("Power-Down");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_TRIG:
|
||||
Serial.println("Shunt Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_BUS_TRIG:
|
||||
Serial.println("Bus Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_TRIG:
|
||||
Serial.println("Shunt and Bus, Triggered");
|
||||
break;
|
||||
case INA226_MODE_ADC_OFF:
|
||||
Serial.println("ADC Off");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_CONT:
|
||||
Serial.println("Shunt Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_BUS_CONT:
|
||||
Serial.println("Bus Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_CONT:
|
||||
Serial.println("Shunt and Bus, Continuous");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Samples average: ");
|
||||
switch (ina.getAverages())
|
||||
{
|
||||
case INA226_AVERAGES_1:
|
||||
Serial.println("1 sample");
|
||||
break;
|
||||
case INA226_AVERAGES_4:
|
||||
Serial.println("4 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_16:
|
||||
Serial.println("16 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_64:
|
||||
Serial.println("64 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_128:
|
||||
Serial.println("128 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_256:
|
||||
Serial.println("256 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_512:
|
||||
Serial.println("512 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_1024:
|
||||
Serial.println("1024 samples");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Bus conversion time: ");
|
||||
switch (ina.getBusConversionTime())
|
||||
{
|
||||
case INA226_BUS_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Shunt conversion time: ");
|
||||
switch (ina.getShuntConversionTime())
|
||||
{
|
||||
case INA226_SHUNT_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Max possible current: ");
|
||||
Serial.print(ina.getMaxPossibleCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max current: ");
|
||||
Serial.print(ina.getMaxCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max shunt voltage: ");
|
||||
Serial.print(ina.getMaxShuntVoltage());
|
||||
Serial.println(" V");
|
||||
|
||||
Serial.print("Max power: ");
|
||||
Serial.print(ina.getMaxPower());
|
||||
Serial.println(" W");
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
lcd.init();
|
||||
pinMode(10, OUTPUT);
|
||||
digitalWrite(10, 0);
|
||||
// drawGradation();
|
||||
// lcd.setFont(&fonts::Font7);
|
||||
// lcd.setTextDatum(textdatum_t::bottom_right);
|
||||
// lcd.setTextDatum(bottom_right);
|
||||
// lcd.setTextColor(0x000000U, 0xFFFFFFU);
|
||||
// lcd.fillScreen(0xFFFFFFU);
|
||||
lcd.setTextColor(0xFFFFFFU, 0x000000U);
|
||||
lcd.fillScreen(0xFFFFFFU);
|
||||
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println("Initialize INA226");
|
||||
Serial.println("-----------------------------------------------");
|
||||
|
||||
Wire.begin(1, 0, 100000);
|
||||
// Default INA226 address is 0x40
|
||||
bool success = ina.begin();
|
||||
// Check if the connection was successful, stop if not
|
||||
if (!success)
|
||||
{
|
||||
Serial.println("Connection error");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
// Configure INA226
|
||||
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
|
||||
// Calibrate INA226. Rshunt = 0.001 ohm, Max excepted current = 4A
|
||||
ina.calibrate(0.001, 40);
|
||||
// Display configuration
|
||||
checkConfig();
|
||||
|
||||
|
||||
}
|
||||
int32_t current;
|
||||
int32_t current_buf[322];
|
||||
float t = 0;
|
||||
void loop(void)
|
||||
{
|
||||
delay(20);
|
||||
|
||||
// lcd.setFont(&fonts::Roboto_Thin_24);
|
||||
// lcd.setTextColor(0x000000U, 0x000000U);
|
||||
// lcd.setFont(&fonts::Font4);
|
||||
// lcd.setTextDatum(bottom_center);
|
||||
// lcd.drawString("V", 180, 50);
|
||||
// lcd.drawString("A", 180, 108);
|
||||
// lcd.drawString("W", 180, 166);
|
||||
|
||||
// lcd.setTextDatum(top_left);
|
||||
// lcd.drawString("Current", 20, 0);
|
||||
|
||||
// lcd.setFont(&fonts::Font6);
|
||||
// lcd.setTextDatum(bottom_right);
|
||||
// lcd.drawFloat(ina.readBusVoltage(), 4, 160, 58);
|
||||
// lcd.drawFloat(abs(ina.readShuntCurrent()), 4, 160, 116);
|
||||
// lcd.drawFloat(ina.readBusPower(), 4, 160, 174);
|
||||
|
||||
// lcd.setTextColor(0xFFFFFFU, 0x000000U);
|
||||
|
||||
// for (size_t i = 0; i < 320; i++)
|
||||
// {
|
||||
// // lcd.drawPixel(i, current_buf[i], 0x000000U);
|
||||
// lcd.drawLine(i - 1, current_buf[i - 1], i, current_buf[i], 0xFFFFFFU);
|
||||
// }
|
||||
|
||||
current = abs(ina.readShuntCurrent()) * 40;
|
||||
// t += 0.1;
|
||||
// current = sin(t) * 30;
|
||||
|
||||
for (size_t i = 0; i < 320; i++)
|
||||
{
|
||||
lcd.drawLine(i, current_buf[i], i + 1, current_buf[i + 1], 0xFFFFFFU);
|
||||
}
|
||||
|
||||
for (size_t i = 320; i > 0; i--)
|
||||
{
|
||||
current_buf[i] = current_buf[i - 1];
|
||||
}
|
||||
current_buf[0] = 150 - current;
|
||||
|
||||
// lcd.clearDisplay(0xFFFFFFU);
|
||||
|
||||
for (size_t i = 0; i < 320; i++)
|
||||
{
|
||||
lcd.drawLine(i, current_buf[i], i + 1, current_buf[i + 1], 0x000000U);
|
||||
}
|
||||
|
||||
// lcd.drawNumber(ina.readBusVoltage(), 120, 120);
|
||||
// ※ 名前が"Free"で始まるフォントは 9pt 12pt 18pt 24ptの4種類があります。
|
||||
// drawNumberTest( &fonts::Font0 );
|
||||
// drawNumberTest( &fonts::Font2 );
|
||||
// drawNumberTest( &fonts::Font4 );
|
||||
// drawNumberTest( &fonts::Font6 );
|
||||
// drawNumberTest( &fonts::Font7 );
|
||||
// drawNumberTest( &fonts::Font8 );
|
||||
// drawNumberTest( &fonts::TomThumb );
|
||||
// drawNumberTest( &fonts::FreeMono9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoOblique9pt7b );
|
||||
// drawNumberTest( &fonts::FreeMonoBoldOblique9pt7b);
|
||||
// drawNumberTest( &fonts::FreeSans9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansOblique9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSansBoldOblique9pt7b);
|
||||
// drawNumberTest( &fonts::FreeSerif9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifBold9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifItalic9pt7b );
|
||||
// drawNumberTest( &fonts::FreeSerifBoldItalic9pt7b);
|
||||
// drawNumberTest( &fonts::Orbitron_Light_24 );
|
||||
// drawNumberTest( &fonts::Roboto_Thin_24 );
|
||||
// drawNumberTest( &fonts::Satisfy_24 );
|
||||
// drawNumberTest( &fonts::Yellowtail_32 );
|
||||
}
|
||||
630
BackUp/绘制图像
Normal file
630
BackUp/绘制图像
Normal file
@@ -0,0 +1,630 @@
|
||||
#include <Wire.h>
|
||||
#include <INA226.h>
|
||||
|
||||
INA226 ina(Wire);
|
||||
|
||||
// #include <Arduino.h>
|
||||
// #include "misakiUTF16FontData.h"
|
||||
#include <LovyanGFX.hpp>
|
||||
// ESP32でLovyanGFXを独自設定で利用する場合の設定例
|
||||
extern const uint8_t rgb888[];
|
||||
extern const uint8_t bgr888[];
|
||||
extern const uint16_t swap565[];
|
||||
extern const uint16_t rgb565[];
|
||||
extern const uint8_t rgb332[];
|
||||
|
||||
static constexpr int image_width = 33;
|
||||
static constexpr int image_height = 31;
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ST7789 _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
|
||||
lgfx::Light_PWM _light_instance;
|
||||
|
||||
public:
|
||||
// コンストラクタを作成し、ここで各種設定を行います。
|
||||
// クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
|
||||
LGFX(void)
|
||||
{
|
||||
{ // バス制御の設定を行います。
|
||||
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
|
||||
|
||||
// SPIバスの設定
|
||||
cfg.spi_host = SPI2_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
|
||||
cfg.spi_mode = 3; // SPI通信モードを設定 (0 ~ 3)
|
||||
cfg.freq_write = 80000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
|
||||
cfg.freq_read = 16000000; // 受信時のSPIクロック
|
||||
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
|
||||
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
|
||||
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
|
||||
cfg.pin_sclk = 4; // SPIのSCLKピン番号を設定
|
||||
cfg.pin_mosi = 5; // SPIのMOSIピン番号を設定
|
||||
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
|
||||
cfg.pin_dc = 6; // SPIのD/Cピン番号を設定 (-1 = disable)
|
||||
// SDカードと共通のSPIバスを使う場合、MISOは省略せず必ず設定してください。
|
||||
_bus_instance.config(cfg); // 設定値をバスに反映します。
|
||||
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
|
||||
}
|
||||
|
||||
{ // 表示パネル制御の設定を行います。
|
||||
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_cs = 8; // CSが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_rst = 7; // RSTが接続されているピン番号 (-1 = disable)
|
||||
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
|
||||
// ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。
|
||||
cfg.panel_width = 172; // 実際に表示可能な幅
|
||||
cfg.panel_height = 320; // 実際に表示可能な高さ
|
||||
cfg.offset_x = 34; // パネルのX方向オフセット量
|
||||
cfg.offset_y = 0; // パネルのY方向オフセット量
|
||||
cfg.offset_rotation = 3; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
|
||||
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
|
||||
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
|
||||
cfg.readable = false; // データ読出しが可能な場合 trueに設定
|
||||
cfg.invert = true; // パネルの明暗が反転してしまう場合 trueに設定
|
||||
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
|
||||
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
|
||||
cfg.bus_shared = false; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
|
||||
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
{ // バックライト制御の設定を行います。(必要なければ削除)
|
||||
auto cfg = _light_instance.config(); // バックライト設定用の構造体を取得します。
|
||||
|
||||
cfg.pin_bl = 10; // バックライトが接続されているピン番号
|
||||
cfg.invert = true; // バックライトの輝度を反転させる場合 true
|
||||
cfg.freq = 44100; // バックライトのPWM周波数
|
||||
cfg.pwm_channel = 1; // 使用するPWMのチャンネル番号
|
||||
|
||||
_light_instance.config(cfg);
|
||||
_panel_instance.setLight(&_light_instance); // バックライトをパネルにセットします。
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance); // 使用するパネルをセットします。
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX lcd;
|
||||
// static LGFX_Sprite sprite(&lcd);
|
||||
|
||||
void drawGradation(void)
|
||||
{
|
||||
// 背景にグラデーションを描画する
|
||||
lcd.startWrite();
|
||||
lcd.setAddrWindow(0, 0, lcd.width(), lcd.height());
|
||||
for (int y = 0; y < lcd.height(); ++y)
|
||||
{
|
||||
for (int x = 0; x < lcd.width(); ++x)
|
||||
{
|
||||
lcd.writeColor(lcd.color888(x >> 1, (x + y) >> 2, y >> 1), 1);
|
||||
}
|
||||
}
|
||||
lcd.endWrite();
|
||||
}
|
||||
|
||||
void checkConfig()
|
||||
{
|
||||
Serial.print("Mode: ");
|
||||
switch (ina.getMode())
|
||||
{
|
||||
case INA226_MODE_POWER_DOWN:
|
||||
Serial.println("Power-Down");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_TRIG:
|
||||
Serial.println("Shunt Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_BUS_TRIG:
|
||||
Serial.println("Bus Voltage, Triggered");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_TRIG:
|
||||
Serial.println("Shunt and Bus, Triggered");
|
||||
break;
|
||||
case INA226_MODE_ADC_OFF:
|
||||
Serial.println("ADC Off");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_CONT:
|
||||
Serial.println("Shunt Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_BUS_CONT:
|
||||
Serial.println("Bus Voltage, Continuous");
|
||||
break;
|
||||
case INA226_MODE_SHUNT_BUS_CONT:
|
||||
Serial.println("Shunt and Bus, Continuous");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Samples average: ");
|
||||
switch (ina.getAverages())
|
||||
{
|
||||
case INA226_AVERAGES_1:
|
||||
Serial.println("1 sample");
|
||||
break;
|
||||
case INA226_AVERAGES_4:
|
||||
Serial.println("4 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_16:
|
||||
Serial.println("16 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_64:
|
||||
Serial.println("64 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_128:
|
||||
Serial.println("128 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_256:
|
||||
Serial.println("256 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_512:
|
||||
Serial.println("512 samples");
|
||||
break;
|
||||
case INA226_AVERAGES_1024:
|
||||
Serial.println("1024 samples");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Bus conversion time: ");
|
||||
switch (ina.getBusConversionTime())
|
||||
{
|
||||
case INA226_BUS_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_BUS_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Shunt conversion time: ");
|
||||
switch (ina.getShuntConversionTime())
|
||||
{
|
||||
case INA226_SHUNT_CONV_TIME_140US:
|
||||
Serial.println("140uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_204US:
|
||||
Serial.println("204uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_332US:
|
||||
Serial.println("332uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_588US:
|
||||
Serial.println("558uS");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_1100US:
|
||||
Serial.println("1.100ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_2116US:
|
||||
Serial.println("2.116ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_4156US:
|
||||
Serial.println("4.156ms");
|
||||
break;
|
||||
case INA226_SHUNT_CONV_TIME_8244US:
|
||||
Serial.println("8.244ms");
|
||||
break;
|
||||
default:
|
||||
Serial.println("unknown");
|
||||
}
|
||||
|
||||
Serial.print("Max possible current: ");
|
||||
Serial.print(ina.getMaxPossibleCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max current: ");
|
||||
Serial.print(ina.getMaxCurrent());
|
||||
Serial.println(" A");
|
||||
|
||||
Serial.print("Max shunt voltage: ");
|
||||
Serial.print(ina.getMaxShuntVoltage());
|
||||
Serial.println(" V");
|
||||
|
||||
Serial.print("Max power: ");
|
||||
Serial.print(ina.getMaxPower());
|
||||
Serial.println(" W");
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
lcd.init();
|
||||
lcd.startWrite();
|
||||
lcd.setBrightness(100);
|
||||
|
||||
Wire.begin(1, 0, 100000);
|
||||
// Default INA226 address is 0x40
|
||||
bool success = ina.begin();
|
||||
// Check if the connection was successful, stop if not
|
||||
if (!success)
|
||||
{
|
||||
Serial.println("Connection error");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
// Configure INA226
|
||||
ina.configure(INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
|
||||
// Calibrate INA226. Rshunt = 0.001 ohm, Max excepted current = 4A
|
||||
ina.calibrate(0.001, 40);
|
||||
// Display configuration
|
||||
checkConfig();
|
||||
}
|
||||
int32_t current;
|
||||
int32_t current_buf[322];
|
||||
float t = 0;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
|
||||
/*
|
||||
画像データを描画する関数は幾つか種類があります。
|
||||
|
||||
方法1.事前に描画範囲を設定しておき、次にデータの長さを指定して描画する方法
|
||||
方法2.描画する座標と幅・高さを指定してデータを描画する方法
|
||||
|
||||
|
||||
|
||||
方法1.事前に描画範囲を設定しておき、次にデータの長さを指定して描画する方法
|
||||
|
||||
この方法では、setWindow/setAddrWindow関数で描画範囲を設定したあと、
|
||||
writePixels/pushPixels関数で画像データの長さを指定して描画します。
|
||||
|
||||
setWindow( x0, y0, x1, y1 ); // 描画範囲の指定。左上座標と右下座標を指定します。
|
||||
setAddrWindow( x, y, w, h ); // 描画範囲の指定。左上座標と幅と高さを指定します。
|
||||
|
||||
setWindow は画面外の座標を指定した場合の動作は保証されません。
|
||||
setAddrWindow は描画範囲外が指定された場合は範囲内に調整されます。
|
||||
※ ただし自動調整された結果、実際に設定される幅や高さが指定した値より小さくなる可能性があるので注意が必要です。
|
||||
|
||||
writePixels ( *data, len, swap ); // 画像を描画する。(事前にstartWrite、事後にendWriteが必要)
|
||||
pushPixels ( *data, len, swap ); // 画像を描画する。(startWrite・endWriteは不要)
|
||||
|
||||
※ writePixelsはAdafruitGFX由来の関数で、pushPixelsはTFT_eSPI由来の関数です。
|
||||
描画内容は同等ですが、startWrite/endWriteが自動で行われるか否かが違います。
|
||||
|
||||
第1引数:画像データのポインタ(データ型に応じて色の形式を判断して変換が行われます。)
|
||||
第2引数:画像データのピクセル数(バイト数でない点に注意。)
|
||||
第3引数:バイト順変換フラグ(省略時は事前にsetSwapBytes関数で設定した値が使用されます。)
|
||||
|
||||
第1引数のdataの型に基づいて色の形式変換が行われます。
|
||||
uint8_t* の場合、 8bitカラー RGB332として扱います。
|
||||
uint16_t* の場合、16bitカラー RGB565として扱います。
|
||||
void* の場合、24bitカラー RGB888として扱います。
|
||||
※ (3バイトのプリミティブ型が無いため、void*型を24bitカラー扱いとしています)
|
||||
|
||||
※ LCDに描画する際に、LCDの色数モードに応じて色形式の変換が自動的に行われます。
|
||||
*/
|
||||
lcd.clear(TFT_WHITE);
|
||||
lcd.setColorDepth(16); // LCDを16bitカラーモードに設定する。
|
||||
lcd.setSwapBytes(true); // バイト順変換を有効にする。
|
||||
int len = image_width * image_height;
|
||||
|
||||
// 画像の幅と高さをsetAddrWindowで事前に設定し、writePixelsで描画します。
|
||||
lcd.setAddrWindow(0, 0, image_width, image_height); // 描画範囲を設定。
|
||||
lcd.writePixels((uint16_t *)rgb565, len); // RGB565の16bit画像データを描画。
|
||||
|
||||
// データとバイト順変換の指定が一致していない場合、色化けします。
|
||||
lcd.setAddrWindow(0, 40, image_width, image_height);
|
||||
// 第3引数でfalseを指定することでバイト順変換の有無を指定できます。
|
||||
lcd.writePixels((uint16_t *)rgb565, len, false); // RGB565の画像をバイト順変換無しで描画すると色が化ける。
|
||||
|
||||
// 描画範囲が画面外にはみ出すなどして画像の幅や高さと合わなくなった場合、描画結果が崩れます。
|
||||
lcd.setAddrWindow(-1, 80, image_width, image_height); // X座標が-1(画面外)のため、正しく設定できない。
|
||||
lcd.writePixels((uint16_t *)rgb565, len); // 描画先の幅と画像の幅が不一致のため描画内容が崩れる。
|
||||
|
||||
// データと型が一致していない場合も、描画結果が崩れます。
|
||||
lcd.setAddrWindow(0, 120, image_width, image_height);
|
||||
// RGB565のデータをわざとuint8_tにキャストし、RGB332の8bitカラーとして扱わせる。
|
||||
lcd.writePixels((uint8_t *)rgb565, len); // 画像の形式と型が一致していないため描画が乱れる。
|
||||
|
||||
// データと型が一致していれば、描画先の色数に合わせて適切な形式変換が行われます。
|
||||
lcd.setAddrWindow(0, 160, image_width, image_height);
|
||||
lcd.writePixels((uint8_t *)rgb332, len); // RGB332のデータでも16bitカラーのLCDに正しく描画できる。
|
||||
|
||||
// ※ LCDへの画像データの送信は、メモリの若いアドレスにあるデータから順に1Byte単位で送信されます。
|
||||
// このため、例えばRGB565の16bit型のデータを素直にuint16_tの配列で用意すると、送信の都合としてはバイト順が入れ替わった状態になります。
|
||||
// この場合は事前にsetSwapBytes(true)を使用したり、第3引数にtrueを指定する事で、バイト順の変換が行われて正常に描画できます。
|
||||
// なお用意する画像データを予め上位下位バイトを入れ替えた状態で作成すれば、この変換は不要になり速度面で有利になります。
|
||||
|
||||
lcd.setAddrWindow(40, 0, image_width, image_height);
|
||||
lcd.writePixels((uint16_t *)swap565, len, false); // 予め上位下位が入れ替わった16bitデータの場合はバイト順変換を無効にする。
|
||||
|
||||
lcd.setAddrWindow(40, 40, image_width, image_height);
|
||||
lcd.writePixels((uint16_t *)swap565, len, true); // 逆に、予め上位下位が入れ替わったデータにバイト順変換を行うと色が化ける。
|
||||
|
||||
lcd.setAddrWindow(40, 80, image_width, image_height);
|
||||
lcd.writePixels((void *)rgb888, len, true); // 24bitのデータも同様に、RGB888の青が下位側にあるデータはバイト順変換が必要。
|
||||
|
||||
lcd.setAddrWindow(40, 120, image_width, image_height);
|
||||
lcd.writePixels((void *)bgr888, len, false); // 同様に、BGR888の赤が下位側にあるデータはバイト順変換は不要。
|
||||
|
||||
lcd.setAddrWindow(40, 160, image_width, image_height);
|
||||
lcd.writePixels((void *)bgr888, len, true); // 設定を誤ると、色が化ける。(赤と青が入れ替わる)
|
||||
|
||||
lcd.display();
|
||||
delay(4000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
/*
|
||||
方法2.描画する座標と幅・高さを指定してデータを描画する方法
|
||||
|
||||
この方法では、pushImage関数を用いて描画範囲と描画データを指定して描画します。
|
||||
|
||||
pushImage( x, y, w, h, *data); // 指定された座標に画像を描画する。
|
||||
|
||||
方法1と違い、画面外にはみ出す座標を指定しても描画が乱れることはありません。(はみ出した部分は描画されません。)
|
||||
方法1と違い、バイト順の変換を指定する引数が無いため、事前にsetSwapBytesによる設定が必要です。
|
||||
なお方法1と同様に、dataの型に応じて色変換が行われます。
|
||||
*/
|
||||
|
||||
lcd.setSwapBytes(true); // バイト順変換を有効にする。
|
||||
|
||||
// 描画先の座標と画像の幅・高さを指定して画像データを描画します。
|
||||
lcd.pushImage(0, 0, image_width, image_height, (uint16_t *)rgb565); // RGB565の16bit画像データを描画。
|
||||
|
||||
// データとバイト順変換の指定が一致していない場合、色化けします。
|
||||
lcd.pushImage(0, 40, image_width, image_height, (uint16_t *)swap565); // NG. バイト順変換済みデータにバイト順変換を行うと色化けする。
|
||||
|
||||
// 描画範囲が画面外にはみ出すなどした場合でも、描画結果が崩れることはありません。
|
||||
lcd.pushImage(-1, 80, image_width, image_height, (uint16_t *)rgb565); // X座標-1(画面外)を指定しても描画は乱れない。
|
||||
|
||||
// データと型が一致していない場合は、描画結果が崩れます。
|
||||
lcd.pushImage(0, 120, image_width, image_height, (uint8_t *)rgb565); // RGB565のデータをuint8_tにキャストし、RGB332として扱わせると描画が乱れる。
|
||||
|
||||
// データと型が一致していれば、適切に形式変換が行われます。
|
||||
lcd.pushImage(0, 160, image_width, image_height, (uint8_t *)rgb332); // RGB332のデータでも正しく描画できる。
|
||||
|
||||
lcd.setSwapBytes(false); // バイト順の変換を無効にする。
|
||||
lcd.pushImage(40, 0, image_width, image_height, (uint8_t *)rgb332); // good. RGB332のデータはバイト順変換の影響を受けない。
|
||||
lcd.pushImage(40, 40, image_width, image_height, (uint16_t *)rgb565); // NG. RGB565のデータはバイト順変換が必要。
|
||||
lcd.pushImage(40, 80, image_width, image_height, (void *)rgb888); // NG. RGB888のデータはバイト順変換が必要。
|
||||
lcd.pushImage(40, 120, image_width, image_height, (uint16_t *)swap565); // good. バイト順変換済みRGB565のデータは色化けしない。
|
||||
lcd.pushImage(40, 160, image_width, image_height, (void *)bgr888); // good. バイト順変換済みRGB888のデータは色化けしない。
|
||||
|
||||
lcd.setSwapBytes(true); // バイト順の変換を有効にする。
|
||||
lcd.pushImage(80, 0, image_width, image_height, (uint8_t *)rgb332); // good. RGB332のデータはバイト順変換の影響を受けない。
|
||||
lcd.pushImage(80, 40, image_width, image_height, (uint16_t *)rgb565); // good. バイト順変換が有効ならRGB565のデータは色化けしない。
|
||||
lcd.pushImage(80, 80, image_width, image_height, (void *)rgb888); // good. バイト順変換が有効ならRGB888のデータは色化けしない。
|
||||
lcd.pushImage(80, 120, image_width, image_height, (uint16_t *)swap565); // NG. バイト順変換済みデータにバイト順変換を行うと色化けする。
|
||||
lcd.pushImage(80, 160, image_width, image_height, (void *)bgr888); // NG. バイト順変換済みデータにバイト順変換を行うと色化けする。
|
||||
|
||||
// データの型として、lgfx::名前空間に定義されている型を利用する事もできます。
|
||||
// これらの型にキャストする場合はsetSwapBytesの設定は無視されます。
|
||||
lcd.pushImage(120, 0, image_width, image_height, (lgfx::rgb332_t *)rgb332); // good 8bitデータ
|
||||
lcd.pushImage(120, 40, image_width, image_height, (lgfx::rgb565_t *)rgb565); // good 16bitデータ
|
||||
lcd.pushImage(120, 80, image_width, image_height, (lgfx::rgb888_t *)rgb888); // good 24bitデータ
|
||||
lcd.pushImage(120, 120, image_width, image_height, (lgfx::swap565_t *)swap565); // good バイト順変換済み16bitデータ
|
||||
lcd.pushImage(120, 160, image_width, image_height, (lgfx::bgr888_t *)bgr888); // good バイト順変換済み24bitデータ
|
||||
|
||||
// 第6引数で透過色を指定できます。透過指定された色のある部分は描画されません。
|
||||
lcd.pushImage(160, 0, image_width, image_height, (lgfx::rgb332_t *)rgb332, 0); // 黒を透過指定
|
||||
lcd.pushImage(160, 40, image_width, image_height, (lgfx::rgb565_t *)rgb565, (uint8_t)0xE0); // 赤を透過指定
|
||||
lcd.pushImage(160, 80, image_width, image_height, (lgfx::rgb888_t *)rgb888, (uint16_t)0x07E0); // 緑を透過指定
|
||||
lcd.pushImage(160, 120, image_width, image_height, (lgfx::swap565_t *)swap565, (uint32_t)0x0000FFU); // 青を透過指定
|
||||
lcd.pushImage(160, 160, image_width, image_height, (lgfx::bgr888_t *)bgr888, TFT_WHITE); // 白を透過指定
|
||||
|
||||
lcd.display();
|
||||
delay(4000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
// pushImageRotateZoom関数を使うと、画像を回転拡大縮小させて描画できます。
|
||||
for (int angle = 0; angle <= 360; ++angle)
|
||||
{
|
||||
lcd.pushImageRotateZoom(lcd.width() >> 2 // 描画先の中心座標X
|
||||
,
|
||||
lcd.height() >> 1 // 描画先の中心座標Y
|
||||
,
|
||||
image_width >> 1 // 画像の中心座標X
|
||||
,
|
||||
image_height >> 1 // 画像の中心座標Y
|
||||
,
|
||||
angle // 回転角度
|
||||
,
|
||||
3.0 // X方向の描画倍率 (マイナス指定で反転可能)
|
||||
,
|
||||
3.0 // Y方向の描画倍率 (マイナス指定で反転可能)
|
||||
,
|
||||
image_width // 画像データの幅
|
||||
,
|
||||
image_height // 画像データの高さ
|
||||
,
|
||||
rgb332 // 画像データのポインタ
|
||||
);
|
||||
|
||||
// pushImageRotateZoomWithAA関数を使うと、アンチエイリアスが有効になります。
|
||||
lcd.pushImageRotateZoomWithAA(lcd.width() * 3 >> 2, lcd.height() >> 1, image_width >> 1, image_height >> 1, angle, 3.0, 3.0, image_width, image_height, rgb332);
|
||||
|
||||
if ((angle % 36) == 0)
|
||||
{
|
||||
lcd.display();
|
||||
}
|
||||
}
|
||||
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
// pushImageAffine関数を使うと、画像をアフィン変換で変形させて描画できます。
|
||||
// アフィン変換のパラメータはfloat型の配列で指定します。
|
||||
{
|
||||
float matrix[6] = // 等倍表示
|
||||
{1.0, 0.0, (float)lcd.width() / 2, 0.0, 1.0, (float)lcd.height() / 2};
|
||||
lcd.pushImageAffine(matrix, image_width, image_height, rgb332);
|
||||
}
|
||||
|
||||
lcd.display();
|
||||
delay(1000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
{
|
||||
float matrix[6] = // 横2倍表示
|
||||
{2.0, 0.0, (float)lcd.width() / 2, 0.0, 1.0, (float)lcd.height() / 2};
|
||||
lcd.pushImageAffine(matrix, image_width, image_height, rgb332);
|
||||
}
|
||||
|
||||
lcd.display();
|
||||
delay(1000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
{
|
||||
float matrix[6] = // 縦2倍表示
|
||||
{1.0, 0.0, (float)lcd.width() / 2, 0.0, 2.0, (float)lcd.height() / 2};
|
||||
lcd.pushImageAffine(matrix, image_width, image_height, rgb332);
|
||||
}
|
||||
|
||||
lcd.display();
|
||||
delay(1000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
{
|
||||
float matrix[6] = // 斜め変形
|
||||
{1.0, -0.4, (float)lcd.width() / 2, 0.0, 1.0, (float)lcd.height() / 2};
|
||||
lcd.pushImageAffine(matrix, image_width, image_height, rgb332);
|
||||
}
|
||||
|
||||
lcd.display();
|
||||
delay(1000);
|
||||
lcd.clear(TFT_DARKGREY);
|
||||
|
||||
// pushImageAffineWithAA関数を使用するとアンチエイリアスが有効になります。
|
||||
{
|
||||
float matrix[6] =
|
||||
{1.0, 0.0, (float)lcd.width() / 2, 0.0, 1.0, (float)lcd.height() / 2};
|
||||
for (int i = -300; i < 300; i++)
|
||||
{
|
||||
float f = (float)i / 100;
|
||||
matrix[1] = f;
|
||||
matrix[3] = f;
|
||||
lcd.pushImageAffineWithAA(matrix, image_width, image_height, rgb332);
|
||||
|
||||
if ((i % 30) == 0)
|
||||
{
|
||||
lcd.display();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define R 0x00, 0x00, 0xFF,
|
||||
#define G 0x00, 0xFF, 0x00,
|
||||
#define B 0xFF, 0x00, 0x00,
|
||||
#define C 0xFF, 0xFF, 0x00,
|
||||
#define M 0xFF, 0x00, 0xFF,
|
||||
#define Y 0x00, 0xFF, 0xFF,
|
||||
#define W 0xFF, 0xFF, 0xFF,
|
||||
#define _ 0x00, 0x00, 0x00,
|
||||
constexpr uint8_t rgb888[] = {
|
||||
#include "image.h"
|
||||
};
|
||||
#undef R
|
||||
#undef G
|
||||
#undef B
|
||||
#undef C
|
||||
#undef M
|
||||
#undef Y
|
||||
#undef W
|
||||
#undef _
|
||||
//----------------------------------------------------------------------------
|
||||
#define R 0xFF, 0x00, 0x00,
|
||||
#define G 0x00, 0xFF, 0x00,
|
||||
#define B 0x00, 0x00, 0xFF,
|
||||
#define C 0x00, 0xFF, 0xFF,
|
||||
#define M 0xFF, 0x00, 0xFF,
|
||||
#define Y 0xFF, 0xFF, 0x00,
|
||||
#define W 0xFF, 0xFF, 0xFF,
|
||||
#define _ 0x00, 0x00, 0x00,
|
||||
constexpr uint8_t bgr888[] = {
|
||||
#include "image.h"
|
||||
};
|
||||
#undef R
|
||||
#undef G
|
||||
#undef B
|
||||
#undef C
|
||||
#undef M
|
||||
#undef Y
|
||||
#undef W
|
||||
#undef _
|
||||
//----------------------------------------------------------------------------
|
||||
#define R 0x00F8,
|
||||
#define G 0xE007,
|
||||
#define B 0x1F00,
|
||||
#define C 0xFF07,
|
||||
#define M 0x1FF8,
|
||||
#define Y 0xE0FF,
|
||||
#define W 0xFFFF,
|
||||
#define _ 0x0000,
|
||||
constexpr uint16_t swap565[] = {
|
||||
#include "image.h"
|
||||
};
|
||||
#undef R
|
||||
#undef G
|
||||
#undef B
|
||||
#undef C
|
||||
#undef M
|
||||
#undef Y
|
||||
#undef W
|
||||
#undef _
|
||||
//----------------------------------------------------------------------------
|
||||
#define R 0xF800,
|
||||
#define G 0x07E0,
|
||||
#define B 0x001F,
|
||||
#define C 0x07FF,
|
||||
#define M 0xF81F,
|
||||
#define Y 0xFFE0,
|
||||
#define W 0xFFFF,
|
||||
#define _ 0x0000,
|
||||
constexpr uint16_t rgb565[] = {
|
||||
#include "image.h"
|
||||
};
|
||||
#undef R
|
||||
#undef G
|
||||
#undef B
|
||||
#undef C
|
||||
#undef M
|
||||
#undef Y
|
||||
#undef W
|
||||
#undef _
|
||||
//----------------------------------------------------------------------------
|
||||
#define R 0xE0,
|
||||
#define G 0x1C,
|
||||
#define B 0x03,
|
||||
#define C 0x1F,
|
||||
#define M 0xE3,
|
||||
#define Y 0xFC,
|
||||
#define W 0xFF,
|
||||
#define _ 0x00,
|
||||
constexpr uint8_t rgb332[] = {
|
||||
#include "image.h"
|
||||
};
|
||||
#undef R
|
||||
#undef G
|
||||
#undef B
|
||||
#undef C
|
||||
#undef M
|
||||
#undef Y
|
||||
#undef W
|
||||
#undef _
|
||||
Reference in New Issue
Block a user