mirror of
https://github.com/pengwon/epd42.git
synced 2025-12-05 15:42:49 +08:00
update html
This commit is contained in:
160
EPD/EPD_Test.c
160
EPD/EPD_Test.c
@@ -1,160 +0,0 @@
|
||||
#include "EPD_Test.h"
|
||||
#include "EPD_4in2.h"
|
||||
|
||||
const unsigned char EPD_4IN2_4Gray_lut_vcom[] =
|
||||
{
|
||||
0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
|
||||
};
|
||||
|
||||
const unsigned char EPD_4IN2_4Gray_lut_ww[] ={
|
||||
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
|
||||
0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
|
||||
0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
};
|
||||
|
||||
const unsigned char EPD_4IN2_4Gray_lut_bw[] ={
|
||||
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
|
||||
0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
};
|
||||
|
||||
const unsigned char EPD_4IN2_4Gray_lut_wb[] ={
|
||||
0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
|
||||
0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
};
|
||||
|
||||
const unsigned char EPD_4IN2_4Gray_lut_bb[] ={
|
||||
0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
|
||||
0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
|
||||
0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
|
||||
0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
|
||||
};
|
||||
|
||||
static void EPD_4IN2_4Gray_lut(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
EPD_4IN2_SendCommand(0x20); //vcom
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_vcom[count]);}
|
||||
|
||||
EPD_4IN2_SendCommand(0x21); //red not use
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
|
||||
|
||||
EPD_4IN2_SendCommand(0x22); //bw r
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bw[count]);}
|
||||
|
||||
EPD_4IN2_SendCommand(0x23); //wb w
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_wb[count]);}
|
||||
|
||||
EPD_4IN2_SendCommand(0x24); //bb b
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bb[count]);}
|
||||
|
||||
EPD_4IN2_SendCommand(0x25); //vcom
|
||||
for(count=0;count<42;count++)
|
||||
{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
|
||||
}
|
||||
|
||||
static void drawNormal(void)
|
||||
{
|
||||
UWORD Width, Height;
|
||||
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
|
||||
Height = EPD_4IN2_HEIGHT;
|
||||
|
||||
EPD_4IN2_SendCommand(0x10);
|
||||
for (UWORD j = 0; j < Height; j++) {
|
||||
for (UWORD i = 0; i < Width; i++) {
|
||||
EPD_4IN2_SendData(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
EPD_4IN2_SendCommand(0x13);
|
||||
for (UWORD j = 0; j < Height; j++) {
|
||||
for (UWORD i = 0; i < Width; i++) {
|
||||
EPD_4IN2_SendData(((j + 1)*2 > Height) ? 0x00 : 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
EPD_4IN2_TurnOnDisplay();
|
||||
}
|
||||
|
||||
static void draw4Gray(void)
|
||||
{
|
||||
UWORD Width, Height;
|
||||
Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
|
||||
Height = EPD_4IN2_HEIGHT;
|
||||
|
||||
EPD_4IN2_SendCommand(0x10);
|
||||
for (UWORD i = 0; i < Width * Height; i++) {
|
||||
UWORD idx = (i % 50) / 12;
|
||||
if (idx > 3) idx = 3;
|
||||
if (idx == 0 || idx == 1) {
|
||||
EPD_4IN2_SendData(0x00);
|
||||
} else if (idx == 2 || idx == 3) {
|
||||
EPD_4IN2_SendData(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
EPD_4IN2_SendCommand(0x13);
|
||||
for (UWORD i = 0; i < Width * Height; i++) {
|
||||
UWORD idx = (i % 50) / 12;
|
||||
if (idx > 3) idx = 3;
|
||||
if (idx == 0 || idx == 2) {
|
||||
EPD_4IN2_SendData(0x00);
|
||||
} else if (idx == 1 || idx == 3) {
|
||||
EPD_4IN2_SendData(0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Load LUT from register
|
||||
EPD_4IN2_SendCommand(0x00);
|
||||
EPD_4IN2_SendData(0x3f);
|
||||
|
||||
EPD_4IN2_4Gray_lut();
|
||||
EPD_4IN2_TurnOnDisplay();
|
||||
|
||||
// Load LUT from OTP
|
||||
EPD_4IN2_SendCommand(0x00);
|
||||
EPD_4IN2_SendData(0x1f);
|
||||
}
|
||||
|
||||
void EPD_4in2_test(void)
|
||||
{
|
||||
DEV_Module_Init();
|
||||
|
||||
EPD_4IN2_Init();
|
||||
EPD_4IN2_Clear();
|
||||
DEV_Delay_ms(500);
|
||||
|
||||
drawNormal();
|
||||
DEV_Delay_ms(1000);
|
||||
|
||||
draw4Gray();
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 402 KiB After Width: | Height: | Size: 278 KiB |
@@ -18,6 +18,7 @@
|
||||
#canvas-box { margin-top: 10px; }
|
||||
|
||||
button { padding: 0.375rem 0.75rem; border: 1px solid #0d6efd; border-radius: 0.375rem; }
|
||||
button:disabled { opacity: 0.65; }
|
||||
button.primary { color: #fff; background-color: #0d6efd; }
|
||||
button.primary:hover { color: #fff; border-color: #0b5ed7; background-color: #0b5ed7; }
|
||||
button.secondary { color: #fff; background-color: #6c757d; }
|
||||
@@ -38,8 +39,8 @@
|
||||
<legend>蓝牙</legend>
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<div>
|
||||
<button id="connectbutton" type="button" class="primary" onclick="preConnect();">连接</button>
|
||||
<button id="reconnectbutton" type="button" class="secondary" onclick="reConnect();">重连</button>
|
||||
<button id="connectbutton" type="button" class="primary" onclick="preConnect()">连接</button>
|
||||
<button id="reconnectbutton" type="button" class="secondary" onclick="reConnect()">重连</button>
|
||||
</div>
|
||||
<div>
|
||||
<label for="epddriver">驱动</label>
|
||||
@@ -50,7 +51,7 @@
|
||||
</select>
|
||||
<label for="epdpins">引脚</label>
|
||||
<input id="epdpins" type="text" value="">
|
||||
<button id="setDriverbutton" type="button" class="primary" onclick="setDriver();">确认</button>
|
||||
<button id="setDriverbutton" type="button" class="primary" onclick="setDriver()">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -59,13 +60,13 @@
|
||||
<legend>传图</legend>
|
||||
<div style="margin-bottom: 10px; display: flex; justify-content: space-between;">
|
||||
<div>
|
||||
<button id="clearcanvasbutton" type="button" class="secondary" onclick="clear_canvas();">清除画布</button>
|
||||
<button id="sendimgbutton" type="button" class="primary" class="primary" onclick="sendimg();">发送图片</button>
|
||||
<button id="clearcanvasbutton" type="button" class="secondary" onclick="clear_canvas()">清除画布</button>
|
||||
<button id="sendimgbutton" type="button" class="primary" onclick="sendimg()">发送图片</button>
|
||||
</div>
|
||||
<div>
|
||||
<button id="clearscreenbutton" type="button" class="secondary" onclick="clearscreen();">清除屏幕</button>
|
||||
<button id="clearscreenbutton" type="button" class="secondary" onclick="clearscreen()">清除屏幕</button>
|
||||
<input type="text" id="cmdTXT" value="">
|
||||
<button id="sendcmdbutton" type="button" class="primary" onclick="sendcmd(document.getElementById("cmdTXT").value);">发送命令</button>
|
||||
<button id="sendcmdbutton" type="button" class="primary" onclick="sendcmd()">发送命令</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 85%; color: #666; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dotted #AAA;"><b>状态:</b><span id="status"></span></div>
|
||||
@@ -93,7 +94,7 @@
|
||||
<label for="threshold">阈值</label>
|
||||
<input type="number" max="255" min="0" value="125" id="threshold" onchange="update_image()">
|
||||
</div>
|
||||
<button type="button" class="secondary" onclick="document.getElementById('log').innerHTML = '';">清空日志</button>
|
||||
<button type="button" class="secondary" onclick="clearLog()">清空日志</button>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<canvas id="canvas" width="400" height="300" style="border: black solid 1px;"></canvas>
|
||||
|
||||
441
html/js/main.js
441
html/js/main.js
@@ -6,290 +6,319 @@ let reconnectTrys = 0;
|
||||
|
||||
let canvas;
|
||||
let startTime;
|
||||
let chunkSize = 38;
|
||||
|
||||
const MAX_PACKET_SIZE = 20;
|
||||
const EpdCmd = {
|
||||
SET_PINS: 0x00,
|
||||
INIT: 0x01,
|
||||
CLEAR: 0x02,
|
||||
SEND_CMD: 0x03,
|
||||
SEND_DATA: 0x04,
|
||||
DISPLAY: 0x05,
|
||||
SLEEP: 0x06,
|
||||
|
||||
SET_CONFIG: 0x90,
|
||||
SYS_RESET: 0x91,
|
||||
SYS_SLEEP: 0x92,
|
||||
CFG_ERASE: 0x99,
|
||||
};
|
||||
|
||||
function resetVariables() {
|
||||
gattServer = null;
|
||||
epdService = null;
|
||||
epdCharacteristic = null;
|
||||
document.getElementById("log").value = '';
|
||||
gattServer = null;
|
||||
epdService = null;
|
||||
epdCharacteristic = null;
|
||||
document.getElementById("log").value = '';
|
||||
}
|
||||
|
||||
async function handleError(error) {
|
||||
console.log(error);
|
||||
resetVariables();
|
||||
if (bleDevice == null)
|
||||
return;
|
||||
if (reconnectTrys <= 5) {
|
||||
reconnectTrys++;
|
||||
await connect();
|
||||
}
|
||||
else {
|
||||
addLog("连接失败!");
|
||||
reconnectTrys = 0;
|
||||
}
|
||||
console.log(error);
|
||||
resetVariables();
|
||||
if (bleDevice == null)
|
||||
return;
|
||||
if (reconnectTrys <= 5) {
|
||||
reconnectTrys++;
|
||||
await connect();
|
||||
}
|
||||
else {
|
||||
addLog("连接失败!");
|
||||
reconnectTrys = 0;
|
||||
}
|
||||
}
|
||||
|
||||
async function sendCommand(cmd) {
|
||||
if (epdCharacteristic) {
|
||||
await epdCharacteristic.writeValue(cmd);
|
||||
} else {
|
||||
addLog("服务不可用,请检查蓝牙连接");
|
||||
}
|
||||
async function write(cmd, data) {
|
||||
if (!epdCharacteristic) {
|
||||
addLog("服务不可用,请检查蓝牙连接");
|
||||
return;
|
||||
}
|
||||
let payload = [cmd];
|
||||
if (data) {
|
||||
if (typeof data == 'string') data = hex2bytes(data);
|
||||
if (data instanceof Uint8Array) data = Array.from(data);
|
||||
payload.push(...data)
|
||||
};
|
||||
if (payload.length > MAX_PACKET_SIZE) {
|
||||
throw new Error("BLE packet too large!");
|
||||
}
|
||||
addLog(`<span class="action">⇑</span> ${bytes2hex(payload)}`);
|
||||
await epdCharacteristic.writeValue(Uint8Array.from(payload));
|
||||
}
|
||||
|
||||
async function sendcmd(cmdTXT) {
|
||||
addLog(`<span class="action">⇑</span> ${cmdTXT}`);
|
||||
await sendCommand(hexToBytes(cmdTXT));
|
||||
async function epdWrite(cmd, data) {
|
||||
const chunkSize = MAX_PACKET_SIZE - 1;
|
||||
const count = Math.round(data.length / chunkSize);
|
||||
let chunkIdx = 0;
|
||||
|
||||
if (typeof data == 'string') data = hex2bytes(data);
|
||||
|
||||
await write(EpdCmd.SEND_CMD, [cmd]);
|
||||
for (let i = 0; i < data.length; i += chunkSize) {
|
||||
let currentTime = (new Date().getTime() - startTime) / 1000.0;
|
||||
setStatus(`命令:0x${cmd.toString(16)}, 数据块: ${chunkIdx+1}/${count+1}, 总用时: ${currentTime}s`);
|
||||
await write(EpdCmd.SEND_DATA, data.slice(i, i + chunkSize));
|
||||
chunkIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
async function setDriver() {
|
||||
const driver = document.getElementById("epddriver").value;
|
||||
const pins = document.getElementById("epdpins").value;
|
||||
await sendcmd(`00${pins}`);
|
||||
await sendcmd(`01${driver}`);
|
||||
await write(EpdCmd.SET_PINS, document.getElementById("epdpins").value);
|
||||
await write(EpdCmd.INIT, document.getElementById("epddriver").value);
|
||||
}
|
||||
|
||||
async function clearscreen() {
|
||||
if(confirm('确认清除屏幕内容?')) {
|
||||
await sendcmd("02");
|
||||
}
|
||||
if(confirm('确认清除屏幕内容?')) {
|
||||
await write(EpdCmd.CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendCmWithData(cmd, data){
|
||||
const count = Math.round(data.length / chunkSize);
|
||||
let chunkIdx = 0;
|
||||
|
||||
await sendcmd(`03${cmd}`);
|
||||
for (let i = 0; i < data.length; i += chunkSize) {
|
||||
let currentTime = (new Date().getTime() - startTime) / 1000.0;
|
||||
let chunk = data.substring(i, i + chunkSize);
|
||||
setStatus(`命令:0x${cmd}, 数据块: ${chunkIdx+1}/${count+1}, 总用时: ${currentTime}s`);
|
||||
await sendcmd(`04${chunk}`);
|
||||
chunkIdx++;
|
||||
}
|
||||
async function sendcmd() {
|
||||
const cmdTXT = document.getElementById('cmdTXT').value;
|
||||
if (cmdTXT == '') return;
|
||||
const bytes = hex2bytes(cmdTXT);
|
||||
await write(bytes[0], bytes.length > 1 ? bytes.slice(1) : null);
|
||||
}
|
||||
|
||||
async function send4GrayLut() {
|
||||
await sendCmWithData("20", "000A0000000160141400000100140000000100130A010001000000000000000000000000000000000000"); // vcom
|
||||
await sendCmWithData("21", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // red not use
|
||||
await sendCmWithData("22", "400A0000000190141400000100140A000001990C01030401000000000000000000000000000000000000"); // bw r
|
||||
await sendCmWithData("23", "400A0000000190141400000100140A000001990B04040101000000000000000000000000000000000000"); // wb w
|
||||
await sendCmWithData("24", "800A0000000190141400000120140A000001501301000001000000000000000000000000000000000000"); // bb b
|
||||
await sendCmWithData("25", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // vcom
|
||||
await epdWrite(0x20, "000A0000000160141400000100140000000100130A010001000000000000000000000000000000000000"); // vcom
|
||||
await epdWrite(0x21, "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // red not use
|
||||
await epdWrite(0x22, "400A0000000190141400000100140A000001990C01030401000000000000000000000000000000000000"); // bw r
|
||||
await epdWrite(0x23, "400A0000000190141400000100140A000001990B04040101000000000000000000000000000000000000"); // wb w
|
||||
await epdWrite(0x24, "800A0000000190141400000120140A000001501301000001000000000000000000000000000000000000"); // bb b
|
||||
await epdWrite(0x25, "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // vcom
|
||||
}
|
||||
|
||||
function getImageData(canvas, driver, mode) {
|
||||
if (mode === '4gray') {
|
||||
return bytesToHex(canvas2gray(canvas));
|
||||
} else {
|
||||
let data = bytesToHex(canvas2bytes(canvas, 'bw'));
|
||||
if (driver === '03') {
|
||||
if (mode.startsWith('bwr')) {
|
||||
data += bytesToHex(canvas2bytes(canvas, 'red'));
|
||||
} else {
|
||||
const count = data.length;
|
||||
data += 'F'.repeat(count);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
if (mode === '4gray') {
|
||||
return canvas2gray(canvas);
|
||||
} else {
|
||||
let data = canvas2bytes(canvas, 'bw');
|
||||
if (driver === '03') {
|
||||
if (mode.startsWith('bwr')) {
|
||||
data.push(...canvas2bytes(canvas, 'red'));
|
||||
} else {
|
||||
const data1= 'F'.repeat(data.length);
|
||||
data.push(...data1);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
async function sendimg() {
|
||||
startTime = new Date().getTime();
|
||||
const canvas = document.getElementById("canvas");
|
||||
const driver = document.getElementById("epddriver").value;
|
||||
const mode = document.getElementById('dithering').value;
|
||||
const imgArray = getImageData(canvas, driver, mode);
|
||||
const bwArrLen = (canvas.width/8) * canvas.height * 2;
|
||||
startTime = new Date().getTime();
|
||||
const canvas = document.getElementById("canvas");
|
||||
const driver = document.getElementById("epddriver").value;
|
||||
const mode = document.getElementById('dithering').value;
|
||||
const imgArray = getImageData(canvas, driver, mode);
|
||||
const bwArrLen = canvas.width * canvas.height / 8;
|
||||
|
||||
if (imgArray.length == bwArrLen * 2) {
|
||||
await sendCmWithData("10", imgArray.slice(0, bwArrLen - 1));
|
||||
await sendCmWithData("13", imgArray.slice(bwArrLen));
|
||||
} else {
|
||||
await sendCmWithData(driver === "03" ? "10" : "13", imgArray);
|
||||
}
|
||||
if (imgArray.length == bwArrLen * 2) {
|
||||
await epdWrite(0x10, imgArray.slice(0, bwArrLen));
|
||||
await epdWrite(0x13, imgArray.slice(bwArrLen));
|
||||
} else {
|
||||
await epdWrite(driver === "03" ? 0x10 : 0x13, imgArray);
|
||||
}
|
||||
|
||||
if (mode === "4gray") {
|
||||
await sendcmd("0300");
|
||||
await sendcmd("043F"); // Load LUT from register
|
||||
await send4GrayLut();
|
||||
await sendcmd("05");
|
||||
await sendcmd("0300");
|
||||
await sendcmd("041F"); // Load LUT from OTP
|
||||
} else {
|
||||
await sendcmd("05");
|
||||
}
|
||||
if (mode === "4gray") {
|
||||
await epdWrite(0x00, [0x3F]); // Load LUT from register
|
||||
await send4GrayLut();
|
||||
await write(EpdCmd.DISPLAY);
|
||||
await epdWrite(0x00, [0x1F]); // Load LUT from OTP
|
||||
} else {
|
||||
await write(EpdCmd.DISPLAY);
|
||||
}
|
||||
|
||||
const sendTime = (new Date().getTime() - startTime) / 1000.0;
|
||||
addLog(`发送完成!耗时: ${sendTime}s`);
|
||||
setStatus(`发送完成!耗时: ${sendTime}s`);
|
||||
const sendTime = (new Date().getTime() - startTime) / 1000.0;
|
||||
addLog(`发送完成!耗时: ${sendTime}s`);
|
||||
setStatus(`发送完成!耗时: ${sendTime}s`);
|
||||
}
|
||||
|
||||
function updateButtonStatus() {
|
||||
const connected = gattServer != null && gattServer.connected;
|
||||
const status = connected ? null : 'disabled';
|
||||
document.getElementById("reconnectbutton").disabled = (gattServer == null || gattServer.connected) ? 'disabled' : null;
|
||||
document.getElementById("sendcmdbutton").disabled = status;
|
||||
document.getElementById("clearscreenbutton").disabled = status;
|
||||
document.getElementById("sendimgbutton").disabled = status;
|
||||
document.getElementById("setDriverbutton").disabled = status;
|
||||
const connected = gattServer != null && gattServer.connected;
|
||||
const status = connected ? null : 'disabled';
|
||||
document.getElementById("reconnectbutton").disabled = (gattServer == null || gattServer.connected) ? 'disabled' : null;
|
||||
document.getElementById("sendcmdbutton").disabled = status;
|
||||
document.getElementById("clearscreenbutton").disabled = status;
|
||||
document.getElementById("sendimgbutton").disabled = status;
|
||||
document.getElementById("setDriverbutton").disabled = status;
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
updateButtonStatus();
|
||||
resetVariables();
|
||||
addLog('已断开连接.');
|
||||
document.getElementById("connectbutton").innerHTML = '连接';
|
||||
updateButtonStatus();
|
||||
resetVariables();
|
||||
addLog('已断开连接.');
|
||||
document.getElementById("connectbutton").innerHTML = '连接';
|
||||
}
|
||||
|
||||
async function preConnect() {
|
||||
if (gattServer != null && gattServer.connected) {
|
||||
if (bleDevice != null && bleDevice.gatt.connected) {
|
||||
await sendcmd("06");
|
||||
bleDevice.gatt.disconnect();
|
||||
}
|
||||
}
|
||||
else {
|
||||
connectTrys = 0;
|
||||
try {
|
||||
bleDevice = await navigator.bluetooth.requestDevice({
|
||||
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
|
||||
acceptAllDevices: true
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.message) addLog(e.message);
|
||||
return;
|
||||
}
|
||||
if (gattServer != null && gattServer.connected) {
|
||||
if (bleDevice != null && bleDevice.gatt.connected) {
|
||||
await write(EpdCmd.SLEEP);
|
||||
bleDevice.gatt.disconnect();
|
||||
}
|
||||
}
|
||||
else {
|
||||
connectTrys = 0;
|
||||
try {
|
||||
bleDevice = await navigator.bluetooth.requestDevice({
|
||||
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
|
||||
acceptAllDevices: true
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.message) addLog(e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
await bleDevice.addEventListener('gattserverdisconnected', disconnect);
|
||||
try {
|
||||
await connect();
|
||||
} catch (e) {
|
||||
await handleError(e);
|
||||
}
|
||||
}
|
||||
await bleDevice.addEventListener('gattserverdisconnected', disconnect);
|
||||
try {
|
||||
await connect();
|
||||
} catch (e) {
|
||||
await handleError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function reConnect() {
|
||||
connectTrys = 0;
|
||||
if (bleDevice != null && bleDevice.gatt.connected)
|
||||
bleDevice.gatt.disconnect();
|
||||
resetVariables();
|
||||
addLog("正在重连");
|
||||
setTimeout(async function () { await connect(); }, 300);
|
||||
connectTrys = 0;
|
||||
if (bleDevice != null && bleDevice.gatt.connected)
|
||||
bleDevice.gatt.disconnect();
|
||||
resetVariables();
|
||||
addLog("正在重连");
|
||||
setTimeout(async function () { await connect(); }, 300);
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
if (epdCharacteristic == null && bleDevice != null) {
|
||||
addLog("正在连接: " + bleDevice.name);
|
||||
if (epdCharacteristic == null && bleDevice != null) {
|
||||
addLog("正在连接: " + bleDevice.name);
|
||||
|
||||
gattServer = await bleDevice.gatt.connect();
|
||||
addLog(' 找到 GATT Server');
|
||||
gattServer = await bleDevice.gatt.connect();
|
||||
addLog(' 找到 GATT Server');
|
||||
|
||||
epdService = await gattServer.getPrimaryService('62750001-d828-918d-fb46-b6c11c675aec');
|
||||
addLog(' 找到 EPD Service');
|
||||
epdService = await gattServer.getPrimaryService('62750001-d828-918d-fb46-b6c11c675aec');
|
||||
addLog(' 找到 EPD Service');
|
||||
|
||||
epdCharacteristic = await epdService.getCharacteristic('62750002-d828-918d-fb46-b6c11c675aec');
|
||||
addLog(' 找到 Characteristic');
|
||||
epdCharacteristic = await epdService.getCharacteristic('62750002-d828-918d-fb46-b6c11c675aec');
|
||||
addLog(' 找到 Characteristic');
|
||||
|
||||
await epdCharacteristic.startNotifications();
|
||||
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
|
||||
addLog(`<span class="action">⇓</span> ${bytesToHex(event.target.value.buffer)}`);
|
||||
document.getElementById("epdpins").value = bytesToHex(event.target.value.buffer.slice(0, 7));
|
||||
document.getElementById("epddriver").value = bytesToHex(event.target.value.buffer.slice(7, 8));
|
||||
});
|
||||
await epdCharacteristic.startNotifications();
|
||||
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
|
||||
addLog(`<span class="action">⇓</span> ${bytes2hex(event.target.value.buffer)}`);
|
||||
document.getElementById("epdpins").value = bytes2hex(event.target.value.buffer.slice(0, 7));
|
||||
document.getElementById("epddriver").value = bytes2hex(event.target.value.buffer.slice(7, 8));
|
||||
});
|
||||
|
||||
await sendcmd("01");
|
||||
await write(EpdCmd.INIT);
|
||||
|
||||
document.getElementById("connectbutton").innerHTML = '断开';
|
||||
updateButtonStatus();
|
||||
}
|
||||
document.getElementById("connectbutton").innerHTML = '断开';
|
||||
updateButtonStatus();
|
||||
}
|
||||
}
|
||||
|
||||
function setStatus(statusText) {
|
||||
document.getElementById("status").innerHTML = statusText;
|
||||
document.getElementById("status").innerHTML = statusText;
|
||||
}
|
||||
|
||||
function addLog(logTXT) {
|
||||
const log = document.getElementById("log");
|
||||
const now = new Date();
|
||||
const time = String(now.getHours()).padStart(2, '0') + ":" +
|
||||
String(now.getMinutes()).padStart(2, '0') + ":" +
|
||||
String(now.getSeconds()).padStart(2, '0') + " ";
|
||||
log.innerHTML += '<span class="time">' + time + '</span>' + logTXT + '<br>';
|
||||
log.scrollTop = log.scrollHeight;
|
||||
while ((log.innerHTML.match(/<br>/g) || []).length > 20) {
|
||||
var logs_br_position = log.innerHTML.search("<br>");
|
||||
log.innerHTML = log.innerHTML.substring(logs_br_position + 4);
|
||||
log.scrollTop = log.scrollHeight;
|
||||
}
|
||||
const log = document.getElementById("log");
|
||||
const now = new Date();
|
||||
const time = String(now.getHours()).padStart(2, '0') + ":" +
|
||||
String(now.getMinutes()).padStart(2, '0') + ":" +
|
||||
String(now.getSeconds()).padStart(2, '0') + " ";
|
||||
log.innerHTML += '<span class="time">' + time + '</span>' + logTXT + '<br>';
|
||||
log.scrollTop = log.scrollHeight;
|
||||
while ((log.innerHTML.match(/<br>/g) || []).length > 20) {
|
||||
var logs_br_position = log.innerHTML.search("<br>");
|
||||
log.innerHTML = log.innerHTML.substring(logs_br_position + 4);
|
||||
log.scrollTop = log.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function hexToBytes(hex) {
|
||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||
return new Uint8Array(bytes);
|
||||
function clearLog() {
|
||||
document.getElementById("log").innerHTML = '';
|
||||
}
|
||||
|
||||
function bytesToHex(data) {
|
||||
return new Uint8Array(data).reduce(
|
||||
function (memo, i) {
|
||||
return memo + ("0" + i.toString(16)).slice(-2);
|
||||
}, "");
|
||||
function hex2bytes(hex) {
|
||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||
return new Uint8Array(bytes);
|
||||
}
|
||||
|
||||
function bytes2hex(data) {
|
||||
return new Uint8Array(data).reduce(
|
||||
function (memo, i) {
|
||||
return memo + ("0" + i.toString(16)).slice(-2);
|
||||
}, "");
|
||||
}
|
||||
|
||||
function intToHex(intIn) {
|
||||
let stringOut = ("0000" + intIn.toString(16)).substr(-4)
|
||||
return stringOut.substring(2, 4) + stringOut.substring(0, 2);
|
||||
let stringOut = ("0000" + intIn.toString(16)).substr(-4)
|
||||
return stringOut.substring(2, 4) + stringOut.substring(0, 2);
|
||||
}
|
||||
|
||||
async function update_image () {
|
||||
const canvas = document.getElementById("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const canvas = document.getElementById("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
let image = new Image();;
|
||||
const image_file = document.getElementById('image_file');
|
||||
if (image_file.files.length > 0) {
|
||||
const file = image_file.files[0];
|
||||
image.src = URL.createObjectURL(file);
|
||||
} else {
|
||||
image.src = document.getElementById('demo-img').src;
|
||||
}
|
||||
let image = new Image();;
|
||||
const image_file = document.getElementById('image_file');
|
||||
if (image_file.files.length > 0) {
|
||||
const file = image_file.files[0];
|
||||
image.src = URL.createObjectURL(file);
|
||||
} else {
|
||||
image.src = document.getElementById('demo-img').src;
|
||||
}
|
||||
|
||||
image.onload = function(event) {
|
||||
URL.revokeObjectURL(this.src);
|
||||
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
|
||||
convert_dithering()
|
||||
}
|
||||
image.onload = function(event) {
|
||||
URL.revokeObjectURL(this.src);
|
||||
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
|
||||
convert_dithering()
|
||||
}
|
||||
}
|
||||
|
||||
function clear_canvas() {
|
||||
if(confirm('确认清除画布内容?')) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
if(confirm('确认清除画布内容?')) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
}
|
||||
|
||||
function convert_dithering() {
|
||||
const ctx = canvas.getContext("2d");
|
||||
const mode = document.getElementById('dithering').value;
|
||||
if (mode.startsWith('bwr')) {
|
||||
ditheringCanvasByPalette(canvas, bwrPalette, mode);
|
||||
} else if (mode === '4gray') {
|
||||
dithering(ctx, canvas.width, canvas.height, 4, "gray");
|
||||
} else {
|
||||
dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode);
|
||||
}
|
||||
const ctx = canvas.getContext("2d");
|
||||
const mode = document.getElementById('dithering').value;
|
||||
if (mode.startsWith('bwr')) {
|
||||
ditheringCanvasByPalette(canvas, bwrPalette, mode);
|
||||
} else if (mode === '4gray') {
|
||||
dithering(ctx, canvas.width, canvas.height, 4, "gray");
|
||||
} else {
|
||||
dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.onload = () => {
|
||||
canvas = document.getElementById('canvas');
|
||||
canvas = document.getElementById('canvas');
|
||||
|
||||
updateButtonStatus();
|
||||
update_image();
|
||||
updateButtonStatus();
|
||||
update_image();
|
||||
|
||||
document.getElementById('dithering').value = 'none';
|
||||
document.getElementById('dithering').value = 'none';
|
||||
}
|
||||
Reference in New Issue
Block a user