config.json, img: added new devices

js+html: added url navigation, "notice" support
This commit is contained in:
Rastislav Vysoky 2026-03-26 13:14:06 +01:00
parent e023661bbc
commit e3e09b4b11
19 changed files with 1390 additions and 175 deletions

File diff suppressed because it is too large Load diff

View file

@ -102,6 +102,10 @@ body:has([v-cloak]):after {
white-space-collapse: preserve;
min-width: 300px;
}
#app a {
text-decoration: underline;
}
#app .version {
flex-wrap: wrap;
}

View file

@ -1,10 +1,12 @@
import "./lib/beer.min.js";
import { createApp, reactive, ref, nextTick, watch, computed } from "./lib/vue.min.js";
import { Dfu } from "./lib/dfu.js";
import { ESPLoader, Transport, HardReset } from "./lib/esp32.js";
import { SerialConsole } from './lib/console.js';
import "/lib/beer.min.js";
import { createApp, reactive, ref, nextTick, watch, computed } from "/lib/vue.min.js";
import { Dfu } from "/lib/dfu.js";
import { ESPLoader, Transport, HardReset } from "/lib/esp32.js";
import { SerialConsole } from '/lib/console.js';
const configRes = await fetch('./config.json');
const searchParams = new URLSearchParams(location.search);
const configName = searchParams.get('config')?.replaceAll(/[^a-z_-]/g, '') ?? 'config';
const configRes = await fetch(`/${configName}.json`);
const config = await configRes.json();
const githubRes = await fetch('/releases');
@ -45,6 +47,12 @@ async function delay(milis) {
return await new Promise((resolve) => setTimeout(resolve, milis));
}
function toSlug(text) {
return String(text).toLowerCase()
.replace(/[^a-z0-9.]+/g, '-')
.replace(/^-|-$/g, '');
}
function getGithubReleases(roleType, files) {
const versions = {};
for(const [fileType, matchRE] of Object.entries(files)) {
@ -129,6 +137,7 @@ function setup() {
firmware: null,
version: null,
wipe: false,
espFlashAddress: 0x10000,
nrfEraserFlashingPercent: 0,
nrfEraserFlashing: false,
port: null,
@ -146,6 +155,26 @@ function setup() {
return fwVersion ? fwVersion[key] || '' : '';
}
const getNotice = (selected) => {
let notice = config.notice[selected.firmware.notice] || selected.firmware.notice || '';
if(notice) {
notice = notice.replaceAll(/\$\{(\w+)\}/g, (_, varName) => selected.device[varName] || '');
}
return notice;
}
const formatChangeLog = (changelog) => {
return changelog
.replace(/change log:\r?\n/i, '')
.replace(/^[-*] /mg, '')
.replace(/#(\d+)$/gm, `<a target="_blank" href="https://github.com/meshcore-dev/MeshCore/pull/$1">#$1</a>`)
// .split(/\r?\n/)
// .map(l => `* ${l}`)
// .join('\n')
}
const flashing = reactive({
supported: 'Serial' in window || 'serial' in window.navigator,
instance: null,
@ -198,6 +227,87 @@ function setup() {
return firmware.version[firstVersion].files.length > 0;
}
// --- URL Routing ---
// NOTE: the server must serve index.html for all paths (catch-all / try_files).
const deviceToSlug = (device) => toSlug([device.class, device.name].join('-'));
const firmwareToSlug = (firmware) => {
const title = getRoleFwValue(firmware, 'title');
const subTitle = getRoleFwValue(firmware, 'subTitle');
return toSlug(subTitle ? `${title}-${subTitle}` : title);
};
let initializingFromUrl = false;
const buildUrl = () => {
if (serialCon.opened) return '/console';
if (!selected.device) return '/';
let path = '/' + deviceToSlug(selected.device) + '/';
if (!selected.firmware) return path;
path += firmwareToSlug(selected.firmware) + '/';
if (selected.version) path += toSlug(selected.version);
return path;
};
const updateUrl = (replace = false) => {
if (initializingFromUrl) return;
const path = buildUrl();
if (window.location.pathname !== path) {
replace ? history.replaceState(null, '', path) : history.pushState(null, '', path);
}
};
const applyUrlPath = (path) => {
initializingFromUrl = true;
const segments = path.replace(/^\/|\/$/g, '').split('/').filter(Boolean);
if (segments.length === 0 || segments[0] === 'console') {
nextTick(() => { initializingFromUrl = false; });
return;
}
const [deviceSlug, roleSlug, versionSlug] = segments;
const matchingDevices = config.device.filter(d => deviceToSlug(d) === deviceSlug);
if (matchingDevices.length === 0) {
nextTick(() => { initializingFromUrl = false; });
return;
}
// When multiple devices share the same slug, use the firmware slug to pick the right one
let device, firmware;
if (roleSlug && matchingDevices.length > 1) {
for (const d of matchingDevices) {
const f = d.firmware.find(f => firmwareToSlug(f) === roleSlug && firmwareHasData(f));
if (f) { device = d; firmware = f; break; }
}
}
if (!device) device = matchingDevices[0];
selected.device = device;
if (!roleSlug) {
nextTick(() => { initializingFromUrl = false; });
return;
}
if (!firmware) firmware = device.firmware.find(f => firmwareToSlug(f) === roleSlug && firmwareHasData(f));
if (!firmware) {
nextTick(() => { initializingFromUrl = false; });
return;
}
selected.firmware = firmware;
// Use nextTick so the firmware watcher sets the default version first,
// then we override it with the version from the URL.
nextTick(() => {
if (versionSlug) {
const versionName = Object.keys(firmware.version).find(v => toSlug(v) === versionSlug);
if (versionName) selected.version = versionName;
}
initializingFromUrl = false;
});
};
const stepBack = () => {
if(selected.device && selected.firmware) {
if(selected.firmware.version[selected.version].customFile) {
@ -215,11 +325,6 @@ function setup() {
}
}
watch(() => selected.firmware, (firmware) => {
if(firmware == null) return;
selected.version = Object.keys(firmware.version)[0];
});
const flasherCleanup = async () => {
flashing.active = false;
flashing.log = '';
@ -302,6 +407,7 @@ function setup() {
);
selected.wipe = true;
selected.espFlashAddress = 0;
}
selected.firmware = {
@ -378,8 +484,6 @@ function setup() {
return;
}
console.log({flashFiles});
let flashData;
if(flashFiles[0].file) {
flashData = flashFiles[0].file;
@ -387,6 +491,7 @@ function setup() {
let flashFile;
if(device.type === 'esp32') {
flashFile = flashFiles.find(f => f.type === (selected.wipe ? 'flash-wipe' : 'flash-update'));
if(selected.wipe) selected.espFlashAddress = 0x00000;
}
else {
flashFile = flashFiles[0];
@ -422,7 +527,7 @@ function setup() {
enableTracing: false,
fileArray: [{
data: await blobToBinaryString(flashData),
address: selected.wipe ? 0x00000 : 0x10000
address: selected.espFlashAddress
}],
reportProgress: async (_, written, total) => {
flashing.percent = (written / total) * 100;
@ -481,12 +586,13 @@ function setup() {
};
const devices = computed(() => {
const classSortPrefix = (d) => d.class === 'ripple' ? '1' : '2';
const classes = ['ripple', 'meshos', 'community'];
const deviceGroups = {};
for(const cls of ['ripple', 'community']) {
let index = 0;
for(const cls of classes) {
const devices = config.device.toSorted(
(a, b) => (classSortPrefix(a) + a.maker + a.name).localeCompare(classSortPrefix(b) + b.maker + b.name)
(a, b) => (index + a.maker + a.name).localeCompare(index + b.maker + b.name)
).filter(
d => d.class === cls && (deviceFilterText.value == '' || d.name.toLowerCase().includes(deviceFilterText.value?.toLowerCase()))
)
@ -516,6 +622,29 @@ function setup() {
consoleEditBox.value.focus();
}
watch(() => selected.firmware, (firmware) => {
if(firmware == null) return;
selected.version = Object.keys(firmware.version)[0];
});
watch(() => selected.device, updateUrl);
watch(() => selected.firmware, updateUrl);
watch(() => selected.version, () => updateUrl(true)); // replace: version is a refinement, not a new nav step
watch(() => serialCon.opened, updateUrl);
window.addEventListener('popstate', () => {
if (serialCon.opened) closeSerialCon();
flashing.active = false;
flashing.log = '';
flashing.error = '';
selected.firmware = null;
selected.version = null;
selected.device = null;
applyUrlPath(window.location.pathname);
});
applyUrlPath(window.location.pathname);
return {
snackbar,
consoleEditBox, consoleWindow, consoleMouseUp,
@ -525,7 +654,8 @@ function setup() {
sendCommand, openSerialGUI,
retry, close, commandReference,
stepBack,
customFirmwareLoad, getFirmwarePath, getSelFwValue, getRoleFwValue,
customFirmwareLoad, getFirmwarePath,
getSelFwValue, getRoleFwValue, getNotice, formatChangeLog,
firmwareHasData,
canFlash, nrfErase
}

1
img/gatiot_gat562.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

1
img/heltec_e213.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

28
img/heltec_e290.svg Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="1534pt" height="704pt" viewBox="0 0 1534 704" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="#f3f4f1ff">
<path fill="#f3f4f1" opacity="1.00" d=" M 113.51 57.49 C 116.68 53.93 121.74 54.80 125.98 54.73 C 554.66 54.75 983.35 54.72 1412.03 54.74 C 1416.93 54.61 1421.47 58.99 1421.14 63.97 C 1421.12 249.31 1421.15 434.66 1421.17 620.01 C 1421.04 623.38 1421.57 627.40 1418.93 630.00 C 1416.23 633.15 1411.69 632.60 1407.99 632.68 C 978.97 632.67 549.96 632.74 120.94 632.65 C 115.90 633.24 110.56 629.48 111.03 624.06 C 111.25 573.20 110.75 522.33 111.12 471.48 C 115.21 471.49 119.31 471.44 123.40 471.33 C 123.53 387.06 123.54 302.79 123.46 218.52 C 119.27 218.44 115.09 218.43 110.90 218.45 C 110.96 198.52 110.82 178.59 110.95 158.66 C 111.15 158.28 111.53 157.52 111.72 157.15 C 124.47 156.42 137.25 157.03 150.01 156.88 C 156.80 156.96 163.64 156.35 170.37 157.48 C 170.50 161.93 170.09 166.42 170.61 170.86 C 171.36 175.20 175.68 178.30 179.98 178.33 C 189.67 178.56 199.37 178.08 209.06 178.45 C 218.21 178.34 226.20 186.94 226.01 195.97 C 226.01 333.65 225.98 471.32 226.05 609.00 C 226.14 612.07 226.51 615.77 229.51 617.45 C 232.85 619.76 237.19 618.78 241.00 619.02 C 624.33 619.02 1007.66 619.02 1390.98 619.02 C 1394.26 618.95 1397.61 619.34 1400.84 618.60 C 1404.66 617.19 1406.83 613.03 1406.55 609.07 C 1406.48 439.05 1406.53 269.03 1406.51 99.01 C 1406.35 90.84 1406.75 82.65 1406.19 74.49 C 1406.24 70.76 1402.48 68.33 1399.10 68.14 C 997.07 68.07 595.02 68.19 192.99 68.08 C 187.96 68.13 182.92 67.78 177.91 68.32 C 174.18 68.79 171.79 72.14 170.31 75.29 C 150.50 75.51 130.68 75.11 110.87 75.46 C 111.51 69.55 109.04 62.34 113.51 57.49 M 141.59 266.66 C 141.62 315.78 141.73 364.90 141.62 414.03 C 141.68 418.65 141.23 423.29 141.76 427.90 C 147.62 427.99 153.49 427.86 159.35 427.95 C 159.38 374.19 159.54 320.42 159.21 266.67 C 153.34 266.68 147.47 266.65 141.59 266.66 Z" />
<path fill="#f3f4f1" opacity="1.00" d=" M 300.58 91.51 C 662.13 91.36 1023.68 91.48 1385.23 91.44 C 1384.47 115.95 1385.00 140.48 1384.87 165.00 C 1384.85 309.87 1385.00 454.72 1384.81 599.58 C 1277.86 599.28 1170.90 599.56 1063.95 599.42 C 791.40 599.53 518.85 599.38 246.30 599.49 C 245.23 594.40 245.80 589.17 245.69 584.01 C 245.67 445.01 245.76 306.01 245.63 167.01 C 245.83 165.84 245.01 163.18 247.07 163.47 C 261.04 163.71 275.00 163.52 288.97 163.59 C 291.99 163.48 295.51 164.17 297.97 161.96 C 299.50 160.80 300.67 159.05 300.54 157.06 C 300.71 135.21 300.55 113.36 300.58 91.51 Z" />
</g>
<g id="#010101ff">
<path fill="#010101" opacity="1.00" d=" M 62.43 47.65 C 65.19 46.81 68.08 46.34 70.98 46.35 C 534.32 46.37 997.67 46.34 1461.01 46.36 C 1471.17 46.14 1481.23 51.87 1486.10 60.82 C 1488.81 65.36 1489.97 70.68 1490.08 75.93 C 1490.11 255.65 1489.86 435.33 1489.93 615.04 C 1491.05 628.45 1481.97 641.89 1469.11 645.81 C 1462.97 647.94 1456.39 647.09 1450.03 647.27 C 991.02 647.26 532.00 647.29 72.99 647.24 C 59.39 647.86 46.64 637.93 43.06 624.97 C 41.90 620.77 42.09 616.36 42.07 612.05 C 42.08 433.35 42.03 254.65 42.07 75.96 C 41.57 63.40 50.36 51.18 62.43 47.65 M 113.51 57.49 C 109.04 62.34 111.51 69.55 110.87 75.46 C 96.46 75.32 82.05 75.40 67.64 75.46 C 67.61 76.96 67.61 78.46 67.63 79.96 C 59.00 83.11 52.50 91.61 52.59 100.92 C 52.28 110.35 58.81 119.27 67.62 122.37 C 67.58 133.72 67.68 145.08 67.60 156.44 C 82.02 156.63 96.45 156.55 110.87 156.48 C 110.89 157.02 110.93 158.11 110.95 158.66 C 110.82 178.59 110.96 198.52 110.90 218.45 C 97.40 218.48 83.91 218.71 70.41 218.45 C 70.36 302.77 70.36 387.10 70.41 471.42 C 83.98 471.31 97.55 471.44 111.12 471.48 C 110.75 522.33 111.25 573.20 111.03 624.06 C 110.56 629.48 115.90 633.24 120.94 632.65 C 549.96 632.74 978.97 632.67 1407.99 632.68 C 1411.69 632.60 1416.23 633.15 1418.93 630.00 C 1421.57 627.40 1421.04 623.38 1421.17 620.01 C 1421.15 434.66 1421.12 249.31 1421.14 63.97 C 1421.47 58.99 1416.93 54.61 1412.03 54.74 C 983.35 54.72 554.66 54.75 125.98 54.73 C 121.74 54.80 116.68 53.93 113.51 57.49 M 1451.51 79.83 C 1441.55 82.40 1434.40 92.65 1435.34 102.88 C 1435.83 111.90 1442.34 120.25 1451.04 122.75 C 1459.13 125.25 1468.45 122.38 1473.91 115.95 C 1481.30 107.59 1481.04 93.75 1473.18 85.78 C 1467.64 80.16 1459.15 77.69 1451.51 79.83 M 1434.51 259.67 C 1428.15 262.17 1427.59 272.24 1433.44 275.60 C 1436.83 277.86 1441.07 277.01 1444.90 277.20 C 1448.77 277.46 1453.16 276.90 1455.69 273.60 C 1459.76 268.84 1457.05 260.59 1450.90 259.30 C 1445.49 258.82 1439.78 258.14 1434.51 259.67 M 1434.30 402.52 C 1427.47 405.44 1427.90 416.66 1434.87 419.11 C 1439.11 420.32 1443.65 419.54 1448.02 419.71 C 1452.18 420.05 1456.09 417.06 1457.12 413.06 C 1458.91 407.44 1453.79 401.15 1447.96 401.63 C 1443.41 401.84 1438.64 400.92 1434.30 402.52 M 69.50 568.75 C 60.80 571.02 54.09 579.15 53.48 588.10 C 52.74 596.32 56.94 604.87 64.13 609.01 C 71.16 613.24 80.65 613.08 87.43 608.42 C 92.66 604.60 96.29 598.62 97.08 592.18 C 97.82 583.54 93.13 574.61 85.43 570.56 C 80.63 567.87 74.77 567.42 69.50 568.75 M 1451.35 568.68 C 1444.01 570.51 1437.96 576.56 1435.83 583.77 C 1432.43 594.65 1439.17 607.52 1450.03 610.95 C 1457.53 613.54 1466.40 611.62 1472.02 605.96 C 1479.98 598.64 1480.83 585.33 1474.28 576.83 C 1469.32 569.67 1459.68 566.54 1451.35 568.68 Z" />
</g>
<g id="#c9cbcaff">
<path fill="#c9cbca" opacity="1.00" d=" M 170.31 75.29 C 171.79 72.14 174.18 68.79 177.91 68.32 C 182.92 67.78 187.96 68.13 192.99 68.08 C 595.02 68.19 997.07 68.07 1399.10 68.14 C 1402.48 68.33 1406.24 70.76 1406.19 74.49 C 1406.75 82.65 1406.35 90.84 1406.51 99.01 C 1406.53 269.03 1406.48 439.05 1406.55 609.07 C 1406.83 613.03 1404.66 617.19 1400.84 618.60 C 1397.61 619.34 1394.26 618.95 1390.98 619.02 C 1007.66 619.02 624.33 619.02 241.00 619.02 C 237.19 618.78 232.85 619.76 229.51 617.45 C 226.51 615.77 226.14 612.07 226.05 609.00 C 225.98 471.32 226.01 333.65 226.01 195.97 C 226.20 186.94 218.21 178.34 209.06 178.45 C 199.37 178.08 189.67 178.56 179.98 178.33 C 175.68 178.30 171.36 175.20 170.61 170.86 C 170.09 166.42 170.50 161.93 170.37 157.48 C 163.64 156.35 156.80 156.96 150.01 156.88 C 137.25 157.03 124.47 156.42 111.72 157.15 C 111.53 157.52 111.15 158.28 110.95 158.66 C 110.93 158.11 110.89 157.02 110.87 156.48 C 130.74 156.19 150.60 156.49 170.47 156.34 C 170.45 129.33 170.78 102.30 170.31 75.29 M 190.32 91.36 C 189.99 111.49 190.38 131.63 190.16 151.76 C 201.79 151.55 213.44 151.59 225.07 151.41 C 229.31 151.24 233.42 152.69 236.85 155.11 C 239.39 156.67 240.93 159.36 243.44 160.96 C 243.59 137.84 243.39 114.72 243.57 91.60 C 225.85 90.76 208.07 91.77 190.32 91.36 M 300.58 91.51 C 300.55 113.36 300.71 135.21 300.54 157.06 C 300.67 159.05 299.50 160.80 297.97 161.96 C 295.51 164.17 291.99 163.48 288.97 163.59 C 275.00 163.52 261.04 163.71 247.07 163.47 C 245.01 163.18 245.83 165.84 245.63 167.01 C 245.76 306.01 245.67 445.01 245.69 584.01 C 245.80 589.17 245.23 594.40 246.30 599.49 C 518.85 599.38 791.40 599.53 1063.95 599.42 C 1170.90 599.56 1277.86 599.28 1384.81 599.58 C 1385.00 454.72 1384.85 309.87 1384.87 165.00 C 1385.00 140.48 1384.47 115.95 1385.23 91.44 C 1023.68 91.48 662.13 91.36 300.58 91.51 Z" />
<path fill="#c9cbca" opacity="1.00" d=" M 205.52 104.13 C 211.41 99.98 219.75 98.92 225.95 103.00 C 235.21 108.08 238.12 121.60 231.69 130.02 C 226.14 125.75 221.78 120.17 216.61 115.47 C 213.03 111.57 208.99 108.12 205.52 104.13 Z" />
<path fill="#c9cbca" opacity="1.00" d=" M 201.97 108.06 C 210.68 116.31 218.73 125.25 227.68 133.24 C 224.43 137.10 218.75 137.90 214.00 137.23 C 204.87 136.14 197.54 127.20 198.27 118.03 C 198.43 114.39 199.97 111.03 201.97 108.06 Z" />
<path fill="#c9cbca" opacity="1.00" d=" M 1434.51 259.67 C 1439.78 258.14 1445.49 258.82 1450.90 259.30 C 1457.05 260.59 1459.76 268.84 1455.69 273.60 C 1453.16 276.90 1448.77 277.46 1444.90 277.20 C 1441.07 277.01 1436.83 277.86 1433.44 275.60 C 1427.59 272.24 1428.15 262.17 1434.51 259.67 Z" />
<path fill="#c9cbca" opacity="1.00" d=" M 141.59 266.66 C 147.47 266.65 153.34 266.68 159.21 266.67 C 159.54 320.42 159.38 374.19 159.35 427.95 C 153.49 427.86 147.62 427.99 141.76 427.90 C 141.23 423.29 141.68 418.65 141.62 414.03 C 141.73 364.90 141.62 315.78 141.59 266.66 Z" />
<path fill="#c9cbca" opacity="1.00" d=" M 1434.30 402.52 C 1438.64 400.92 1443.41 401.84 1447.96 401.63 C 1453.79 401.15 1458.91 407.44 1457.12 413.06 C 1456.09 417.06 1452.18 420.05 1448.02 419.71 C 1443.65 419.54 1439.11 420.32 1434.87 419.11 C 1427.90 416.66 1427.47 405.44 1434.30 402.52 Z" />
</g>
<g id="#cc252cff">
<path fill="#cc252c" opacity="1.00" d=" M 67.64 75.46 C 82.05 75.40 96.46 75.32 110.87 75.46 C 130.68 75.11 150.50 75.51 170.31 75.29 C 170.78 102.30 170.45 129.33 170.47 156.34 C 150.60 156.49 130.74 156.19 110.87 156.48 C 96.45 156.55 82.02 156.63 67.60 156.44 C 67.68 145.08 67.58 133.72 67.62 122.37 C 67.81 108.23 67.84 94.09 67.63 79.96 C 67.61 78.46 67.61 76.96 67.64 75.46 Z" />
</g>
<g id="#a3a4a4ff">
<path fill="#a3a4a4" opacity="1.00" d=" M 190.32 91.36 C 208.07 91.77 225.85 90.76 243.57 91.60 C 243.39 114.72 243.59 137.84 243.44 160.96 C 240.93 159.36 239.39 156.67 236.85 155.11 C 233.42 152.69 229.31 151.24 225.07 151.41 C 213.44 151.59 201.79 151.55 190.16 151.76 C 190.38 131.63 189.99 111.49 190.32 91.36 M 205.52 104.13 C 208.99 108.12 213.03 111.57 216.61 115.47 C 221.78 120.17 226.14 125.75 231.69 130.02 C 238.12 121.60 235.21 108.08 225.95 103.00 C 219.75 98.92 211.41 99.98 205.52 104.13 M 201.97 108.06 C 199.97 111.03 198.43 114.39 198.27 118.03 C 197.54 127.20 204.87 136.14 214.00 137.23 C 218.75 137.90 224.43 137.10 227.68 133.24 C 218.73 125.25 210.68 116.31 201.97 108.06 Z" />
</g>
<g id="#c79c2cff">
<path fill="#c79c2c" opacity="1.00" d=" M 70.41 218.45 C 83.91 218.71 97.40 218.48 110.90 218.45 C 115.09 218.43 119.27 218.44 123.46 218.52 C 123.54 302.79 123.53 387.06 123.40 471.33 C 119.31 471.44 115.21 471.49 111.12 471.48 C 97.55 471.44 83.98 471.31 70.41 471.42 C 70.36 387.10 70.36 302.77 70.41 218.45 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

1
img/heltec_v4_exp.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

1
img/heltec_wt2.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 44 KiB

1
img/lilygo_meshos.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 157 KiB

View file

@ -0,0 +1 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 758 1321" width="758" height="1321"><style>.a{fill:#8d9192}.b{fill:#292d2f}.c{fill:#505050}.d{fill:#e6822a}</style><path class="a" d="m148.1 27.1c13.3-5.2 27.6-7.8 41.9-8.6 12-0.4 24 0 36 0.1 21.7 0 43.3 0.1 65 0.1 17.7 0.4 35.3-0.2 53 0.4 11 0.1 22-0.4 33-0.2 9.3 0.5 18.6 0.2 27.9 0.3 58.7 0 117.4 0.3 176.1 0.3 18.9 0.4 37.7 4.7 54.8 12.7 26.9 12.9 50.7 33.3 65.5 59.5 11.8 21 17.5 45.2 17.2 69.3 0 108.3-0.3 216.7-0.3 325 0.2 30.4-0.3 60.7 0.2 91 6 8.1 13.6 14.8 20.1 22.5 1.7 2.2 2.2 4.9 2.1 7.5q-0.1 62.5-0.5 125.1c-0.5 22.3-0.3 44.7-0.4 67-0.5 6.3-8.5 7.2-11.5 11.9-0.7 3.2-0.5 6.6-0.1 9.9 3.3 4.1 11.2 4.6 11.5 11-0.1 54.7-0.2 109.4-0.3 164.1-0.3 4.7 0.9 9.8-1.1 14.3-6.8 8.7-14.9 16.5-21.5 25.5-0.2 6.7-0.1 13.4 0.1 20.1 1 1.5 2.3 3.1 2.2 5 0.4 9.4-0.3 18.8-0.2 28.2 0.4 3.3-2.7 5.6-2.6 8.8 0.1 22.4 0.1 44.7-0.1 67.1-0.9 24-7 48-19.4 68.7-21.2 36.7-60.7 61.2-102.6 66-10.3 1.3-20.7 1-31.1 1-114 0-228 0-341.9 0-13-0.1-26 0.5-38.9-0.9-32.5-3.3-63.9-17.8-86.6-41.3-26.1-26.7-39.1-64.5-38-101.5 0.1-40.3 0.2-80.7 0-121-0.8-4-4.5-6.6-7-9.6-4.5-4.8-8.6-10.1-13-15-2.4-2.5-3.2-6-3.2-9.4 0.2-40.6 0.4-81.3 0.5-122q0.1-1.8 0.2-3.7c0.6-8.5 0.2-17 0.2-25.6-0.1-5.2 0.2-10.5 0-15.7 0-2.7-0.1-5.7 2.1-7.6 3.9-3.7 8.7-6.1 13-9.2q0.1-3.2 0.1-6.4c-4.4-2.3-9.1-4.1-12.9-7.4-2.1-1.9-2.3-4.8-2.2-7.4 0.1-64.4 0.3-128.7 0.3-193 0.6-3.6 2.7-6.6 5.3-9 6-5.7 11.7-11.8 17.3-18 0.3-33.8 0.1-67.7 0.2-101.5-2.7-1.6-5.7-3.4-6.6-6.6-0.7-2.5-0.5-5.3-0.6-7.9-0.2-39.6 0-79.3-0.1-119 0-5 0.1-10.2 1.8-14.9 0.9-2.5 3.5-3.4 5.5-4.6-0.1-9.9-0.1-19.8 0.1-29.6-1.8-1-3.8-1.8-4.9-3.6-2.1-3-1.9-6.8-2-10.3-0.1-35.3 0.1-70.6-0.1-106 0.1-3-0.1-6.2 1.5-8.9 1.2-2.1 3.5-3.2 5.6-4.4 0.1-13.5 1.4-27.2 4.9-40.3 6.3-24.3 19.8-46.6 38.4-63.4 13.4-12.3 28.9-22.5 46.1-28.9zm49.1 27.2c-27.1 2-55 11.7-73.4 32.4-18.1 20.5-25.7 48.4-25.5 75.3-0.1 274-0.1 548-0.2 822 0.2 18-0.6 36-0.2 54-0.6 42.3-0.1 84.7-0.2 127 0.3 21.5 7.3 42.9 20 60.3 10.2 13.3 23.2 24.5 38.3 31.7 15.2 7.6 32.1 11.1 49 11.1 46 0 92 0.2 138-0.2 24 0.6 48-0.1 72 0.2 53.3 0 106.6 0.1 160 0 34.9-0.1 69.5-18.3 88.3-47.9 10.8-17.3 16.3-37.8 16-58.2 0.1-42 0.2-84-0.2-126 0-212 0.1-424-0.1-636-0.3-78 0.4-156-0.1-234 0.6-19.5-2.6-39.3-10.7-57.1-7-15.3-18.6-28.4-32.7-37.4-14.7-9-31.4-14.4-48.5-16.4-10.6-1.5-21.3-0.7-32-0.9-96.3 0-192.7 0.8-289 0-22.9 0.1-45.9-0.4-68.8 0.1z"/><path class="b" d="m197.2 54.3c22.9-0.5 45.9 0 68.8-0.1 96.3 0.8 192.7 0 289 0 10.7 0.2 21.4-0.6 32 0.9 17.1 2 33.8 7.4 48.5 16.4 14.1 9 25.7 22.1 32.7 37.4 8.1 17.8 11.3 37.6 10.7 57.1 0.5 78-0.2 156 0.1 234 0.2 212 0.1 424 0.1 636 0.4 42 0.3 84 0.2 126 0.3 20.4-5.2 40.9-16 58.2-18.8 29.6-53.4 47.8-88.3 47.9-53.4 0.1-106.7 0-160 0-24-0.3-48 0.4-72-0.2-46 0.4-92 0.2-137.9 0.2-16.9 0-33.9-3.5-49-11.1-15.2-7.2-28.2-18.4-38.3-31.7-12.8-17.4-19.8-38.8-20.1-60.3 0.1-42.3-0.4-84.7 0.2-127-0.3-18 0.4-36 0.2-54 0.2-274 0.2-548 0.2-822-0.2-26.9 7.4-54.8 25.5-75.3 18.5-20.7 46.3-30.4 73.4-32.4zm13.1 33.2c-19.9 2.3-38.8 11.7-53.4 25.4-13.6 13.6-23.3 31.2-26.6 50.1-2 10.6-1.3 21.3-1.4 32 0 311.6 0 623.3 0 935-0.5 14.6 1.2 29.5 7.1 43 12.2 29.4 40.4 51.6 71.9 55.9 12.3 1.6 24.7 0.8 37 1q150.6-0.1 301.1 0c8.6-0.1 17.4 0.4 25.9-1.2 27.3-4.6 52.1-22 65.3-46.4 7.9-14.1 11.6-30.3 11.3-46.3 0.1-320.4 0-640.7 0.1-961-0.4-12.6-4-25-9.4-36.3-15.3-32.1-50.7-53.3-86.2-51.9-107 0-214 0-321 0-7.2 0.1-14.5-0.3-21.7 0.7z"/><path class="c" d="m210.3 87.5c7.2-1 14.5-0.6 21.7-0.7 107 0 214 0 321 0 35.5-1.4 70.9 19.8 86.2 51.9 5.4 11.3 9 23.7 9.4 36.3-0.1 320.3 0 640.6-0.1 961 0.3 16-3.4 32.2-11.3 46.3-13.2 24.4-38 41.8-65.3 46.4-8.5 1.6-17.3 1.1-25.9 1.2q-150.5-0.1-301.1 0c-12.3-0.2-24.7 0.6-37-1-31.5-4.3-59.7-26.5-71.9-55.9-5.9-13.5-7.6-28.4-7.1-43 0-311.7 0-623.4 0-935 0.1-10.7-0.6-21.4 1.4-32 3.3-18.9 13-36.5 26.6-50.1 14.6-13.7 33.5-23.1 53.4-25.4z"/><path class="d" d="m19.9 851.8c5.1-0.9 10.2-1.3 15.4-1 0 8.5 0.5 17-0.2 25.5-5 0-10-0.3-15-0.9-3.1-0.4-6.1-3.1-5.9-6.3-0.1-3.8-0.1-7.7 0.4-11.4 0.2-2.9 2.4-5.4 5.3-5.9z"/></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 832 1286" width="832" height="1286"><style>.a{fill:#20201e}.b{fill:#b8bab9}.c{fill:#3a3a3a}.d{fill:#a0a09e}</style><path class="a" d="m230.1 8.1c4.8-3.5 11-4.8 16.9-4.8 59.3 0.2 118.7 0.2 178 0.3 40.6 0.2 81.3-0.8 122 0.8 7.6 0.4 15.4 0.4 22.9 2.1 7.1 1.7 13.5 6.1 17.4 12.2 2.5 4 3.4 8.7 3.7 13.3 1.1 41.8 6.8 84.3 24.1 122.7 8.4 17.2 19.1 34.4 35.8 44.7 8.3 5.5 18.7 4.7 27.9 7.8 17.5 5.6 34.6 13.4 48.5 25.6 8.7 7.8 16.5 16.8 21.1 27.6-1.8 1-3.5 2-5.2 3-8.2-7-16.1-14.6-25.4-20.1-20.6-12.4-43.8-21.1-67.9-22.6-157.3-0.7-314.6-1.6-471.9-2.3-9.6-0.1-19.3-0.3-28.9 1.2-12.7 1.7-24.9 5.8-36.7 10.8-13.3 5.9-26 13.4-36.4 23.5-2.6 2.6-5.1 5.3-7.9 7.7-1.8-0.9-3.5-1.9-5.3-2.8 1.9-3.7 4.3-7 6.9-10.1 20-23.9 48.8-40.1 79.4-45.8 14.4-3.2 26.3-13.2 35.1-24.8 16.4-22.3 25.6-49.1 30.8-76.1 5.5-26.7 7.8-53.9 8.5-81 0-5 2.4-10.1 6.6-12.9z"/><path class="a" d="m154.5 244.7c4.8-0.8 9.7-1.2 14.6-1.1 72.3 0.4 144.5 1 216.8 1.2 88.3 0.8 176.6 0.8 264.8 1.5 30.2 1.3 58.8 19.3 73.5 45.5 5.4 9.4 9.3 19.7 11.1 30.4 2.3 11.1 1.7 22.5 1.8 33.8q-0.1 300-0.1 600c0.2 13.2-2.2 26.5-7.4 38.6-8.9 21.4-26.3 39.3-47.7 48.2-11.9 5.4-24.9 7.3-37.9 7.2-147.3 0.3-294.7 0.5-442 1.1-14.4-0.2-28.7 0.5-43.1-0.2-30.4-1.7-58.9-20.5-73.7-46.9-9-15.7-13.2-34-12.9-52q0.1-43 0.8-86c0-51.7 0.4-103.3 0.6-155 0.4-42.6 0.6-85.3 0.7-128 0.3-74 1-148 1.1-222 0.2-15-0.7-30.3 2.6-45.1 4.2-18.8 14.1-36.4 28.7-49.1 13.3-11.9 30.2-19.5 47.7-22.1zm-8.6 145c-0.3 68.4 0 136.9-0.1 205.3 0.1 105.3-0.2 210.6 0.1 315.9 63 0.5 126.1 0.1 189.1 0.2 80.7 0 161.4 0 242 0 29.6-0.1 59.2 0.3 88.8-0.2q0.1-260.5 0.1-521.1c-2 0-4-0.2-5.9-0.2-171.4 0.1-342.8-0.1-514.1 0.1z"/><path class="a" d="m60.6 1049c-0.3-2.1 2-2.9 3.3-4 2.2 2.5 4.7 4.7 7.2 6.8 20.6 16.2 43.6 31 69.8 35.3 15.5 3 31.4 1.8 47.1 2.2q73.5 0.4 147 1c53.3 0.2 106.6 0.6 160 1.1 48.7 0 97.4 0.7 146 0.8 17.2-0.5 34.2-4.2 49.9-11.4 18-7.7 35-17.7 50.2-30.1 2 1.4 4.2 2.7 6.3 3.9-6.7 8.4-13.7 16.7-22.4 23.2-13.9 10.2-29.4 18.8-46.5 22-17.3 3.5-34.6 12-44.6 27.2-9 14.1-17 29-23.4 44.4-11.2 25.6-19.6 52.4-26.1 79.5-1.7 6.6-1.9 13.8-6 19.5-4.2 5.6-9.8 10.6-16.6 12.5-10 3-20.6 1.3-30.8 1.3-27.7-1.4-55.3-1.8-83-2.4-52.6-1.2-105.3-1.9-157.9-0.4-15.4 0.4-30.7 1.2-46.1 1.5-9.3 0.3-19.2-2.3-26-8.9-4.3-4.1-5.8-10.2-5.6-16 0.3-25.9-4.4-51.7-13-76.1-4.8-15.1-11-29.8-18.4-43.9-5.2-10-11.2-19.8-19.1-28-4.2-4.5-10.2-6.2-15.7-8.4-11.4-4.4-23.1-7.8-34.4-12.5-15.9-6.5-31.2-15.2-43.4-27.4-3.2-3.7-7.1-7.6-7.8-12.7z"/><path class="b" d="m149.1 219.6c9.6-1.5 19.3-1.3 28.9-1.2 157.3 0.7 314.6 1.6 471.9 2.3 24.1 1.5 47.3 10.2 67.9 22.6 9.3 5.5 17.2 13.1 25.4 20.1 3.6 2.3 5.3 6.3 7.7 9.7 13.6 20.8 19.6 45.6 21.8 70.1 1.7 12.9 0.9 25.9 1 38.8-0.1 5.9 0.2 11.7-0.2 17.6-3.7 3.3-5.8 7.8-7.6 12.3-8.6 20.2-7.4 43.7 0.1 64.1 1.9 4.7 3.2 9.7 6.6 13.6l0.9 1.2c0.2 18.7-0.3 37.5-0.3 56.2-0.1 2.9 0.3 5.9-0.7 8.7-2.1 6.3-4 12.7-5.8 19.1-1.7 6.3-1 12.8-1 19.2 0.2 43.6 0.7 87.3 1.2 131 0.9 14.7-0.2 29.6 3.3 44 0.1 1.3 1.4 1.8 2.2 2.5 0.2 68.5-0.1 137-0.2 205.5-1 19.8-6.2 39.6-16.5 56.6-4.2 6.2-8.8 12.4-14.6 17.1-15.2 12.4-32.2 22.4-50.2 30.1-15.7 7.2-32.7 10.9-49.9 11.4-48.6-0.1-97.3-0.8-146-0.8-53.4-0.5-106.7-0.9-160-1.1q-73.5-0.6-147-1c-15.7-0.4-31.6 0.8-47.1-2.2-26.2-4.3-49.2-19.1-69.8-35.3-2.5-2.1-5-4.3-7.2-6.8-17.1-19.7-27.9-45-30-71-0.9-9.3-0.3-18.7-0.3-28 1.3-106.4 2.1-212.7 2.8-319.1 0.6-86.3 1.3-172.6 1.7-258.9 0.1-14.4-0.3-28.8 2.1-43 3.3-19.9 10.3-39.4 21.9-56 1.8-2.7 3.6-5.3 6-7.4 2.8-2.4 5.3-5.1 7.9-7.7 10.4-10.1 23.1-17.6 36.4-23.5 11.8-5 24-9.1 36.7-10.8zm5.4 25.1c-17.6 2.6-34.4 10.2-47.7 22.1-14.6 12.7-24.5 30.3-28.8 49.1-3.2 14.8-2.3 30.1-2.5 45.1-0.1 74-0.8 148-1.1 222-0.1 42.7-0.3 85.4-0.7 128-0.2 51.7-0.6 103.3-0.6 155q-0.7 43-0.8 86c-0.3 18 3.9 36.3 12.9 52 14.8 26.4 43.3 45.2 73.7 46.9 14.4 0.7 28.7 0 43.1 0.2 147.3-0.6 294.7-0.8 442-1.1 13 0.1 26-1.8 37.9-7.2 21.4-8.9 38.8-26.8 47.7-48.2 5.2-12.1 7.6-25.4 7.4-38.6q0-300 0.1-600c-0.1-11.3 0.5-22.7-1.8-33.8-1.8-10.7-5.7-21-11.1-30.4-14.7-26.2-43.3-44.2-73.5-45.5-88.2-0.7-176.5-0.7-264.8-1.5-72.3-0.2-144.6-0.8-216.9-1.2-4.8-0.1-9.7 0.3-14.5 1.1z"/><path class="c" d="m145.9 389.7c171.3-0.2 342.7 0 514.1-0.1 1.9 0 3.9 0.2 5.9 0.2q0 260.6-0.1 521.1c-29.6 0.5-59.2 0.1-88.8 0.2-80.7 0-161.3 0-242 0-63-0.1-126.1 0.3-189.1-0.2-0.3-105.3 0-210.6-0.1-315.9 0.1-68.4-0.2-136.9 0.1-205.3z"/><path class="d" d="m773.5 399.6c8.8 0.3 17.6-0.5 26.5-0.8 3.5 5.8 8.6 10.7 11.1 17.1 3.4 8.2 4 17.3 4.2 26.1 0.2 11.4-0.3 23.4-5.8 33.6-2.6 4.6-5.4 9.2-8.7 13.3-9.4 1-18.9-0.7-28.2 0.7-3.4-3.9-4.7-8.9-6.6-13.6-7.5-20.4-8.7-43.9-0.1-64.1 1.8-4.5 3.9-9 7.6-12.3z"/><path class="d" d="m766.7 574.8c1.8-6.4 3.7-12.8 5.8-19.1 3.3 0.4 6.6 0.3 9.8 1.1 3 0.9 3.1 4.5 3.2 7.1 1.9 63.7 2.9 127.4 4.6 191.1 0.8 9.4-8.4 18-17.7 16.5-0.8-0.7-2.1-1.2-2.2-2.4-3.5-14.5-2.4-29.4-3.3-44.1-0.5-43.7-1-87.3-1.2-131 0-6.4-0.7-12.9 1-19.2z"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 34 KiB

1
img/rak_13302.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 176 KiB

1
img/rak_3112.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 93 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Before After
Before After

View file

@ -5,9 +5,9 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MeshCore flasher</title>
<link href="./css/beer.css" rel="stylesheet">
<link href="./css/flasher.css" rel="stylesheet">
<script type="module" src="./flasher.js"></script>
<link href="/css/beer.css" rel="stylesheet">
<link href="/css/flasher.css" rel="stylesheet">
<script type="module" src="/flasher.js"></script>
</head>
<body class="dark">
@ -97,6 +97,7 @@
</li>
</ul>
</article>
<div v-if="getNotice(selected)" v-html="getNotice(selected)"></div>
<nav class="version">
<div class="field label suffix border small">
<select v-model="selected.version">
@ -108,7 +109,8 @@
<i>arrow_drop_down</i>
</div>
<div class="max pre" v-if="getSelFwValue('notes')">
<b>Changelog:</b><br>{{ getSelFwValue('notes').replace('Change log:\r\n', '') }}
<b>Changelog:</b><br>
<span v-html="formatChangeLog(getSelFwValue('notes'))"></span>
</div>
</nav>
</header>
@ -184,6 +186,9 @@
<li v-if="selected.device.type === 'nrf52' && selected.device.erase">
<a data-ui="menu-selector" :href="`${config.staticPath}/${selected.device.erase.replace('.zip', '.uf2')}`" download>{{ selected.device.erase.replace('.zip', '.uf2') }}</a>
</li>
<li v-if="selected.device.type === 'nrf52' && selected.device.bootloader">
<a data-ui="menu-selector" :href="`${config.staticPath}/${selected.device.bootloader}`" download>{{ selected.device.bootloader }}</a>
</li>
</menu>
<div class="tooltip left max">Download a copy of the firmware files for use with other flashers</div>
</button>
@ -217,7 +222,7 @@
<nav>
<i>bolt</i>
<h5 class="small max logo-top">
<img src="img/meshcore.svg"> <span>flasher</span>
<img src="/img/meshcore.svg"> <span>flasher</span>
</h5>
<button class="transparent hide-mobile" @click="openSerialGUI()">
<i>manufacturing</i>
@ -244,12 +249,17 @@
<details open>
<summary style="background-color: var(--surface-container)">
<div>
<strong>{{ type === 'community' ? 'Community Firmware' : 'Ripple Firmware' }}</strong>
<strong v-if="type === 'ripple'">Ripple Firmware</strong>
<strong v-else-if="type === 'meshos'">MeshOS Firmware</strong>
<strong v-else-if="type === 'community'">Community Firmware</strong>
<div class="tooltip right max">
<template v-if="type === 'ripple'">
Freemium firmware provided by <a class="inverse-link" target="_blank" href="https://buymeacoffee.com/ripplebiz">Ripple Radios</a>
</template>
<template v-else>
<template v-if="type === 'meshos'">
Freemium firmware provided by Andy Kirby
</template>
<template v-else-if="type === 'community'">
Open Source <a class="inverse-link" target="_blank" href="https://github.com/meshcore-dev/MeshCore">Community firmware</a>
</template>
</div>
@ -305,6 +315,6 @@
</pre>
</div>
</div>
<script src="./lib/iframeResizer.contentWindow.min.js"></script>
<script src="/lib/iframeResizer.contentWindow.min.js"></script>
</body>
</html>

View file

@ -80,30 +80,7 @@ function calcCrc16(data, crc = 0xFFFF) {
}
function sleep(milliseconds) {
return new Promise((resolve) => {
const startTime = performance.now();
const targetTime = startTime + milliseconds;
function checkTime() {
if (performance.now() >= targetTime) {
resolve();
} else {
requestAnimationFrame(checkTime);
}
}
const initialDelay = Math.max(0, milliseconds - 16); // Wake up ~1 frame early to start polling
if (initialDelay > 0) {
setTimeout(() => {
// Now start the more precise polling
checkTime();
}, initialDelay);
} else {
// If the desired sleep is very short, go straight to polling
checkTime();
}
});
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}
// --- HciPacket Class (adapted from dfu/dfu_transport_serial.py) ---
@ -219,15 +196,22 @@ export class Dfu {
}
catch(e) {
HciPacket.sequenceNumber = 0;
throw e;
}
finally {
reader.releaseLock();
}
// Decode SLIP
const decodedData = this.decodeSlip(buffer);
// Extract ACK number (assuming it's in the decoded data)
if (decodedData.length < 2) { // Check for sufficient length
// Extract the SLIP frame between the two 0xC0 delimiters, ignoring any
// stale bytes that arrived before the opening delimiter.
const firstC0 = buffer.indexOf(0xC0);
const secondC0 = buffer.indexOf(0xC0, firstC0 + 1);
if (firstC0 === -1 || secondC0 === -1) {
throw new Error("Received incomplete ACK.");
}
const decodedData = this.decodeSlip(buffer.slice(firstC0 + 1, secondC0));
if (decodedData.length < 2) {
throw new Error("Received incomplete ACK.");
}
const ack = (decodedData[0] >> 3) & 0x07;
@ -358,6 +342,10 @@ export class Dfu {
}
let bytesSent = 0;
// Brief stabilization pause before starting data transfer (mirrors Python's implicit
// pause at count=0 — it sleeps FLASH_PAGE_WRITE_TIME after the very first packet).
await sleep(FLASH_PAGE_WRITE_TIME * 1000);
// Send firmware packets
for (const [index, pkt] of frames.entries()) {
await this.sendPacket(pkt);
@ -388,6 +376,7 @@ export class Dfu {
}
this.transferInProgress = true;
this.lastAck = -1; // Reset last ACK
HciPacket.sequenceNumber = 0; // Reset HCI sequence number
const decoder = new TextDecoder();
try {
await this.port.open({ baudRate: 115200 }); // Open with correct baudrate