From 9945631765d6e42b5fa1724a8442b30a4e3b8515 Mon Sep 17 00:00:00 2001 From: Ritika Mishra Date: Mon, 14 Oct 2024 12:17:32 +0530 Subject: [PATCH 1/8] updated values of input in css --- src/app/globals.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 972b839..a3392d3 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -29,7 +29,7 @@ --destructive-foreground: 210 40% 98%; --border: 214.3 31.8% 91.4%; - --input: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 80%; /* Darkened from 91.4% to 80% */ --ring: 222.2 84% 4.9%; --radius: 0.5rem; @@ -61,7 +61,7 @@ --destructive-foreground: 210 40% 98%; --border: 217.2 32.6% 17.5%; - --input: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 25%; /* Darkened from 17.5% to 25% */ --ring: 212.7 26.8% 83.9%; } } From b30e5da56c46a0fd278530c1d2e26832e2752602 Mon Sep 17 00:00:00 2001 From: Ritika Mishra Date: Sat, 16 Nov 2024 13:26:10 +0530 Subject: [PATCH 2/8] updated buttons of first section --- src/components/LandingComp/HeadSection.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LandingComp/HeadSection.tsx b/src/components/LandingComp/HeadSection.tsx index 9c1782e..81cf88d 100644 --- a/src/components/LandingComp/HeadSection.tsx +++ b/src/components/LandingComp/HeadSection.tsx @@ -64,7 +64,7 @@ const HeadSection: React.FC = () => {
-
)} + {isConnected && ( = ({
{/* Buttons */}
+ + + - - + + + + + + + + + + + + + + + + + + + + + + + +
))} @@ -1199,7 +1443,6 @@ const Connection: React.FC = ({
)} - {/* Canvas control buttons with tooltip */} {isConnected && ( diff --git a/src/components/filters.tsx b/src/components/filters.tsx index e5b9317..29b5b31 100644 --- a/src/components/filters.tsx +++ b/src/components/filters.tsx @@ -1,5 +1,131 @@ //Notch Filter 50Hz/60Hz +export class Filters { + // Properties to hold the state of the filter + private z1: number; + private z2: number; + private x1: number; + private x2: number; + private x3: number; + private x4: number; + + constructor() { + // Initialize state variables + this.z1 = 0; + this.z2 = 0; + + this.x1 = 0; + this.x2 = 0; + this.x3 = 0; + this.x4 = 0; + + } + //sample 1.500 2.250 + //TYPE 1.ECG + //2.EOG + //3.EEG + //4.EMG + + + // Method to apply the filter + process(input: number, type: number, sample: number): number { + let output = input; + switch (sample) { + //samplerate 500Hz + case 1: + switch (type) { + case 1: // ECG Sampling rate: 500.0 Hz, frequency: 30.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x1 = output - (-1.47548044 * this.z1) - (0.58691951 * this.z2); + output = 0.02785977 * this.x1 + 0.05571953 * this.z1 + 0.02785977 * this.z2; + this.z2 = this.z1; + this.z1 = this.x1; + console.log("ecg500"); + break; + case 2: // EOG Sampling rate: 500.0 Hz, frequency: 10.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x2 = output - (-1.82269493 * this.z1) - (0.83718165 * this.z2); + output = 0.00362168 * this.x2 + 0.00724336 * this.z1 + 0.00362168 * this.z2; + this.z2 = this.z1; + this.z1 = this.x2; + console.log("eog500"); + break; + + case 3: // EEG Sampling rate: 500.0 Hz, frequency: 45.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x3 = output - (-0.51930341 * this.z1) - (0.21965398 * this.z2); + output = 0.17508764 * this.x3 + 0.35017529 * this.z1 + 0.17508764 * this.z2; + this.z2 = this.z1; + this.z1 = this.x3; + console.log("eeg500"); + break; + + case 4: // EMG Sampling rate: 500.0 Hz, frequency: 70.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x4 = output - (-0.82523238 * this.z1) - (0.29463653 * this.z2); + output = 0.52996723 * this.x4 + -1.05993445 * this.z1 + 0.52996723 * this.z2; + this.z2 = this.z1; + this.z1 = this.x4; + console.log("emg500"); + break; + + default: + break; + } + break; + case 2: + //samplerate 250Hz + switch (type) { + case 1: // ECG Sampling rate: 250.0 Hz, frequency: 30.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x1 = output - -0.98240579 * this.z1 - 0.34766539 * this.z2; + output = 0.09131490 * this.x1 + 0.18262980 * this.z1 + 0.09131490 * this.z2; + this.z2 = this.z1; + this.z1 = this.x1; + console.log("ecg250"); + break; + + case 2: // EOG Sampling rate: 250.0 Hz, frequency: 10.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x2 = output - -1.64745998 * this.z1 - 0.70089678 * this.z2; + output = 0.01335920 * this.x2 + 0.02671840 * this.z1 + 0.01335920 * this.z2; + this.z2 = this.z1; + this.z1 = this.x2; + console.log("eog250"); + break; + + case 3: // EEG Sampling rate: 250.0 Hz, frequency: 45.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x3 = output - -0.51930341 * this.z1 - 0.21965398 * this.z2; + output = 0.17508764 * this.x3 + 0.35017529 * this.z1 + 0.17508764 * this.z2; + this.z2 = this.z1; + this.z1 = this.x3; + console.log("eeg250"); + break; + + case 4: // EMG Sampling rate: 250.0 Hz, frequency: 70.0 Hz. + // Filter is order 2, implemented as second-order sections (biquads). + this.x4 = output - 0.22115344 * this.z1 - 0.18023207 * this.z2; + output = 0.23976966 * this.x4 + -0.47953932 * this.z1 + 0.23976966 * this.z2; + this.z2 = this.z1; + this.z1 = this.x4; + console.log("emg250"); + break; + + default: + break; + } + break; + default: + break; + + } + return output; + } +} + + + export class Notch { // Properties to hold the state of the filter sections private z1_1: number; @@ -26,6 +152,7 @@ export class Notch { // Method to apply the filter process(input: number, type: number, sample: number): number { let output = input; + console.log(type); switch (sample) { case 1: // 500Hz switch (type) { @@ -34,7 +161,7 @@ export class Notch { output = 0.96508099 * this.x_1 + -1.56202714 * this.z1_1 + 0.96508099 * this.z2_1; this.z2_1 = this.z1_1; this.z1_1 = this.x_1; - + console.log("50notch500"); // Second filter section this.x_2 = output - (-1.61100358 * this.z1_2) - (0.96592171 * this.z2_2); output = 1.0 * this.x_2 + -1.61854514 * this.z1_2 + 1.0 * this.z2_2; @@ -46,7 +173,7 @@ export class Notch { output = 0.96508099 * this.x_1 + (-1.40747202 * this.z1_1) + (0.96508099 * this.z2_1); this.z2_1 = this.z1_1; this.z1_1 = this.x_1; - + console.log("60notch500"); // Second filter section this.x_2 = output - (-1.45687509 * this.z1_2) - (0.96573127 * this.z2_2); output = 1.00000000 * this.x_2 + (-1.45839783 * this.z1_2) + (1.00000000 * this.z2_2); @@ -97,4 +224,305 @@ export class Notch { return output; } -} \ No newline at end of file +} + + + + +// +// +//
+// {/* Decrease Canvas Button */} +// +// +// +// +// +//

+// {canvasCount === 1 +// ? "At Least One Canvas Required" +// : "Decrease Channel"} +//

+//
+//
+ +// + +// {/* Toggle All Channels Button */} +// +// +// +// +// +//

+// {showAllChannels +// ? "Hide All Channels" +// : "Show All Channels"} +//

+//
+//
+ +// + +// {/* Increase Canvas Button */} +// +// +// +// +// +//

+// {canvasCount >= 6 +// ? "Maximum Channels Reached" +// : "Increase Channel"} +//

+//
+//
+//
+//
+//
+// {isConnected && ( +// +// +// +// +// +//
+//
+// {/* Filter Name */} +//
+// {/* Buttons */} +//
+// +// +// + +// +// +//
+//
+//
+// {["CH1", "CH2", "CH3", "CH4", "CH5", "CH6"].map((filterName, index) => ( +//
+// {/* Filter Name */} +//
{filterName}
+ +// {/* Buttons */} +//
+// +// +// + +// +// +//
+//
+// ))} +//
+//
+//
+ +//
+// )} From f306d32414dd3d5b10a0c9026ebd8fbdc9807466 Mon Sep 17 00:00:00 2001 From: Aman Maheshwari Date: Tue, 26 Nov 2024 17:57:18 +0530 Subject: [PATCH 6/8] Update filters UI and functionality --- src/components/Connection.tsx | 452 ++++++++++++++-------------------- src/components/filters.tsx | 358 +++------------------------ 2 files changed, 214 insertions(+), 596 deletions(-) diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx index ea9ac33..a77fffb 100644 --- a/src/components/Connection.tsx +++ b/src/components/Connection.tsx @@ -2,7 +2,7 @@ import React, { useState, useRef, useCallback, useEffect } from "react"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; -import { Filters, Notch } from './filters'; +import { EXGFilter, Notch } from './filters'; import { Cable, @@ -75,7 +75,7 @@ const Connection: React.FC = ({ const isRecordingRef = useRef(false); // Ref to track if the device is recording const [isEndTimePopoverOpen, setIsEndTimePopoverOpen] = useState(false); const [detectedBits, setDetectedBits] = useState(null); // State to store the detected bits - const detectedBitsRef = React.useRef(null); + const detectedBitsRef = React.useRef("ten"); const [isRecordButtonDisabled, setIsRecordButtonDisabled] = useState(false); // New state variable const [datasets, setDatasets] = useState([]); // State to store the recorded datasets const [hasData, setHasData] = useState(false); @@ -265,19 +265,6 @@ const Connection: React.FC = ({ toast.error("Failed to connect to device."); } }; - const sample = useCallback((bits: BitSelection | null): number => { - if (bits === null) { - return 0; // Default value for null input - } - switch (bits) { - case "fourteen": - return 1; - case "ten": - return 2; - default: - return 0; // Fallback value for unexpected cases - } - }, []); const disconnectDevice = async (): Promise => { try { @@ -325,31 +312,31 @@ const Connection: React.FC = ({ } }; const appliedFiltersRef = React.useRef<{ [key: number]: number }>({}); - const appliedbioFiltersRef = React.useRef<{ [key: number]: number }>({}); + const appliedEXGFiltersRef = React.useRef<{ [key: number]: number }>({}); const [, forceUpdate] = React.useReducer((x) => x + 1, 0); - const [, forcebioUpdate] = React.useReducer((x) => x + 1, 0); + const [, forceEXGUpdate] = React.useReducer((x) => x + 1, 0); - const removebioFilter = (channelIndex: number) => { - delete appliedbioFiltersRef.current[channelIndex]; // Remove the filter for the channel - forcebioUpdate(); // Trigger re-render + const removeEXGFilter = (channelIndex: number) => { + delete appliedEXGFiltersRef.current[channelIndex]; // Remove the filter for the channel + forceEXGUpdate(); // Trigger re-render console.log(`Filter removed from Channel ${channelIndex}`); }; // Function to handle frequency selection - const handleFrequencySelectionbio = (channelIndex: number, frequency: number) => { - appliedbioFiltersRef.current[channelIndex] = frequency; // Update the filter for the channel - forcebioUpdate(); //Trigger re-render + const handleFrequencySelectionEXG = (channelIndex: number, frequency: number) => { + appliedEXGFiltersRef.current[channelIndex] = frequency; // Update the filter for the channel + forceEXGUpdate(); //Trigger re-render console.log( `Channel ${channelIndex} selected with frequency ${frequency}Hz` ); }; // Function to set the same filter for all channels - const applybioFilterToAllChannels = (channels: number[], frequency: number) => { + const applyEXGFilterToAllChannels = (channels: number[], frequency: number) => { channels.forEach((channelIndex) => { - appliedbioFiltersRef.current[channelIndex] = frequency; // Set the filter for the channel + appliedEXGFiltersRef.current[channelIndex] = frequency; // Set the filter for the channel }); - forcebioUpdate(); // Trigger re-render + forceEXGUpdate(); // Trigger re-render console.log( `Filter set to ${frequency}Hz for all channels: ${channels.join(", ")}` ); @@ -357,11 +344,11 @@ const Connection: React.FC = ({ // Function to remove the filter for all channels - const removebioFilterFromAllChannels = (channels: number[]) => { + const removeEXGFilterFromAllChannels = (channels: number[]) => { channels.forEach((channelIndex) => { - delete appliedbioFiltersRef.current[channelIndex]; // Remove the filter for the channel + delete appliedEXGFiltersRef.current[channelIndex]; // Remove the filter for the channel }); - forcebioUpdate(); // Trigger re-render + forceEXGUpdate(); // Trigger re-render console.log(`Filters removed from all channels: ${channels.join(", ")}`); }; @@ -411,23 +398,14 @@ const Connection: React.FC = ({ const SYNC_BYTE2 = 0x7c; // Second synchronization byte const END_BYTE = 0x01; // End byte to signify the end of a packet let previousCounter: number | null = null; // Variable to store the previous counter value for loss detection - const notchFilters = [ - new Notch(), // Notch_1 - new Notch(), // Notch_2 - new Notch(), // Notch_3 - new Notch(), // Notch_4 - new Notch(), // Notch_5 - new Notch(), // Notch_6 - ]; - const bioFilters = [ - new Filters(), // biofilter_1 - new Filters(), // biofilter_2 - new Filters(), // biofilter_3 - new Filters(), // biofilter_4 - new Filters(), // biofilter_5 - new Filters(), // biofilter_6 - ]; - + const notchFilters = Array.from({ length: 6 }, () => new Notch()); + const EXGFilters = Array.from({ length: 6 }, () => new EXGFilter()); + notchFilters.forEach((filter) => { + filter.setSample(detectedBitsRef.current); // Set the sample value for all instances + }); + EXGFilters.forEach((filter) => { + filter.setSample(detectedBitsRef.current); // Set the sample value for all instances + }); try { // Loop while the device is connected while (isConnectedRef.current) { @@ -473,76 +451,16 @@ const Connection: React.FC = ({ const lowByte = packet[channel * 2 + HEADER_LENGTH + 1]; const value = (highByte << 8) | lowByte; - - if (appliedbioFiltersRef.current[channel] !== undefined && appliedFiltersRef.current[channel] !== undefined) { - - channelData.push( - notchFilters[channel].process( - bioFilters[channel].process( - value, - appliedbioFiltersRef.current[channel], - sample(detectedBitsRef.current) - ), - appliedFiltersRef.current[channel], - sample(detectedBitsRef.current) - ) - ); - // } else { - // channelData.push(bioFilters[channel].process( - // value, - // appliedbioFiltersRef.current[channel], - // sample(detectedBitsRef.current) - // )); - // } - } else if (appliedbioFiltersRef.current[channel] !== undefined) { - channelData.push( - bioFilters[channel].process( - value, - appliedbioFiltersRef.current[channel], - sample(detectedBitsRef.current) - ) - ); - } - else if (appliedFiltersRef.current[channel] !== undefined) { - channelData.push( - notchFilters[channel].process( + channelData.push( + notchFilters[channel].process( + EXGFilters[channel].process( value, - appliedFiltersRef.current[channel], - sample(detectedBitsRef.current) - ) - ); - } else { - channelData.push(value); - } + appliedEXGFiltersRef.current[channel] + ), + appliedFiltersRef.current[channel] + ) + ); - - // if (appliedFiltersRef.current[channel] !== undefined ) { - // // Apply the filter if one is set for this channel - // channelData.push( - // notchFilters[channel].process( - // value, - // appliedFiltersRef.current[channel], - // sample(detectedBitsRef.current) - // ) - // ); - // }else if(appliedFiltersRef.current[channel] !== undefined){ - // channelData.push( - // notchFilters[channel].process( - // bioFilters[channel].process(value,appliedbioFiltersRef.current[channel],sample(detectedBitsRef.current)), - // appliedFiltersRef.current[channel], - // sample(detectedBitsRef.current) - // ) - // ); - // } - // else if(appliedbioFiltersRef.current[channel] !== undefined){ - // channelData.push( - // bioFilters[channel].process(value,appliedbioFiltersRef.current[channel],sample(detectedBitsRef.current)) - // ); - // } - // else { - // // Push raw value if no filter is applied - // channelData.push(value); - // } } const counter = packet[2]; // Extract the counter value from the packet @@ -1151,7 +1069,7 @@ const Connection: React.FC = ({ onClick={saveData} disabled={!hasData} > - + @@ -1194,7 +1112,7 @@ const Connection: React.FC = ({
)} - + {isConnected && ( = ({
{/* Buttons */}
- - - +
+ + +
+
+ - - + + +
@@ -1317,129 +1239,115 @@ const Connection: React.FC = ({
{/* Filter Name */}
{filterName}
- {/* Buttons */}
- +
- - - - - - - +
+
- - - - - - - - - - - - + +
))}
-
)} diff --git a/src/components/filters.tsx b/src/components/filters.tsx index 29b5b31..ecfe355 100644 --- a/src/components/filters.tsx +++ b/src/components/filters.tsx @@ -1,6 +1,16 @@ +// TypeScript filter classes for Chords +// Made with <3 at Upside Down labs +// Author: Aman Maheshwari +// +// Reference: +// https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html +// https://courses.ideate.cmu.edu/16-223/f2020/Arduino/FilterDemos/filter_gen.py +// +// Note: +// filter_gen.py provides C/C++ type functions which we have converted to TS //Notch Filter 50Hz/60Hz -export class Filters { +export class EXGFilter { // Properties to hold the state of the filter private z1: number; private z2: number; @@ -8,6 +18,7 @@ export class Filters { private x2: number; private x3: number; private x4: number; + private sample: string | null; constructor() { // Initialize state variables @@ -18,21 +29,24 @@ export class Filters { this.x2 = 0; this.x3 = 0; this.x4 = 0; - + this.sample = null; } //sample 1.500 2.250 //TYPE 1.ECG //2.EOG //3.EEG //4.EMG + // function to apply the + setSample(sample: string): void { + this.sample = sample; + } - - // Method to apply the filter - process(input: number, type: number, sample: number): number { + process(input: number, type: number): number { + if(!type) return input; let output = input; - switch (sample) { + switch (this.sample) { //samplerate 500Hz - case 1: + case "fourteen": switch (type) { case 1: // ECG Sampling rate: 500.0 Hz, frequency: 30.0 Hz. // Filter is order 2, implemented as second-order sections (biquads). @@ -40,7 +54,6 @@ export class Filters { output = 0.02785977 * this.x1 + 0.05571953 * this.z1 + 0.02785977 * this.z2; this.z2 = this.z1; this.z1 = this.x1; - console.log("ecg500"); break; case 2: // EOG Sampling rate: 500.0 Hz, frequency: 10.0 Hz. // Filter is order 2, implemented as second-order sections (biquads). @@ -48,32 +61,26 @@ export class Filters { output = 0.00362168 * this.x2 + 0.00724336 * this.z1 + 0.00362168 * this.z2; this.z2 = this.z1; this.z1 = this.x2; - console.log("eog500"); break; - case 3: // EEG Sampling rate: 500.0 Hz, frequency: 45.0 Hz. // Filter is order 2, implemented as second-order sections (biquads). this.x3 = output - (-0.51930341 * this.z1) - (0.21965398 * this.z2); output = 0.17508764 * this.x3 + 0.35017529 * this.z1 + 0.17508764 * this.z2; this.z2 = this.z1; this.z1 = this.x3; - console.log("eeg500"); break; - case 4: // EMG Sampling rate: 500.0 Hz, frequency: 70.0 Hz. // Filter is order 2, implemented as second-order sections (biquads). this.x4 = output - (-0.82523238 * this.z1) - (0.29463653 * this.z2); output = 0.52996723 * this.x4 + -1.05993445 * this.z1 + 0.52996723 * this.z2; this.z2 = this.z1; this.z1 = this.x4; - console.log("emg500"); break; - default: break; } break; - case 2: + case "ten": //samplerate 250Hz switch (type) { case 1: // ECG Sampling rate: 250.0 Hz, frequency: 30.0 Hz. @@ -82,7 +89,6 @@ export class Filters { output = 0.09131490 * this.x1 + 0.18262980 * this.z1 + 0.09131490 * this.z2; this.z2 = this.z1; this.z1 = this.x1; - console.log("ecg250"); break; case 2: // EOG Sampling rate: 250.0 Hz, frequency: 10.0 Hz. @@ -91,7 +97,6 @@ export class Filters { output = 0.01335920 * this.x2 + 0.02671840 * this.z1 + 0.01335920 * this.z2; this.z2 = this.z1; this.z1 = this.x2; - console.log("eog250"); break; case 3: // EEG Sampling rate: 250.0 Hz, frequency: 45.0 Hz. @@ -100,7 +105,6 @@ export class Filters { output = 0.17508764 * this.x3 + 0.35017529 * this.z1 + 0.17508764 * this.z2; this.z2 = this.z1; this.z1 = this.x3; - console.log("eeg250"); break; case 4: // EMG Sampling rate: 250.0 Hz, frequency: 70.0 Hz. @@ -109,7 +113,6 @@ export class Filters { output = 0.23976966 * this.x4 + -0.47953932 * this.z1 + 0.23976966 * this.z2; this.z2 = this.z1; this.z1 = this.x4; - console.log("emg250"); break; default: @@ -137,6 +140,8 @@ export class Notch { private x_1: number; private x_2: number; + private sample: string | null; + constructor() { // Initialize state variables for both filter sections this.z1_1 = 0; @@ -147,21 +152,25 @@ export class Notch { this.x_1 = 0; this.x_2 = 0; + this.sample = null; + } + + setSample(sample: string): void { + this.sample = sample; } // Method to apply the filter - process(input: number, type: number, sample: number): number { + process(input: number, type: number): number { + if(!type) return input; let output = input; - console.log(type); - switch (sample) { - case 1: // 500Hz + switch (this.sample) { + case "fourteen": // 500Hz switch (type) { case 1: // Notch Sampling rate: 500.0 Hz, frequency: [48.0, 52.0] Hz. this.x_1 = output - (-1.56858163 * this.z1_1) - (0.96424138 * this.z2_1); output = 0.96508099 * this.x_1 + -1.56202714 * this.z1_1 + 0.96508099 * this.z2_1; this.z2_1 = this.z1_1; this.z1_1 = this.x_1; - console.log("50notch500"); // Second filter section this.x_2 = output - (-1.61100358 * this.z1_2) - (0.96592171 * this.z2_2); output = 1.0 * this.x_2 + -1.61854514 * this.z1_2 + 1.0 * this.z2_2; @@ -173,7 +182,6 @@ export class Notch { output = 0.96508099 * this.x_1 + (-1.40747202 * this.z1_1) + (0.96508099 * this.z2_1); this.z2_1 = this.z1_1; this.z1_1 = this.x_1; - console.log("60notch500"); // Second filter section this.x_2 = output - (-1.45687509 * this.z1_2) - (0.96573127 * this.z2_2); output = 1.00000000 * this.x_2 + (-1.45839783 * this.z1_2) + (1.00000000 * this.z2_2); @@ -185,7 +193,7 @@ export class Notch { } break; - case 2: // 250Hz + case "ten": // 250Hz switch (type) { case 1: // Notch Sampling rate: 250.0 Hz, frequency: [48.0, 52.0] Hz. this.x_1 = output - (-0.53127491 * this.z1_1) - (0.93061518 * this.z2_1); @@ -228,301 +236,3 @@ export class Notch { - -// -// -//
-// {/* Decrease Canvas Button */} -// -// -// -// -// -//

-// {canvasCount === 1 -// ? "At Least One Canvas Required" -// : "Decrease Channel"} -//

-//
-//
- -// - -// {/* Toggle All Channels Button */} -// -// -// -// -// -//

-// {showAllChannels -// ? "Hide All Channels" -// : "Show All Channels"} -//

-//
-//
- -// - -// {/* Increase Canvas Button */} -// -// -// -// -// -//

-// {canvasCount >= 6 -// ? "Maximum Channels Reached" -// : "Increase Channel"} -//

-//
-//
-//
-//
-//
-// {isConnected && ( -// -// -// -// -// -//
-//
-// {/* Filter Name */} -//
-// {/* Buttons */} -//
-// -// -// - -// -// -//
-//
-//
-// {["CH1", "CH2", "CH3", "CH4", "CH5", "CH6"].map((filterName, index) => ( -//
-// {/* Filter Name */} -//
{filterName}
- -// {/* Buttons */} -//
-// -// -// - -// -// -//
-//
-// ))} -//
-//
-//
- -//
-// )} From ec63de2cf4244e5e225a724d6b9f3d5b4b11c89d Mon Sep 17 00:00:00 2001 From: Aman Maheshwari Date: Wed, 27 Nov 2024 14:04:44 +0530 Subject: [PATCH 7/8] Add EXG filters --- src/components/Canvas.tsx | 5 +- src/components/Connection.tsx | 86 ++++++++++++++--------------------- src/components/filters.tsx | 22 +++++++-- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/src/components/Canvas.tsx b/src/components/Canvas.tsx index 0ef6418..9e4739c 100644 --- a/src/components/Canvas.tsx +++ b/src/components/Canvas.tsx @@ -238,14 +238,11 @@ const Canvas = forwardRef( }); linesRef.current.forEach((line, i) => { - const bitsPoints = Math.pow(2, getValue(selectedBits)); // Adjust according to your ADC resolution - const yScale = 2 / bitsPoints; - const chData = (data[i] - bitsPoints / 2) * yScale; // Use a separate sweep position for each line currentSweepPos.current[i] = sweepPositions.current[i]; // Plot the new data at the current sweep position - line.setY(currentSweepPos.current[i] % line.numPoints, chData); + line.setY(currentSweepPos.current[i] % line.numPoints, data[i]); // Clear the next point to create a gap (optional, for visual effect) const clearPosition = (currentSweepPos.current[i] + (numX / 100)) % line.numPoints; diff --git a/src/components/Connection.tsx b/src/components/Connection.tsx index a77fffb..a3f5db4 100644 --- a/src/components/Connection.tsx +++ b/src/components/Connection.tsx @@ -319,16 +319,14 @@ const Connection: React.FC = ({ const removeEXGFilter = (channelIndex: number) => { delete appliedEXGFiltersRef.current[channelIndex]; // Remove the filter for the channel forceEXGUpdate(); // Trigger re-render - console.log(`Filter removed from Channel ${channelIndex}`); + }; // Function to handle frequency selection const handleFrequencySelectionEXG = (channelIndex: number, frequency: number) => { appliedEXGFiltersRef.current[channelIndex] = frequency; // Update the filter for the channel forceEXGUpdate(); //Trigger re-render - console.log( - `Channel ${channelIndex} selected with frequency ${frequency}Hz` - ); + }; // Function to set the same filter for all channels @@ -337,9 +335,7 @@ const Connection: React.FC = ({ appliedEXGFiltersRef.current[channelIndex] = frequency; // Set the filter for the channel }); forceEXGUpdate(); // Trigger re-render - console.log( - `Filter set to ${frequency}Hz for all channels: ${channels.join(", ")}` - ); + }; @@ -349,24 +345,16 @@ const Connection: React.FC = ({ delete appliedEXGFiltersRef.current[channelIndex]; // Remove the filter for the channel }); forceEXGUpdate(); // Trigger re-render - console.log(`Filters removed from all channels: ${channels.join(", ")}`); - }; - - - const removeFilter = (channelIndex: number) => { + }; + const removeNotchFilter = (channelIndex: number) => { delete appliedFiltersRef.current[channelIndex]; // Remove the filter for the channel forceUpdate(); // Trigger re-render - console.log(`Filter removed from Channel ${channelIndex}`); }; - // Function to handle frequency selection const handleFrequencySelection = (channelIndex: number, frequency: number) => { appliedFiltersRef.current[channelIndex] = frequency; // Update the filter for the channel forceUpdate(); //Trigger re-render - console.log( - `Channel ${channelIndex} selected with frequency ${frequency}Hz` - ); }; // Function to set the same filter for all channels @@ -375,18 +363,14 @@ const Connection: React.FC = ({ appliedFiltersRef.current[channelIndex] = frequency; // Set the filter for the channel }); forceUpdate(); // Trigger re-render - console.log( - `Filter set to ${frequency}Hz for all channels: ${channels.join(", ")}` - ); }; // Function to remove the filter for all channels - const removeFilterFromAllChannels = (channels: number[]) => { + const removeNotchFromAllChannels = (channels: number[]) => { channels.forEach((channelIndex) => { delete appliedFiltersRef.current[channelIndex]; // Remove the filter for the channel }); forceUpdate(); // Trigger re-render - console.log(`Filters removed from all channels: ${channels.join(", ")}`); }; // Function to read data from a connected device and process it @@ -407,7 +391,7 @@ const Connection: React.FC = ({ filter.setSample(detectedBitsRef.current); // Set the sample value for all instances }); try { - // Loop while the device is connected + // Loop while the device is connectedconsole.log(`Filters removed from all channels: ${channels.join(", ")}`); while (isConnectedRef.current) { const streamData = await readerRef.current?.read(); // Read data from the device if (streamData?.done) { @@ -1134,14 +1118,14 @@ const Connection: React.FC = ({
{/* Buttons */}
-
+
-
+
-
+