Arduino之个人健康助理——简易智能药盒系列2
OLED顯示
1.所需硬件
脈搏傳感器
OLED模塊
Arduino主板
2.連接方式
脈搏傳感器與主板連接
s — A0
+— 5V
-— GND
OLED模塊與主板連接
GND—GND
VCC—3.3V或5V
SCL—A5
SDA—A4
3.基本思路
脈搏傳感器原理
首先,需要簡要了解一下脈搏傳感器大致原理。
脈搏傳感器能把脈搏跳動(dòng)壓力轉(zhuǎn)化為電信號輸出(以電壓形式)。基于這種原理,就可以利用電壓值的變化計(jì)算脈搏跳動(dòng)數(shù)。
計(jì)算脈搏數(shù)的思路
如圖,跳離直線y=v0的點(diǎn)A1,A2,A3可表示為脈搏跳動(dòng)的點(diǎn)(脈搏跳動(dòng),輸出電壓增大),而直線y=v0上的其余點(diǎn)則為脈搏平靜時(shí)的點(diǎn)。如果可以獲得每次跳動(dòng)時(shí)的時(shí)刻點(diǎn)t1,t2,t3,從而求得Δt,就可利用 跳動(dòng)次數(shù)=總時(shí)間/時(shí)間間隔 的公式求得每段Δt上的平均脈搏數(shù)。
繪制心率圖的思路
因?yàn)槊}搏的跳動(dòng)導(dǎo)致電壓的變化,于是就可以利用電壓的變化來繪制折線圖(先繪點(diǎn),再連線)。將某一點(diǎn)的電壓值以一定比例縮放為合適的值,作為該點(diǎn)的縱坐標(biāo),對應(yīng)該點(diǎn)的橫坐標(biāo)(橫坐標(biāo)對應(yīng)時(shí)刻點(diǎn))。隨著時(shí)間變化,點(diǎn)的橫坐標(biāo)向前推移,縱坐標(biāo)隨之變化。此時(shí)再將點(diǎn)與點(diǎn)之間連上直線,即可繪制出心率折線圖。
4.代碼
聲明
#include <Adafruit_SSD1306.h> //調(diào)用一個(gè)庫文件#define OLED_Address 0x3C //用OLED_Address取代0x3C//0x3C——16進(jìn)制數(shù)(通訊地址) #define UpperThreshold 550 //用UpperThreshold取代550 #define LowerThreshold 500 //用LowerThreshold取代500 //UpperThreshold,LowerThreshold為引腳輸出模擬電壓值的閾值 Adafruit_SSD1306 oled; //定義變量名為oled定義變量
//定義變量 int x=0; //當(dāng)前點(diǎn)的橫坐標(biāo) int lastx=0; //上一個(gè)點(diǎn)的橫坐標(biāo) int lasty=0; //上一個(gè)點(diǎn)的縱坐標(biāo) int LastTime=0; //上一次測量的毫秒數(shù) bool BPMTiming=false; //LastTime是否為正確的脈搏起始計(jì)時(shí)點(diǎn) bool BeatComplete=false; //一次跳動(dòng)是否完成=是否可以開始計(jì)算下一次跳動(dòng)(取決于起始計(jì)時(shí)點(diǎn)是否正確和是否為跳動(dòng)間隔期) int BPM=0; //脈搏跳動(dòng)數(shù)setup函數(shù)
void setup() {oled.begin(SSD1306_SWITCHCAPVCC, OLED_Address); //初始化oled屏幕的通訊地址為OLED_Address(也就是0x3C)oled.clearDisplay(); //oled清空顯示oled.setTextSize(2); //設(shè)置oled顯示字體為2號字體 }loop函數(shù)
void loop() {if(x>127) //若屏幕顯示已滿,清空再來{oled.clearDisplay(); //oled清空顯示x=0; //當(dāng)前點(diǎn)橫坐標(biāo)賦值為0lastx=x; //上一個(gè)點(diǎn)橫坐標(biāo)也為賦值為0}int value=analogRead(0); //analogRead函數(shù)用于讀取引腳的模擬電壓值,參數(shù)0表示所有獲取電壓值的引腳為A0,返回值為引腳的模擬量電壓值oled.setTextColor(WHITE); //oled顯示字體為白色int y=20-(value/45); //當(dāng)前點(diǎn)的縱坐標(biāo)(取決于引腳獲取的電壓值)oled.writeLine(lastx,lasty,x,y,WHITE); //從上一個(gè)點(diǎn)到當(dāng)前點(diǎn)畫線lasty=y; //將當(dāng)前點(diǎn)坐標(biāo)賦給上一個(gè)點(diǎn),當(dāng)前點(diǎn)變成上一個(gè)點(diǎn)lastx=x;//計(jì)算BMP if(value>UpperThreshold) //如果跳動(dòng){if(BeatComplete) //如果上一次跳動(dòng)完成,可以開始計(jì)算下一次跳動(dòng){ BPM=millis()-LastTime; //millis函數(shù)返回的Arduino板開始運(yùn)行當(dāng)前程序時(shí)的毫秒數(shù),兩次測量中間間隔的毫秒數(shù)BPM=int(60/(float(BPM)/1000)); //計(jì)算BPM(跳動(dòng)數(shù)=總時(shí)間/跳動(dòng)時(shí)間間隔)BPMTiming=false; //該次跳動(dòng)的BPM值已經(jīng)計(jì)算,要進(jìn)入下一次BPM計(jì)算,而起始計(jì)時(shí)點(diǎn)還為原來的起始計(jì)時(shí)點(diǎn)BeatComplete=false; //起始計(jì)時(shí)點(diǎn)錯(cuò)誤,跳動(dòng)未完成}if(BPMTiming==false) //將起始計(jì)時(shí)點(diǎn)變?yōu)檎_起始計(jì)時(shí)點(diǎn){LastTime=millis(); //將現(xiàn)在的毫秒數(shù)賦變?yōu)樯弦淮蔚暮撩霐?shù) BPMTiming=true; }}if((value<LowerThreshold)&(BPMTiming)) //如果起始計(jì)時(shí)點(diǎn)正確且進(jìn)入跳動(dòng)間隔期BeatComplete=true; //一次跳動(dòng)完成//顯示BMP值oled.writeFillRect(0,19,128,20,BLACK); //畫一個(gè)填充矩形 oled.setCursor(0,19); //設(shè)置oled內(nèi)容顯示的位置oled.print(BPM); //設(shè)置oled顯示的內(nèi)容oled.print(" BPM");oled.display(); //設(shè)置完成,更新顯示內(nèi)容x++; //橫坐標(biāo)+1,進(jìn)入下一個(gè)循環(huán) }5.最終效果
最終OLED模塊上顯示出心率折線圖和脈搏數(shù)(BPM)。
PS: 代碼小白初次嘗試,還請大佬們多多包涵,多多指點(diǎn)。
總結(jié)
以上是生活随笔為你收集整理的Arduino之个人健康助理——简易智能药盒系列2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我眼中的人工智能(2017年初)
- 下一篇: 人在死去的一瞬间是否会害怕,这些回答够真