传感器
耳夹式心率传感器
控制部分
Geduino UNO
转接板
Base shield
执行机构
电机 6V
ws2812灯条
工作过程
Arduino上电后先执行校准程序,显示开机信号(彩虹慢速流动效果)
然后开始执行校准过程,累计20心跳间隔,计算出佩戴者的标准心跳。
绿色短闪一次后校准完毕。
开始监测佩戴者的心跳,如果心跳超过阈值,控制电机转动并显示彩虹快速流动。
校准和监测过程每次心跳都会触发一次红色短闪
更新下代码部分吧
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define STRIP_PIN 6
#define MODE_CALIBRATION 0
#define MODE_CALCULATE 1
const int time_max = 2000;//you can change it follow your system's request.
int mode = 0;
int MRRIGHT_THRESHOLD = 600;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, STRIP_PIN, NEO_GRB + NEO_KHZ800);
unsigned long data[4];
int tail = 0;
bool succeed = true;
unsigned long time_taking;
int BPM = 0;
unsigned long data_init[21];
int data_init_tail = 0;
void setup() {
strip.begin();
strip.setBrightness(30);
strip.show(); // Initialize all pixels to 'off'
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
digitalWrite(8, LOW);
digitalWrite(7, LOW);
Serial.begin(9600);
digitalWrite(8, HIGH);
delay(1000);
digitalWrite(8, LOW);
uint16_t i, j;
for(j=0; j<256*3; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(10);
}
Serial.println("begin measure!");
attachInterrupt(digitalPinToInterrupt(2), heartBeat, RISING);
}
void loop() {
// Some example procedures showing how to display to the pixels:
}
void MrRightLIGHT() {
detachInterrupt(digitalPinToInterrupt(2));
uint16_t i, j;
for(j=0; j<256*3; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delayMicroseconds(1000);
}
attachInterrupt(digitalPinToInterrupt(2), heartBeat, RISING);
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void colorWipeShort(int num){
for(int i=0; i< num; i++){
strip.setPixelColor(i, strip.Color(255,0,0));
strip.show();
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void MrRight(){
digitalWrite(7, HIGH);
MrRightLIGHT();
delay(5000);
digitalWrite(7,LOW);
succeed = true;
}
void heartBeatLight(unsigned long time_take){
colorWipe(strip.Color(0,0,0),0);
colorWipeShort(map(time_take, MRRIGHT_THRESHOLD, MRRIGHT_THRESHOLD+100, 10, 1));
delay(10);
}
void heartBeat(){
if(mode == MODE_CALCULATE){
data[tail] = millis();
Serial.println(tail,DEC);
if(tail == 0){
time_taking = data[tail] - data[3];
Serial.println(time_taking);
}else{
time_taking = data[tail] - data[tail - 1];
Serial.println(time_taking);
}
if(time_taking > time_max){
succeed = 0;
Serial.println("Heart rate measure error,test will restart!" );
for(unsigned char i=0;i < 4;i ++)
{
data[i]=0;
}
data[3]=millis();
}
if(succeed){
heartBeatLight(time_taking);
if(tail >= 3){
tail = 0;
Serial.print("heart rate is : ");
Serial.println(180000/(data[3]-data[0]));
if((data[1]-data[0] < MRRIGHT_THRESHOLD)&&(data[2]-data[1] < MRRIGHT_THRESHOLD)&&(data[3]-data[2] < MRRIGHT_THRESHOLD)){
MrRight();
}
}else{
tail++;
}
}else{
tail = 0;
succeed = 1;
}
}else{
Serial.print("calibrating now, step ");
Serial.println(data_init_tail);
data_init[data_init_tail] = millis();
data_init_tail++;
colorWipe(strip.Color(255,0,0),10);
colorWipe(strip.Color(0,0,0),0);
delay(10);
if(data_init_tail >= 21){
for(int i=0; i<20; i++){
data_init[i] = data_init[i+1]-data_init[i];
}
for(int i=0; i<20; i++){
for(int j=i+1; j<=20; j++){
if(data_init[i] > data_init[j]){
data_init[i] = data_init[i] ^ data_init[j];
data_init[j] = data_init[i] ^ data_init[j];
data_init[i] = data_init[i] ^ data_init[j];
}
}
}
Serial.print("data_init = ");
for(int i=0; i<21; i++){
Serial.print(data_init[i]);
Serial.print(",");
}
Serial.println();
MRRIGHT_THRESHOLD = (data_init[5]+data_init[4]+data_init[3]) / 3 - 50;
Serial.print("Threhold is : ");
Serial.println(MRRIGHT_THRESHOLD);
mode = MODE_CALCULATE;
colorWipe(strip.Color(0,255,0),10);
colorWipe(strip.Color(0,0,0),0);
}
}
}