Skip to content

Commit

Permalink
update html
Browse files Browse the repository at this point in the history
  • Loading branch information
tsl0922 committed Dec 12, 2024
1 parent d3b28d0 commit c2c2308
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 99 deletions.
20 changes: 8 additions & 12 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<title>4.2 寸电子墨水屏蓝牙控制器</title>
<style type="text/css">
.main { width: 800px; margin: 0 auto;}
.main { width: 950px; margin: 0 auto;}
h3 { padding-bottom: .3em; border-bottom: 1px solid #CCC; }
fieldset { border: 2px dotted #AAA; padding: 10px; margin-bottom: 10px; }
fieldset legend { font-weight: bold; }
Expand All @@ -12,8 +12,9 @@
#toolbar { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dotted #AAA;}
#status { margin: 10px 0; }
#filebox { margin-bottom: 10px; }
#cmdIMAGE { width: 350px; height: 300px; float: right}
#log { width: 100%; min-height: 200px; margin-top: 10px; background: #DDD; }
#log { width: 500px; height: 300px; margin: 0;background: #DDD; float: right; overflow: auto; }
#log .time { color: #333; }
#log .action {color: #666; }
#canvas-box { margin-top: 10px; }
</style>
</head>
Expand All @@ -35,7 +36,7 @@ <h3>4.2 寸电子墨水屏蓝牙控制器(nRF51)</h3>
<button id="setDriverbutton" type="button" onclick="setDriver();">确认</button>
</div>
<button id="connectbutton" type="button" onclick="preConnect();">连接</button>
<button type="button" onclick="reConnect();">重连</button>
<button id="reconnectbutton" type="button" onclick="reConnect();">重连</button>
</fieldset>

<fieldset>
Expand All @@ -48,12 +49,13 @@ <h3>4.2 寸电子墨水屏蓝牙控制器(nRF51)</h3>
</div>
<div style="margin-bottom: 10px;">
<button id="clearscreenbutton" type="button" onclick="clear_canvas();">清除画布</button>
<button id="sendimgbutton" type="button" onclick="sendimg(document.getElementById(&quot;cmdIMAGE&quot;).value);">发送图片</button>
<button id="sendimgbutton" type="button" onclick="sendimg();">发送图片</button>
</div>
<div style="font-size: 85%; color: #666;"><b>状态:</b><span id="status"></span></div>
</div>
<div id="sendimg">
<div id="filebox">
<button type="button" onclick="document.getElementById('log').innerHTML = '';" style="float: right;">清空日志</button>
<input type="file" id="image_file" onchange="update_image()" accept=".png,.jpg,.bmp,.webp,.jpeg">
取模算法:
<select id="dithering" title="取模算法" onchange="update_image()">
Expand All @@ -74,16 +76,10 @@ <h3>4.2 寸电子墨水屏蓝牙控制器(nRF51)</h3>
阈值:
<input type="number" max="255" min="0" value="125" id="threshold" onchange="update_image()">
</div>
<textarea id="cmdIMAGE"></textarea>
<div id="log"></div>
<canvas id="canvas" width="400" height="300" style="border: black solid 1px;"></canvas>
</div>
</fieldset>

<fieldset>
<legend>日志</legend>
<button type="button" onclick="document.getElementById('log').innerHTML = '';">清空日志</button>
<div id="log"></div>
</fieldset>
<fieldset>
<legend>提示</legend>
<ul>
Expand Down
43 changes: 0 additions & 43 deletions html/js/dithering.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,49 +147,6 @@ function canvas2bytes(canvas, type='bw') {
return arr;
}

function bytes2canvas(bytes, canvas) {
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(canvas.width, canvas.height);

let buffer = [];
for (let byte of bytes) {
const binaryString = byte.toString(2).padStart(8, '0');
buffer.push(...binaryString.split('').map(bit => parseInt(bit, 10)));
}
let len = buffer.length;

// bw
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const i = (canvas.width * y + x) * 4;
const bit = buffer.shift();
const value = bit === 0 ? 0 : 255;
imageData.data[i] = value; // R
imageData.data[i + 1] = value; // G
imageData.data[i + 2] = value; // B
imageData.data[i + 3] = 255; // A
}
}

// red
if (buffer.length * 2 == len) {
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const i = (canvas.width * y + x) * 4;
const bit = buffer.shift();
if (bit === 0) {
imageData.data[i] = 255; // R
imageData.data[i + 1] = 0; // G
imageData.data[i + 2] = 0; // B
imageData.data[i + 3] = 255; // A
}
}
}
}

ctx.putImageData(imageData, 0, 0);
}

