Atharv Kashyap‘s Status Report for 10/03/2026
This week I moved from planning the signal-processing pipeline to building it. I implemented the first Python version of the SynapSys decoder, including bandpass/notch filtering, CCA, three-command classification, and rejection logic. I kept the main parameters configurable so we can easily change things like sample rate, window length, harmonics, and thresholds once we start testing with our own hardware. The next step for next week will be converting this to C/C++ using tools like Claude so that it runs on the ESP32 as well as testing on real datasets to make sure all parts are working (this was only tested this week with synthetic data).
For now, the classifier compares the EEG against 8.57, 12, and 15 Hz references and gives each one a CCA score. The highest score is the predicted command. I also added confidence and winner-vs-runner-up margin checks so the system can eventually reject unclear inputs instead of always forcing a YES, NO, or HELP result. This is exactly what we documented for our design report and what Theodora presented last week. I have not chosen the final thresholds yet because these need to be determined from our own calibration recordings.
Here is a screenshot of the repository:

I (using Claude) also wrote automated tests for all the different coding stages. Right now, 193 tests pass with no failures. These cover the reference signals, filtering, CCA calculations, classification/rejection logic, synthetic EEG generation, metrics, and data loading.

Before moving to real EEG, I tested everything using synthetic data where I already knew the correct answer. I generated fake EEG containing 8.57, 12, or 15 Hz signals, then added noise, drift, 60 Hz interference, and differences between channels. For example, a synthetic 12 Hz trial should produce the largest CCA correlation for the 12 Hz reference rather than 8.57 or 15 Hz. There was no noise in these data points so obviously I expected a big spike and strong correlation scores. This was just to test if the processing worked. I repeated this for all three commands.
Example CCA output:

I cannot upload thet tests.csv files due to security reasons on WordPress blocking me.
For clean signals, the correct CCA reference clearly gives the highest score for all three commands as expected.

I then added much more noise and also tested pure noise, off-target signals, and ambiguous mixtures. The correct reference still tended to score highest for valid trials, but the scores became closer together as the inputs got worse. This was useful because it showed exactly why we need rejection logic instead of just picking the largest score every time.

Python is being used as our reference implementation and analysis environment, while the final filtering, CCA, and rejection logic will run in C/C++ on the ESP32-S3.
Schedule
I am on track right now. Next week is going to be busy because we also need to finish the design report and get the PCB ready to send out.
Deliverables for Next Week
Finalize and send out the PCB design (will help with layout and BOM finalization), test CCA against Wang et al. SSVEP dataset and once it works, port the Python to C/C++ for the ESP32 and finish my parts for the design report.
