Compare commits

..

7 Commits
dev ... main

Author SHA1 Message Date
ZK 4aa117841f fix bugs 2024-05-21 20:17:02 +08:00
ZK 83989d8e40 fix bugs 2024-05-21 10:06:26 +08:00
BoomPC 370206729a 完成初版设计 2024-05-21 02:24:27 +08:00
BoomPC c9186cda7b 增加波形,不闪屏 2024-05-20 02:34:50 +08:00
VincyGMY fcd81163ce drawLine 2024-05-19 18:15:59 +08:00
BoomPC 3589b979ce test 2024-05-07 23:41:02 +08:00
Boooom 0e635c93a7 Merge pull request 'test' (#1) from dev into main
Reviewed-on: #1
2024-05-07 23:32:27 +08:00
6 changed files with 1401 additions and 101 deletions

54
.vscode/settings.json vendored
View File

@ -1,7 +1,7 @@
{ {
"stm32-for-vscode.openOCDPath": false, "stm32-for-vscode.openOCDPath": false,
"stm32-for-vscode.makePath": false, "stm32-for-vscode.makePath": false,
"stm32-for-vscode.armToolchainPath": false, "stm32-for-vscode.armToolchainPath": "E:\\SOFTWARE_DEVELOP_TOOLS\\GCC-ARM-NONE-EABI-10.3-2021.10-WIN32\\GCC-ARM-NONE-EABI-10.3-2021.10\\BIN",
"files.associations": { "files.associations": {
"刷新画线": "c", "刷新画线": "c",
"optional": "cpp", "optional": "cpp",
@ -10,6 +10,54 @@
"new": "cpp", "new": "cpp",
"*.tcc": "cpp", "*.tcc": "cpp",
"cmath": "cpp", "cmath": "cpp",
"utility": "cpp" "utility": "cpp",
} "array": "cpp",
"atomic": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"ratio": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"mutex": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
},
"C_Cpp.errorSquiggles": "disabled"
} }

372
BackUp/202405191704copy Normal file
View File

@ -0,0 +1,372 @@
#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 = 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等でバス制御を行います)
// 以下は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 = 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");
}
float InitialDataV,InitialDataI;
float ProcessedDataV,ProcessedDataI;
float DataPower;
void setup(void)
{
lcd.init();
lcd.startWrite();
lcd.fillScreen(0xFFFFFFU);
// drawGradation();
// lcd.fillScreen(0xFFFFFFU);
lcd.setBrightness(128);
Serial.begin(115200);
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();
lcd.setTextColor(0xFFFFFFU, 0x000000U);
lcd.fillScreen(0x000000U);
lcd.setFont(&fonts::Font4);
lcd.setTextDatum(bottom_center);
lcd.drawString("V", 180, 50);
lcd.drawString("A", 180, 108);
lcd.drawString("W", 180, 166);
InitialDataV=ina.readBusVoltage();
InitialDataI=ina.readShuntCurrent();
ProcessedDataV=InitialDataV;
ProcessedDataI=InitialDataI;
lcd.setFont(&fonts::Font6);
lcd.setTextDatum(bottom_right);
}
// 一阶滞后滤波法
#define FILTER_A 0.01
float Filter(float PreData,float NewData)
{
float Value;
Value = (float)NewData * FILTER_A + (1.0 - FILTER_A) * (float)PreData;
return Value;
}
void DataProcess(void)
{
InitialDataV=ina.readBusVoltage();
InitialDataI=ina.readShuntCurrent();
ProcessedDataV=InitialDataV;
ProcessedDataI=abs(InitialDataI);
DataPower=ProcessedDataI*ProcessedDataV;
// ProcessedDataV=Filter(ProcessedDataV,InitialDataV);
// ProcessedDataI=abs(Filter(ProcessedDataI,InitialDataI));
}
void DataDisplay(void)
{
DataProcess();
if(ProcessedDataV<10.0f)
lcd.drawFloat(ProcessedDataV, 4, 160, 58);
else
lcd.drawFloat(ProcessedDataV, 3, 160, 58);
lcd.drawFloat(ProcessedDataI, 4, 160, 116);
if(DataPower<10.0f)
lcd.drawFloat(DataPower, 4, 160, 174);
else
lcd.drawFloat(DataPower, 3, 160, 174);
// Serial.print(DataPower,5);
}
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)
{
DataDisplay();
delay(100);
}

