After pleasantly surprised at the fact my web app project is unlikely to leave my old Android phones behind, I got back to my “learn by doing” process. As originally planned, I’m going to leave my first draft “Basic” UI as-is for fallback/debug purposes. I made a copy to serve as the starting point of my “Standard” UI and initial focus is on sensor integration time.
Full Width Control
First change was minor and cosmetic: “Basic” didn’t use any CSS styles, and “Standard” started with just one style to make input sliders 100% of available width. The default width was annoyingly narrow. Making it full width helps me make finer adjustments.
ASTEP Value Fixed at ~10ms
AS7341 sensor integration time is controlled by two parameters: ATIME and ASTEP. As per datasheet, the resulting integration time follows the formula: (ATIME+1)*(ASTEP+1)*2.78 microseconds. My “Basic” UI exposed both parameters directly, but I want to use something more human-friendly for the “Standard” UI. I decided to keep ASTEP fixed at 3596. Per the formula (3596+1)2.78 microseconds = 9999.66 microseconds, or just a tiny bit less than 10 milliseconds. Keeping ASTEP fixed at 3596 means the ATIME range of 0-255 can dictate integration time anywhere from 10ms to 2560ms a.k.a. 2.56 seconds. This covers the entire time range I want for initial experiments. I may adjust this range in the future after playing with the sensor some more.
Read Time is Double Integration Time
Once I had set up the UI to adjust integration in 10ms increments, I took a few readings at various settings and noticed the actual time spent in
readAllChannels() is a lot longer than integration time. If I configure for 1 second (1000ms), I end up waiting two seconds. I added a bit of tracking code to my ESP32 Arduino sketch and verified it wasn’t just my imagination: actual read time is over double integration time.
This was puzzling until I remembered
readAllChannels() implementation: it configures AS7341 sensor multiplexor (SMUX) to read sensors F1-F4 plus clear and NIR, performs a read, then configures SMUX for sensors F5-F8 (keeping clear and NIR) and perform a second read. So, a one-second sensor integration time meant one second spent for F1-F4 and another second spent on F4-F8. Add in a few tens of milliseconds for processing and communication overhead, and we’ve explained the observation of a little bit over twice integration time.
This is something to keep in mind depending on sensor application. For example, if I want my browser UI to update once a second, I need to set integration time to be less than half a second.
UX Design Decision
Which led to the next question: Should my browser UI show the integration time, because that’s how I’m configuring the sensor? Or should it show double that time, because that is a better estimate of time I should expect to wait for a reading? I decided to go with double for my “Standard” UI: this is a user experience issue, so I should be faithful to what the user will experience.
Code for this project is publicly available on GitHub