Pukhraj Dhiman
Published © GPL3+

DNN Based Homemade ECG

Due to High cost of ECG this project aims to be cost-effective still be able to perform early detection of Heart Problems

AdvancedWork in progress6 hours4,664
DNN Based Homemade ECG

Things used in this project

Hardware components

Raspberry Pi 4 Model B
Raspberry Pi 4 Model B
For processing the pulses and executing the code on it
×1
Raspberry Pi Touch Display
Raspberry Pi Touch Display
For a real-time visualization of patient's Pulses
×1
Nucleo 144 STM32F7
ST STM32L4, STM32F7 Nucleo 144 STM32F7
For processing the digital data from the ECG Module
×1
AD8232 Heart Rate Monitor Module
For reading the pulses of the patient
×1
ADS1115 Analog to Digital Convertor
For converting the analog signals to Digital Signals from ECG
×1
USB to Serial Adaptor
×1

Software apps and online services

GNAT Community
AdaCore GNAT Community
GNAT Pro
AdaCore GNAT Pro

Story

Read more

Schematics

schematics

Code

Code for Raspberry Pi

Python
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import re
import threading
from scipy.signal import filtfilt, iirnotch, freqz, butter
from scipy.fftpack import fft, fftshift, fftfreq
import numpy as np
import scipy.fftpack

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    cutoff = cutoff1 / nyq
    b, a = butter(order, cutoff, btype='low', analog=False)
    return b, a

gData = [0]

fig = plt.figure()
ax = fig.add_subplot(111)
hl, = ax.plot(range(len(gData)), gData)
plt.ylim(0, 3300)
plt.xlim(0,500)


f0 = 40
fs = 100
# Filtering using iirnotch
w0 = f0/(fs/2)
Q = 20
#b, a = iirnotch(w0, Q)
b, a = butter_lowpass(40, fs, 10)

# filter response
w, h = freqz(b, a)
filt_freq = w*fs/(2*np.pi)

def filter_50(signal):
    for i in np.arange(50,500,50):
        fs = 1000.0  # Sample frequency (Hz)
        f0 = i  # Frequency to be removed from signal (Hz)
        w0 = f0 / (fs / 2)  # Normalized Frequency
        Q= 30
        b, a = iirnotch(w0, Q)
        signal = scipy.signal.filtfilt(b, a, signal)
    return(signal)


def GetData(out_data):
    with serial.Serial('\\.\COM9',115200, timeout=1) as ser:
        print(ser.isOpen())
        while True:
            line = ser.readline().decode('utf-8')

def update_line(num, hl, data):
    global filt_freq, ax2, b, a

    if len(data) > 50:
        y_filt = filtfilt(b, a, data)
    else:
        y_filt = data
    hl.set_data(list(range(1,len(data)+1)), y_filt)
    
    plt.ylim(min(data),max(data))

    return hl,


dataCollector = threading.Thread(target = GetData, args=(gData,))
dataCollector.start()

plt.show()

dataCollector.join()

Code For Microcontroller

C/C++
with Ada.Numerics;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
with Ada.Exceptions;
with Console;

package body FFT is
   
   procedure Generic_FFT (X : Complex_Vector; Y : out Complex_Vector) is
 
      package Complex_Elementary_Functions is
        new Ada.Numerics.Generic_Complex_Elementary_Functions
          (Complex_Arrays.Complex_Types);
 
      use Ada.Numerics;
      use Complex_Elementary_Functions;
      use Complex_Arrays.Complex_Types;
      
      procedure FFT (X : Complex_Vector; N, S : Positive; Y : out Complex_Vector) is
      begin
         
         if N = 1 then
            Y := (1..1 => X (X'First));
         else
            declare
               F : constant Complex  := exp (Pi * j / Real_Arrays.Real (N/2));
               Even : Complex_Vector(1..N/2);-- := FFT (X, N/2, 2*S);
               Odd  : Complex_Vector(1..N/2);-- := FFT (X (X'First + S..X'Last), N/2, 2*S);
            begin
               FFT (X, N/2, 2*S, Even);
               FFT (X (X'First + S..X'Last), N/2, 2*S, Odd);
               
               for K in 0..(N/2 - 1) loop
                  declare
                     T : constant Complex := Odd (Odd'First + K) / F ** K;
                  begin
                     Odd  (Odd'First  + K) := Even (Even'First + K) - T;
                     Even (Even'First + K) := Even (Even'First + K) + T;
                  end;
               end loop;
               Y := Even & Odd;
               --return Even & Odd;
            end;
         end if;
      end FFT;
      
   begin
      FFT(X, X'Length, 1, Y);
      --return FFT(X, X'Length, 1);
      
   exception
      when error : others =>
         Console.put(Ada.Exceptions.Exception_Information(error) & ASCII.CR & ASCII.LF); 
   end Generic_FFT;
      
end FFT;

Credits

Pukhraj Dhiman

Pukhraj Dhiman

13 projects • 5 followers

Comments