Finalize documenting and clean up of website code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Signed-off-by: Severin Kaderli <severin@kaderli.dev>
This commit is contained in:
parent
436e261fa7
commit
79fbcdedc3
5 changed files with 142 additions and 69 deletions
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<!-- Pattern will only match valid ASCII characters -->
|
<!-- The pattern on the input will only match valid ASCII characters -->
|
||||||
<input
|
<input
|
||||||
required
|
required
|
||||||
minlength="1"
|
minlength="1"
|
||||||
|
|
|
@ -1,13 +1,37 @@
|
||||||
/**
|
class Constants {
|
||||||
* The amount of time in ms a bit takes to transmit.
|
/**
|
||||||
*
|
* The amount of time in ms a bit takes to transmit.
|
||||||
* @type {Number}
|
*
|
||||||
*/
|
* @type {Number}
|
||||||
const CLOCK_TIME = 500;
|
*/
|
||||||
|
static get CLOCK_TIME() {
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The preamble that is sent before the packet.
|
* The preamble that is sent before the packet.
|
||||||
*
|
*
|
||||||
* @type {Number[]}
|
* @type {Number[]}
|
||||||
*/
|
*/
|
||||||
const PREAMBLE = [1, 1, 1, 0, 0, 0, 1, 1, 1];
|
static get PREAMBLE() {
|
||||||
|
return [1, 1, 1, 0, 0, 0, 1, 1, 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of workers that should be started.
|
||||||
|
*
|
||||||
|
* @type {Number}
|
||||||
|
*/
|
||||||
|
static get NUMBER_OF_WORKERS() {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CSS class to add to buttons that should be hidden.
|
||||||
|
*
|
||||||
|
* @type {String}
|
||||||
|
*/
|
||||||
|
static get HIDE_CLASS() {
|
||||||
|
return "hide";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,27 +1,61 @@
|
||||||
const hideClass = "hide";
|
/**
|
||||||
let isSending = false;
|
* Global flag that indicates if any bits should be transmitted. This flag
|
||||||
|
* is used to stop the transmission of bits.
|
||||||
|
*
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
let isTransmitting = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array that contains all currently running web workers.
|
||||||
|
*
|
||||||
|
* @type {Worker[]}
|
||||||
|
*/
|
||||||
let workers = [];
|
let workers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HTMLInputElement}
|
||||||
|
*/
|
||||||
const textInput = document.getElementById("textInput");
|
const textInput = document.getElementById("textInput");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HTMLButtonElement}
|
||||||
|
*/
|
||||||
const startSendingButton = document.getElementById("start-sending-button");
|
const startSendingButton = document.getElementById("start-sending-button");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HTMLButtonElement}
|
||||||
|
*/
|
||||||
const stopSendingButton = document.getElementById("stop-sending-button");
|
const stopSendingButton = document.getElementById("stop-sending-button");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HTMLButtonElement}
|
||||||
|
*/
|
||||||
const startCalibrationButton = document.getElementById("start-calibration-button");
|
const startCalibrationButton = document.getElementById("start-calibration-button");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HTMLButtonElement}
|
||||||
|
*/
|
||||||
const stopCalibrationButton = document.getElementById("stop-calibration-button");
|
const stopCalibrationButton = document.getElementById("stop-calibration-button");
|
||||||
|
|
||||||
|
// Add event listeners to the buttons
|
||||||
startCalibrationButton.addEventListener("click", startCalibration);
|
startCalibrationButton.addEventListener("click", startCalibration);
|
||||||
stopCalibrationButton.addEventListener("click", stopCalibration);
|
stopCalibrationButton.addEventListener("click", stopCalibration);
|
||||||
startSendingButton.addEventListener("click", startSending);
|
startSendingButton.addEventListener("click", startSending);
|
||||||
stopSendingButton.addEventListener("click", stopSending);
|
stopSendingButton.addEventListener("click", stopSending);
|
||||||
|
|
||||||
function getWebWorker() {
|
/**
|
||||||
return new Worker("./scripts/Worker.js");
|
* Starts the web workers and add them to the global worker array.
|
||||||
}
|
*/
|
||||||
|
|
||||||
function startWorkers() {
|
function startWorkers() {
|
||||||
for (let i = 0; i < 8; i++) {
|
for (let i = 0; i < Constants.NUMBER_OF_WORKERS; i++) {
|
||||||
workers.push(getWebWorker());
|
workers.push(new Worker("./scripts/Worker.js"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates all currently running workers and clear out the worker array.
|
||||||
|
*/
|
||||||
function stopWorkers() {
|
function stopWorkers() {
|
||||||
for (const worker of workers) {
|
for (const worker of workers) {
|
||||||
worker.terminate();
|
worker.terminate();
|
||||||
|
@ -30,32 +64,38 @@ function stopWorkers() {
|
||||||
workers = [];
|
workers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the calibration process by simply starting all web workers.
|
||||||
|
*/
|
||||||
function startCalibration() {
|
function startCalibration() {
|
||||||
console.log("Starting calibration");
|
|
||||||
|
|
||||||
startCalibrationButton.classList.add(hideClass);
|
|
||||||
stopCalibrationButton.classList.remove(hideClass);
|
|
||||||
Utility.setMessage("Calibration currently ongoing.");
|
Utility.setMessage("Calibration currently ongoing.");
|
||||||
|
|
||||||
|
startCalibrationButton.classList.add(Constants.HIDE_CLASS);
|
||||||
|
stopCalibrationButton.classList.remove(Constants.HIDE_CLASS);
|
||||||
|
|
||||||
startWorkers();
|
startWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the calibration process by stopping all currently running web workers.
|
||||||
|
*/
|
||||||
function stopCalibration() {
|
function stopCalibration() {
|
||||||
console.log("Stopping calibration");
|
|
||||||
|
|
||||||
stopCalibrationButton.classList.add(hideClass);
|
|
||||||
startCalibrationButton.classList.remove(hideClass);
|
|
||||||
Utility.setMessage("");
|
Utility.setMessage("");
|
||||||
|
|
||||||
|
stopCalibrationButton.classList.add(Constants.HIDE_CLASS);
|
||||||
|
startCalibrationButton.classList.remove(Constants.HIDE_CLASS);
|
||||||
|
|
||||||
stopWorkers();
|
stopWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts sending the message in the input after validating that the input is
|
||||||
|
* valid.
|
||||||
|
*/
|
||||||
function startSending() {
|
function startSending() {
|
||||||
textInput.setCustomValidity("");
|
|
||||||
// Validate the input
|
// Validate the input
|
||||||
|
textInput.setCustomValidity("");
|
||||||
if (!textInput.checkValidity()) {
|
if (!textInput.checkValidity()) {
|
||||||
|
|
||||||
console.log(textInput.validity);
|
|
||||||
if (textInput.validity.valueMissing) {
|
if (textInput.validity.valueMissing) {
|
||||||
textInput.setCustomValidity("Please enter between 1 and 16 characters.");
|
textInput.setCustomValidity("Please enter between 1 and 16 characters.");
|
||||||
}
|
}
|
||||||
|
@ -68,37 +108,41 @@ function startSending() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
startSendingButton.classList.add(hideClass);
|
|
||||||
stopSendingButton.classList.remove(hideClass);
|
|
||||||
Utility.setMessage(`Sending message: ${textInput.value}`);
|
Utility.setMessage(`Sending message: ${textInput.value}`);
|
||||||
console.log(`Start sending message: ${textInput.value}`);
|
console.log(`Start sending message: ${textInput.value}`);
|
||||||
|
startSendingButton.classList.add(Constants.HIDE_CLASS);
|
||||||
|
stopSendingButton.classList.remove(Constants.HIDE_CLASS);
|
||||||
|
|
||||||
const packet = new Packet(textInput.value);
|
const packet = new Packet(textInput.value);
|
||||||
const signal = Utility.manchesterEncode(packet.getData());
|
const signal = Utility.manchesterEncode(packet.getData());
|
||||||
|
|
||||||
isSending = true;
|
isTransmitting = true;
|
||||||
transmitSignal(signal);
|
transmitSignal(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the sending process.
|
||||||
|
*/
|
||||||
function stopSending() {
|
function stopSending() {
|
||||||
console.log("Stop Sending");
|
console.log("Stop Sending");
|
||||||
Utility.setMessage("");
|
Utility.setMessage("");
|
||||||
|
|
||||||
stopSendingButton.classList.add(hideClass);
|
stopSendingButton.classList.add(Constants.HIDE_CLASS);
|
||||||
startSendingButton.classList.remove(hideClass);
|
startSendingButton.classList.remove(Constants.HIDE_CLASS);
|
||||||
isSending = false;
|
isTransmitting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transmit the given bit array until the sending is stopped.
|
* Transmits the given bit array until the sending is stopped. The transmission
|
||||||
|
* is stopped when the global isTransmitting flag is set to false.
|
||||||
*
|
*
|
||||||
* @param {Number[]} signal
|
* @param {Number[]} signal
|
||||||
*/
|
*/
|
||||||
async function transmitSignal(signal) {
|
async function transmitSignal(signal) {
|
||||||
while (isSending) {
|
while (isTransmitting) {
|
||||||
// Send the preamble
|
// Send the preamble
|
||||||
for (const bit of PREAMBLE) {
|
for (const bit of Constants.PREAMBLE) {
|
||||||
if (!isSending) {
|
if (!isTransmitting) {
|
||||||
stopWorkers();
|
stopWorkers();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +152,7 @@ async function transmitSignal(signal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < signal.length; i++) {
|
for (let i = 0; i < signal.length; i++) {
|
||||||
if (!isSending) {
|
if (!isTransmitting) {
|
||||||
stopWorkers();
|
stopWorkers();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -120,17 +164,17 @@ async function transmitSignal(signal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This either starts or stops the web workers depending on the bit value
|
* Starts or stops the web workers depending on the bit value and then waits
|
||||||
* and then waits for a duration of CLOCK_TIME.
|
* for a duration of Constants.CLOCK_TIME.
|
||||||
*
|
*
|
||||||
* @param {Number} bit
|
* @param {Number} bit
|
||||||
*/
|
*/
|
||||||
function transmitBit(bit) {
|
function transmitBit(bit) {
|
||||||
if (bit === 1) {
|
if (bit === 1) {
|
||||||
startWorkers();
|
startWorkers();
|
||||||
return new Promise((resolve) => setTimeout(resolve, CLOCK_TIME));
|
return new Promise((resolve) => setTimeout(resolve, Constants.CLOCK_TIME));
|
||||||
}
|
}
|
||||||
|
|
||||||
stopWorkers();
|
stopWorkers();
|
||||||
return new Promise((resolve) => setTimeout(resolve, CLOCK_TIME));
|
return new Promise((resolve) => setTimeout(resolve, Constants.CLOCK_TIME));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* This class represents a packet containing a header, payload and checksum.
|
||||||
*/
|
*/
|
||||||
class Packet {
|
class Packet {
|
||||||
/**
|
/**
|
||||||
|
@ -26,6 +25,8 @@ class Packet {
|
||||||
#checksum = [];
|
#checksum = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Creates a new packet with the given text as the payload.
|
||||||
|
*
|
||||||
* @param {String} payloadText
|
* @param {String} payloadText
|
||||||
*/
|
*/
|
||||||
constructor(payloadText) {
|
constructor(payloadText) {
|
||||||
|
@ -53,11 +54,11 @@ class Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a string into an array of ASCII code points.
|
* Turns a string into an array of ASCII code points.
|
||||||
*
|
*
|
||||||
* @param {String} text
|
* @param {String} text
|
||||||
* @return {Number[]}
|
* @return {Number[]}
|
||||||
*/
|
*/
|
||||||
#textToCodePoints(text) {
|
#textToCodePoints(text) {
|
||||||
const codePoints = [];
|
const codePoints = [];
|
||||||
for (let i = 0; i < text.length; i++) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
@ -67,11 +68,11 @@ class Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a string into an bit array.
|
* Turns a string into a bit array.
|
||||||
*
|
*
|
||||||
* @param {String} text
|
* @param {String} text
|
||||||
* @return {Number[]}
|
* @return {Number[]}
|
||||||
*/
|
*/
|
||||||
#textToBitArray(text) {
|
#textToBitArray(text) {
|
||||||
const codePoints = this.#textToCodePoints(text);
|
const codePoints = this.#textToCodePoints(text);
|
||||||
let bitArray = [];
|
let bitArray = [];
|
||||||
|
@ -82,17 +83,22 @@ class Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the checksum of the given array of bytes and return it
|
* Calculates the checksum of the given array of bytes and return it
|
||||||
* as an bit array.
|
* as a bit array.
|
||||||
*
|
*
|
||||||
* @param {Number[]} bytes
|
* @param {Number[]} bytes
|
||||||
* @return {Number[]}
|
* @return {Number[]}
|
||||||
*/
|
*/
|
||||||
#calculateChecksum(bytes) {
|
#calculateChecksum(bytes) {
|
||||||
const checksum = Utility.crc8Autosar(bytes);
|
const checksum = Utility.crc8Autosar(bytes);
|
||||||
return this.#numberToBitArray(checksum, 8);
|
return this.#numberToBitArray(checksum, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all data of the packet as a bit array.
|
||||||
|
*
|
||||||
|
* @return {Number[]}
|
||||||
|
*/
|
||||||
getData() {
|
getData() {
|
||||||
return [...this.#header, ...this.#payload, ...this.#checksum];
|
return [...this.#header, ...this.#payload, ...this.#checksum];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class Utility {
|
class Utility {
|
||||||
/**
|
/**
|
||||||
* This method calculates the CRC-8-AUTOSAR checksum of the given
|
* Calculates the CRC-8-AUTOSAR checksum of the given array of bytes.
|
||||||
* array of bytes.
|
|
||||||
*
|
*
|
||||||
* This code is based on the code examples from the following page:
|
* This code is based on the code examples from the following page:
|
||||||
* http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
|
* http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
|
||||||
|
@ -48,7 +47,7 @@ class Utility {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take a bit array and encode the contents using manchester encoding.
|
* Eencode the contents of the given bit array using manchester encoding.
|
||||||
*
|
*
|
||||||
* @param {Number[]} bitArray
|
* @param {Number[]} bitArray
|
||||||
* @return {Number[]}
|
* @return {Number[]}
|
||||||
|
@ -65,7 +64,7 @@ class Utility {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the information message on the page to the given string.
|
* Sets the information message on the page to the given string.
|
||||||
* @param {String} text
|
* @param {String} text
|
||||||
*/
|
*/
|
||||||
static setMessage(text) {
|
static setMessage(text) {
|
||||||
|
|
Reference in a new issue