add led and wakeup support

This commit is contained in:
Shuanglei Tao
2024-11-16 15:33:12 +08:00
parent 107f639b0b
commit 0cfacae939
8 changed files with 133 additions and 55 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 319 KiB

BIN
html/images/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

View File

@@ -21,7 +21,6 @@
<body>
<div class="main">
<h3>4.2 寸电子墨水屏蓝牙控制器nRF51</h3>
<a href="https://github.com/tsl0922/EPD-nRF51" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#ddd; color:#151513; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<fieldset>
<legend>蓝牙</legend>
<div style="float: right;">
@@ -90,21 +89,36 @@
<li>
<b>指令列表(指令和参数全部要使用十六进制):</b>
<ul>
<li><code>00</code>+<code>引脚配置</code>: 设置引脚映射(见上面引脚配置)</li>
<li><code>01</code>+<code>驱动 ID</code>: 驱动初始化(支持的驱动 ID: <code>01</code>/<code>02</code>/<code>03</code></li>
<li><code>02</code>: 清空屏幕(把屏幕刷为白色</li>
<li><code>03</code>+<code>命令</code>: 发送命令到屏幕(请参考屏幕主控手册</li>
<li><code>04</code>+<code>数据</code>: 写入数据到屏幕内存(同上</li>
<li><code>05</code>: 刷新屏幕(显示已写入屏幕内存的数据</li>
<li><code>06</code>: 让屏幕进入睡眠状态</li>
<li>驱动相关:
<ul>
<li><code>00</code>+<code>引脚配置</code>: 设置引脚映射(见上面引脚配置</li>
<li><code>01</code>+<code>驱动 ID</code>: 驱动初始化(支持的驱动 ID: <code>01</code>/<code>02</code>/<code>03</code></li>
<li><code>02</code>: 清空屏幕(把屏幕刷为白色</li>
<li><code>03</code>+<code>命令</code>: 发送命令到屏幕(请参考屏幕主控手册</li>
<li><code>04</code>+<code>数据</code>: 写入数据到屏幕内存(同上)</li>
<li><code>05</code>: 刷新屏幕(显示已写入屏幕内存的数据)</li>
<li><code>06</code>: 屏幕睡眠</li>
</ul>
</li>
<li>系统相关:
<ul>
<li><code>90</code>+<code>配置</code>: 写入配置信息(重启生效,格式参考源码 <code>epd_config_t</code></li>
<li><code>91</code>: 系统重启</li>
<li><code>92</code>: 系统睡眠</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>
系统睡眠后可通过线圈NFC/无线充电器)唤醒(需正确配置线圈对应的引脚才有效),否则一旦系统睡眠只有重新上电才能开启蓝牙。如果价签上带有 LED系统启动时 LED 会闪一下(需正确配置 LED 对应的引脚才有效),以便知道系统是否已经被线圈唤醒。
</p>
<p style="color: #666;">
<strong>致谢:</strong>屏幕驱动代码来自微雪 <a href="https://www.waveshare.net/wiki/E-Paper_Shield" target="_blank">E-Paper Shield</a>,本网页代码最初基于 <a href="https://github.com/atc1441/ATC_TLSR_Paper" target="_blank">atc1441/ATC_TLSR_Paper</a> 项目的网页控制端代码修改而来。
</p>
</fieldset>
</div>
<a href="https://github.com/tsl0922/EPD-nRF51" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#ddd; color:#151513; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<script type="text/javascript" src="js/dithering.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>

View File

@@ -39,24 +39,20 @@ async function sendCommand(cmd) {
}
async function sendcmd(cmdTXT) {
let cmd = hexToBytes(cmdTXT);
addLog(`发送命令: ${cmdTXT}`);
await sendCommand(cmd);
await sendCommand(hexToBytes(cmdTXT));
}
async function setDriver() {
let epdDriver = document.getElementById("epddriver").value;
let pins = document.getElementById("epdpins").value;
const epdDriver = document.getElementById("epddriver").value;
const pins = document.getElementById("epdpins").value;
await sendcmd("00" + pins);
await sendcmd("01" + epdDriver);
await sendcmd("06");
}
async function clearscreen() {
if(confirm('确认清除屏幕内容?')) {
await sendcmd("01");
await sendcmd("02");
await sendcmd("06");
}
}
@@ -76,11 +72,10 @@ async function sendIMGArray(imgArray, type = 'bw'){
async function sendimg(cmdIMG) {
startTime = new Date().getTime();
let epdDriver = document.getElementById("epddriver").value;
let imgArray = cmdIMG.replace(/(?:\r\n|\r|\n|,|0x| )/g, '');
const epdDriver = document.getElementById("epddriver").value;
const imgArray = cmdIMG.replace(/(?:\r\n|\r|\n|,|0x| )/g, '');
const bwArrLen = (canvas.width/8) * canvas.height * 2;
await sendcmd("01");
if (imgArray.length == bwArrLen * 2) {
await sendcmd("0310");
await sendIMGArray(imgArray.slice(0, bwArrLen - 1));
@@ -92,16 +87,14 @@ async function sendimg(cmdIMG) {
}
await sendcmd("05");
let sendTime = (new Date().getTime() - startTime) / 1000.0;
const sendTime = (new Date().getTime() - startTime) / 1000.0;
addLog(`发送完成!耗时: ${sendTime}s`);
setStatus(`发送完成!耗时: ${sendTime}s`);
await sendcmd("06");
}
function updateButtonStatus() {
let connected = gattServer != null && gattServer.connected;
let status = connected ? null : 'disabled';
const connected = gattServer != null && gattServer.connected;
const status = connected ? null : 'disabled';
document.getElementById("sendcmdbutton").disabled = status;
document.getElementById("clearscreenbutton").disabled = status;
document.getElementById("sendimgbutton").disabled = status;
@@ -117,8 +110,10 @@ function disconnect() {
async function preConnect() {
if (gattServer != null && gattServer.connected) {
if (bleDevice != null && bleDevice.gatt.connected)
if (bleDevice != null && bleDevice.gatt.connected) {
await sendcmd("06");
bleDevice.gatt.disconnect();
}
}
else {
connectTrys = 0;
@@ -159,11 +154,13 @@ async function connect() {
await epdCharacteristic.startNotifications();
epdCharacteristic.addEventListener('characteristicvaluechanged', (event) => {
addLog(`> 收到配置:${bytesToHex(event.target.value.buffer.slice(0,8))}`);
addLog(`> 收到配置:${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 sendcmd("01");
document.getElementById("connectbutton").innerHTML = '断开';
updateButtonStatus();
}
@@ -174,8 +171,8 @@ function setStatus(statusText) {
}
function addLog(logTXT) {
var today = new Date();
var time = ("0" + today.getHours()).slice(-2) + ":" + ("0" + today.getMinutes()).slice(-2) + ":" + ("0" + today.getSeconds()).slice(-2) + " : ";
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) {
@@ -198,15 +195,21 @@ function bytesToHex(data) {
}
function intToHex(intIn) {
var stringOut = "";
stringOut = ("0000" + intIn.toString(16)).substr(-4)
let stringOut = ("0000" + intIn.toString(16)).substr(-4)
return stringOut.substring(2, 4) + stringOut.substring(0, 2);
}
function updateImageData(canvas) {
const epdDriver = document.getElementById("epddriver").value;
const dithering = document.getElementById('dithering').value;
document.getElementById('cmdIMAGE').value = bytesToHex(canvas2bytes(canvas, 'bw'));
if (document.getElementById('dithering').value.startsWith('bwr')) {
document.getElementById('cmdIMAGE').value += bytesToHex(canvas2bytes(canvas, 'bwr'));
if (epdDriver === '03') {
if (dithering.startsWith('bwr')) {
document.getElementById('cmdIMAGE').value += bytesToHex(canvas2bytes(canvas, 'bwr'));
} else {
const count = document.getElementById('cmdIMAGE').value.length;
document.getElementById('cmdIMAGE').value += 'F'.repeat(count);
}
}
}