當我試 “MAX30102心率計模块” 時,我用嘅 “SparkFun_MAX3010x_Library” 裏面有個 example 用到 Arduino IDE2 新加嘅 Serial Plotter 功能,可以 plot 紅外線穿透手指嘅能力而測出心率,我覺得好精對好有用,因為一般用 web plot chart 例如 Highcharts 最快只限一秒一個数,用 canvas 嘅 Chart.js 會快啲可以去倒大約 10Hz 但小好多野 set,再快嘅話就要插 com port 快到 1ms 一個数都得。用法好簡單,如果只有一個数,用 Serial.println(value);
放喺 loop 就可以,如果多過一個数,最簡單係用 CSV format 用 comma 隔開幾個数就得。之後可以喺 UI parse 或者柬睇邊個数。

既然預插線用 com port 嘅話,我再上網預吓有無類似嘅 alternative,發現有人介紹 CoolTerm,咁就可以避免開 Arduino IDE2 咁麻煩,要 plot chart 時淨係開佢,一樣都識睇 CSV,可以 parse 或者柬睇邊個数,而且多左可以 zoom x 同 zoom,自訂 icon 方便黚,最重要係可以 save 低 capture 番黎嘅 CSV。

save 低嘅 CSV 可以放上 Google Sheet 或者自己寫 Highcharts 讀佢 plot 番靚個 chart,但要加番 timestamp 個 column 解決每行嘅次序先後上下掉乱嘅問題,而 javascript 識讀 1ms 嘅 timestamp,要用 Arduino 砌好個 CSV format,出黎每行係 1751378429774,26853,10328
咁図,會牽涉到點用 NTP time server 攞 internet 時間,最簡單係用 “Time Library“。
#include <TimeLib.h> // time for ntp const uint8_t TIMEZONE = 8; struct tm time_tm; time_t time_ntp = 0; uint64_t timestamp_ms(); String pad2digit(uint8_t number); void fn_ntp_sync(uint8_t timeZone = TIMEZONE); setup(){ // ...... after wifi connected fn_ntp_sync(); } loop(){ Serial.print(timestamp_ms()); Serial.print(","); Serial.print(ina_power); //plot chart data1 Serial.print(","); Serial.println(ina_voltage); //plot chart data2 } //******************************************************************************************* // functions //******************************************************************************************* void fn_ntp_sync(int timeZone) { configTime(0, 0, "pool.ntp.org", "asia.pool.ntp.org"); uint32_t beginWait = millis(); while ((millis() - beginWait < 1000) && (time_ntp < 16 * 60 * 60)) { delay(200); time_ntp = time(nullptr); if (time_ntp > 16 * 60 * 60) { time_ntp = time_ntp + 1 + (timeZone * 60 * 60); setTime(time_ntp); gmtime_r(&time_ntp, &time_tm); Serial.print("IP: "); Serial.println(WiFi.localIP()); Serial.print("Time: "); Serial.println(pad2digit(hour()) + ":" + pad2digit(minute()) + ":" + pad2digit(second())); } } } uint64_t timestamp_ms() { return (uint64_t)now() * 1000ULL + (millis() % 1000); } String pad2digit(uint8_t number) { if (number < 10) { String s = String(number); return '0' + s; } else { String s = String(number); return s; } }
Reference: