reduced message bytes for BLE

Dependencies:   BLE_API mbed nRF51822

Fork of Inp_Fiber_Logo_FOTA by inupathy

Committer:
ayaando
Date:
Fri Jul 07 02:42:28 2017 +0000
Revision:
10:867018503cd3
Parent:
9:4363af5affba
Child:
11:8301a86310c9
???????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ayaando 10:867018503cd3 1 // 20170703 BRIGHTNESS_MAXを100に変更
ayaando 10:867018503cd3 2 // シリアル通信のプロトコルを、文字列→バイト列に変更
ayaando 7:4118d5a717bc 3 // 20170619 DeviceInformationのSerialNumberにIND+Macアドレスを適用し、DEVICENAMEはINUPATHYとした
jojisdogakane 6:35f536162183 4 // 20170617 ストレス値を"R"(relax)から"S"(stress)に変更し、(1.0 - relaxRatio)を送るよう改変
jojisdogakane 6:35f536162183 5 // 20170617 輝度調整の方法をrgbの合計値を基準にするように調整した。
jojisdogakane 6:35f536162183 6
jojisdogakane 0:2f6112d75752 7 #include "mbed.h"
jojisdogakane 0:2f6112d75752 8 #include "neopixel.h"
jojisdogakane 0:2f6112d75752 9 #include "nrf_soc.h"
jojisdogakane 0:2f6112d75752 10 #include "common.h"
jojisdogakane 0:2f6112d75752 11 #include "ble/BLE.h"
jojisdogakane 0:2f6112d75752 12 #include "ble/services/HeartRateService.h"
jojisdogakane 0:2f6112d75752 13 #include "ble/services/BatteryService.h"
jojisdogakane 0:2f6112d75752 14 #include "ble/services/DeviceInformationService.h"
jojisdogakane 0:2f6112d75752 15 #include "UARTService.h"
ayaando 1:f28bdfaf3005 16 #include "ble_gap.h"
ayaando 2:221df6d014f5 17 #include "ble/services/DFUService.h" // ★OTA用
ayaando 2:221df6d014f5 18
jojisdogakane 0:2f6112d75752 19 #define RAINBOW_RATIO 1
jojisdogakane 0:2f6112d75752 20 #define RCFILTER 0.9
jojisdogakane 0:2f6112d75752 21 #define RCFILTER2 0.9
jojisdogakane 4:a0150e0f285b 22 #define NEOPIXEL_COUNT 6
jojisdogakane 0:2f6112d75752 23 #define MIN_LIGHT 0
jojisdogakane 0:2f6112d75752 24 #define PNNX_FACTOR 0.1 // 0.06
jojisdogakane 4:a0150e0f285b 25 #define MAXARRAY 15 //15 // 心拍平均値計算用の配列サイズ //20
jojisdogakane 4:a0150e0f285b 26 #define MAXHRVARRAY 10 //30 // 脈間ゆらぎ平均値計算用の配列サイズ
jojisdogakane 0:2f6112d75752 27 #define MIN_INTERVAL 200
jojisdogakane 0:2f6112d75752 28 #define INTERVAL 10 // Loopの間隔 通常時推奨1 通信時推奨20
jojisdogakane 0:2f6112d75752 29 #define MAXCOLORARRAY 1 //(MIN_INTERVAL / INTERVAL) // 色平均値計算用の配列サイズ (MIN_INTERVAL / 7)
jojisdogakane 0:2f6112d75752 30 #define MAXCONARRAY 10
jojisdogakane 0:2f6112d75752 31 #define MAXSTRESSARRAY 3
jojisdogakane 6:35f536162183 32
ayaando 8:1ad3ab5148bc 33 #define BRIGHTNESS_MAX 100 // RGBLED1セットのpwm合計値の上限 ws2812b型のneopixelが6個の場合、150を超えた値にするとセンサーが誤作動する
jojisdogakane 6:35f536162183 34
jojisdogakane 6:35f536162183 35 #define DIM_LED ((float)(BRIGHTNESS_MAX) / (float)(255)) // R, G, Bそれぞれのpwm値がBRIGHTNESS_MAXを超えない様にする制限
jojisdogakane 6:35f536162183 36
jojisdogakane 0:2f6112d75752 37
jojisdogakane 0:2f6112d75752 38 // 心拍数の最低値、最高値
jojisdogakane 0:2f6112d75752 39 // 人間の場合は60~150、標準80
jojisdogakane 0:2f6112d75752 40 // 犬の場合は40~200、標準60
jojisdogakane 0:2f6112d75752 41 #define HR_MIN 40
jojisdogakane 0:2f6112d75752 42 #define HR_MAX 150
jojisdogakane 0:2f6112d75752 43
jojisdogakane 0:2f6112d75752 44 #define RELAX_RATIO_MIN 0.6
jojisdogakane 0:2f6112d75752 45
jojisdogakane 0:2f6112d75752 46 // ラジアンを度に変換する.
jojisdogakane 0:2f6112d75752 47 #define RadianToDegree(radian) ((180 / 3.14159) * (radian))
jojisdogakane 0:2f6112d75752 48
jojisdogakane 0:2f6112d75752 49 // 度をラジアンに変換する.
jojisdogakane 0:2f6112d75752 50 #define DegreeToRadian(degree) ((3.14159 / 180) * (degree))
jojisdogakane 0:2f6112d75752 51
jojisdogakane 0:2f6112d75752 52 // 色の識別値設定(ピンではない)
jojisdogakane 0:2f6112d75752 53 #define RED 0
jojisdogakane 0:2f6112d75752 54 #define BLUE 1
jojisdogakane 0:2f6112d75752 55 #define GREEN 2
jojisdogakane 0:2f6112d75752 56
jojisdogakane 0:2f6112d75752 57 #define SHOW_EXCITE 1
jojisdogakane 0:2f6112d75752 58 #define SHOW_HAPPY 2
jojisdogakane 0:2f6112d75752 59 #define SHOW_CONCENTRATION 4
jojisdogakane 0:2f6112d75752 60
jojisdogakane 0:2f6112d75752 61
jojisdogakane 0:2f6112d75752 62 BLE ble;
ayaando 2:221df6d014f5 63 DFUService *dfuService; // ★OTA用
jojisdogakane 0:2f6112d75752 64
jojisdogakane 0:2f6112d75752 65 AnalogIn HRSigIn(P0_4);
jojisdogakane 0:2f6112d75752 66
jojisdogakane 0:2f6112d75752 67
ayaando 7:4118d5a717bc 68 const static char DEVICE_NAME[] = "INUPATHY";
jojisdogakane 0:2f6112d75752 69 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
jojisdogakane 0:2f6112d75752 70 GattService::UUID_DEVICE_INFORMATION_SERVICE};
jojisdogakane 0:2f6112d75752 71 static volatile bool triggerSensorPolling = true;
jojisdogakane 0:2f6112d75752 72
jojisdogakane 4:a0150e0f285b 73 short ColorArrayR[NEOPIXEL_COUNT];
jojisdogakane 4:a0150e0f285b 74 short ColorArrayG[NEOPIXEL_COUNT];
jojisdogakane 4:a0150e0f285b 75 short ColorArrayB[NEOPIXEL_COUNT];
jojisdogakane 0:2f6112d75752 76
jojisdogakane 4:a0150e0f285b 77 short TargetColorArrayR[NEOPIXEL_COUNT];
jojisdogakane 4:a0150e0f285b 78 short TargetColorArrayG[NEOPIXEL_COUNT];
jojisdogakane 4:a0150e0f285b 79 short TargetColorArrayB[NEOPIXEL_COUNT];
jojisdogakane 0:2f6112d75752 80
jojisdogakane 0:2f6112d75752 81
jojisdogakane 4:a0150e0f285b 82 #define NEOPIXEL_COMMANDLEN ((NEOPIXEL_COUNT * 3) + 1 + 1)
jojisdogakane 0:2f6112d75752 83
jojisdogakane 0:2f6112d75752 84
jojisdogakane 0:2f6112d75752 85 unsigned long pixelStartCounter;
jojisdogakane 0:2f6112d75752 86
jojisdogakane 0:2f6112d75752 87 int mainCurrentPixel = 0;
jojisdogakane 0:2f6112d75752 88 int mainPrevPixel = 0;
jojisdogakane 0:2f6112d75752 89 int mainPixelLightCount;
jojisdogakane 0:2f6112d75752 90 int mainPixelStep = 0;
jojisdogakane 0:2f6112d75752 91 int mainStepsRemain = 0;
jojisdogakane 0:2f6112d75752 92
jojisdogakane 0:2f6112d75752 93 unsigned long currentmillis = 0;
jojisdogakane 0:2f6112d75752 94 unsigned long prevmillis = 0;
jojisdogakane 0:2f6112d75752 95 unsigned long intervalmillis = 0;
jojisdogakane 0:2f6112d75752 96 unsigned long prevIntervalmillis = 0;
jojisdogakane 0:2f6112d75752 97 unsigned long intervalmillisArray[MAXARRAY] = {1000};
jojisdogakane 4:a0150e0f285b 98 unsigned long intervalmillisHRVArray[MAXHRVARRAY] = {1000};
jojisdogakane 0:2f6112d75752 99 float conArray[MAXCONARRAY] = {0.5};
jojisdogakane 0:2f6112d75752 100
jojisdogakane 0:2f6112d75752 101 //float stressArray[MAXSTRESSARRAY] = {0.5};
jojisdogakane 0:2f6112d75752 102
jojisdogakane 0:2f6112d75752 103 float prevFilteredAngle = 0.5;
jojisdogakane 0:2f6112d75752 104 float happyRatio = 0.0;
jojisdogakane 4:a0150e0f285b 105 float happyRatioNow = 0.0;
jojisdogakane 0:2f6112d75752 106 float prevRelaxRatio = 1.0;
jojisdogakane 0:2f6112d75752 107 float prevFilteredDistRatio = 0.0;
jojisdogakane 4:a0150e0f285b 108
jojisdogakane 4:a0150e0f285b 109 #define HR_THRESHOLD 2
jojisdogakane 6:35f536162183 110 int HRThreshold[] = {100, 1000};
jojisdogakane 4:a0150e0f285b 111
jojisdogakane 0:2f6112d75752 112
jojisdogakane 4:a0150e0f285b 113 // 気分判定フラグ
jojisdogakane 4:a0150e0f285b 114 #define IS_RELAX 0
jojisdogakane 4:a0150e0f285b 115 #define IS_EXCITED 1
jojisdogakane 4:a0150e0f285b 116 #define IS_HAPPY 2
jojisdogakane 4:a0150e0f285b 117 #define IS_INTERESTED 3
jojisdogakane 4:a0150e0f285b 118 #define IS_STRESSED 4 // IS_STRESSEDはMOODの個数としても扱うので最後の番号にすること
jojisdogakane 4:a0150e0f285b 119 #define MOOD_COUNT IS_STRESSED + 1
jojisdogakane 0:2f6112d75752 120
jojisdogakane 4:a0150e0f285b 121 // 気分判定係数
jojisdogakane 4:a0150e0f285b 122 #define CONMARGIN 0.85
jojisdogakane 4:a0150e0f285b 123 #define RELAXMARGIN 0.2
jojisdogakane 4:a0150e0f285b 124 #define HAPPYMARGIN 0.225
jojisdogakane 9:4363af5affba 125 #define EXCITEMARGIN 1.15
jojisdogakane 9:4363af5affba 126
jojisdogakane 9:4363af5affba 127 #define HRM_AVERAGE_COUNT 100
jojisdogakane 9:4363af5affba 128 short HRM_Average[HRM_AVERAGE_COUNT] = {70};
jojisdogakane 0:2f6112d75752 129
jojisdogakane 4:a0150e0f285b 130 // 気分判定フラグを索引にする
jojisdogakane 4:a0150e0f285b 131 int MoodColorR[NEOPIXEL_COUNT][MOOD_COUNT];
jojisdogakane 4:a0150e0f285b 132 int MoodColorG[NEOPIXEL_COUNT][MOOD_COUNT];
jojisdogakane 4:a0150e0f285b 133 int MoodColorB[NEOPIXEL_COUNT][MOOD_COUNT];
jojisdogakane 4:a0150e0f285b 134
jojisdogakane 0:2f6112d75752 135
jojisdogakane 4:a0150e0f285b 136 unsigned char RainbowR[] = { 50, 50, 50, 127, 200, 255};
jojisdogakane 4:a0150e0f285b 137 unsigned char RainbowG[] = { 50, 127, 255, 127, 100, 50};
jojisdogakane 4:a0150e0f285b 138 unsigned char RainbowB[] = {255, 127, 50, 50, 50, 50};
jojisdogakane 4:a0150e0f285b 139
jojisdogakane 6:35f536162183 140 unsigned char HappyR[] = { 50, 50, 50, 127, 200, 255};
jojisdogakane 6:35f536162183 141 unsigned char HappyG[] = { 50, 127, 255, 127, 100, 50};
jojisdogakane 6:35f536162183 142 unsigned char HappyB[] = {255, 127, 50, 50, 50, 50};
jojisdogakane 6:35f536162183 143
jojisdogakane 6:35f536162183 144 unsigned char RelaxR[] = { 0, 0, 0, 0, 0, 0};
jojisdogakane 4:a0150e0f285b 145 unsigned char RelaxG[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 6:35f536162183 146 unsigned char RelaxB[] = { 0, 0, 0, 0, 0, 0};
jojisdogakane 0:2f6112d75752 147
jojisdogakane 4:a0150e0f285b 148 unsigned char ExciteR[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 4:a0150e0f285b 149 unsigned char ExciteG[] = {100, 100, 100, 100, 100, 100};
jojisdogakane 6:35f536162183 150 unsigned char ExciteB[] = { 0, 0, 0, 0, 0, 0};
jojisdogakane 6:35f536162183 151
jojisdogakane 6:35f536162183 152 unsigned char StressR[] = {100, 100, 100, 100, 100, 100};
jojisdogakane 4:a0150e0f285b 153 unsigned char StressG[] = { 0, 0, 0, 0, 0, 0};
jojisdogakane 6:35f536162183 154 unsigned char StressB[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 4:a0150e0f285b 155
jojisdogakane 4:a0150e0f285b 156 unsigned char InterestR[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 4:a0150e0f285b 157 unsigned char InterestG[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 6:35f536162183 158 unsigned char InterestB[] = {255, 255, 255, 255, 255, 255};
jojisdogakane 0:2f6112d75752 159
jojisdogakane 0:2f6112d75752 160 float rainbowOffset = 0.0;
jojisdogakane 0:2f6112d75752 161
jojisdogakane 0:2f6112d75752 162 bool bConcentration;
jojisdogakane 0:2f6112d75752 163 unsigned long loopCounter = 0;
jojisdogakane 0:2f6112d75752 164 int lightPos = 1;
jojisdogakane 0:2f6112d75752 165 int prevLightPos = 1;
jojisdogakane 0:2f6112d75752 166
jojisdogakane 0:2f6112d75752 167 double relaxRatio = 0.0;
jojisdogakane 0:2f6112d75752 168 float conRatio = 0.5;
jojisdogakane 0:2f6112d75752 169 float conRatioNow = 0.5;
jojisdogakane 0:2f6112d75752 170 double HR_ratio = 0.0;
jojisdogakane 0:2f6112d75752 171
jojisdogakane 0:2f6112d75752 172 unsigned long IBI;
jojisdogakane 0:2f6112d75752 173
jojisdogakane 0:2f6112d75752 174 int x3, y3;
jojisdogakane 0:2f6112d75752 175
jojisdogakane 0:2f6112d75752 176 int mainPixelCounter;
jojisdogakane 0:2f6112d75752 177
jojisdogakane 0:2f6112d75752 178 int prevInterval;
jojisdogakane 0:2f6112d75752 179 int prevprevInterval;
jojisdogakane 0:2f6112d75752 180
jojisdogakane 0:2f6112d75752 181 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
jojisdogakane 0:2f6112d75752 182 {
jojisdogakane 0:2f6112d75752 183 ble.gap().startAdvertising(); // restart advertising
jojisdogakane 0:2f6112d75752 184 }
jojisdogakane 0:2f6112d75752 185 /*
jojisdogakane 0:2f6112d75752 186 void ConnectTimeoutCallback(Gap::EventCallback_t timeoutCallback)
jojisdogakane 0:2f6112d75752 187 {
jojisdogakane 0:2f6112d75752 188 ble.gap().startAdvertising(); // restart advertising
jojisdogakane 0:2f6112d75752 189 }
jojisdogakane 0:2f6112d75752 190 */
jojisdogakane 0:2f6112d75752 191
jojisdogakane 0:2f6112d75752 192 uint8_t BPM = 0;
jojisdogakane 0:2f6112d75752 193 float sensorValue = 0;
jojisdogakane 0:2f6112d75752 194 Timer t;
jojisdogakane 0:2f6112d75752 195 Timer tRand;
jojisdogakane 0:2f6112d75752 196
jojisdogakane 0:2f6112d75752 197 float redVal = 0;
jojisdogakane 0:2f6112d75752 198 float blueVal = 255;
jojisdogakane 0:2f6112d75752 199 float greenVal = 0;
jojisdogakane 0:2f6112d75752 200
jojisdogakane 0:2f6112d75752 201 Ticker neopixelTick;
jojisdogakane 0:2f6112d75752 202
jojisdogakane 0:2f6112d75752 203 UARTService *uartServicePtr;
jojisdogakane 0:2f6112d75752 204
jojisdogakane 0:2f6112d75752 205 void neopixelTick_Handler() {
jojisdogakane 0:2f6112d75752 206 return;
jojisdogakane 0:2f6112d75752 207 }
jojisdogakane 0:2f6112d75752 208
jojisdogakane 4:a0150e0f285b 209 void SetMoodColor() {
jojisdogakane 4:a0150e0f285b 210 int i = 0;
jojisdogakane 4:a0150e0f285b 211
jojisdogakane 4:a0150e0f285b 212 for(i = 0; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 213 MoodColorR[i][IS_RELAX] = RelaxR[i];
jojisdogakane 4:a0150e0f285b 214 MoodColorG[i][IS_RELAX] = RelaxG[i];
jojisdogakane 4:a0150e0f285b 215 MoodColorB[i][IS_RELAX] = RelaxB[i];
jojisdogakane 4:a0150e0f285b 216 }
jojisdogakane 4:a0150e0f285b 217 for(i = 0; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 218 MoodColorR[i][IS_EXCITED] = ExciteR[i];
jojisdogakane 4:a0150e0f285b 219 MoodColorG[i][IS_EXCITED] = ExciteG[i];
jojisdogakane 4:a0150e0f285b 220 MoodColorB[i][IS_EXCITED] = ExciteB[i];
jojisdogakane 4:a0150e0f285b 221 }
jojisdogakane 4:a0150e0f285b 222
jojisdogakane 4:a0150e0f285b 223 for(i = 0; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 224 MoodColorR[i][IS_HAPPY] = HappyR[i];
jojisdogakane 4:a0150e0f285b 225 MoodColorG[i][IS_HAPPY] = HappyG[i];
jojisdogakane 4:a0150e0f285b 226 MoodColorB[i][IS_HAPPY] = HappyB[i];
jojisdogakane 4:a0150e0f285b 227 }
jojisdogakane 4:a0150e0f285b 228 for(i = 0; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 229 MoodColorR[i][IS_INTERESTED] = InterestR[i];
jojisdogakane 4:a0150e0f285b 230 MoodColorG[i][IS_INTERESTED] = InterestG[i];
jojisdogakane 4:a0150e0f285b 231 MoodColorB[i][IS_INTERESTED] = InterestB[i];
jojisdogakane 4:a0150e0f285b 232 }
jojisdogakane 4:a0150e0f285b 233 for(i = 0; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 234 MoodColorR[i][IS_STRESSED] = StressR[i];
jojisdogakane 4:a0150e0f285b 235 MoodColorG[i][IS_STRESSED] = StressG[i];
jojisdogakane 4:a0150e0f285b 236 MoodColorB[i][IS_STRESSED] = StressB[i];
jojisdogakane 4:a0150e0f285b 237 }
jojisdogakane 0:2f6112d75752 238 }
jojisdogakane 0:2f6112d75752 239
jojisdogakane 9:4363af5affba 240
jojisdogakane 9:4363af5affba 241 float BPM_Average = 0.0;
jojisdogakane 9:4363af5affba 242 int currentBPM = 0;
jojisdogakane 9:4363af5affba 243
jojisdogakane 4:a0150e0f285b 244 // 現在の気分の判定
jojisdogakane 4:a0150e0f285b 245 int getMood(int bpm, double relaxRatio, double happyRatio, double conRatio) {
jojisdogakane 4:a0150e0f285b 246 // 第一優先:集中
jojisdogakane 4:a0150e0f285b 247 // 集中係数が0.95以上なら集中と判定
jojisdogakane 4:a0150e0f285b 248 if(conRatio >= CONMARGIN)
jojisdogakane 4:a0150e0f285b 249 {
jojisdogakane 4:a0150e0f285b 250 return IS_INTERESTED;
jojisdogakane 4:a0150e0f285b 251 }
jojisdogakane 0:2f6112d75752 252
jojisdogakane 4:a0150e0f285b 253 // 第二優先:Stress
jojisdogakane 4:a0150e0f285b 254 // リラックス係数が0.2以下
jojisdogakane 4:a0150e0f285b 255 if(relaxRatio <= RELAXMARGIN) {
jojisdogakane 4:a0150e0f285b 256 return IS_STRESSED;
jojisdogakane 4:a0150e0f285b 257 }
jojisdogakane 0:2f6112d75752 258
jojisdogakane 4:a0150e0f285b 259 // 第三優先:Happy
jojisdogakane 4:a0150e0f285b 260 // Happy係数が0.2以上
jojisdogakane 4:a0150e0f285b 261 if(happyRatio >= HAPPYMARGIN && relaxRatio > 0.5) {
jojisdogakane 4:a0150e0f285b 262 return IS_HAPPY;
jojisdogakane 4:a0150e0f285b 263 }
jojisdogakane 0:2f6112d75752 264
jojisdogakane 9:4363af5affba 265 // 平均の心拍より1.2倍以上だと興奮
jojisdogakane 9:4363af5affba 266 // それ以外は安静
jojisdogakane 9:4363af5affba 267 if((float)currentBPM / BPM_Average >= EXCITEMARGIN) {
jojisdogakane 4:a0150e0f285b 268 return IS_EXCITED;
jojisdogakane 0:2f6112d75752 269 }
jojisdogakane 9:4363af5affba 270 else {
jojisdogakane 9:4363af5affba 271 return IS_RELAX;
jojisdogakane 9:4363af5affba 272 }
jojisdogakane 4:a0150e0f285b 273 }
jojisdogakane 0:2f6112d75752 274
jojisdogakane 4:a0150e0f285b 275 //Serial mySerial(USBTX, USBRX);
jojisdogakane 4:a0150e0f285b 276 //Serial mySerial(P0_9, P0_11);
jojisdogakane 0:2f6112d75752 277
ayaando 7:4118d5a717bc 278 // MACアドレスを取得してBLEのSerialNumberに組み込む
ayaando 7:4118d5a717bc 279 void setBleSerialNumber(char *serialNumber)
ayaando 1:f28bdfaf3005 280 {
ayaando 1:f28bdfaf3005 281 int i;
ayaando 1:f28bdfaf3005 282
ayaando 1:f28bdfaf3005 283 ble_gap_addr_t mac_address;
ayaando 1:f28bdfaf3005 284
ayaando 1:f28bdfaf3005 285 if(sd_ble_gap_address_get(&mac_address) != NRF_SUCCESS){
ayaando 1:f28bdfaf3005 286 return;
ayaando 1:f28bdfaf3005 287 }
ayaando 1:f28bdfaf3005 288
ayaando 1:f28bdfaf3005 289 // ADDR_LENは6
ayaando 1:f28bdfaf3005 290 for(i=BLE_GAP_ADDR_LEN-1; i>=0; i--){
ayaando 7:4118d5a717bc 291 sprintf(serialNumber, "%s%02x", serialNumber, (mac_address.addr)[i]);
ayaando 1:f28bdfaf3005 292 }
ayaando 7:4118d5a717bc 293 sprintf(serialNumber, "%s%s", serialNumber, "\0");
ayaando 1:f28bdfaf3005 294
ayaando 7:4118d5a717bc 295 }
jojisdogakane 0:2f6112d75752 296
jojisdogakane 0:2f6112d75752 297 int main(void)
jojisdogakane 0:2f6112d75752 298 {
ayaando 10:867018503cd3 299 /*
jojisdogakane 0:2f6112d75752 300 char msgIBI[100];
jojisdogakane 0:2f6112d75752 301 int nMsgIBILen = 0;
jojisdogakane 0:2f6112d75752 302 char msgHappy[10];
jojisdogakane 0:2f6112d75752 303 int nMsgHappyLen = 0;
jojisdogakane 0:2f6112d75752 304 char msgConcentration[10];
jojisdogakane 0:2f6112d75752 305 int nMsgConcentrationLen = 0;
jojisdogakane 0:2f6112d75752 306 char msgRelax[10];
jojisdogakane 0:2f6112d75752 307 int nMsgRelaxLen = 0;
ayaando 10:867018503cd3 308 */
ayaando 10:867018503cd3 309 byte_t msgHeader[3] = {0x49,0x4e,0x50};
jojisdogakane 0:2f6112d75752 310
ayaando 10:867018503cd3 311 byte_t msg[19];
ayaando 10:867018503cd3 312 // int nMsgLen = 0;
jojisdogakane 0:2f6112d75752 313
jojisdogakane 0:2f6112d75752 314 float Brightness = 1.0;
jojisdogakane 0:2f6112d75752 315 bool brighten = true;
jojisdogakane 0:2f6112d75752 316 float brightenSpeedMs = 1000.0;
jojisdogakane 0:2f6112d75752 317 float colorSpeedMs = 1000.0;
jojisdogakane 0:2f6112d75752 318 float conRatioShow = 0.5;
jojisdogakane 0:2f6112d75752 319
jojisdogakane 0:2f6112d75752 320 int i;
jojisdogakane 0:2f6112d75752 321 unsigned long lightPrevMillis = 0;
jojisdogakane 0:2f6112d75752 322
jojisdogakane 0:2f6112d75752 323 float fBeatIndex = 0.0;
jojisdogakane 0:2f6112d75752 324
jojisdogakane 0:2f6112d75752 325 static uint8_t rrIntervalH = 0;
jojisdogakane 0:2f6112d75752 326 static uint8_t rrIntervalL = 1;
jojisdogakane 6:35f536162183 327
jojisdogakane 6:35f536162183 328 int r = 0;
jojisdogakane 6:35f536162183 329 int g = 0;
jojisdogakane 6:35f536162183 330 int b = 0;
jojisdogakane 6:35f536162183 331 int brightnessSum = 0;
jojisdogakane 6:35f536162183 332 int brightnessMax = 0;
jojisdogakane 0:2f6112d75752 333
jojisdogakane 0:2f6112d75752 334 neopixel_strip_t neopixel1;
jojisdogakane 0:2f6112d75752 335 neopixel_init(&neopixel1, P0_7, 1);
jojisdogakane 0:2f6112d75752 336 neopixel_clear(&neopixel1);
jojisdogakane 0:2f6112d75752 337
jojisdogakane 0:2f6112d75752 338 neopixel_strip_t neopixel2;
jojisdogakane 0:2f6112d75752 339 neopixel_init(&neopixel2, P0_8, 1);
jojisdogakane 0:2f6112d75752 340 neopixel_clear(&neopixel2);
jojisdogakane 0:2f6112d75752 341
jojisdogakane 0:2f6112d75752 342 neopixel_strip_t neopixel3;
jojisdogakane 0:2f6112d75752 343 neopixel_init(&neopixel3, P0_10, 1);
jojisdogakane 0:2f6112d75752 344 neopixel_clear(&neopixel3);
jojisdogakane 0:2f6112d75752 345
jojisdogakane 0:2f6112d75752 346 neopixel_strip_t neopixel4;
jojisdogakane 0:2f6112d75752 347 neopixel_init(&neopixel4, P0_9, 1);
jojisdogakane 0:2f6112d75752 348 neopixel_clear(&neopixel4);
jojisdogakane 0:2f6112d75752 349
jojisdogakane 0:2f6112d75752 350 neopixel_strip_t neopixel5;
jojisdogakane 0:2f6112d75752 351 neopixel_init(&neopixel5, P0_15, 1);
jojisdogakane 0:2f6112d75752 352 neopixel_clear(&neopixel5);
jojisdogakane 0:2f6112d75752 353
jojisdogakane 0:2f6112d75752 354 neopixel_strip_t neopixel6;
jojisdogakane 0:2f6112d75752 355 neopixel_init(&neopixel6, P0_11, 1);
jojisdogakane 0:2f6112d75752 356 neopixel_clear(&neopixel6);
jojisdogakane 0:2f6112d75752 357
jojisdogakane 0:2f6112d75752 358 neopixel_strip_t *pixels[6];
jojisdogakane 0:2f6112d75752 359
jojisdogakane 0:2f6112d75752 360 pixels[0] = &neopixel1;
jojisdogakane 0:2f6112d75752 361 pixels[1] = &neopixel2;
jojisdogakane 0:2f6112d75752 362 pixels[2] = &neopixel3;
jojisdogakane 0:2f6112d75752 363 pixels[3] = &neopixel4;
jojisdogakane 0:2f6112d75752 364 pixels[4] = &neopixel5;
jojisdogakane 0:2f6112d75752 365 pixels[5] = &neopixel6;
jojisdogakane 0:2f6112d75752 366
jojisdogakane 4:a0150e0f285b 367
jojisdogakane 6:35f536162183 368
jojisdogakane 4:a0150e0f285b 369 SetMoodColor();
jojisdogakane 4:a0150e0f285b 370
jojisdogakane 0:2f6112d75752 371 ble.init();
jojisdogakane 0:2f6112d75752 372 ble.gap().onDisconnection(disconnectionCallback);
jojisdogakane 0:2f6112d75752 373
jojisdogakane 4:a0150e0f285b 374
jojisdogakane 0:2f6112d75752 375 UARTService uartService(ble);
jojisdogakane 0:2f6112d75752 376 uartServicePtr = &uartService;
jojisdogakane 0:2f6112d75752 377
ayaando 2:221df6d014f5 378 // ★OTA用
ayaando 2:221df6d014f5 379 dfuService = new DFUService(ble, NULL);
jojisdogakane 4:a0150e0f285b 380
jojisdogakane 0:2f6112d75752 381 /* Setup primary service. */
jojisdogakane 0:2f6112d75752 382 HeartRateService hrServiceBPM(ble, BPM, HeartRateService::LOCATION_CHEST);
jojisdogakane 0:2f6112d75752 383 // HeartRateService hrServiceIBI(ble, IBI, HeartRateService::LOCATION_FINGER);
jojisdogakane 0:2f6112d75752 384
jojisdogakane 0:2f6112d75752 385 // BatteryService batteryService(ble, 100);
jojisdogakane 0:2f6112d75752 386
jojisdogakane 0:2f6112d75752 387 /* Setup auxiliary service. */
ayaando 2:221df6d014f5 388 //DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
ayaando 7:4118d5a717bc 389
ayaando 7:4118d5a717bc 390 char serialNumber[16] = "IND";
ayaando 7:4118d5a717bc 391 // SerialNumberStringにMACアドレスを組み込む
ayaando 7:4118d5a717bc 392 setBleSerialNumber(serialNumber);
ayaando 7:4118d5a717bc 393
ayaando 2:221df6d014f5 394 // ★
ayaando 7:4118d5a717bc 395 DeviceInformationService deviceInfo(ble, "INUPATHY01", "0.0.1", serialNumber, "0.0.1", "0.0.1", "0.0.1");
ayaando 1:f28bdfaf3005 396
jojisdogakane 0:2f6112d75752 397 /* Setup advertising. */
jojisdogakane 0:2f6112d75752 398 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
jojisdogakane 0:2f6112d75752 399 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
jojisdogakane 0:2f6112d75752 400 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
jojisdogakane 0:2f6112d75752 401 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
jojisdogakane 0:2f6112d75752 402 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jojisdogakane 0:2f6112d75752 403 ble.gap().setAdvertisingInterval(800); /* 1000ms */
jojisdogakane 0:2f6112d75752 404 ble.gap().startAdvertising();
jojisdogakane 0:2f6112d75752 405
jojisdogakane 4:a0150e0f285b 406 for( i = 0; i < NEOPIXEL_COUNT; i++)
jojisdogakane 6:35f536162183 407 {
jojisdogakane 6:35f536162183 408 // 起動時の色パターンを設定
jojisdogakane 6:35f536162183 409 ColorArrayR[i] = RainbowR[i];
jojisdogakane 6:35f536162183 410 ColorArrayG[i] = RainbowG[i];
jojisdogakane 6:35f536162183 411 ColorArrayB[i] = RainbowB[i];
jojisdogakane 6:35f536162183 412
jojisdogakane 4:a0150e0f285b 413 TargetColorArrayR[i] = ColorArrayR[i];
jojisdogakane 4:a0150e0f285b 414 TargetColorArrayG[i] = ColorArrayG[i];
jojisdogakane 4:a0150e0f285b 415 TargetColorArrayB[i] = ColorArrayB[i];
jojisdogakane 6:35f536162183 416
jojisdogakane 6:35f536162183 417 // 輝度調整
jojisdogakane 6:35f536162183 418 r = ColorArrayR[i] * DIM_LED;
jojisdogakane 6:35f536162183 419 g = ColorArrayG[i] * DIM_LED;
jojisdogakane 6:35f536162183 420 b = ColorArrayB[i] * DIM_LED;
jojisdogakane 6:35f536162183 421
jojisdogakane 6:35f536162183 422 brightnessSum = r + g + b;
jojisdogakane 6:35f536162183 423
jojisdogakane 6:35f536162183 424 // 輝度の合計値が上限を超えた場合は補正する
jojisdogakane 6:35f536162183 425 if(brightnessSum > BRIGHTNESS_MAX) {
jojisdogakane 6:35f536162183 426 r = (int)(r * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 6:35f536162183 427 g = (int)(g * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 6:35f536162183 428 b = (int)(b * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 6:35f536162183 429 }
jojisdogakane 6:35f536162183 430
jojisdogakane 0:2f6112d75752 431 neopixel_set_color(
jojisdogakane 0:2f6112d75752 432 pixels[i],
jojisdogakane 0:2f6112d75752 433 0,
jojisdogakane 6:35f536162183 434 short(r),
jojisdogakane 6:35f536162183 435 short(g),
jojisdogakane 6:35f536162183 436 short(b));
jojisdogakane 0:2f6112d75752 437 neopixel_show(pixels[i]);
jojisdogakane 0:2f6112d75752 438 }
jojisdogakane 4:a0150e0f285b 439
jojisdogakane 0:2f6112d75752 440 t.start();
jojisdogakane 0:2f6112d75752 441
jojisdogakane 0:2f6112d75752 442 prevmillis = t.read_ms();
jojisdogakane 0:2f6112d75752 443
jojisdogakane 0:2f6112d75752 444 bool bPulseEvent = false;
jojisdogakane 0:2f6112d75752 445
jojisdogakane 0:2f6112d75752 446 float degPoint = 0;
jojisdogakane 0:2f6112d75752 447 float degRatio = 0;
jojisdogakane 0:2f6112d75752 448
jojisdogakane 0:2f6112d75752 449 bool bSwingR = false;
jojisdogakane 0:2f6112d75752 450
jojisdogakane 0:2f6112d75752 451 float swingIndex = 0.0;
jojisdogakane 0:2f6112d75752 452
jojisdogakane 0:2f6112d75752 453 float midPoint = 0.5;
jojisdogakane 0:2f6112d75752 454
jojisdogakane 9:4363af5affba 455
jojisdogakane 0:2f6112d75752 456 // neopixelTick.attach(neopixelTick_Handler, 0.005);
jojisdogakane 0:2f6112d75752 457
jojisdogakane 0:2f6112d75752 458 while (1) {
jojisdogakane 0:2f6112d75752 459
jojisdogakane 0:2f6112d75752 460 // batteryService.updateBatteryLevel( (uint8_t)read_battery_level());
jojisdogakane 0:2f6112d75752 461
jojisdogakane 0:2f6112d75752 462 float currentValue = HRSigIn;
jojisdogakane 0:2f6112d75752 463
jojisdogakane 0:2f6112d75752 464 bPulseEvent = false;
jojisdogakane 0:2f6112d75752 465
jojisdogakane 4:a0150e0f285b 466 if ((currentValue <= 0.3) && (sensorValue > 0.3))
jojisdogakane 0:2f6112d75752 467 {
jojisdogakane 0:2f6112d75752 468 bPulseEvent = true;
jojisdogakane 0:2f6112d75752 469 }
jojisdogakane 0:2f6112d75752 470
jojisdogakane 0:2f6112d75752 471 int sens = 1023 * currentValue;
jojisdogakane 0:2f6112d75752 472
jojisdogakane 0:2f6112d75752 473 // printf("S%d", sens);
jojisdogakane 0:2f6112d75752 474 // printf("S%d\n", sens);
jojisdogakane 0:2f6112d75752 475
jojisdogakane 0:2f6112d75752 476 sensorValue = currentValue;
jojisdogakane 0:2f6112d75752 477
jojisdogakane 0:2f6112d75752 478 if(bPulseEvent) {
jojisdogakane 0:2f6112d75752 479 fBeatIndex = 0.0;
jojisdogakane 0:2f6112d75752 480 // batteryService.updateBatteryLevel( (uint8_t)read_battery_level());
jojisdogakane 0:2f6112d75752 481
jojisdogakane 0:2f6112d75752 482 // 現在の時刻を取得
jojisdogakane 0:2f6112d75752 483 // t.stop(); // stop, startは時間計測の結果を有意に短くしてしまうので使わない
jojisdogakane 0:2f6112d75752 484 currentmillis = t.read_ms();
jojisdogakane 0:2f6112d75752 485 // t.start();
jojisdogakane 0:2f6112d75752 486 // 現在時刻から過去時刻を引き、間隔を求める
jojisdogakane 0:2f6112d75752 487 intervalmillis = currentmillis - prevmillis;
jojisdogakane 0:2f6112d75752 488
jojisdogakane 0:2f6112d75752 489 // 心拍の間の間隔
jojisdogakane 0:2f6112d75752 490 IBI = intervalmillis;
jojisdogakane 0:2f6112d75752 491
jojisdogakane 0:2f6112d75752 492 // 現在の時刻を過去時刻として記録
jojisdogakane 0:2f6112d75752 493 prevmillis = currentmillis;
jojisdogakane 0:2f6112d75752 494
jojisdogakane 0:2f6112d75752 495 // 平均値算出用配列に値を詰める
jojisdogakane 0:2f6112d75752 496 double averageIntervalMillis;
jojisdogakane 0:2f6112d75752 497
jojisdogakane 0:2f6112d75752 498 for(i = 0; i < MAXARRAY ; i++)
jojisdogakane 0:2f6112d75752 499 {
jojisdogakane 0:2f6112d75752 500 // 最後尾以外の場合
jojisdogakane 0:2f6112d75752 501 if(i != MAXARRAY - 1)
jojisdogakane 0:2f6112d75752 502 {
jojisdogakane 0:2f6112d75752 503 // 次の要素の値をコピーする
jojisdogakane 0:2f6112d75752 504 intervalmillisArray[i] = intervalmillisArray[i + 1];
jojisdogakane 0:2f6112d75752 505 }
jojisdogakane 0:2f6112d75752 506 // 最後尾の場合
jojisdogakane 0:2f6112d75752 507 else {
jojisdogakane 0:2f6112d75752 508 // 最新値を詰める
jojisdogakane 0:2f6112d75752 509 intervalmillisArray[i] = intervalmillis;
jojisdogakane 0:2f6112d75752 510 }
jojisdogakane 0:2f6112d75752 511 }
jojisdogakane 0:2f6112d75752 512 // 先頭が0の間は何もしない
jojisdogakane 0:2f6112d75752 513 unsigned long sumIntervalMillis = 0;
jojisdogakane 0:2f6112d75752 514 unsigned long sumIntervalMillisV = 0;
jojisdogakane 0:2f6112d75752 515 if (intervalmillisArray[0] != 0)
jojisdogakane 0:2f6112d75752 516 {
jojisdogakane 0:2f6112d75752 517 // 平均値算出
jojisdogakane 0:2f6112d75752 518 averageIntervalMillis = 0;
jojisdogakane 0:2f6112d75752 519 for(i = 0; i < MAXARRAY ; i++)
jojisdogakane 0:2f6112d75752 520 {
jojisdogakane 0:2f6112d75752 521 sumIntervalMillis += intervalmillisArray[i];
jojisdogakane 0:2f6112d75752 522 sumIntervalMillisV += intervalmillisArray[i] * intervalmillisArray[i];
jojisdogakane 0:2f6112d75752 523 }
jojisdogakane 0:2f6112d75752 524 double squ;
jojisdogakane 0:2f6112d75752 525 double var;
jojisdogakane 0:2f6112d75752 526 double stdDev;
jojisdogakane 0:2f6112d75752 527
jojisdogakane 0:2f6112d75752 528 averageIntervalMillis = (double)sumIntervalMillis / (double)MAXARRAY;
jojisdogakane 0:2f6112d75752 529
jojisdogakane 0:2f6112d75752 530 squ = sumIntervalMillisV - (double)(sumIntervalMillis * sumIntervalMillis) / (double)MAXARRAY;
jojisdogakane 0:2f6112d75752 531 var = squ / (double)(MAXARRAY - 1);
jojisdogakane 0:2f6112d75752 532 stdDev = sqrt(var);
jojisdogakane 0:2f6112d75752 533
jojisdogakane 0:2f6112d75752 534 BPM = min32_of(60000 / averageIntervalMillis, 255);
jojisdogakane 0:2f6112d75752 535 // if(intervalmillis < averageIntervalMillis - stdDev) { // || intervalmillis > averageIntervalMillis + stdDev) {
jojisdogakane 0:2f6112d75752 536
jojisdogakane 0:2f6112d75752 537 currentBPM = min32_of(60000 / intervalmillis, 255);
jojisdogakane 0:2f6112d75752 538 /* }
jojisdogakane 0:2f6112d75752 539 else {
jojisdogakane 0:2f6112d75752 540 currentBPM = BPM;
jojisdogakane 0:2f6112d75752 541 } */
jojisdogakane 0:2f6112d75752 542 }
jojisdogakane 9:4363af5affba 543
jojisdogakane 9:4363af5affba 544
jojisdogakane 9:4363af5affba 545 // BPMの平均値計算
jojisdogakane 9:4363af5affba 546 int BPM_sum = 0;
jojisdogakane 9:4363af5affba 547 for(i = 0; i < HRM_AVERAGE_COUNT ; i++)
jojisdogakane 9:4363af5affba 548 {
jojisdogakane 9:4363af5affba 549 BPM_sum += HRM_Average[i];
jojisdogakane 9:4363af5affba 550 }
jojisdogakane 9:4363af5affba 551 BPM_Average = (float)BPM_sum/(float)HRM_AVERAGE_COUNT;
jojisdogakane 9:4363af5affba 552
jojisdogakane 9:4363af5affba 553
jojisdogakane 9:4363af5affba 554 if(currentBPM > 0) {
jojisdogakane 9:4363af5affba 555 for(i = 0; i < HRM_AVERAGE_COUNT ; i++)
jojisdogakane 9:4363af5affba 556 {
jojisdogakane 9:4363af5affba 557 // 最後尾以外の場合
jojisdogakane 9:4363af5affba 558 if(i != HRM_AVERAGE_COUNT - 1)
jojisdogakane 9:4363af5affba 559 {
jojisdogakane 9:4363af5affba 560 // 次の要素の値をコピーする
jojisdogakane 9:4363af5affba 561 HRM_Average[i] = HRM_Average[i + 1];
jojisdogakane 9:4363af5affba 562 }
jojisdogakane 9:4363af5affba 563 // 最後尾の場合
jojisdogakane 9:4363af5affba 564 else {
jojisdogakane 9:4363af5affba 565 // 最新値を詰める
jojisdogakane 9:4363af5affba 566 HRM_Average[i] = currentBPM;
jojisdogakane 9:4363af5affba 567 }
jojisdogakane 9:4363af5affba 568 }
jojisdogakane 9:4363af5affba 569 }
jojisdogakane 9:4363af5affba 570
jojisdogakane 0:2f6112d75752 571 /*
jojisdogakane 0:2f6112d75752 572 int IBI1024 = IBI * (1024/1000);
jojisdogakane 0:2f6112d75752 573
jojisdogakane 0:2f6112d75752 574 bpm[1] = BPM;
jojisdogakane 0:2f6112d75752 575 bpm[6] = (IBI1024 & 0xFF00) >> 8;
jojisdogakane 0:2f6112d75752 576 bpm[7] = (IBI1024 & 0xFF);
jojisdogakane 0:2f6112d75752 577 */
jojisdogakane 0:2f6112d75752 578 // update bpm
jojisdogakane 0:2f6112d75752 579 if(ble.gap().getState().connected == 1)
jojisdogakane 0:2f6112d75752 580 {
jojisdogakane 0:2f6112d75752 581 hrServiceBPM.updateHeartRate(BPM);
jojisdogakane 0:2f6112d75752 582 // hrServiceIBI.updateHeartRate(IBI);
jojisdogakane 0:2f6112d75752 583 }
jojisdogakane 0:2f6112d75752 584
jojisdogakane 0:2f6112d75752 585 // printf("B%d\n", BPM);
jojisdogakane 0:2f6112d75752 586 // printf("Q%d\n", IBI);
jojisdogakane 0:2f6112d75752 587
jojisdogakane 0:2f6112d75752 588 // nMsgLen = sprintf(msg,"B%d\0", BPM);
jojisdogakane 0:2f6112d75752 589 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t*)msg, nMsgLen);
jojisdogakane 0:2f6112d75752 590
ayaando 10:867018503cd3 591 // nMsgIBILen = sprintf(msgIBI,"Q%d\0", IBI);
jojisdogakane 0:2f6112d75752 592 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t*)msg, nMsgLen);
jojisdogakane 0:2f6112d75752 593
jojisdogakane 0:2f6112d75752 594 // 平均値算出用配列に値を詰める
jojisdogakane 0:2f6112d75752 595 for(i = 0; i < MAXHRVARRAY ; i++)
jojisdogakane 0:2f6112d75752 596 {
jojisdogakane 0:2f6112d75752 597 // 最後尾以外の場合
jojisdogakane 0:2f6112d75752 598 if(i != MAXHRVARRAY - 1)
jojisdogakane 0:2f6112d75752 599 {
jojisdogakane 0:2f6112d75752 600 // 次の要素の値をコピーする
jojisdogakane 0:2f6112d75752 601 intervalmillisHRVArray[i] = intervalmillisHRVArray[i + 1];
jojisdogakane 0:2f6112d75752 602 }
jojisdogakane 0:2f6112d75752 603 // 最後尾の場合
jojisdogakane 0:2f6112d75752 604 else {
jojisdogakane 0:2f6112d75752 605 // 最新値を詰める
jojisdogakane 0:2f6112d75752 606 intervalmillisHRVArray[i] = intervalmillis;
jojisdogakane 0:2f6112d75752 607 }
jojisdogakane 0:2f6112d75752 608 }
jojisdogakane 0:2f6112d75752 609
jojisdogakane 0:2f6112d75752 610 // 平均値算出
jojisdogakane 0:2f6112d75752 611 int nNNInterval;
jojisdogakane 0:2f6112d75752 612 unsigned long ulIntervalSum = 0;
jojisdogakane 0:2f6112d75752 613 int nSampleCount = 0;
jojisdogakane 0:2f6112d75752 614 for(i = 0; i < MAXHRVARRAY ; i++)
jojisdogakane 0:2f6112d75752 615 {
jojisdogakane 0:2f6112d75752 616 if(intervalmillisHRVArray[i] > 0)
jojisdogakane 0:2f6112d75752 617 {
jojisdogakane 0:2f6112d75752 618 ulIntervalSum += intervalmillisHRVArray[i];
jojisdogakane 0:2f6112d75752 619 nSampleCount++;
jojisdogakane 0:2f6112d75752 620 }
jojisdogakane 0:2f6112d75752 621 }
jojisdogakane 0:2f6112d75752 622
jojisdogakane 0:2f6112d75752 623 float IntervalAverage = 0.0;
jojisdogakane 0:2f6112d75752 624 if(nSampleCount > 0){
jojisdogakane 0:2f6112d75752 625 IntervalAverage = (float)ulIntervalSum / (float)nSampleCount;
jojisdogakane 0:2f6112d75752 626 }
jojisdogakane 0:2f6112d75752 627
jojisdogakane 0:2f6112d75752 628 nNNInterval = (int)((float)IntervalAverage * PNNX_FACTOR);
jojisdogakane 0:2f6112d75752 629
jojisdogakane 0:2f6112d75752 630
jojisdogakane 0:2f6112d75752 631 bool bContinue = false;
jojisdogakane 0:2f6112d75752 632 int nNNxCount = 0;
jojisdogakane 0:2f6112d75752 633 for(i = 0; i < MAXHRVARRAY ; i++)
jojisdogakane 0:2f6112d75752 634 {
jojisdogakane 0:2f6112d75752 635 // if not end
jojisdogakane 0:2f6112d75752 636 if(i < MAXHRVARRAY - 1) {
jojisdogakane 0:2f6112d75752 637 if(abs((int)(intervalmillisHRVArray[i] - intervalmillisHRVArray[i + 1])) >= nNNInterval)
jojisdogakane 0:2f6112d75752 638 {
jojisdogakane 0:2f6112d75752 639 if(bContinue == false)
jojisdogakane 0:2f6112d75752 640 {
jojisdogakane 0:2f6112d75752 641 nNNxCount++;
jojisdogakane 0:2f6112d75752 642 }
jojisdogakane 0:2f6112d75752 643 nNNxCount++;
jojisdogakane 0:2f6112d75752 644 bContinue = true;
jojisdogakane 0:2f6112d75752 645 }
jojisdogakane 0:2f6112d75752 646 else {
jojisdogakane 0:2f6112d75752 647 bContinue = false;
jojisdogakane 0:2f6112d75752 648 }
jojisdogakane 0:2f6112d75752 649 }
jojisdogakane 0:2f6112d75752 650 }
jojisdogakane 0:2f6112d75752 651
jojisdogakane 0:2f6112d75752 652 float diffRatio = (float)nNNxCount / (float)nSampleCount;
jojisdogakane 0:2f6112d75752 653
jojisdogakane 0:2f6112d75752 654 if(diffRatio > 1)
jojisdogakane 0:2f6112d75752 655 {
jojisdogakane 0:2f6112d75752 656 diffRatio = 1;
jojisdogakane 0:2f6112d75752 657 }
jojisdogakane 0:2f6112d75752 658
jojisdogakane 0:2f6112d75752 659 // リラックスの係数を算出する
jojisdogakane 0:2f6112d75752 660 relaxRatio = diffRatio;
jojisdogakane 0:2f6112d75752 661
ayaando 10:867018503cd3 662 // nMsgRelaxLen = sprintf(msgRelax,"S%0.2f\0", (1-relaxRatio));
jojisdogakane 0:2f6112d75752 663
jojisdogakane 0:2f6112d75752 664 // nMsgLen = sprintf(msg,"R%0.2f\0", relaxRatio);
jojisdogakane 0:2f6112d75752 665 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t*)msg, nMsgLen);
jojisdogakane 0:2f6112d75752 666
jojisdogakane 0:2f6112d75752 667 // 現在値から最低値を引く
jojisdogakane 0:2f6112d75752 668 // relaxRatio = relaxRatio - RELAX_RATIO_MIN;
jojisdogakane 0:2f6112d75752 669
jojisdogakane 0:2f6112d75752 670 // 1.0 / 最低値 × 現在値
jojisdogakane 0:2f6112d75752 671 // relaxRatio = relaxRatio * (1.0 / (1.0 - RELAX_RATIO_MIN));
jojisdogakane 0:2f6112d75752 672
jojisdogakane 0:2f6112d75752 673 int x1, y1, x2, y2;
jojisdogakane 0:2f6112d75752 674 int tempx1, tempy1, tempx2, tempy2, tempx3, tempy3;
jojisdogakane 0:2f6112d75752 675 int longx, shortx, longy, shorty;
jojisdogakane 0:2f6112d75752 676 long xx1, xx2, yy1, yy2;
jojisdogakane 0:2f6112d75752 677
jojisdogakane 0:2f6112d75752 678 int movex, movey;
jojisdogakane 0:2f6112d75752 679
jojisdogakane 0:2f6112d75752 680 double dist1, dist2;
jojisdogakane 0:2f6112d75752 681 double conRatioRatio;
jojisdogakane 0:2f6112d75752 682
jojisdogakane 0:2f6112d75752 683 /*
jojisdogakane 0:2f6112d75752 684 // 最後尾の3データから二つのx, y地点を作る。
jojisdogakane 0:2f6112d75752 685 x1 = intervalmillisArray[nSampleCount - 1];
jojisdogakane 0:2f6112d75752 686 y1 = intervalmillisArray[nSampleCount - 2];
jojisdogakane 0:2f6112d75752 687 x2 = intervalmillisArray[nSampleCount - 2];
jojisdogakane 0:2f6112d75752 688 y2 = intervalmillisArray[nSampleCount - 3];
jojisdogakane 0:2f6112d75752 689 */
jojisdogakane 0:2f6112d75752 690
jojisdogakane 0:2f6112d75752 691 x1 = intervalmillis;
jojisdogakane 0:2f6112d75752 692 y1 = prevInterval;
jojisdogakane 0:2f6112d75752 693 x2 = prevInterval;
jojisdogakane 0:2f6112d75752 694 y2 = prevprevInterval;
jojisdogakane 0:2f6112d75752 695
jojisdogakane 0:2f6112d75752 696 // 2地点を結ぶ直線の長さを算出する。
jojisdogakane 0:2f6112d75752 697 if(x1 > x2)
jojisdogakane 0:2f6112d75752 698 {
jojisdogakane 0:2f6112d75752 699 longx = x1;
jojisdogakane 0:2f6112d75752 700 shortx = x2;
jojisdogakane 0:2f6112d75752 701 }
jojisdogakane 0:2f6112d75752 702 else {
jojisdogakane 0:2f6112d75752 703 longx = x2;
jojisdogakane 0:2f6112d75752 704 shortx = x1;
jojisdogakane 0:2f6112d75752 705 }
jojisdogakane 0:2f6112d75752 706
jojisdogakane 0:2f6112d75752 707 if(y1 > y2)
jojisdogakane 0:2f6112d75752 708 {
jojisdogakane 0:2f6112d75752 709 longy = y1;
jojisdogakane 0:2f6112d75752 710 shorty = y2;
jojisdogakane 0:2f6112d75752 711 }
jojisdogakane 0:2f6112d75752 712 else {
jojisdogakane 0:2f6112d75752 713 longy = y2;
jojisdogakane 0:2f6112d75752 714 shorty = y1;
jojisdogakane 0:2f6112d75752 715 }
jojisdogakane 0:2f6112d75752 716
jojisdogakane 0:2f6112d75752 717 xx1 = longx - shortx;
jojisdogakane 0:2f6112d75752 718 yy1 = longy - shorty;
jojisdogakane 0:2f6112d75752 719
jojisdogakane 0:2f6112d75752 720 dist1 = sqrt((double)((xx1 * xx1) + (yy1 * yy1)));
jojisdogakane 0:2f6112d75752 721
jojisdogakane 0:2f6112d75752 722 dist2 = longx + longy;
jojisdogakane 0:2f6112d75752 723 float distRatio = dist1 / dist2;
jojisdogakane 0:2f6112d75752 724
jojisdogakane 0:2f6112d75752 725 conRatioNow = 1 - distRatio;
jojisdogakane 0:2f6112d75752 726
jojisdogakane 0:2f6112d75752 727 // 平均値算出用配列に値を詰める
jojisdogakane 0:2f6112d75752 728 float averageConRatio = 0.5;
jojisdogakane 0:2f6112d75752 729 for(i = 0; i < MAXCONARRAY ; i++)
jojisdogakane 0:2f6112d75752 730 {
jojisdogakane 0:2f6112d75752 731 // 最後尾以外の場合
jojisdogakane 0:2f6112d75752 732 if(i != MAXCONARRAY - 1)
jojisdogakane 0:2f6112d75752 733 {
jojisdogakane 0:2f6112d75752 734 // 次の要素の値をコピーする
jojisdogakane 0:2f6112d75752 735 conArray[i] = conArray[i + 1];
jojisdogakane 0:2f6112d75752 736 }
jojisdogakane 0:2f6112d75752 737 // 最後尾の場合
jojisdogakane 0:2f6112d75752 738 else {
jojisdogakane 0:2f6112d75752 739 // 最新値を詰める
jojisdogakane 0:2f6112d75752 740 conArray[i] = distRatio;
jojisdogakane 0:2f6112d75752 741 }
jojisdogakane 0:2f6112d75752 742 }
jojisdogakane 0:2f6112d75752 743 // 先頭が0の間は何もしない
jojisdogakane 0:2f6112d75752 744 if (conArray[0] != 0)
jojisdogakane 0:2f6112d75752 745 {
jojisdogakane 0:2f6112d75752 746 // 平均値算出
jojisdogakane 0:2f6112d75752 747 averageConRatio = 0;
jojisdogakane 0:2f6112d75752 748 for(i = 0; i < MAXCONARRAY ; i++)
jojisdogakane 0:2f6112d75752 749 {
jojisdogakane 0:2f6112d75752 750 averageConRatio += conArray[i];
jojisdogakane 0:2f6112d75752 751 }
jojisdogakane 0:2f6112d75752 752 averageConRatio = averageConRatio / (double)MAXCONARRAY;
jojisdogakane 0:2f6112d75752 753 }
jojisdogakane 0:2f6112d75752 754 /*
jojisdogakane 0:2f6112d75752 755 float averageStressRatio = 0.5;
jojisdogakane 0:2f6112d75752 756 for(i = 0; i < MAXSTRESSARRAY ; i++)
jojisdogakane 0:2f6112d75752 757 {
jojisdogakane 0:2f6112d75752 758 // 最後尾以外の場合
jojisdogakane 0:2f6112d75752 759 if(i != MAXSTRESSARRAY - 1)
jojisdogakane 0:2f6112d75752 760 {
jojisdogakane 0:2f6112d75752 761 // 次の要素の値をコピーする
jojisdogakane 0:2f6112d75752 762 stressArray[i] = stressArray[i + 1];
jojisdogakane 0:2f6112d75752 763 }
jojisdogakane 0:2f6112d75752 764 // 最後尾の場合
jojisdogakane 0:2f6112d75752 765 else {
jojisdogakane 0:2f6112d75752 766 // 最新値を詰める
jojisdogakane 0:2f6112d75752 767 if(x1 > y1) {
jojisdogakane 0:2f6112d75752 768 stressArray[i] = y1 / x1;
jojisdogakane 0:2f6112d75752 769 }
jojisdogakane 0:2f6112d75752 770 else {
jojisdogakane 0:2f6112d75752 771 stressArray[i] = x1 / y1;
jojisdogakane 0:2f6112d75752 772 }
jojisdogakane 0:2f6112d75752 773 }
jojisdogakane 0:2f6112d75752 774 }
jojisdogakane 0:2f6112d75752 775 // 先頭が0の間は何もしない
jojisdogakane 0:2f6112d75752 776 if (stressArray[0] != 0)
jojisdogakane 0:2f6112d75752 777 {
jojisdogakane 0:2f6112d75752 778 // 平均値算出
jojisdogakane 0:2f6112d75752 779 averageStressRatio = 0;
jojisdogakane 0:2f6112d75752 780 for(i = 0; i < MAXSTRESSARRAY ; i++)
jojisdogakane 0:2f6112d75752 781 {
jojisdogakane 0:2f6112d75752 782 averageStressRatio += stressArray[i];
jojisdogakane 0:2f6112d75752 783 }
jojisdogakane 0:2f6112d75752 784 averageStressRatio = averageStressRatio / (double)MAXSTRESSARRAY;
jojisdogakane 0:2f6112d75752 785 }
jojisdogakane 0:2f6112d75752 786 */
jojisdogakane 0:2f6112d75752 787
jojisdogakane 0:2f6112d75752 788 /* float rcFilter = RCFILTER2;
jojisdogakane 0:2f6112d75752 789 float filteredDistRatio = 0.0;
jojisdogakane 0:2f6112d75752 790 float a;
jojisdogakane 0:2f6112d75752 791 if(prevFilteredDistRatio != 0) {
jojisdogakane 0:2f6112d75752 792 a = rcFilter * prevFilteredDistRatio;
jojisdogakane 0:2f6112d75752 793 filteredDistRatio = a + (1 - rcFilter) * distRatio;
jojisdogakane 0:2f6112d75752 794 }
jojisdogakane 0:2f6112d75752 795 else {
jojisdogakane 0:2f6112d75752 796 filteredDistRatio = (1 - rcFilter) * distRatio;
jojisdogakane 0:2f6112d75752 797 }
jojisdogakane 0:2f6112d75752 798 prevFilteredDistRatio = filteredDistRatio ;
jojisdogakane 0:2f6112d75752 799
jojisdogakane 0:2f6112d75752 800 conRatio = filteredDistRatio ;
jojisdogakane 0:2f6112d75752 801 */
jojisdogakane 0:2f6112d75752 802 conRatio = averageConRatio;
jojisdogakane 0:2f6112d75752 803 conRatio = 1 - conRatio;
jojisdogakane 0:2f6112d75752 804
ayaando 10:867018503cd3 805 // nMsgConcentrationLen = sprintf(msgConcentration,"C%0.2f\0", conRatio);
jojisdogakane 0:2f6112d75752 806
jojisdogakane 0:2f6112d75752 807 // nMsgLen = sprintf(msg,"C%0.2f\0", conRatio);
jojisdogakane 0:2f6112d75752 808 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t*)msg, nMsgLen);
jojisdogakane 0:2f6112d75752 809
jojisdogakane 0:2f6112d75752 810
jojisdogakane 0:2f6112d75752 811 prevprevInterval = prevInterval;
jojisdogakane 0:2f6112d75752 812 prevInterval = intervalmillis;
jojisdogakane 0:2f6112d75752 813
jojisdogakane 0:2f6112d75752 814 // (x2, y2)が原点となるように座標を変換する
jojisdogakane 0:2f6112d75752 815 movex = x2 * -1;
jojisdogakane 0:2f6112d75752 816 movey = y2 * -1;
jojisdogakane 0:2f6112d75752 817
jojisdogakane 0:2f6112d75752 818 tempx1 = x1 - movex;
jojisdogakane 0:2f6112d75752 819 tempy1 = y1 - movey;
jojisdogakane 0:2f6112d75752 820 tempx2 = x2 - movex;
jojisdogakane 0:2f6112d75752 821 tempy2 = y2 - movey;
jojisdogakane 0:2f6112d75752 822 tempx3 = x3 - movex;
jojisdogakane 0:2f6112d75752 823 tempy3 = y3 - movey;
jojisdogakane 0:2f6112d75752 824
jojisdogakane 0:2f6112d75752 825 // (x2, y2)を中心とした円を考える。
jojisdogakane 0:2f6112d75752 826
jojisdogakane 0:2f6112d75752 827 // (x3, y3)を(x2, y2)を中心に180°回転する。→(rotx3, roty3)
jojisdogakane 0:2f6112d75752 828 double theta = DegreeToRadian(180);
jojisdogakane 0:2f6112d75752 829
jojisdogakane 0:2f6112d75752 830 double rotx3 = (tempx3) * cos(theta) - (tempy3) * sin(theta);
jojisdogakane 0:2f6112d75752 831 double roty3 = (tempx3) * sin(theta) + (tempy3) * cos(theta);
jojisdogakane 0:2f6112d75752 832
jojisdogakane 0:2f6112d75752 833 // ベクトル1とベクトル3の内積を求める
jojisdogakane 0:2f6112d75752 834 double vecInt = tempx1 * rotx3 + tempy1 * roty3;
jojisdogakane 0:2f6112d75752 835
jojisdogakane 0:2f6112d75752 836 // ベクトル1とベクトル3の外積を求める
jojisdogakane 0:2f6112d75752 837 double vecExt = tempx1 * roty3 - tempy1 * rotx3;
jojisdogakane 0:2f6112d75752 838
jojisdogakane 0:2f6112d75752 839 // ベクトル1とベクトル3の角度を求める
jojisdogakane 0:2f6112d75752 840 theta = atan2(vecExt, vecInt);
jojisdogakane 0:2f6112d75752 841
jojisdogakane 0:2f6112d75752 842 double deg = RadianToDegree(theta);
jojisdogakane 0:2f6112d75752 843
jojisdogakane 0:2f6112d75752 844 midPoint = degRatio;
jojisdogakane 0:2f6112d75752 845
jojisdogakane 0:2f6112d75752 846 if( deg <= 11.25 && deg >= -11.25) {
jojisdogakane 0:2f6112d75752 847 degPoint = 0.5;
jojisdogakane 0:2f6112d75752 848 }
jojisdogakane 0:2f6112d75752 849 else if(deg >= 11.25 && deg <= 33.75) {
jojisdogakane 0:2f6112d75752 850 degPoint = 0.375;
jojisdogakane 0:2f6112d75752 851 }
jojisdogakane 0:2f6112d75752 852 else if(deg >= 33.75 && deg <= 56.25) {
jojisdogakane 0:2f6112d75752 853 degPoint = 0.25;
jojisdogakane 0:2f6112d75752 854 }
jojisdogakane 0:2f6112d75752 855 else if(deg >= 56.25 && deg <= 78.75) {
jojisdogakane 0:2f6112d75752 856 degPoint = 0.125;
jojisdogakane 0:2f6112d75752 857 }
jojisdogakane 0:2f6112d75752 858 else if(deg >= 78.75 && deg <= 101.25) {
jojisdogakane 0:2f6112d75752 859 degPoint = 0;
jojisdogakane 0:2f6112d75752 860 }
jojisdogakane 0:2f6112d75752 861 else if(deg >= 101.25 && deg <= 123.75) {
jojisdogakane 0:2f6112d75752 862 degPoint = 0.125;
jojisdogakane 0:2f6112d75752 863 }
jojisdogakane 0:2f6112d75752 864 else if(deg >= 123.75 && deg <= 146.25) {
jojisdogakane 0:2f6112d75752 865 degPoint = 0.25;
jojisdogakane 0:2f6112d75752 866 }
jojisdogakane 0:2f6112d75752 867 else if(deg >= 146.25 && deg <= 168.75) {
jojisdogakane 0:2f6112d75752 868 degPoint = 0.375;
jojisdogakane 0:2f6112d75752 869 }
jojisdogakane 0:2f6112d75752 870 else if(deg >= 168.75 && deg <= 180 || deg <= 0 && deg >= -11.25) {
jojisdogakane 0:2f6112d75752 871 degPoint = 0.5;
jojisdogakane 0:2f6112d75752 872 }
jojisdogakane 0:2f6112d75752 873 else if(deg <= -11.25 && deg >= -33.75) {
jojisdogakane 0:2f6112d75752 874 degPoint = 0.625;
jojisdogakane 0:2f6112d75752 875 }
jojisdogakane 0:2f6112d75752 876 else if(deg <= -33.75 && deg >= -56.25) {
jojisdogakane 0:2f6112d75752 877 degPoint = 0.75;
jojisdogakane 0:2f6112d75752 878 }
jojisdogakane 0:2f6112d75752 879 else if(deg <= -56.25 && deg >= -78.75) {
jojisdogakane 0:2f6112d75752 880 degPoint = 0.875;
jojisdogakane 0:2f6112d75752 881 }
jojisdogakane 0:2f6112d75752 882 else if(deg <= -78.75 && deg >= -101.25) {
jojisdogakane 0:2f6112d75752 883 degPoint = 1;
jojisdogakane 0:2f6112d75752 884 }
jojisdogakane 0:2f6112d75752 885 else if(deg <= -101.25 && deg >= -123.75) {
jojisdogakane 0:2f6112d75752 886 degPoint = 0.875;
jojisdogakane 0:2f6112d75752 887 }
jojisdogakane 0:2f6112d75752 888 else if(deg <= -123.75 && deg >= -146.25) {
jojisdogakane 0:2f6112d75752 889 degPoint = 0.75;
jojisdogakane 0:2f6112d75752 890 }
jojisdogakane 0:2f6112d75752 891 else if(deg <= -146.25 && deg >= -168.75) {
jojisdogakane 0:2f6112d75752 892 degPoint = 0.625;
jojisdogakane 0:2f6112d75752 893 }
jojisdogakane 0:2f6112d75752 894 else {
jojisdogakane 0:2f6112d75752 895 degPoint = 0;
jojisdogakane 0:2f6112d75752 896 }
jojisdogakane 0:2f6112d75752 897
jojisdogakane 4:a0150e0f285b 898 happyRatioNow = degPoint;
jojisdogakane 4:a0150e0f285b 899
jojisdogakane 0:2f6112d75752 900 degRatio = (deg + 180.0) / 360.0;
jojisdogakane 0:2f6112d75752 901
jojisdogakane 0:2f6112d75752 902 float rcFilter = RCFILTER;
jojisdogakane 0:2f6112d75752 903 float filteredAngle = rcFilter * prevFilteredAngle + (1 - rcFilter) * degPoint;
jojisdogakane 0:2f6112d75752 904 prevFilteredAngle = filteredAngle ;
jojisdogakane 0:2f6112d75752 905
jojisdogakane 0:2f6112d75752 906 happyRatio = filteredAngle - 0.5;
jojisdogakane 0:2f6112d75752 907
jojisdogakane 0:2f6112d75752 908 if(happyRatio <= 0){
jojisdogakane 0:2f6112d75752 909 happyRatio = abs(happyRatio);
jojisdogakane 0:2f6112d75752 910 }
jojisdogakane 0:2f6112d75752 911 else {
jojisdogakane 0:2f6112d75752 912 happyRatio = 0;
jojisdogakane 0:2f6112d75752 913 }
jojisdogakane 0:2f6112d75752 914
jojisdogakane 0:2f6112d75752 915 // happyRatio = averageStressRatio ;// @@@
jojisdogakane 0:2f6112d75752 916
ayaando 10:867018503cd3 917 // nMsgHappyLen = sprintf(msgHappy,"H%0.2f\0", happyRatio);
jojisdogakane 0:2f6112d75752 918
jojisdogakane 0:2f6112d75752 919 // nMsgLen = sprintf(msg,"H%0.2f\0", happyRatio);
jojisdogakane 0:2f6112d75752 920 // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t*)msg, nMsgLen);
jojisdogakane 0:2f6112d75752 921
jojisdogakane 4:a0150e0f285b 922 // happyRatio = happyRatio * happyRatio * happyRatio;
jojisdogakane 0:2f6112d75752 923
jojisdogakane 4:a0150e0f285b 924 // happyRatio *= 10;
jojisdogakane 0:2f6112d75752 925
jojisdogakane 0:2f6112d75752 926 x3 = x2;
jojisdogakane 0:2f6112d75752 927 y3 = y2;
jojisdogakane 0:2f6112d75752 928
jojisdogakane 0:2f6112d75752 929 int HR_range = 0;
jojisdogakane 0:2f6112d75752 930
jojisdogakane 0:2f6112d75752 931 int HR_tempval = currentBPM;
jojisdogakane 0:2f6112d75752 932
jojisdogakane 0:2f6112d75752 933
jojisdogakane 0:2f6112d75752 934 // 心拍の係数を算出する
jojisdogakane 0:2f6112d75752 935
jojisdogakane 0:2f6112d75752 936 // 最大心拍数以上→最大心拍数に
jojisdogakane 0:2f6112d75752 937 if( HR_MAX < HR_tempval)
jojisdogakane 0:2f6112d75752 938 {
jojisdogakane 0:2f6112d75752 939 HR_tempval = HR_MAX;
jojisdogakane 0:2f6112d75752 940 }
jojisdogakane 0:2f6112d75752 941
jojisdogakane 0:2f6112d75752 942 // 最少心拍数以下→最少心拍数に
jojisdogakane 0:2f6112d75752 943 if( HR_MIN > HR_tempval)
jojisdogakane 0:2f6112d75752 944 {
jojisdogakane 0:2f6112d75752 945 HR_tempval = HR_MIN;
jojisdogakane 0:2f6112d75752 946 }
jojisdogakane 0:2f6112d75752 947
jojisdogakane 0:2f6112d75752 948 // 心拍の幅を計算
jojisdogakane 0:2f6112d75752 949 HR_range = HR_MAX - HR_MIN;
jojisdogakane 0:2f6112d75752 950
jojisdogakane 0:2f6112d75752 951 // 現在値-最少心拍数
jojisdogakane 0:2f6112d75752 952 HR_tempval = HR_tempval - HR_MIN;
jojisdogakane 0:2f6112d75752 953
jojisdogakane 0:2f6112d75752 954 // 心拍の係数を算出。0 ~ 1.0
jojisdogakane 0:2f6112d75752 955 HR_ratio = (double)HR_tempval / (double)HR_range;
jojisdogakane 0:2f6112d75752 956
jojisdogakane 0:2f6112d75752 957 if(conRatioNow >= 0.95 /* && averageAngle >= 0.7*/)
jojisdogakane 0:2f6112d75752 958 {
jojisdogakane 0:2f6112d75752 959 bConcentration = true;
jojisdogakane 0:2f6112d75752 960 }
jojisdogakane 0:2f6112d75752 961 else {
jojisdogakane 0:2f6112d75752 962 bConcentration = false;
jojisdogakane 0:2f6112d75752 963 }
jojisdogakane 0:2f6112d75752 964 prevRelaxRatio = relaxRatio;
jojisdogakane 0:2f6112d75752 965
jojisdogakane 0:2f6112d75752 966 int hval = 1023 * happyRatio;
jojisdogakane 0:2f6112d75752 967 int rval = 1023 * relaxRatio;
jojisdogakane 0:2f6112d75752 968 int cval = 1023 * conRatio;
jojisdogakane 0:2f6112d75752 969
jojisdogakane 0:2f6112d75752 970 // printf("H%d\n", hval);
jojisdogakane 0:2f6112d75752 971 // printf("R%d\n", rval);
jojisdogakane 0:2f6112d75752 972 // printf("C%d\n", cval);
jojisdogakane 0:2f6112d75752 973
ayaando 10:867018503cd3 974 // sprintf(msg,"%s%s%s%s\0", msgIBI, msgHappy, msgRelax, msgConcentration);
ayaando 10:867018503cd3 975
ayaando 10:867018503cd3 976 float relaxRatioFloat = float(1-relaxRatio);
ayaando 10:867018503cd3 977
ayaando 10:867018503cd3 978 memcpy(msg, msgHeader, sizeof(msgHeader));
ayaando 10:867018503cd3 979 memcpy(&(msg[ 3]), &IBI , sizeof(IBI) );
ayaando 10:867018503cd3 980 memcpy(&(msg[ 7]), &happyRatio , sizeof(happyRatio));
ayaando 10:867018503cd3 981 memcpy(&(msg[11]), &relaxRatioFloat, sizeof(relaxRatioFloat));
ayaando 10:867018503cd3 982 memcpy(&(msg[15]), &conRatio , sizeof(conRatio) );
jojisdogakane 0:2f6112d75752 983 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),
ayaando 10:867018503cd3 984 (uint8_t*)msg, sizeof(msg));
ayaando 10:867018503cd3 985 // (uint8_t*)msg, nMsgIBILen + nMsgHappyLen + nMsgRelaxLen + nMsgConcentrationLen);
jojisdogakane 0:2f6112d75752 986 // (uint8_t*)msg, nMsgIBILen + 1 + nMsgHappyLen + 1 + nMsgRelaxLen + 1 + nMsgConcentrationLen);
jojisdogakane 0:2f6112d75752 987
jojisdogakane 0:2f6112d75752 988 // determine color range
jojisdogakane 0:2f6112d75752 989
jojisdogakane 0:2f6112d75752 990 conRatio = conRatio - 0.5;
jojisdogakane 0:2f6112d75752 991
jojisdogakane 0:2f6112d75752 992 if(conRatio < 0) {
jojisdogakane 0:2f6112d75752 993 conRatio = 0;
jojisdogakane 0:2f6112d75752 994 }
jojisdogakane 0:2f6112d75752 995
jojisdogakane 0:2f6112d75752 996 conRatio = conRatio * 2;
jojisdogakane 0:2f6112d75752 997
jojisdogakane 0:2f6112d75752 998 // happyRatio = happyRatio * 2;
jojisdogakane 0:2f6112d75752 999 // happyRatio = happyRatio * 2;
jojisdogakane 0:2f6112d75752 1000 if(happyRatio > 1) {
jojisdogakane 0:2f6112d75752 1001 happyRatio = 1;
jojisdogakane 0:2f6112d75752 1002 }
jojisdogakane 4:a0150e0f285b 1003 /*
jojisdogakane 0:2f6112d75752 1004 if(BPM >= HR_MIN) {
jojisdogakane 0:2f6112d75752 1005 happyRatio /= ((float)(BPM * 2) / 255.0) ;
jojisdogakane 0:2f6112d75752 1006 }
jojisdogakane 4:a0150e0f285b 1007 */
jojisdogakane 0:2f6112d75752 1008 }
jojisdogakane 0:2f6112d75752 1009
jojisdogakane 4:a0150e0f285b 1010 if(BPM > 0 && bPulseEvent) {
jojisdogakane 4:a0150e0f285b 1011 int NewMood = getMood(BPM, relaxRatio, happyRatio, conRatio) ;
jojisdogakane 4:a0150e0f285b 1012
jojisdogakane 4:a0150e0f285b 1013 for(i = 0 ; i < NEOPIXEL_COUNT; i++) {
jojisdogakane 4:a0150e0f285b 1014 TargetColorArrayR[i] = MoodColorR[i][NewMood];
jojisdogakane 4:a0150e0f285b 1015 TargetColorArrayG[i] = MoodColorG[i][NewMood];
jojisdogakane 4:a0150e0f285b 1016 TargetColorArrayB[i] = MoodColorB[i][NewMood];
jojisdogakane 0:2f6112d75752 1017 }
jojisdogakane 4:a0150e0f285b 1018 }
jojisdogakane 0:2f6112d75752 1019
jojisdogakane 6:35f536162183 1020 for(i = NEOPIXEL_COUNT - 1; i >= 0; i--) {
jojisdogakane 6:35f536162183 1021 if(ColorArrayR[i] < TargetColorArrayR[i]) {
jojisdogakane 9:4363af5affba 1022 ColorArrayR[i]+=2;
jojisdogakane 9:4363af5affba 1023 if(ColorArrayR[i] > TargetColorArrayR[i]) {
jojisdogakane 9:4363af5affba 1024 ColorArrayR[i] = TargetColorArrayR[i];
jojisdogakane 9:4363af5affba 1025 }
jojisdogakane 6:35f536162183 1026 }
jojisdogakane 6:35f536162183 1027 else if(ColorArrayR[i] > TargetColorArrayR[i]) {
jojisdogakane 9:4363af5affba 1028 ColorArrayR[i]-=2;
jojisdogakane 9:4363af5affba 1029 if(ColorArrayR[i] < TargetColorArrayR[i]) {
jojisdogakane 9:4363af5affba 1030 ColorArrayR[i] = TargetColorArrayR[i];
jojisdogakane 9:4363af5affba 1031 }
jojisdogakane 4:a0150e0f285b 1032 }
jojisdogakane 6:35f536162183 1033 if(ColorArrayG[i] < TargetColorArrayG[i]) {
jojisdogakane 9:4363af5affba 1034 ColorArrayG[i]+=2;
jojisdogakane 9:4363af5affba 1035 if(ColorArrayG[i] > TargetColorArrayG[i]) {
jojisdogakane 9:4363af5affba 1036 ColorArrayG[i] = TargetColorArrayG[i];
jojisdogakane 9:4363af5affba 1037 }
jojisdogakane 4:a0150e0f285b 1038 }
jojisdogakane 6:35f536162183 1039 else if(ColorArrayG[i] > TargetColorArrayG[i]) {
jojisdogakane 9:4363af5affba 1040 ColorArrayG[i]-=2;
jojisdogakane 9:4363af5affba 1041 if(ColorArrayG[i] < TargetColorArrayG[i]) {
jojisdogakane 9:4363af5affba 1042 ColorArrayG[i] = TargetColorArrayG[i];
jojisdogakane 9:4363af5affba 1043 }
jojisdogakane 6:35f536162183 1044 }
jojisdogakane 6:35f536162183 1045 if(ColorArrayB[i] < TargetColorArrayB[i]) {
jojisdogakane 9:4363af5affba 1046 ColorArrayB[i]+=2;
jojisdogakane 9:4363af5affba 1047 if(ColorArrayB[i] > TargetColorArrayB[i]) {
jojisdogakane 9:4363af5affba 1048 ColorArrayB[i] = TargetColorArrayB[i];
jojisdogakane 9:4363af5affba 1049 }
jojisdogakane 4:a0150e0f285b 1050 }
jojisdogakane 6:35f536162183 1051 else if(ColorArrayB[i] > TargetColorArrayB[i]) {
jojisdogakane 9:4363af5affba 1052 ColorArrayB[i]-=2;
jojisdogakane 9:4363af5affba 1053 if(ColorArrayB[i] < TargetColorArrayB[i]) {
jojisdogakane 9:4363af5affba 1054 ColorArrayB[i] = TargetColorArrayB[i];
jojisdogakane 9:4363af5affba 1055 }
jojisdogakane 4:a0150e0f285b 1056 }
jojisdogakane 6:35f536162183 1057
jojisdogakane 6:35f536162183 1058 // 輝度調整
jojisdogakane 6:35f536162183 1059 r = ColorArrayR[i] * DIM_LED;
jojisdogakane 6:35f536162183 1060 g = ColorArrayG[i] * DIM_LED;
jojisdogakane 6:35f536162183 1061 b = ColorArrayB[i] * DIM_LED;
jojisdogakane 6:35f536162183 1062
jojisdogakane 6:35f536162183 1063 brightnessSum = r + g + b;
jojisdogakane 6:35f536162183 1064
jojisdogakane 6:35f536162183 1065 // 輝度の合計値が上限を超えた場合は補正する
jojisdogakane 6:35f536162183 1066 if(brightnessSum > BRIGHTNESS_MAX) {
jojisdogakane 6:35f536162183 1067 r = (int)(r * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 6:35f536162183 1068 g = (int)(g * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 6:35f536162183 1069 b = (int)(b * ((float)BRIGHTNESS_MAX / (float)brightnessSum));
jojisdogakane 0:2f6112d75752 1070 }
jojisdogakane 0:2f6112d75752 1071
jojisdogakane 4:a0150e0f285b 1072 neopixel_set_color(
jojisdogakane 6:35f536162183 1073 pixels[i],
jojisdogakane 4:a0150e0f285b 1074 0,
jojisdogakane 6:35f536162183 1075 short(r),
jojisdogakane 6:35f536162183 1076 short(g),
jojisdogakane 6:35f536162183 1077 short(b));
jojisdogakane 6:35f536162183 1078 neopixel_show(pixels[i]);
jojisdogakane 0:2f6112d75752 1079 }
jojisdogakane 4:a0150e0f285b 1080 //wait_ms(1);
jojisdogakane 6:35f536162183 1081 wait_ms(10); // 500usまで下げてもセンサー共振は起こらないことを確認
jojisdogakane 0:2f6112d75752 1082 }
jojisdogakane 0:2f6112d75752 1083 }
ayaando 10:867018503cd3 1084