Last active
May 30, 2020 17:03
-
-
Save en129/6c36d9b329c1476d989eabd99be99a82 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* waaaaaa_forM5StickC_modv2.ino | |
2020.05.31 | |
オリジナルとの差分は以下の通りです。 | |
・起動時に心拍数を0として表示 | |
・Bluetooth経由で心拍数をPCに送信可能 | |
・低消費電力化 1時間くらいは動作します | |
・心拍数の更新が早くなるようにするために脈のサンプル数を10→3に変更(HEARTPLUSE_SAMPLE_Nで変更可能) | |
・心拍数に移動平均をかけるようにした(サンプル数はHEART_RATE_AVG_Nで変更可能) | |
・心拍を検知したときにドットを表示する機能を追加 | |
・簡易的なバッテリー残量表示機能を追加 | |
*/ | |
#include <M5StickC.h> | |
#include "BluetoothSerial.h" | |
#define HEARTPLUSE_SAMPLE_N (3) //default:10 | |
#define USE_MOVING_AVERAGE (true) | |
#if USE_MOVING_AVERAGE | |
#define HEART_RATE_AVG_N (5)//default:10 | |
#endif | |
BluetoothSerial BTcom; | |
unsigned char counter; | |
unsigned long temp[21]; | |
unsigned long sub; | |
bool data_effect = true; | |
unsigned int heart_rate; | |
unsigned int heart_rate_avg; | |
unsigned int tmp_avg[HEART_RATE_AVG_N]={0}; | |
unsigned char tmp_avg_cnt = 0; | |
unsigned int tmp_avg_sum; | |
int hrm_output; | |
int hrm_output_tmp; | |
const int max_heartpluse_duty = 2000; | |
void setup() | |
{ | |
M5.begin(); | |
setCpuFrequencyMhz(80); | |
Serial.begin(9600); | |
//Bluetooth SPP起動 | |
BTcom.begin("waaaaaa_COMPORT"); | |
delay(500); | |
arrayInit(); | |
pinMode(33, INPUT); | |
//起動時に心拍数を0として表示 | |
M5.Lcd.setCursor(10, 10); | |
M5.Lcd.setRotation(1); | |
M5.Lcd.fillScreen(BLACK); | |
M5.Lcd.setTextSize(1); | |
M5.Lcd.setTextFont(7); | |
M5.Lcd.printf("%d", 0); | |
} | |
void loop() | |
{ | |
lcdBrightnessCtrl(); | |
dispBatteryCap(); | |
interrupt(); | |
delay(50); | |
} | |
//USB接続時は輝度最大、非接続時は輝度8に設定 | |
void lcdBrightnessCtrl(void) | |
{ | |
if(M5.Axp.GetVBusVoltage() < 4.5){ | |
M5.Axp.ScreenBreath(8); | |
} | |
else{ | |
M5.Axp.ScreenBreath(15); | |
} | |
} | |
//バッテリ上限電圧4.1V、下限電圧3.0Vとして残量を表示 | |
void dispBatteryCap(void) | |
{ | |
static uint8_t updateCount = 20*3; | |
float vbat; | |
int8_t SOC; | |
if(updateCount>=(20*3)) | |
{ | |
updateCount = 0; | |
M5.Lcd.setTextFont(1); | |
M5.Lcd.setTextSize(2); | |
M5.Lcd.fillRect(100, 65, 16*4, 16, BLACK); | |
M5.Lcd.setCursor(100, 65); | |
vbat = M5.Axp.GetVbatData() * 1.1 / 1000; // V | |
SOC = int8_t((100*(vbat - 3.0)) / (4.1-3.0)); | |
if(SOC > 100){ | |
SOC = 100; | |
}else if(SOC < 0){ | |
SOC = 0; | |
} | |
M5.Lcd.printf("%d %%", SOC); | |
} | |
else | |
{ | |
updateCount++; | |
} | |
} | |
void sum() | |
{ | |
if(data_effect) | |
{ | |
heart_rate = (60000*HEARTPLUSE_SAMPLE_N) / (temp[HEARTPLUSE_SAMPLE_N] - temp[0]); | |
M5.Lcd.setCursor(10, 10); | |
M5.Lcd.fillRect(10, 10, 48*2, 48, BLACK); | |
M5.Lcd.setTextFont(7); | |
M5.Lcd.setTextSize(1); | |
#if USE_MOVING_AVERAGE | |
tmp_avg[tmp_avg_cnt] = heart_rate; | |
if(tmp_avg_cnt >= HEART_RATE_AVG_N) | |
{ | |
tmp_avg_cnt = 0; | |
} | |
else | |
{ | |
tmp_avg_cnt++; | |
} | |
tmp_avg_sum = 0; | |
for(int i=0;i<HEART_RATE_AVG_N;i++) | |
{ | |
tmp_avg_sum += tmp_avg[i]; | |
} | |
heart_rate_avg = tmp_avg_sum/HEART_RATE_AVG_N; | |
Serial.println(heart_rate_avg); | |
BTcom.println(heart_rate_avg); | |
M5.Lcd.printf("%d\n", heart_rate_avg); | |
#else | |
Serial.println(heart_rate); | |
BTcom.println(heart_rate); | |
M5.Lcd.printf("%d\n", heart_rate); | |
#endif | |
} | |
data_effect = 1; | |
} | |
void interrupt() | |
{ | |
hrm_output_tmp = digitalRead(33); | |
if(hrm_output_tmp == 0) | |
{ | |
hrm_output = 0; | |
//ハートビート表示用ドット消し | |
M5.Lcd.fillRect(10, 65, 16, 16, BLACK); | |
return; | |
} | |
if(hrm_output_tmp == hrm_output) | |
{ | |
//ハートビート表示用ドット消し | |
M5.Lcd.fillRect(10, 65, 16, 16, BLACK); | |
return; | |
} | |
//ハートビート表示用ドット | |
M5.Lcd.setTextFont(1); | |
M5.Lcd.setTextSize(2); | |
M5.Lcd.setCursor(10, 65); | |
M5.Lcd.setTextColor(RED); | |
M5.Lcd.printf("."); | |
M5.Lcd.setTextColor(WHITE); | |
hrm_output = hrm_output_tmp; | |
temp[counter] = millis(); | |
//Serial.println(counter,DEC); | |
//Serial.println(temp[counter]); | |
switch(counter) | |
{ | |
case 0: | |
sub = temp[counter] - temp[HEARTPLUSE_SAMPLE_N]; | |
//Serial.println(sub); | |
break; | |
default: | |
sub = temp[counter] - temp[counter - 1]; | |
//Serial.println(sub); | |
break; | |
} | |
if(sub > max_heartpluse_duty) | |
{ | |
data_effect = 0; | |
counter = 0; | |
Serial.println("error - please restart device." ); | |
arrayInit(); | |
} | |
if ((counter == HEARTPLUSE_SAMPLE_N) && data_effect) | |
{ | |
counter = 0; | |
sum(); | |
} | |
else if((counter != HEARTPLUSE_SAMPLE_N) && data_effect) | |
{ | |
counter++; | |
} | |
else | |
{ | |
counter = 0; | |
data_effect = 1; | |
} | |
} | |
void arrayInit() | |
{ | |
for(unsigned char i = 0; i < HEARTPLUSE_SAMPLE_N; i++) | |
{ | |
temp[i] = 0; | |
} | |
temp[HEARTPLUSE_SAMPLE_N] = millis(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment