添加 vfd 相关文件
This commit is contained in:
parent
588df7567a
commit
579a17c5c5
140
doc/vfd_log.txt
Normal file
140
doc/vfd_log.txt
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
1b 0b // boot
|
||||||
|
1b 21 01 // PowerOn
|
||||||
|
1b 32 02 // Set Language
|
||||||
|
|
||||||
|
1b 0c // Clear
|
||||||
|
1b 52 // Stop Scroll
|
||||||
|
1b 40 00 00 00 00 9f 02 // Set Option
|
||||||
|
1b 41 00 // Set Speed
|
||||||
|
1b 50 1e 83 4a 81 5b 83 68 82 f0 82 a9 82 b4 82 b5 82 c4 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // カードをかざしてください
|
||||||
|
1b 51 // Start Scroll
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 20 83 4a 81 5b 83 68 82 f0 97 a3 82 b3 82 c8 82 a2 82 c5 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // カードを離さないでください
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 1c 82 b5 82 ce 82 e7 82 ad 82 a8 91 d2 82 bf 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // しばらくお待ちください
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 30 00 00 00 8f 80 94 f5 92 86 82 c5 82 b7 81 63 // 準備中です…
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 1c 82 b5 82 ce 82 e7 82 ad 82 a8 91 d2 82 bf 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // しばらくお待ちください
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b9 82 f1 // 電子決済できません
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 02 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2e 6e 61 6e 61 63 6f 20 20 20 20 20 20 8c f0 92 ca 8c 6e 20 20 20 20 20 20 57 41 4f 4e 20 20 20 20 20 20 50 41 53 45 4c 49 20 20 20 20 20 20 // nanaco 交通系 WAON PASELI
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b9 82 f1 // 電子決済できません
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 02 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2e 6e 61 6e 61 63 6f 20 20 20 20 20 20 8c f0 92 ca 8c 6e 20 20 20 20 20 20 57 41 4f 4e 20 20 20 20 20 20 50 41 53 45 4c 49 20 20 20 20 20 20 // nanaco 交通系 WAON PASELI
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2c 50 41 53 45 4c 49 8e 78 95 a5 0d 0a 83 4a 81 5b 83 68 82 f0 83 5e 83 62 83 60 82 b5 82 c4 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // PASELI支払 カードをタッチしてください
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 02 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2e 6e 61 6e 61 63 6f 20 20 20 20 20 20 8c f0 92 ca 8c 6e 20 20 20 20 20 20 57 41 4f 4e 20 20 20 20 20 20 50 41 53 45 4c 49 20 20 20 20 20 20 // nanaco 交通系 WAON PASELI
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2c 50 41 53 45 4c 49 8e 78 95 a5 0d 0a 83 4a 81 5b 83 68 82 f0 83 5e 83 62 83 60 82 b5 82 c4 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // PASELI支払 カードをタッチしてください
|
||||||
|
1b 30 00 00 02 6e 61 6e 61 63 6f 8e 78 95 a5 20 5c 31 30 30 nanaco支払 \100
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2c 50 41 53 45 4c 49 8e 78 95 a5 0d 0a 83 4a 81 5b 83 68 82 f0 83 5e 83 62 83 60 82 b5 82 c4 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // PASELI支払 カードをタッチしてください
|
||||||
|
1b 30 00 00 02 6e 61 6e 61 63 6f 8e 63 8d 82 20 5c 31 30 31 nanaco残高 \101
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 02 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2e 6e 61 6e 61 63 6f 20 20 20 20 20 20 8c f0 92 ca 8c 6e 20 20 20 20 20 20 57 41 4f 4e 20 20 20 20 20 20 50 41 53 45 4c 49 20 20 20 20 20 20 // nanaco 交通系 WAON PASELI
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 00 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2c 50 41 53 45 4c 49 8e 78 95 a5 0d 0a 83 4a 81 5b 83 68 82 f0 83 5e 83 62 83 60 82 b5 82 c4 82 ad 82 be 82 b3 82 a2 20 20 20 20 20 20 // PASELI支払 カードをタッチしてください
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
||||||
|
1b 40 00 00 02 00 9f 02
|
||||||
|
1b 41 00
|
||||||
|
1b 50 2e 6e 61 6e 61 63 6f 20 20 20 20 20 20 8c f0 92 ca 8c 6e 20 20 20 20 20 20 57 41 4f 4e 20 20 20 20 20 20 50 41 53 45 4c 49 20 20 20 20 20 20 // nanaco 交通系 WAON PASELI
|
||||||
|
1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
1b 51
|
||||||
|
|
||||||
|
1b 0c
|
||||||
|
1b 52
|
195
tools/segatools-edit/vfd.c
Normal file
195
tools/segatools-edit/vfd.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/* This is some sort of LCD display found on various cabinets. It is driven
|
||||||
|
directly by amdaemon, and it has something to do with displaying the status
|
||||||
|
of electronic payments.
|
||||||
|
|
||||||
|
Part number in schematics is "VFD GP1232A02A FUTABA".
|
||||||
|
|
||||||
|
Little else about this board is known. Black-holing the RS232 comms that it
|
||||||
|
receives seems to be sufficient for the time being. */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "board/vfd.h"
|
||||||
|
|
||||||
|
#include "hook/iohook.h"
|
||||||
|
|
||||||
|
#include "hooklib/uart.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
#include "util/dump.h"
|
||||||
|
|
||||||
|
static HRESULT vfd_handle_irp(struct irp *irp);
|
||||||
|
|
||||||
|
static struct uart vfd_uart;
|
||||||
|
static uint8_t vfd_written[512];
|
||||||
|
static uint8_t vfd_readable[512];
|
||||||
|
static uint8_t vfd_enable, vfd_redirect;
|
||||||
|
static HANDLE com_device;
|
||||||
|
UINT codepage;
|
||||||
|
|
||||||
|
HRESULT vfd_hook_init(unsigned int port_no)
|
||||||
|
{
|
||||||
|
vfd_enable = GetPrivateProfileIntW(L"vfd", L"enable", 1, L".\\segatools.ini");
|
||||||
|
vfd_redirect = GetPrivateProfileIntW(L"vfd", L"redirect", 0, L".\\segatools.ini");
|
||||||
|
if (!vfd_enable)
|
||||||
|
{
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char com_name[10];
|
||||||
|
// sprintf(com_name, "\\\\.\\COM%d", port_no);
|
||||||
|
// com_device = CreateFile(com_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
// if (com_device != INVALID_HANDLE_VALUE)
|
||||||
|
// {
|
||||||
|
// CloseHandle(com_device);
|
||||||
|
// if (!vfd_redirect)
|
||||||
|
// {
|
||||||
|
// return S_FALSE;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
uart_init(&vfd_uart, port_no);
|
||||||
|
vfd_uart.written.bytes = vfd_written;
|
||||||
|
vfd_uart.written.nbytes = sizeof(vfd_written);
|
||||||
|
vfd_uart.readable.bytes = vfd_readable;
|
||||||
|
vfd_uart.readable.nbytes = sizeof(vfd_readable);
|
||||||
|
|
||||||
|
if (vfd_redirect) // 将 vfd 串口数据重写到另一个 com,用于调试
|
||||||
|
{
|
||||||
|
dprintf("VFD: redirect enable, target COM%d.\n", vfd_redirect);
|
||||||
|
sprintf(com_name, "\\\\.\\COM%d", vfd_redirect);
|
||||||
|
com_device = CreateFile(com_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (com_device != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
dprintf("VFD: CreateFile OK.\n");
|
||||||
|
DCB dcbSerialParams = {0};
|
||||||
|
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
||||||
|
GetCommState(com_device, &dcbSerialParams);
|
||||||
|
dcbSerialParams.BaudRate = 115200;
|
||||||
|
dcbSerialParams.ByteSize = 8;
|
||||||
|
dcbSerialParams.StopBits = ONESTOPBIT;
|
||||||
|
dcbSerialParams.Parity = NOPARITY;
|
||||||
|
SetCommState(com_device, &dcbSerialParams);
|
||||||
|
|
||||||
|
// COMMTIMEOUTS timeouts = {0};
|
||||||
|
// timeouts.ReadIntervalTimeout = 1;
|
||||||
|
// timeouts.ReadTotalTimeoutConstant = 1;
|
||||||
|
// timeouts.ReadTotalTimeoutMultiplier = 1;
|
||||||
|
// timeouts.WriteTotalTimeoutConstant = 1;
|
||||||
|
// timeouts.WriteTotalTimeoutMultiplier = 1;
|
||||||
|
// SetCommTimeouts(com_device, &timeouts);
|
||||||
|
|
||||||
|
EscapeCommFunction(com_device, SETDTR);
|
||||||
|
EscapeCommFunction(com_device, SETRTS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("VFD: CreateFile error.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
codepage = GetACP(); // 获取当前系统的 Code page,用于后续转码显示
|
||||||
|
dprintf("VFD: hook enabled.\n");
|
||||||
|
return iohook_push_handler(vfd_handle_irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT vfd_handle_irp(struct irp *irp)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(irp != NULL);
|
||||||
|
|
||||||
|
if (!uart_match_irp(&vfd_uart, irp))
|
||||||
|
{
|
||||||
|
return iohook_invoke_next(irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = uart_handle_irp(&vfd_uart, irp);
|
||||||
|
|
||||||
|
if (FAILED(hr) || irp->op != IRP_OP_WRITE)
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vfd_redirect && com_device != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD bytesWritten;
|
||||||
|
if (WriteFile(com_device, vfd_uart.written.bytes, vfd_uart.written.pos, &bytesWritten, NULL))
|
||||||
|
{
|
||||||
|
dprintf("VFD: WriteFile %lu.\n", bytesWritten);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t cmd = 0;
|
||||||
|
uint8_t str_1[512]; // 两行数据的缓冲区
|
||||||
|
uint8_t str_2[512];
|
||||||
|
uint8_t str_1_len = 0;
|
||||||
|
uint8_t str_2_len = 0;
|
||||||
|
for (size_t i = 0; i < vfd_uart.written.pos; i++)
|
||||||
|
{
|
||||||
|
if (vfd_uart.written.bytes[i] == 0x1B)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
cmd = vfd_uart.written.bytes[i];
|
||||||
|
if (cmd == 0x30)
|
||||||
|
{
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
else if (cmd == 0x50)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cmd == 0x30)
|
||||||
|
{
|
||||||
|
str_1[str_1_len++] = vfd_uart.written.bytes[i];
|
||||||
|
}
|
||||||
|
else if (cmd == 0x50)
|
||||||
|
{
|
||||||
|
str_2[str_2_len++] = vfd_uart.written.bytes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_1_len)
|
||||||
|
{
|
||||||
|
str_1[str_1_len++] = '\0';
|
||||||
|
if (codepage != 932)
|
||||||
|
{ // 如果非日文系统,则转码后输出 https://en.wikipedia.org/wiki/Code_page_932_(Microsoft_Windows)
|
||||||
|
WCHAR buffer[512];
|
||||||
|
MultiByteToWideChar(932, 0, (LPCSTR)str_1, str_1_len, buffer, str_1_len);
|
||||||
|
char str_recode[str_1_len * 3];
|
||||||
|
WideCharToMultiByte(codepage, 0, buffer, str_1_len, str_recode, str_1_len * 3, NULL, NULL);
|
||||||
|
dprintf("VFD: %s\n", str_recode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("VFD: %s\n", str_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_2_len)
|
||||||
|
{
|
||||||
|
str_2[str_2_len++] = '\0';
|
||||||
|
if (codepage != 932)
|
||||||
|
{
|
||||||
|
WCHAR buffer[512];
|
||||||
|
MultiByteToWideChar(932, 0, (LPCSTR)str_2, str_2_len, buffer, str_2_len);
|
||||||
|
char str_recode[str_2_len * 3];
|
||||||
|
WideCharToMultiByte(codepage, 0, buffer, str_2_len, str_recode, str_2_len * 3, NULL, NULL);
|
||||||
|
dprintf("VFD: %s\n", str_recode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("VFD: %s\n", str_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vfd_uart.written.pos = 0;
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
256
tools/vfd_test/vfd_test.ino
Normal file
256
tools/vfd_test/vfd_test.ino
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
// 本程序已于 2023/07/09 停止开发
|
||||||
|
// 展示信息的小屏幕,波特率 115200,只会出现在支持 電子決済 的框体,设备仅接收数据,不需要回复
|
||||||
|
// 在启用 emoney 时,显示支持的卡片种类和付款情况
|
||||||
|
// com 序号在 config_common.json > emoney > display_port 定义
|
||||||
|
// https://github.com/djhackersdev/segatools/blob/master/board/vfd.c
|
||||||
|
// vfd 串口数据没有固定格式,没有长度位
|
||||||
|
// 测试程序显示文字用的是 u8g2 库,默认用的是 utf8 编码,无法直接使用 vfd 串口的 shift-jis 编码数据
|
||||||
|
|
||||||
|
// 字库相关的信息:
|
||||||
|
// https://github.com/olikraus/u8g2/discussions/1508
|
||||||
|
// https://github.com/larryli/u8g2_wqy
|
||||||
|
// https://github.com/breakstring/u8g2_fontmaker
|
||||||
|
// https://github.com/createskyblue/Easy-u8g2-font-generate-tools/blob/master/main.py
|
||||||
|
|
||||||
|
#define SerialDevice Serial
|
||||||
|
|
||||||
|
#include <U8g2lib.h>
|
||||||
|
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
|
||||||
|
|
||||||
|
static uint8_t state = 0;
|
||||||
|
static char textBuffer[];
|
||||||
|
static uint8_t text_len = 0;
|
||||||
|
// https://r12a.github.io/app-encodings/
|
||||||
|
// https://www.mgo-tec.com/blog-entry-utf8-sjis-wroom-arduino-lib.html
|
||||||
|
// https://github.com/mgo-tec/UTF8SJIS_for_ESP8266/blob/master/src/UTF8toSJIS.cpp
|
||||||
|
// https://github.com/mgo-tec/ESP32_SD_UTF8toSJIS
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
SerialDevice.begin(115200);
|
||||||
|
SerialDevice.setTimeout(0);
|
||||||
|
Wire.setClock(800000);
|
||||||
|
u8g2.begin();
|
||||||
|
u8g2.setFont(u8g2_font_6x12_mf);
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
while (SerialDevice.available()) {
|
||||||
|
uint8_t r = SerialDevice.read();
|
||||||
|
if (r == 0x1B) {
|
||||||
|
r = SerialDevice.read();
|
||||||
|
state = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!state) {
|
||||||
|
state = r;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (state) {
|
||||||
|
case 0x0B: // 仅开机出现过
|
||||||
|
// 1b 0b
|
||||||
|
break;
|
||||||
|
case 0x0C:
|
||||||
|
// 1b 0c
|
||||||
|
text_len = 0;
|
||||||
|
break;
|
||||||
|
case 0x21: // 仅开机出现过,在 0b 后面
|
||||||
|
// 1b 21 01
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
textBuffer[text_len++] = r;
|
||||||
|
continue;
|
||||||
|
// 1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b7 // 電子決済できます
|
||||||
|
// 1b 30 00 00 00 93 64 8e 71 8c 88 8d cf 82 c5 82 ab 82 dc 82 b9 82 f1 // 電子決済できません
|
||||||
|
// 1b 30 00 00 02 6e 61 6e 61 63 6f 8e 78 95 a5 20 5c 35 30 30 // anaco支払 \500
|
||||||
|
case 0x32: // 仅开机出现过,在 21 后面
|
||||||
|
// 1b 32 02
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
// 1b 40 00 00 (00|02) 00 9f 02
|
||||||
|
uint8_t prm1 = SerialDevice.read();
|
||||||
|
uint8_t prm2 = SerialDevice.read();
|
||||||
|
uint8_t Line = SerialDevice.read();
|
||||||
|
uint8_t BoxSize_x = SerialDevice.read();
|
||||||
|
uint8_t BoxSize_y = SerialDevice.read();
|
||||||
|
// 缺少一位
|
||||||
|
break;
|
||||||
|
case 0x41: // 在 40 后面,speed 只发现是 00,用途未知
|
||||||
|
// 1b 41 00
|
||||||
|
uint8_t speed = SerialDevice.read();
|
||||||
|
break;
|
||||||
|
case 0x50: // 长度后面是字符内容
|
||||||
|
uint8_t len = SerialDevice.read();
|
||||||
|
textBuffer[text_len++] = r;
|
||||||
|
continue;
|
||||||
|
case 0x51: // 仅在有输出时,作为最后一条指令发送
|
||||||
|
// 1b 51
|
||||||
|
break;
|
||||||
|
case 0x52: // 跟在 0c 后面
|
||||||
|
// 1b 52
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// oled 显示测试
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <U8g2lib.h>
|
||||||
|
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);
|
||||||
|
// https://github.com/olikraus/u8g2/wiki/fntlistallplain
|
||||||
|
// https://github.com/olikraus/u8g2/wiki/u8g2reference
|
||||||
|
|
||||||
|
char text1[] = {
|
||||||
|
0xe9, 0x9b, 0xbb,
|
||||||
|
0xe5, 0xad, 0x90,
|
||||||
|
0xe6, 0xb1, 0xba,
|
||||||
|
0xe6, 0xb8, 0x88,
|
||||||
|
0xe3, 0x81, 0xa7,
|
||||||
|
0xe3, 0x81, 0x8d,
|
||||||
|
0xe3, 0x81, 0xbe,
|
||||||
|
0xe3, 0x81, 0x99,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
char text2[] = {
|
||||||
|
0x6e, 0x61, 0x6e, 0x61, 0x63, 0x6f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe4, 0xba, 0xa4, 0xe9, 0x80, 0x9a, 0xe7, 0xb3, 0xbb, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x41, 0x4f, 0x4e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x41, 0x53, 0x45, 0x4c, 0x49, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
u8g2_uint_t titleW, msgW, DisplayW; // 字符、屏幕宽度
|
||||||
|
u8g2_uint_t title_offset, msg_offset; // 字符的偏移位置
|
||||||
|
|
||||||
|
bool is_display = false;
|
||||||
|
uint8_t state, title_len, msg_len;
|
||||||
|
char title_buffer[256];
|
||||||
|
char msg_buffer[256];
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
SerialDevice.begin(115200);
|
||||||
|
SerialDevice.setTimeout(0);
|
||||||
|
Wire.setClock(800000);
|
||||||
|
u8g2.begin();
|
||||||
|
u8g2.setFont(u8g2_font_unifont_t_japanese3);
|
||||||
|
u8g2.enableUTF8Print();
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
|
||||||
|
DisplayW = u8g2.getDisplayWidth();
|
||||||
|
// Serial.println(titleW);
|
||||||
|
// Serial.println(msgW);
|
||||||
|
// Serial.println(DisplayW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void displayTask() {
|
||||||
|
if (!is_display) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
u8g2.clearBuffer();
|
||||||
|
if (titleW) {
|
||||||
|
// SerialDevice.println("titleW");
|
||||||
|
if (titleW < DisplayW) {
|
||||||
|
u8g2.drawUTF8(0, 14, title_buffer);
|
||||||
|
// u8g2.setCursor(0, 14);
|
||||||
|
// u8g2.print(text1);
|
||||||
|
} else {
|
||||||
|
u8g2_uint_t x = title_offset;
|
||||||
|
do {
|
||||||
|
u8g2.drawUTF8(x, 14, title_buffer);
|
||||||
|
x += titleW;
|
||||||
|
} while (x < DisplayW);
|
||||||
|
title_offset -= 1;
|
||||||
|
if ((u8g2_uint_t)title_offset < (u8g2_uint_t)-titleW) {
|
||||||
|
title_offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgW) {
|
||||||
|
// SerialDevice.println("msgW");
|
||||||
|
if (msgW < DisplayW) {
|
||||||
|
u8g2.drawUTF8(0, 30, msg_buffer);
|
||||||
|
} else {
|
||||||
|
u8g2_uint_t x = msg_offset;
|
||||||
|
do {
|
||||||
|
u8g2.drawUTF8(x, 30, msg_buffer);
|
||||||
|
x += msgW;
|
||||||
|
} while (x < DisplayW);
|
||||||
|
msg_offset -= 1;
|
||||||
|
if ((u8g2_uint_t)msg_offset < (u8g2_uint_t)-msgW) {
|
||||||
|
msg_offset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u8g2.sendBuffer();
|
||||||
|
// delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
msg_len = 0;
|
||||||
|
// memset(title_buffer, 0, 256);
|
||||||
|
// memset(msg_buffer, 0, 256);
|
||||||
|
// bool pre_display = false;
|
||||||
|
while (SerialDevice.available()) {
|
||||||
|
msg_buffer[msg_len++] = SerialDevice.read();
|
||||||
|
// uint8_t r = SerialDevice.read();
|
||||||
|
// if (r == 0x1B) {
|
||||||
|
// state = 0;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (!state) {
|
||||||
|
// state = SerialDevice.read();
|
||||||
|
// }
|
||||||
|
// switch (state) {
|
||||||
|
// case 0x0C:
|
||||||
|
// title_len = 0;
|
||||||
|
// msg_len = 0;
|
||||||
|
// titleW = 0;
|
||||||
|
// msgW = 0;
|
||||||
|
// is_display = false;
|
||||||
|
// // memset(title_buffer, 0, 256);
|
||||||
|
// // memset(msg_buffer, 0, 256);
|
||||||
|
// u8g2.clearBuffer();
|
||||||
|
// u8g2.sendBuffer();
|
||||||
|
// SerialDevice.println("clear");
|
||||||
|
// break;
|
||||||
|
// case 0x30:
|
||||||
|
// title_buffer[title_len++] = r;
|
||||||
|
// pre_display = true;
|
||||||
|
// continue;
|
||||||
|
// case 0x50:
|
||||||
|
// msg_buffer[msg_len++] = r;
|
||||||
|
// pre_display = true;
|
||||||
|
// continue;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// if (pre_display) {
|
||||||
|
// if (title_len) {
|
||||||
|
// title_buffer[title_len++] = 0;
|
||||||
|
// titleW = u8g2.getUTF8Width(title_buffer);
|
||||||
|
// title_offset = 0;
|
||||||
|
// is_display = true;
|
||||||
|
// SerialDevice.println("pre_display title_len");
|
||||||
|
// }
|
||||||
|
if (msg_len) {
|
||||||
|
msg_buffer[msg_len++] = 0;
|
||||||
|
msgW = u8g2.getUTF8Width(msg_buffer);
|
||||||
|
SerialDevice.println(msgW);
|
||||||
|
msg_offset = 0;
|
||||||
|
is_display = true;
|
||||||
|
SerialDevice.println("pre_display msg_len");
|
||||||
|
}
|
||||||
|
// pre_display = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
displayTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user