View File

@ -0,0 +1,363 @@
#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 = 320;
static constexpr int image_height = 172;
int32_t current;
uint16_t current_buf[320];
float t = 0;
#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
uint16_t rgb565[image_height * (image_width + 10)];
uint16_t imageLine[image_height][image_width];
//----------------------------------------------------------------------------
/// 独自の設定を行うクラスを、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);
Serial.begin(115200);
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();
for (size_t i = 0; i < image_height * image_width; i++)
{
rgb565[i] = 0x0;
}
// delay(1000);
// Serial.print("test");
}
void LCD_BackBuffer_DrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
rgb565[image_width * y + x] = color;
}
void Graph_DrawCurve(uint16_t *data, uint16_t color)
{
uint16_t y;
for (uint16_t i = 0; i < image_width; i++)
{
// 超出图表范围,忽略
if (data[i] >= 150)
continue;
// y轴是倒过来的
y = 150 - data[i];
// Serial.print(i);
// Serial.print("+");
// Serial.print(y);
// Serial.println();
LCD_BackBuffer_DrawPixel(i, y, color);
// 为了更好的显示效果,可以在数据点的邻域添加绘制点
// LCD_BackBuffer_DrawPixel(i + 1, y, color);
// LCD_BackBuffer_DrawPixel(i - 1, y, color);
// LCD_BackBuffer_DrawPixel(i, y + 1, color);
// LCD_BackBuffer_DrawPixel(i, y - 1, color);
}
}
void loop(void)
{
// 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); // 描画範囲を設定。
for (size_t i = 0; i < 320; i++)
{
current_buf[i] = current_buf[i+1];
}
current_buf[319] = uint16_t(ina.readShuntCurrent() * 50);
Graph_DrawCurve(current_buf, 0xffff);
lcd.writePixels((uint16_t *)rgb565, len); // RGB565の16bit画像データを描画。
for (size_t i = 0; i < image_height * image_width; i++)
{
rgb565[i] = 0;
}
}

357
BackUp/绘制波形Demo Normal file
View File

@ -0,0 +1,357 @@
#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");
}
#include <vector>
#define LINE_COUNT 6
static std::vector<int> points[LINE_COUNT];
static int colors[] = {TFT_RED, TFT_GREEN, TFT_BLUE, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW};
static int xoffset, yoffset, point_count;
int getBaseColor(int x, int y)
{
return ((x ^ y) & 3 || ((x - xoffset) & 31 && y & 31) ? TFT_BLACK : ((!y || x == xoffset) ? TFT_WHITE : TFT_DARKGREEN));
}
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();
if (lcd.width() < lcd.height())
lcd.setRotation(lcd.getRotation() ^ 1);
yoffset = lcd.height() >> 1;
xoffset = lcd.width() >> 1;
point_count = lcd.width() + 1;
for (int i = 0; i < LINE_COUNT; i++)
{
points[i].resize(point_count);
}
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(getBaseColor(x, y - yoffset), 1);
}
}
lcd.endWrite();
}
void loop(void)
{
static int prev_sec;
static int fps;
++fps;
int sec = millis() / 1000;
if (prev_sec != sec)
{
prev_sec = sec;
lcd.setCursor(0, 0);
lcd.printf("fps:%03d", fps);
fps = 0;
}
static int count;
for (int i = 0; i < LINE_COUNT; i++)
{
points[i][count % point_count] = (sinf((float)count / (10 + 30 * i)) + sinf((float)count / (13 + 37 * i))) * (lcd.height() >> 2);
}
++count;
lcd.startWrite();
int index1 = count % point_count;
for (int x = 0; x < point_count - 1; x++)
{
int index0 = index1;
index1 = (index0 + 1) % point_count;
for (int i = 0; i < LINE_COUNT; i++)
{
int y = points[i][index0];
if (y != points[i][index1])
{
lcd.writePixel(x, y + yoffset, getBaseColor(x, y));
}
}
for (int i = 0; i < LINE_COUNT; i++)
{
int y = points[i][index1];
lcd.writePixel(x, y + yoffset, colors[i]);
}
}
lcd.endWrite();
}

