Dependencies: mbed LSM9DS1 FastPWM
Diff: main.cpp
- Revision:
- 0:33061e64e773
- Child:
- 1:72bcbf11c621
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 05 13:55:16 2019 +0000 @@ -0,0 +1,409 @@ +#include "mbed.h" +#include "LSM9DS1.h" +#include "FastPWM.h" +#include <math.h> +// setting of MIX DEVICE +#define DA_PS_BT false //Digital Accelerometer + Pulse Sensor + Bluetooth +#define AA_PS_BT false// Analog Accelerometer + Pulse Sensor + Bluetooth +#define DA_PS_Op true//Digital Accelerometer + Pulse Sensor + Optical +#define AA_PS_Op false// Analog Accelerometer + Pulse Sensor + Optical + +#define PS_MODE false // On/Off Pulse Sensor +#define PS_PIN A3 //Pulse Sensor pin + +#define ACC_X_PIN A6 +#define ACC_Y_PIN A5 //Analog Accelerometer pins +#define ACC_Z_PIN A4 + +#define X0 1.69 //calibrated counts of analog Accelerometer +#define Y0 1.67 +#define Z0 1.68 +#define Sx 0.65 +#define Sy 0.65 +#define Sz 0.65 + +#define BT_TX_PIN PA_9 // Bluetooth pins +#define BT_RX_PIN PA_10 + +#define OPT_TX_PIN A7 // optical pins, pwm, baudrate +#define OPT_RX_PIN A2 +#define BAUD_RATE 19200 +#define PWM_PIN D10 +#define PWM_MODE 455 + +#if (DA_PS_Op || DA_PS_BT) + LSM9DS1 acc(D4, D5); + //acc.setAcceleroRange(LSM9DS1_ACCELERO_RANGE_2G); +#endif + +#if (AA_PS_BT || DA_PS_BT) // uart's init + Serial pc(SERIAL_TX, SERIAL_RX); // tx, rx + Serial BT(BT_TX_PIN, BT_RX_PIN); // tx, rx + float acc_x,acc_y,acc_z; +#endif + +#if (AA_PS_Op || DA_PS_Op) + Serial Serial2(OPT_TX_PIN,OPT_RX_PIN,BAUD_RATE); + int16_t acc_x,acc_y,acc_z; +#endif + +#if (AA_PS_BT || AA_PS_Op) + AnalogIn X(ACC_X_PIN); + AnalogIn Y(ACC_Y_PIN); + AnalogIn Z(ACC_Z_PIN); +#endif + +#if (PS_MODE) + AnalogIn P(ACC_X_PIN); +#endif + +DigitalOut myled(LED1, 1); + +PwmOut buzz(A1); + +float ARes = 2.0 / 32768.0; // Digital ACC have datatype int16_t + +int Signal = 0; +int total = 0; + +int average = 0; +int IsoLine = 0; +int Tpulse = 0; +int Tpulse2 = 0; +uint16_t count2=0; +uint16_t count3=0; +int AccData[3]; +unsigned int trame1,trame2,trame3,trame4,trame5,trame6,trame7,trame8, trame9,tramePULSE; +int cptmesure; +Timer t; +Timer T1; +Timer T2; + +//variables globals + +float delta; + +double Last, Now; +bool START = false; +int coun; + +float tableau_x[10], tableau_y[10], tableau_z[10], t_delta[10]; + +int numReadings = 70; +int Index = 0; +int readings[70]; +int IndexBPM = 5; +int IndexB = 0; +int readingsBPM[5]; +int k; +int totalBPM; +int averageBPM; +int verif; +int patient; + +void setup() +{ + #if (AA_PS_Op || DA_PS_Op) + FastPWM mypwm(PWM_PIN,1); //Initializing of clock Output + //Clock settings for 38kHz + if (PWM_MODE == 38) + { + mypwm.period_us(26.3158); + mypwm.pulsewidth_us(13.1579);//Duty-Cycle 50% here + } + //Clock settings for 455kHz + if (PWM_MODE == 455) + { + mypwm.period_us(2.1978); + mypwm.pulsewidth_us(1.0989);//Duty-Cycle 50% here + } + #endif + + #if (AA_PS_BT || DA_PS_BT) + BT.baud(115200); + pc.baud(115200); // Start serial at 115200 bps + #endif + + #if (DA_PS_BT || DA_PS_Op) + acc.setAcceleroRange(LSM9DS1_ACCELERO_RANGE_2G); + #endif + buzz.period_us(2272.7f); + buzz.write(0.0f); +} +#if (PS_MODE) + int readMean(int samples) + { + int sum = 0; + for (int i = 0; i < samples; i++) + { + sum = sum + (4096 * P); + } + return sum/samples; + } + + +void pulse() +{ + Signal = readMean(10); + total = total - readings[Index]; + readings[Index] = Signal; // ...которое было считано от сенсора: + total = total + readings[Index]; // добавляем его к общей сумме: + Index = Index + 1; // продвигаемся к следующему значению в массиве: + if (Index >= numReadings) + Index = 0; // ...возвращаемся к началу: + int Maxn = 0; //обнуляем максимальное значение предидущих выборок массив + for (int i = 0; i < numReadings; i++) // поиск макимальеого значения в масиве из "numReadings" выборок + { + if (readings[i]>Maxn) + Maxn = readings[i]; + } + average = total/numReadings; + IsoLine = average + ((Maxn - average)*0.7); + + //Serial2.printf("%u %u %u\n", Signal, IsoLine ,average); + if ((Signal > IsoLine) && (k > 0)) + { + T1.stop(); + Tpulse = Tpulse2 + T1.read_us(); + int Tpulse22 = (long)(60L*1000L*1000L)/Tpulse; + totalBPM = totalBPM - readingsBPM[IndexB]; + readingsBPM[IndexB] = Tpulse; // ...которое было считано от сенсора: + totalBPM = totalBPM + readingsBPM[IndexB]; // добавляем его к общей сумме: + IndexB = IndexB + 1; // продвигаемся к следующему значению в массиве: + averageBPM = 60000000L/((long)totalBPM/IndexBPM); + if(IndexB >= 5)IndexB = 0; // если мы в конце массива возвращаемся к началу: + //Serial2.printf("BPM: %d averageBPM: %d\n", Tpulse22, averageBPM); + T1.reset(); + T1.start(); + k--; + } + else + { + if (k < 1) + { + T1.stop(); + Tpulse2 = T1.read_us(); + T1.reset(); + T1.start(); + k++; + } + } +} +#endif +void matrice_euler() +{ + tableau_x[coun-1]=acc_x; + tableau_y[coun-1]=acc_y; + tableau_z[coun-1]=acc_z; + t_delta[coun-1]=delta; +} + +void read_capteur() +{ + #if (DA_PS_BT) //Digital acc init + acc_x = -acc.getAcceleroRawY()*ARes; + acc_y = acc.getAcceleroRawX()*ARes; + acc_z = acc.getAcceleroRawZ()*ARes; + #elif (AA_PS_BT) // !!axis directions are correct!! + acc_x = (Y*3.3-Y0)/Sy; + acc_y = -(X*3.3-X0)/Sx; + acc_z = -(Z*3.3-Z0)/Sz; + #elif (AA_PS_Op) + acc_x = Y*4096; + acc_y = -X*4096; + acc_z = -Z*4096; + #elif (DA_PS_Op) + //acc.getAcceleroRaw(AccData); + acc_x = -acc.getAcceleroRawY(); + acc_y = acc.getAcceleroRawX(); + acc_z = acc.getAcceleroRawZ(); + #endif + + #if (PS_MODE) + pulse(); + #endif +} + +void loop () +{ + read_capteur(); + matrice_euler(); + + #if (AA_PS_BT || DA_PS_BT) + if (coun>=10 && count3>=20) + { + char s1[50]; //size of the number + char s2[50]; + char s3[50]; + char s4[50]; + char s5[50]; + + myled=!myled; + coun=0; + for(int i=0; i<10; i++) + { + sprintf(s1, "%g", tableau_x[i]); + sprintf(s2, "%g", tableau_y[i]); + sprintf(s4, "%g", tableau_z[i]); + sprintf(s3, "%g", t_delta[i]); + #if (PS_MODE) + sprintf(s5, "%g", averageBPM); + BT.printf("%s;%s;%s;%s;%s|", s1,s2,s4,s3,s5); + #else + BT.printf("%s;%s;%s;%s|", s1,s2,s4,s3); + #endif + } + } + #else //(DA_PS_Op || AA_PS_Op) + //increment of measurement: avoids the redundancy of the display on the server + cptmesure++; + if(cptmesure == 8) + cptmesure = 0; + + trame2 = (acc_x & 0xFF00) >> 8; // mask 1111 1111 0000 0000 (ACC 16 bit) int16_t + trame3 = (acc_x & 0xFF); // mask 0000 0000 1111 1111 + trame4 = (acc_y & 0xFF00) >> 8; + trame5 = (acc_y & 0xFF); + trame6 = (acc_z & 0xFF00) >> 8; + trame7 = (acc_z & 0xFF); + + verif = (trame2 << 3) + cptmesure ; + + //first frame: patient + verif (2 bits high) + trame1 = (patient << 4) + ((verif & 0x700) >> 7);//mask 111 0000 0000 + + trame8 = (verif & 0xFF);//mask 1111 1111 + + //fifth frame: patient + increment measurement + trame9 = (patient << 4) + (cptmesure << 1); + +/* IMPORTANT TO UNDERSTAND (ONLY FOR NUCLEO) + We fill the table which gonna be sent + TrameTab[0] = 255; + TrameTab[1] = trame1; + + TrameTab[2] = trame2; + TrameTab[3] = trame3; + + TrameTab[4] = trame8; + TrameTab[5] = trame9; + + //We sent the table through the serial port + //Serial2.write(TrameTab,6,0,0); + //Serial.write to send the information under 8 bits. Serial.print sends a number digit by digit to use to have a display on the monitor. + //BUT if we will use write() then sketch will stuck after 166 seconds. putc() working same as write(). +*/ + Serial2.putc(255); + Serial2.putc(trame1); + Serial2.putc(trame2); + Serial2.putc(trame3); + Serial2.putc(trame4); + Serial2.putc(trame5); + Serial2.putc(trame6); + Serial2.putc(trame7); + #if (PS_MODE) + Serial2.putc((uint8_t)averageBPM); + #endif + Serial2.putc(trame8); + Serial2.putc(trame9); + #if (!PS_MODE) + switch(BAUD_RATE) + { + case 4800 : + //wait_us(20000); + wait_us(41666.66); + wait_us(3200); + break; + case 9600 : + wait_us(20833.33); + wait_us(1100); + break; + case 19200 : + wait_us(10416.66); + wait_us(200); + break; + case 38400 : + wait_us(4836.6);//data transfer compensation -351.7us for 38400 baud and 5208.3us delay + //for using the same resistor that we use for optical ECG we should save the equation T_delay = 2*T_transmission + break; + default : + wait_ms(50); + } + #endif + #if (PS_MODE) + switch(BAUD_RATE) + { + case 4800 : + //wait_us(20000); + wait_us(41666.66 + 4166.66); + wait_us(3200 + 320); + break; + case 9600 : + wait_us(20833.33 + 2083.33); + wait_us(1100 + 110); + break; + case 19200 : + wait_us(10416.66 + 1041.66); + wait_us(200 + 20); + break; + case 38400 : + wait_us(4836.6 + 520.83);//data transfer compensation -351.7us for 38400 baud and 5208.3us delay + //for using the same resistor that we use for optical ECG we should save the equation T_delay = 2*T_transmission + break; + default : + wait_ms(50); + } + #endif + #endif +} + +int main() +{ + + setup(); + t.start(); + Last = t.read_us(); + coun=0; + count3=0; + + while (true) + { + #if (AA_PS_BT || DA_PS_BT) //bluetooth mode + Now = t.read_us(); + delta = (float)(Now-Last)/1000000.0f; + if (delta>=0.1f && START==true) + { + Last=Now; + coun+=1; + if (count3<=81) + { + count3+=1; + } + + loop(); //Get sensor values + } + if (BT.readable()) + { + char c = BT.getc(); + if(c == '1'){ + //BT.printf("\nOK\n"); + START=true; + count3=0; + } + if(c == '0') + { + //BT.printf("\nOK\n"); + START=false; + myled=1; + buzz.write(0.50f); + wait(3); + buzz.write(0.0f); + } + } + #else + //optical + loop(); + #endif + } +} +