esptool-js
esptool-js copied to clipboard
Compatibiity With Electron
Hi, Does anyone have an example project of being able to flash an ESP32 using esptool-js from an Electron app?
I'm currently getting this error.
Error: TypeError: Cannot read properties of undefined (reading 'get_info')
at new ESPLoader (esploader.js:124:1)
at HTMLButtonElement.<anonymous> (renderer.js:73:27)
// renderer.js
const { SerialPort } = require('serialport');
const requireESM = require('esm')(module);
const esptool = requireESM('esptool-js');
const fs = require('fs');
const axios = require('axios');
const dropdown = document.getElementById('serial-dropdown');
const status = document.getElementById('status');
let selectedPort;
function updateStatus(text) {
status.innerHTML = text;
}
// Consts
const REMOTE_FIRMWARE_URL = "";
const REMOTE_BOOTLOADER_URL = "";
const REMOTE_PARTITIONS_URL = "";
async function listSerialPorts() {
try {
const ports = await SerialPort.list();
// Clear the dropdown
dropdown.innerHTML = '';
if (ports.length > 0) {
selectedPort = ports[0].path;
}
ports.forEach(port => {
const option = document.createElement('option');
option.value = port.path;
option.text = port.path + (port.manufacturer ? ` (${port.manufacturer})` : '');
dropdown.appendChild(option);
});
} catch (error) {
console.error('Error listing serial ports:', error);
}
}
listSerialPorts();
dropdown.addEventListener('change', (e) => {
console.log(`Selected serial port: ${e.target.value}`);
selectedPort = e.target.value;
});
document.getElementById('refreshButton').addEventListener('click', async () => {
listSerialPorts();
});
// Flashing
async function downloadFile(url, outputPath) {
const response = await axios({
method: 'get',
url: url,
responseType: 'arraybuffer'
});
fs.writeFileSync(outputPath, new Uint8Array(response.data));
}
document.getElementById('flashButton').addEventListener('click', async () => {
updateStatus('Flashing...');
try {
const espLoader = new esptool.ESPLoader({
port: selectedPort,
chip: 'esp32',
logLevel: 'debug'
});
updateStatus('Erasing flash...');
// Erase the flash first.
await espLoader.eraseFlash();
updateStatus('Downloading files...');
// Download the necessary files
await downloadFile(REMOTE_FIRMWARE_URL, './tempFirmware.bin');
await downloadFile(REMOTE_BOOTLOADER_URL, './tempBootloader.bin');
await downloadFile(REMOTE_PARTITIONS_URL, './tempPartitions.bin');
updateStatus('Flashing bootloader...');
// Flash the bootloader.
const bootloader = await espLoader.readFirmware('./tempBootloader.bin');
await espLoader.flashFirmware(bootloader, 0x10000);
updateStatus('Flashing firmware...');
// Flash the firmware.
const firmware = await espLoader.readFirmware('./tempFirmware.bin');
await espLoader.flashFirmware(firmware, 0x1000);
updateStatus('Flashing partition...');
// Flash the partitions.
const partitions = await espLoader.readPartitions('./tempPartitions.bin');
await espLoader.flashPartitions(partitions, 0x8000);
await espLoader.close();
updateStatus('Cleanup...');
// Clean up the temporary files
fs.unlinkSync('./tempFirmware.bin');
fs.unlinkSync('./tempBootloader.bin');
fs.unlinkSync('./tempPartitions.bin');
console.log('Flashing complete');
updateStatus('Flashing completed successfully!');
} catch (error) {
console.error('Error:', error);
updateStatus(error.toString());
}
});
esptool-js
will not work on electron because it requires the window.navigator.serial
API which is not supported on whatever browser electron uses. Since you're already using Electron you could package your app with the python version of esptool which is more supported and works better.
esptool-js
will not work on electron because it requires thewindow.navigator.serial
API which is not supported on whatever browser electron uses. Since you're already using Electron you could package your app with the python version of esptool which is more supported and works better.
esptool-js
uses the Web Serial
API which is supported in electron. Electron uses chromium browser which supports both Web Serial
and Web Bluetooth
APIs.
Documentation for the same can be found here - https://www.electronjs.org/docs/latest/tutorial/devices#web-serial-api
I'm sorry, I completely missed that page. It seems electron has a couple extra steps to work with web serial so that might be why esptool-js
doesn't work out of the box.
I don't have an example code but esptool-js
should work with electron. Just try using the Web Serial
API instead of the serialport
package.