31
src/image.h Normal file
View File

@ -0,0 +1,31 @@
_ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R R R _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ R R R R R R R R R R R R R _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ R R R R _ _ _ _ _ _ R R R R R _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ R R R R R _ _ R R R _ _ R R R R R _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ R R R R R _ _ R R R _ _ R R R R R _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R _ _ _ _ _ _ R R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R _ _ R R _ _ R R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R _ _ R R R _ _ R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R _ _ R R R _ _ R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R _ _ R R R _ _ R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ _ R R R R R R R R R R R R R R R R R R R _ _ _ _ _ _ _
_ _ _ _ _ _ G Y Y Y Y Y Y R R R R R R R M M M M M M B _ _ _ _ _ _
_ _ _ _ G G G G Y Y Y Y Y Y Y R R R M M M M M M M B B B B _ _ _ _
_ _ _ G G G G G Y Y Y Y Y Y Y Y R M M M M M M M M B B B B B _ _ _
_ _ G G G G G G G Y Y Y Y Y Y Y W M M M M M M M B B B B B B B _ _
_ G G G G G G G G G Y Y Y Y Y W W W M M M M M B B B B B B B B B _
_ G G G G G G G G G G Y Y Y Y W W W M M M M B B B B B B B B B B _
G G G G G G G G G G G G G Y W W W W W M B B B B B B B B B B B B B
G G G G G _ _ _ _ G G G G G C C C C C B B B B _ _ _ _ _ B B B B B
G G G G _ _ G G _ _ G G G G C C C C C B B B B _ _ B B _ _ B B B B
G G G G _ _ G G G G G G G G C C C C C B B B B _ _ B B _ _ B B B B
G G G G _ _ G G G G G G G G C C C C C B B B B _ _ _ _ _ B B B B B
G G G G _ _ G _ _ _ G G G G C C C C C B B B B _ _ B B _ _ B B B B
G G G G _ _ G G _ _ G G G G C C C C C B B B B _ _ B B _ _ B B B B
_ G G G _ _ G G _ _ G G G G G C C C B B B B B _ _ B B _ _ B B B _
_ G G G G _ _ _ _ G G G G G G C C C B B B B B _ _ _ _ _ B B B B _
_ _ G G G G G G G G G G G G G G C B B B B B B B B B B B B B B _ _
_ _ _ G G G G G G G G G G G G G _ B B B B B B B B B B B B B _ _ _
_ _ _ _ G G G G G G G G G G G _ _ _ B B B B B B B B B B B _ _ _ _
_ _ _ _ _ _ G G G G G G G _ _ _ _ _ _ _ B B B B B B B _ _ _ _ _ _

View File

