From e7e5e403c46d1d6c94199d71461db7bfdd6c648d Mon Sep 17 00:00:00 2001 From: Jake Date: Mon, 29 Sep 2025 14:07:25 +0800 Subject: [PATCH] save/load working --- index.html | 4 +-- script.js | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++--- serial.js | 7 +++++ 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index dbbc136..154d1fc 100644 --- a/index.html +++ b/index.html @@ -3,13 +3,13 @@ - ESP32 Animation Creator + Little Sophia Control Panel -

ESP32 Animation Creator

+

Little Sophia Control Panel

diff --git a/script.js b/script.js index b983599..5f8ad1b 100644 --- a/script.js +++ b/script.js @@ -199,14 +199,22 @@ window.onload = () => { }); break; - case 0x03: { // CMD_LOAD_FILE + case 0x03: // CMD_LOAD_FILE const fileData = new Uint8Array(payload); console.log(`Received file (${fileData.length} bytes)`); - + document.getElementById('log').value += `Loaded file\n`; // 🔹 Do something with the file handleLoadedFile(fileData); break; - } + case 0x05: // CMD_SAVE_FILE + + console.log(`Saved file Response Recieved`); + console.log(new Uint8Array(payload)); + document.getElementById('log').value += `Saved file Response Recieved\n`; + // 🔹 Do something with the file + //handleLoadedFile(fileData); + break; + // Add more cases as needed default: @@ -306,6 +314,77 @@ window.onload = () => { deleteButton.disabled = false; } + async function sendAnimationToESP32() { + const frameCount = 500; + const numChannels = 5; + const frameRate = 50; + const version = 1; + + const headerSize = 16; + const frameDataSize = frameCount * numChannels * 2; + const keyframeCount = dialKeyframes.reduce((sum, channel) => { + return sum + Object.keys(channel).length; + }, 0); + + + ///const keyframeCount = dialKeyframes.length; + const keyframeDataSize = keyframeCount * 5; + for (var i = 0; i < 5; i++) { + console.log(dialKeyframes[i]); + } + console.log(dialKeyframes); + console.log(keyframeCount); + + const totalSize = headerSize + 2 + keyframeDataSize; + console.log(totalSize); + const buffer = new ArrayBuffer(totalSize); + const view = new DataView(buffer); + let offset = 0; + + // 🔹 Header + view.setUint8(offset++, "A".charCodeAt(0)); + view.setUint8(offset++, "N".charCodeAt(0)); + view.setUint8(offset++, "I".charCodeAt(0)); + view.setUint8(offset++, "M".charCodeAt(0)); + view.setUint16(offset, frameCount, true); offset += 2; + view.setUint8(offset++, version); + view.setUint8(offset++, frameRate); + offset += 8; // reserved + + // 🔹 Frame data (all zeroes) + //offset += frameDataSize; + + // 🔹 Keyframe count + view.setUint16(offset, keyframeCount, true); offset += 2; + + const keyframeList = []; + + + Object.entries(dialKeyframes).forEach(([motorIdStr, frameMap]) => { + const motorId = parseInt(motorIdStr, 10); + + Object.entries(frameMap).forEach(([frameStr, position]) => { + const frame = parseInt(frameStr, 10); + if (position !== undefined) { + keyframeList.push({ motorId, frame, position }); + } + }); + }); + + // 🔹 Keyframes + keyframeList.forEach(({ motorId, frame, position }) => { + view.setUint8(offset++, motorId); + view.setUint16(offset, frame, true); offset += 2; + view.setUint16(offset, position, true); offset += 2; + }); + + console.log("Keyframe count: " + keyframeCount); + console.log(keyframeList); + + // 🔹 Send to ESP32 + const payload = new Uint8Array(buffer); + serial.saveFile(payload); // CMD_SAVE_ANIMATION + } @@ -472,7 +551,7 @@ window.onload = () => { document.getElementById('saveAnimation').onclick = async () => { - + await sendAnimationToESP32(); }; diff --git a/serial.js b/serial.js index eeeb576..2de0b33 100644 --- a/serial.js +++ b/serial.js @@ -7,6 +7,7 @@ const BAUD_RATE = 1000000; const CMD_ID_REQUEST = 0x01; const CMD_FILE_LIST = 0x02; const CMD_LOAD_FILE = 0x03; +const CMD_SAVE_FILE = 0x05; const CMD_DELETE_FILE = 0x04; export class SerialManager { @@ -50,11 +51,17 @@ export class SerialManager { } async requestFile(filename) { + console.log("Requesting File: " + filename); const encoder = new TextEncoder(); const payload = Array.from(encoder.encode(filename)); await this.send(CMD_LOAD_FILE, payload); // CMD_LOAD_FILE } + async saveFile(payload){ + console.log("Saving File: " + "filename"); + await this.send(CMD_SAVE_FILE, payload); + } + startReading(onPacket) { const decoder = new TextDecoder();