Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define PROCESSING_VISUALIZER 1
- #define SERIAL_PLOTTER 2
- #include <LiquidCrystal.h>
- LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
- int pulsePin = 0; // контакт провода данных на A0
- volatile int BPM; // удары в минуту
- volatile int Signal; // входной сигнал
- volatile int IBI = 600; // интервал между ударами
- volatile boolean Pulse = false; // обнаружено ли сердцебиение
- volatile boolean QS = false;
- volatile int rate[10]; // IBI
- volatile unsigned long sampleCounter = 0; // определить синхронизацию импульсов
- volatile unsigned long lastBeatTime = 0; // IBI
- volatile int P =512; // пик в пульсовой волне
- volatile int T = 512; // яма в пульсовой волне
- volatile int thresh = 530; // поиск момента сердца, seeded
- volatile int amp = 0; // амплитуда, seeded
- volatile boolean firstBeat = true;
- volatile boolean secondBeat = false;
- void interruptSetup(){
- TCCR2A = 0x02; // CTC
- TCCR2B = 0x06; // F/256
- OCR2A = 0x7C; // 124 (500Hz)
- TIMSK2 = 0x02; // прерывание по совпадению
- sei();
- }
- ISR(TIMER2_COMPA_vect){
- cli();
- Signal = analogRead(pulsePin);
- sampleCounter += 2; // время в мс переведём с помощью этой переменной
- int N = sampleCounter - lastBeatTime; // Следить за временем с момента последнего удара, чтобы избежать шума
- // Найти пик и впадину пульсовой волны
- if(Signal < thresh && N > (IBI/5)*3){ // избегаем шума, выжидая 3/5 от последнего IBI
- 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; // Установить флаг Pulse, когда мы думаем, что есть импульс
- 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(); // enable interrupts again
- return;
- }
- // Сохранить текущую совокупность последних 10 значений IBI
- word runningTotal = 0;
- for(int i=0; i<=8; i++){ // сдвигаем данные
- rate[i] = rate[i+1]; // И отбросить старое значение IBI
- runningTotal += rate[i]; // Суммировать 9 самых старых значений IBI
- }
- rate[9] = IBI; // Добавьте последний IBI в массив
- runningTotal += rate[9]; // Добавьте последний IBI в runningTotal
- runningTotal /= 10; // среднее
- BPM = 60000/runningTotal; // считаем УД/М
- QS = true;
- }
- }
- if (Signal < thresh && Pulse == true){ // Когда значения падают, ритм заканчивается
- Pulse = false;
- amp = P - T; // амплитуда
- thresh = amp/2 + T; // яма = 50% от амплитуды
- P = thresh;
- T = thresh;
- }
- if (N > 2500){ // если 2.5 секунды без биений
- thresh = 530; //
- P = 512; // всё по умолчанию
- T = 512; //
- lastBeatTime = sampleCounter;
- firstBeat = true;
- secondBeat = false;
- }
- sei();
- }
- volatile char firstStr[16] = {
- 0x42, // B
- 0x61, // a
- 0xC1, // ш
- 0x20, // _
- 0xBE, // п
- 0x79, // y
- 0xBB, // л
- 0xC4, // ь
- 0x63, // c
- 0x3A, // :
- 0x20, // _
- 0x20, // _
- 0x20, // _
- 0x20, // _
- 0x20, // _
- 0x20 // _
- };
- volatile char secondStr[10] = {
- 0x20, // _
- 0x28, // (
- 0xA9, // У
- 0xE3, // д
- 0x2F, // /
- 0x4D, // M
- 0xB8, // и
- 0xBD, // н
- 0x29, // )
- 0x20 // _
- };
- void setup(){
- lcd.begin(16, 2);
- lcd.clear();
- lcd.print((char*)firstStr);
- interruptSetup();
- }
- void loop(){
- lcd.setCursor(0, 1);
- lcd.print(BPM);
- lcd.print((char*)secondStr);
- delay(50);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement