BASIC4MCU | 질문게시판 | 심박수와 만보계
페이지 정보
작성자 이채희 작성일2019-06-12 21:38 조회4,291회 댓글0건본문
#include <TimerOne.h>
#include <TFT.h> //아두이노 LCD 라이브러리 포함
#include <SPI.h> //아두이노 SPI 라이브러리 포함#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); //블루투스의 Tx, Rx핀을 2번 3번핀으로 설정
#define MPU_SDA_PIN A4
#define MPU_SCL_PIN A5
#define cs 10 //CS or Chip Select
#define dc 9 //DC or A0, Data/Command
#define rst 8 //Reset#define PROCESSING_VISUALIZER 1
#define SERIAL_PLOTTER 2
#include "kproject_mpu6050.h"int pulsePin=A6,blinkPin=13,fadePin=5;
int fadeRate=0,initCounter=0,initBPM=0;
int prev_count = 0;
int sw1 = 7; //스위치volatile int BPM,difference;
volatile int Signal;
volatile int IBI=600;
volatile bool Pulse=false;
volatile bool QS=false;
static int outputType=SERIAL_PLOTTER;
int speaker=5;// TFT 클래스 생성
//CS와 DC, Reset만 추가하면 된다.
//하드웨어 SPI는 클래스 내부에서 자동 생성 됨.
TFT TFTscreen = TFT(cs, dc, rst);// 센서 값을 저장할 변수
char sensorPrintout[4];char str[100];
void setup()
{
pinMode(speaker, OUTPUT); //스피커pinMode(3,OUTPUT);
pinMode(blinkPin,OUTPUT);
pinMode(fadePin,OUTPUT);
Serial.begin(9600);
mySerial.begin(9600);
interruptSetup();
pinMode(sw1, INPUT_PULLUP); //스위치
//TFT 클래스 시작
TFTscreen.begin();// 검정색으로 초기화
TFTscreen.background(0, 0, 0);// 폰트 칼라 설정 (흰색)
TFTscreen.stroke(255, 255, 255);
// 폰트 크기를 2로 설정
TFTscreen.setTextSize(3);
// LCD에 글씨 표시
// "Sensor Value :
// 0, 0
TFTscreen.text("WALK :\n ", 0, 0);
// 폰트를 5로 설정
TFTscreen.setTextSize(3);TFTscreen.text("PULSE :\n ", 0, 50);
// 폰트를 5로 설정
TFTscreen.setTextSize(3);Serial.begin(9600);
InitMPU6050();
if ( GetDeviceID() != 0x68 )
{
Serial.println("#############################");
Serial.println("INIT FAIL!");
Serial.println("#############################");
while (1);
}
delay(10);
Timer1.initialize(50000);
prev_count = 0;
}
int index;
unsigned long count = 0; // 1보에 2씩 증가 걸음 수는 count/2임.
int prev_val;
unsigned long last_millis;
void loop()
{if(BPM<40){ //스피커
digitalWrite(5,800); //스피커
delay(1000); //스피커
} //스피커
else{ //스피커
digitalWrite(5,0); //스피커
} //스피커if(digitalRead(sw1)==LOW){ //스위치
count=0;} //스위치
// A0의 값을 받아와서 문자열 변수에 저장.
// String sensorVal = String(analogRead(A0));sprintf(sensorPrintout, "%d", count);
sprintf(str, "%d", BPM);// 읽어온 센서 문자열 변수를 가지고
// 각각의 캐릭터(char) 변수에 저장
// ex>
// sensorVal = "1234"
// sensorPrintOut[0] = 1
// sensorPrintOut[1] = 2
// sensorPrintOut[2] = 3
// sensorPrintOut[3] = 4
// sensorVal.toCharArray(sensorPrintout, 4);// 흰색으로 변경
TFTscreen.stroke(255, 255, 255);
// LCD에 X : 0, Y : 20 위치에 글씨 표시
TFTscreen.text(sensorPrintout, 0, 20);
TFTscreen.text(str, 0, 80);
// 250ms 기다림.
delay(250);
// 지금 쓴 글씨를 제거하기 위해 색을 검정색으로 변경
TFTscreen.stroke(0, 0, 0);
// 동일한 글씨를 검정색으로 표시하기 때문에 지워짐.
TFTscreen.text(sensorPrintout, 0, 20);
TFTscreen.text(str, 0, 80);//다시 loop함수 처음으로 이동
int ax, ay, az, gx, gy, gz;
ax = GetData(ACCEL_XOUT_H);
ay = GetData(ACCEL_YOUT_H);
az = GetData(ACCEL_ZOUT_H);
gx = GetData(GYRO_XOUT_H);
gy = GetData(GYRO_YOUT_H);
gz = GetData(GYRO_ZOUT_H);
ax = ax / 1000;
ay = ay / 1000;
az = az / 1000;
int val = ax * ax + ay * ay + az * az;
if ( ( val > 500 ) && ( prev_val <= 500 ) )
{
if ( ( millis() - last_millis ) > 300 ) // 0.3초 미만 간격으로 걸음이 추가되는 경우는 실제 걸음이 아니라 센서의 흔들림 및 노이즈일 가능성이 많음.
{
count++;
last_millis = millis();
}
}
prev_val = val;
// Serial.println(val);if ( prev_count != count )
{
Serial.println(count / 2);
prev_count = count;
}serialOutput();
delay(1000);
}void ledFadeToBeat(){
fadeRate-=15; fadeRate=constrain(fadeRate,0,255); analogWrite(fadePin,fadeRate);
}
//
void serialOutput(){
switch(outputType){
case PROCESSING_VISUALIZER: sprintf(str,"Signal: %d\r\n",Signal); Serial.print(str); mySerial.print(str); break;
case SERIAL_PLOTTER: sprintf(str,"%d\r\n",BPM); Serial.print(str); mySerial.print(str); break;
}
}
//
void serialOutputWhenBeatHappens(){
switch(outputType){
case PROCESSING_VISUALIZER: sprintf(str,"BPM: %dd\r\n",BPM); Serial.print(str); mySerial.print(str); break;
}
}
//
volatile int rate[10];
volatile unsigned long sampleCounter=0;
volatile unsigned long lastBeatTime=0;
volatile int P=512;
volatile int T=512;
volatile int thresh=530;
volatile int amp=0;
volatile boolean firstBeat=true;
volatile boolean secondBeat=false;
//
void interruptSetup(){
TCCR2A=0x02; TCCR2B=0x06; OCR2A=0X7C; TIMSK2=0x02; sei();
}
//
ISR(TIMER2_COMPA_vect){
cli();
Signal=analogRead(pulsePin);
sampleCounter+=2;
int N=sampleCounter-lastBeatTime;
//
if(Signal<thresh&&N>(IBI/5)*3){ if(Signal<T)T=Signal; }
//
if(Signal>thresh&&Signal>P){ P=Signal; }
//
if(N>250){
if((Signal>thresh)&&(Pulse==false)&&(N>(IBI/5)*3)){
Pulse=true;
digitalWrite(blinkPin,HIGH);
IBI=sampleCounter-lastBeatTime;
lastBeatTime=sampleCounter;
//
if(secondBeat){ secondBeat=false; for(int i=0; i<=9; i++)rate[i]=IBI; }
//
if(firstBeat){ firstBeat=false; secondBeat=true; sei(); return; }
//
word runningTotal=0;
for(int i=0; i<=8; i++){ rate[i]=rate[i+1]; runningTotal+=rate[i]; }
rate[9]=IBI;
runningTotal+=rate[9]; runningTotal/=10;
BPM=60000/runningTotal;
//
if(initCounter==0){ initBPM=BPM; initCounter=1; }
//
difference=initBPM-BPM;
QS=true;
}
}
if(Signal<thresh&&Pulse==true){
digitalWrite(blinkPin,LOW); Pulse=false; amp=P-T; thresh=amp/2+T; P=thresh; T=thresh;
}
//
if(N>2500){
thresh=530; P=512; T=512; lastBeatTime=sampleCounter; firstBeat=true; secondBeat=false;
}
sei();
}
위 코드에서 loop안에 delay(1000); 을 넣으면 앱 인벤터에서 블루투스로 받는 값이 한개씩 잘 뜨지만 만보계 count가 잘 올라가지 않습니다.
만보계가 잘 측정되도록 delay(1000); 을 빼면 앱 인벤터에서 블루투스로 받는 값이 한개씩 뜨지않고 여러개가 한줄로 뜨고 만보계 count가 잘 올라갑니다.
만보계도 잘 측정이되고 블루투스로 값을 한개씩 잘 받으려면 어떻게 해야하나요...
댓글 0
조회수 4,291등록된 댓글이 없습니다.