@ -7,7 +7,33 @@ INA226 ina(Wire);
// #include "misakiUTF16FontData.h" // #include "misakiUTF16FontData.h"
#include <LovyanGFX.hpp> #include <LovyanGFX.hpp>
// ESP32でLovyanGFXを独自設定で利用する場合の設定例 // ESP32でLovyanGFXを独自設定で利用する場合の設定例
static constexpr int image_width = 320;
static constexpr int image_height = 130;
int32_t current;
uint16_t current_buf[100];
float t = 0;
#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
uint16_t rgb565[image_height * (image_width + 10)];
uint16_t imageLine[image_height][image_width];
/// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。 /// 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。
class LGFX : public lgfx::LGFX_Device class LGFX : public lgfx::LGFX_Device
{ {
@ -248,18 +274,102 @@ void checkConfig()
Serial.println(" W"); Serial.println(" W");
} }
float InitialDataV, InitialDataI;
float ProcessedDataV, ProcessedDataI;
float DataPower;
// 一阶滞后滤波法
#define FILTER_A 0.01
float Filter(float PreData, float NewData)
{
float Value;
Value = (float)NewData * FILTER_A + (1.0 - FILTER_A) * (float)PreData;
return Value;
}
void DataProcess(void)
{
InitialDataV = ina.readBusVoltage();
InitialDataI = ina.readShuntCurrent() - 0.0026f;
ProcessedDataV = InitialDataV;
ProcessedDataI = abs(InitialDataI);
DataPower = ProcessedDataI * ProcessedDataV;
// ProcessedDataV=Filter(ProcessedDataV,InitialDataV);
// ProcessedDataI=abs(Filter(ProcessedDataI,InitialDataI));
}
void DataDisplay(void)
{
DataProcess();
if (ProcessedDataV < 10.0f)
{
lcd.setTextColor(0xaa96daU, 0x000000U);
lcd.drawFloat(ProcessedDataV, 4, 10, 140);
}
else
{
lcd.setTextColor(0xaa96daU, 0x000000U);
lcd.drawFloat(ProcessedDataV, 3, 10, 140);
}
lcd.setTextColor(0xfcbad3U, 0x000000U);
lcd.drawFloat(ProcessedDataI, 4, 110, 140);
if (DataPower < 10.0f)
{
lcd.setTextColor(0xffffd2U, 0x000000U);
lcd.drawFloat(DataPower, 4, 210, 140);
}
else
{
lcd.setTextColor(0xffffd2U, 0x000000U);
lcd.drawFloat(DataPower, 3, 210, 140);
}
}
void LCD_BackBuffer_DrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
rgb565[image_width * y + x] = color;
}
void Graph_DrawCurve(uint16_t *data, uint16_t color)
{
uint16_t y;
for (uint16_t i = 0; i < image_width; i++)
{
// 超出图表范围,忽略
if (data[i] >= 150)
continue;
// y轴是倒过来的
y = 150 - data[i];
LCD_BackBuffer_DrawPixel(i, y, color);
// 为了更好的显示效果,可以在数据点的邻域添加绘制点
// LCD_BackBuffer_DrawPixel(i + 1, y, color);
// LCD_BackBuffer_DrawPixel(i - 1, y, color);
// LCD_BackBuffer_DrawPixel(i, y + 1, color);
// LCD_BackBuffer_DrawPixel(i, y - 1, color);
}
}
#include <vector>
#define LINE_COUNT 1
uint32_t number = 0;
static std::vector<int> points[LINE_COUNT];
static int colors[] = {TFT_PINK, 0xaa96daU, TFT_BLUE, TFT_CYAN, TFT_MAGENTA, TFT_YELLOW};
static int xoffset, yoffset, point_count;
int getBaseColor(int x, int y)
{
return ((x ^ y) & 3 || ((x - xoffset) & 31 && y & 31) ? TFT_BLACK : ((!y || x == xoffset) ? TFT_DARKGRAY : TFT_DARKGRAY));
}
void setup(void) void setup(void)
{ {
lcd.init(); lcd.init();
lcd.startWrite(); // lcd.startWrite();
lcd.fillScreen(0xFFFFFFU); lcd.fillScreen(0);
// drawGradation(); // drawGradation();
// lcd.fillScreen(0xFFFFFFU); // lcd.fillScreen(0xFFFFFFU);
lcd.setBrightness(128); lcd.setBrightness(128);
// Serial.begin(115200);
Serial.begin(115200);
Wire.begin(1, 0, 100000); Wire.begin(1, 0, 100000);
// Default INA226 address is 0x40 // Default INA226 address is 0x40
@ -278,107 +388,126 @@ void setup(void)
// Display configuration // Display configuration
checkConfig(); checkConfig();
lcd.setTextColor(0xFFFFFFU, 0x000000U); if (lcd.width() < lcd.height())
lcd.fillScreen(0x000000U); lcd.setRotation(lcd.getRotation() ^ 1);
}
unsigned short int lastX, lastY; yoffset = image_height >> 1;
unsigned char firstPoint = 1; xoffset = image_width >> 1;
void drawCurve(short int rawValue) point_count = image_width + 1;
{
unsigned short int x, y; for (int i = 0; i < LINE_COUNT; i++)
y = 120 - rawValue / 280; // data processing code
// 这里之所以是120-rawValue/280与屏幕的扫描方向有关如果出现上下颠倒的情况可以改成120 +
if (firstPoint) // 如果是第一次画点,则无需连线,直接描点即可
{ {
lcd.drawPixel(0, y); points[i].resize(point_count);
lastX = 0;
lastY = y;
firstPoint = 0;
} }
else
lcd.startWrite();
lcd.setAddrWindow(0, 0, image_width, image_height);
for (int y = 0; y < image_height; y++)
{ {
x = lastX + 1; for (int x = 0; x < image_width; x++)
if (x < 320) // 不超过屏幕宽度
{ {
lcd.drawLine(lastX, lastY, x, y); lcd.writeColor(getBaseColor(x, y - yoffset), 1);
lastX = x;
lastY = y;
}
else // 超出屏幕宽度,清屏,从第一个点开始绘制,实现动态更新效果
{
lcd.fillScreen(0xFFFFFFU); // 清屏,白色背景
lcd.drawPixel(0, y);
lastX = 0;
lastY = y;
} }
} }
} lcd.endWrite();
void loop(void) // lcd.setTextColor(0xFFFFFFU, 0x000000U);
{ // lcd.fillScreen(0x000000U);
// Serial.print("Bus voltage: ");
// Serial.print(ina.readBusVoltage(), 5);
// Serial.println(" V");
// Serial.print("Bus power: "); lcd.setFont(&fonts::Font2);
// Serial.print(ina.readBusPower(), 5); lcd.setTextDatum(top_left);
// Serial.println(" W"); lcd.setTextColor(0xaa96daU, 0x000000U);
lcd.drawString("V", 90, 145);
lcd.setTextColor(0xfcbad3U, 0x000000U);
lcd.drawString("A", 190, 145);
lcd.setTextColor(0xffffd2U, 0x000000U);
lcd.drawString("W", 290, 145);
// Serial.print("Shunt voltage: "); // InitialDataV = ina.readBusVoltage();
// Serial.print(ina.readShuntVoltage(), 5); // InitialDataI = ina.readShuntCurrent();
// Serial.println(" V"); // ProcessedDataV = InitialDataV;
// ProcessedDataI = InitialDataI;
// Serial.print("Shunt current: ");
// Serial.print(ina.readShuntCurrent(), 5);
// Serial.println(" A");
// Serial.println("");
delay(10);
// delay(1000);
// lcd.clearDisplay(0xFFFFFFU);
// lcd.setFont(&fonts::Roboto_Thin_24);
// lcd.setFont(&fonts::Font4);
// lcd.setTextDatum(bottom_center);
// lcd.drawString("V", 220, 50);
// lcd.drawString("A", 220, 108);
// lcd.drawString("W", 220, 166);
// lcd.setFont(&fonts::Font6); // lcd.setFont(&fonts::Font6);
// lcd.setTextDatum(bottom_right);
// lcd.drawFloat(ina.readBusVoltage(), 4, 200, 58);
// lcd.drawFloat(abs(ina.readShuntCurrent()), 4, 200, 116);
// lcd.drawFloat(ina.readBusPower(), 4, 200, 174);
// float current = abs(ina.readShuntCurrent()); // // DataDisplay();
// drawCurve(current * 10000); // lcd.setColorDepth(16); // LCDを16bitカラーモードに設定する。
// drawCurve(current); // // lcd.setSwapBytes(true); // バイト順変換を有効にする。
// Serial.print(current, 4); // int len = image_width * image_height;
// Serial.print("\r\n"); // lcd.setAddrWindow(220, 0, image_width, image_height); // 描画範囲を設定。
// lcd.drawNumber(ina.readBusVoltage(), 120, 120); }
// ※ 名前が"Free"で始まるフォントは 9pt 12pt 18pt 24ptの種類があります。 void loop(void)
// drawNumberTest( &fonts::Font0 ); {
// drawNumberTest( &fonts::Font2 ); static int prev_sec;
// drawNumberTest( &fonts::Font4 ); static int fps;
// drawNumberTest( &fonts::Font6 ); ++fps;
// drawNumberTest( &fonts::Font7 ); int sec = millis() / 1000;
// drawNumberTest( &fonts::Font8 ); if (prev_sec != sec)
// drawNumberTest( &fonts::TomThumb ); {
// drawNumberTest( &fonts::FreeMono9pt7b ); lcd.setFont(&fonts::Font2);
// drawNumberTest( &fonts::FreeMonoBold9pt7b ); lcd.setTextColor(TFT_LIGHTGRAY, 0x000000U);
// drawNumberTest( &fonts::FreeMonoOblique9pt7b ); prev_sec = sec;
// drawNumberTest( &fonts::FreeMonoBoldOblique9pt7b); lcd.setCursor(10, 10);
// drawNumberTest( &fonts::FreeSans9pt7b ); lcd.printf("FPS : %03d", fps);
// drawNumberTest( &fonts::FreeSansBold9pt7b ); // lcd.drawNumber(fps, 320, 0);
// drawNumberTest( &fonts::FreeSansOblique9pt7b ); fps = 0;
// drawNumberTest( &fonts::FreeSansBoldOblique9pt7b); }
// drawNumberTest( &fonts::FreeSerif9pt7b );
// drawNumberTest( &fonts::FreeSerifBold9pt7b ); static int count;
// drawNumberTest( &fonts::FreeSerifItalic9pt7b );
// drawNumberTest( &fonts::FreeSerifBoldItalic9pt7b); for (int i = 0; i < LINE_COUNT; i++)
// drawNumberTest( &fonts::Orbitron_Light_24 ); {
// drawNumberTest( &fonts::Roboto_Thin_24 ); points[i][count % point_count] = -uint16_t(abs(ina.readShuntCurrent() - 0.0026f) * 50) + 65;
// drawNumberTest( &fonts::Satisfy_24 ); // points[1][count % point_count] = -uint16_t(ina.readBusVoltage() * 5) + 65;
// drawNumberTest( &fonts::Yellowtail_32 ); }
++count;
lcd.startWrite();
int index1 = count % point_count;
for (int x = 0; x < point_count - 1; x++)
{
int index0 = index1;
index1 = (index0 + 1) % point_count;
for (int i = 0; i < LINE_COUNT; i++)
{
int y = points[i][index0];
if (y != points[i][index1])
{
lcd.writePixel(x, y + yoffset, getBaseColor(x, y));
}
}
for (int i = 0; i < LINE_COUNT; i++)
{
int y = points[i][index1];
lcd.writePixel(x, y + yoffset, colors[i]);
}
}
lcd.endWrite();
// lcd.startWrite();
// // lcd.setSwapBytes(true); // バイト順変換を有効にする。
// for (size_t i = 0; i < image_width; i++)
// {
// current_buf[i] = current_buf[i + 1];
// }
// current_buf[image_width - 1] = uint16_t(ina.readShuntCurrent() * 50);
// Graph_DrawCurve(current_buf, W);
// lcd.writePixels((uint16_t *)rgb565, image_width * image_height); // RGB565の16bit画像データを描画。
// for (size_t i = 0; i < image_height * image_width; i++)
// {
// rgb565[i] = 0;
// }
// lcd.endWrite();
number++;
if (number == 100)
{
lcd.setFont(&fonts::Font4);
DataDisplay();
number = 0;
}
// delay(100);
} }