Pulspletysmografi - (IR-pulsmätare) (4 / 5 steg)
Steg 4: Arduino programvara
Att komma igång behöver du GFX och ST7735 Arduino biblioteken från Adafruit. Du hittar dem här (tack Limor).
GFX bibliotek
https://github.com/adafruit/Adafruit-gfx-Library
ST7735 bibliotek
https://github.com/adafruit/Adafruit-ST7735-Library
Inte säker på hur man installerar en Arduino bibliotek? Sedan gå här för fullständiga instruktioner;
https://www.Arduino.cc/en/guide/libraries
Hur det fungerar
Vid start, programvaran vänder på IR-Led och anger att användaren av produkten krävs och kommer att inledas i 10 sekunder. Detta ger användartid placera sitt finger i sensorn.
Under allt programvaran läser utdata för att ADC för 10000 gånger, pausa kort för 1mS per läst. Detta används för att registrera de högsta och lägsta gränserna av den råa samplade signalen.
Dessa högsta och lägsta värden används för att bestämma dynamiska triggerpunkter att upptäcka en kraftigt stigande kanten i hjärtrytm aktivera tidpunkten för perioden mellan pulser och därmed beräkna BPM.
Den låga trigger introducerar hysteres och är nödvändiga för att förhindra åter utlösa på grund av hög samplingsfrekvens som visar ovan.
Hög nivå trigger point iPulseTriggerLevelHigh är 90% av toppen (gröna stjärnor i diagrammen ovan) och låg nivå trigger-punkt är iPulseTiggerLevelLow är 70% av toppen (blå stjärnor i diagrammen ovan).
Programvaran kommer då in en oändlig loop signal provtagning efter en förfluten tid dikteras av ulElapsedTime, ungefärligt 1mS eller 1000Hz. Detta kan justeras genom att variera #define SAMPLE_PERIOD_uS.
Förfluten tid förseningen är inte ett blockerande samtal så andra bakgrunden uppgiften kan utföras vid behov.
När ett prov av hjärtat slå läses från ADC värdet skalas för att passa fönstret vågform. Denna skala är bara en direkt 0-5v = > 0-1023 = > 0-100.
Jag utelämnats avsiktligt automatisk skalning för fönstret vågform som jag hittade när jag tagit den, vågformen ganska mycket försedda fönstret varje gång, som du förväntar. Gör så att du förlorat en hel del viktig information, till exempel när mina fingrar var kallt eller dåligt placerade i sensorn och följaktligen pulsen utgång nivå var låg. Det kändes det mer användbart att hålla denna information närvarande. Dock gav jag en variabel fAmplificationFactor (linje 171, inställd på 2.1) som kan användas för att skala din signal om dina färdigheter i elektronik och konstruktion ger en mindre känslig signal än vad jag kan uppnå.
Koden avgör sedan om detta är en stigande kant (se diagram ovan för logik). Om det är någon fallande kant har upptäckts tiden lagras i ulPulseCurrentTime. Men om det är och en fallande kant har upptäckt detta innebär att den totala träningstiden är perioden mellan pulser.
Programvaran sedan beräknar BPM (som i diagrammen ovan) och justerar för en sjal i funktionsanropet millis() om det behövs.
Denna nya puls lagras sekventiellt i den rullande fönster buffer array lBPMArray [] och genomsnittligt beräknats över alla prover. Den nya beräknade BPM är jämfört med den gamla BPM. Om det är skillnad på uppdateras displayen med det nya värdet. Vilket minskar TFT uppdatering overhead.
Under utvecklingen av koden jag märkte att det inte var möjligt att optimera en enda avsökningshastighet av TFT för BPMs sträcker sig 50... 200. Så ändras iSampleCountMax dynamiskt när pulsen överstiger 100BPM så att skärmen inte blir för trångt och formen på pulsen är fortfarande tydlig.
Den programvara sedan klipp vågformen om av någon anledning är det tog stora för visning och uppdaterar skärmen med det senaste ADC provet och tomter i fönstret vågform.
Tidigare plottade värden först tas bort genom att skriva en lodrät svart linje före handlingen ställning "i farten".
Loopen upprepas.
Rullande medelvärde
Puls beräknas genom att ta en kontinuerligt uppdaterad rullande medelvärde av perioder mellan pulser. Längden på det flytande medelvärdet kan justeras genom att ändra värdet för #define MAX_BPM_ARRAY_SIZE. Ju längre gör du det desto långsammare uppdateringar, men desto bättre tillnärmning (förutsatt att fingret hålls stadigt i sensorn).
För att frön genomsnittet med ett startvärde är array lBPMArray [] pre-lastat med en puls på 60BPM på starta upp.
.
En kopia av koden har inkluderats nedan.