function getColorDistance(rgba1, rgba2) {
const [r1, b1, g1] = rgba1;
const [r2, b2, g2] = rgba2;
Expand Down
98 changes: 54 additions & 44 deletions html/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async function sendCommand(cmd) {
}

async function sendcmd(cmdTXT) {
addLog(`发送命令: ${cmdTXT}`);
addLog(`<span class="action">⇑</span> ${cmdTXT}`);
await sendCommand(hexToBytes(cmdTXT));
}

Expand Down Expand Up @@ -71,9 +71,6 @@ async function sendCmWithData(cmd, data){
}

async function send4GrayLut() {
await sendcmd("0300");
await sendcmd("043F"); // Load LUT from register

await sendCmWithData("20", "000A0000000160141400000100140000000100130A010001000000000000000000000000000000000000"); // vcom
await sendCmWithData("21", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // red not use
await sendCmWithData("22", "400A0000000190141400000100140A000001990C01030401000000000000000000000000000000000000"); // bw r
Expand All @@ -82,11 +79,29 @@ async function send4GrayLut() {
await sendCmWithData("25", "400A0000000190141400000110140A000001A01301000001000000000000000000000000000000000000"); // vcom
}

async function sendimg(cmdIMG) {
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;
}
}

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 = cmdIMG.replace(/(?:\r\n|\r|\n|,|0x| )/g, '');
const imgArray = getImageData(canvas, driver, mode);
const bwArrLen = (canvas.width/8) * canvas.height * 2;

if (imgArray.length == bwArrLen * 2) {
Expand All @@ -95,10 +110,14 @@ async function sendimg(cmdIMG) {
} else {
await sendCmWithData(driver === "03" ? "10" : "13", imgArray);
}

if (mode === "4gray") {
await sendcmd("0300");
await sendcmd("043F"); // Load LUT from register
await send4GrayLut();
await sendcmd("05");
await sendcmd(`01${driver}`); // restore lut
await sendcmd("0300");
await sendcmd("041F"); // Load LUT from OTP
} else {
await sendcmd("05");
}
Expand All @@ -111,17 +130,18 @@ async function sendimg(cmdIMG) {
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;
}

function disconnect() {
updateButtonStatus();
resetVariables();
addLog('已断开连接.');
document.getElementById("connectbutton").innerHTML = '连接';
updateButtonStatus();
}

async function preConnect() {
Expand All @@ -133,10 +153,16 @@ async function preConnect() {
}
else {
connectTrys = 0;
bleDevice = await navigator.bluetooth.requestDevice({
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
acceptAllDevices: true
});
try {
bleDevice = await navigator.bluetooth.requestDevice({
optionalServices: ['62750001-d828-918d-fb46-b6c11c675aec'],
acceptAllDevices: true
});
} catch (e) {
addLog(e.message);
return;
}

await bleDevice.addEventListener('gattserverdisconnected', disconnect);
try {
await connect();
Expand All @@ -156,21 +182,21 @@ async function reConnect() {
}

async function connect() {
if (epdCharacteristic == null) {
if (epdCharacteristic == null && bleDevice != null) {
addLog("正在连接: " + bleDevice.name);

gattServer = await bleDevice.gatt.connect();
addLog('> 找到 GATT Server');
addLog(' 找到 GATT Server');

epdService = await gattServer.getPrimaryService('62750001-d828-918d-fb46-b6c11c675aec');
addLog('> 找到 EPD Service');
addLog(' 找到 EPD Service');

epdCharacteristic = await epdService.getCharacteristic('62750002-d828-918d-fb46-b6c11c675aec');
addLog('> 找到 Characteristic');
addLog(' 找到 Characteristic');

await epdCharacteristic.startNotifications();
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
addLog(`> 收到配置:${bytesToHex(event.target.value.buffer)}`);
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));
});
Expand All @@ -187,13 +213,17 @@ function setStatus(statusText) {
}

function addLog(logTXT) {
const today = new Date();
const time = ("0" + today.getHours()).slice(-2) + ":" + ("0" + today.getMinutes()).slice(-2) + ":" + ("0" + today.getSeconds()).slice(-2) + " : ";
document.getElementById("log").innerHTML += time + logTXT + '<br>';
console.log(time + logTXT);
while ((document.getElementById("log").innerHTML.match(/<br>/g) || []).length > 10) {
var logs_br_position = document.getElementById("log").innerHTML.search("<br>");
document.getElementById("log").innerHTML = document.getElementById("log").innerHTML.substring(logs_br_position + 4);
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;
}
}

Expand All @@ -215,24 +245,6 @@ function intToHex(intIn) {
return stringOut.substring(2, 4) + stringOut.substring(0, 2);
}

function updateImageData(canvas) {
const driver = document.getElementById("epddriver").value;
const mode = document.getElementById('dithering').value;
if (mode === '4gray') {
document.getElementById('cmdIMAGE').value = bytesToHex(canvas2gray(canvas));
} else {
document.getElementById('cmdIMAGE').value = bytesToHex(canvas2bytes(canvas, 'bw'));
if (driver === '03') {
if (mode.startsWith('bwr')) {
document.getElementById('cmdIMAGE').value += bytesToHex(canvas2bytes(canvas, 'red'));
} else {
const count = document.getElementById('cmdIMAGE').value.length;
document.getElementById('cmdIMAGE').value += 'F'.repeat(count);
}
}
}
}

async function update_image () {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
Expand All @@ -258,7 +270,6 @@ function clear_canvas() {
const ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
document.getElementById('cmdIMAGE').value = '';
}
}

Expand All @@ -272,7 +283,6 @@ function convert_dithering() {
} else {
dithering(ctx, canvas.width, canvas.height, parseInt(document.getElementById('threshold').value), mode);
}
updateImageData(canvas);
}

document.body.onload = () => {
Expand Down

0 comments on commit c2c2308

Please sign in to comment.