Coder Social home page Coder Social logo

jingjie-li / ecgmonitor Goto Github PK

View Code? Open in Web Editor NEW
45.0 5.0 21.0 208.55 MB

A ECG/Oximeter Monitor design using TI's AFE4400 and ADS1293 IC, and MSP430MCU. Also we have an Android app to display waveform.

License: MIT License

Java 22.58% C 56.05% C++ 13.91% MATLAB 0.89% Processing 6.56%
ecg oximeter msp430

ecgmonitor's People

Contributors

jingjie-li avatar lijinmi avatar timothyzero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ecgmonitor's Issues

ADS1293 Stuff Hand Over

已经经过Arduino验证,ADS1293可以工作并且可以记录心电了,后面下一步就是你们用MSP430实现配置控制、和读数的功能了。

主要需要注意的要点有如下:

连线问题

可以直接用单片机给ADS芯片供电,注意要接__5V__和地线,千万不要接3V3,5v段没有电压可能会烧坏电源LDO芯片,单片机和ADS芯片__一定要共地__

剩下的只需要接SPI四根线,片选(CS),MOSI,MISO,SCLK(注意不要接到CLK上去了,那个是ADS输出时钟同步用的)

SPI时钟设置以及时序问题

经过arduino验证,SPI关键参数设置如下可以工作

  • 时钟极性 Clock Polarity (CPOL): 1

  • 时钟相位 Clock Phase (CPHA): 0

  • 输出边沿 Output Edge: 上升沿 Rising

  • 数据捕获边沿Data Capture: 下降沿 Falling
    这些对应Arduino SPI模式2,在Arduino上体现在这一句话SPI.setDataMode(SPI_MODE2);

  • 时钟分频,在Arduino上设为了21,相当于4MHz的SPI时钟频率

  • 字节输出顺序:MSBFIRST (most-significant bit first).

这块的意思大概是,最重要的字节先出去,意思就是从左往右的顺序输出01010这样,就是正常的顺序,貌似类似 big edian,这个设置非常重要,一定要设对!

SPI位数以及片选问题

这个是一个很重要的问题,我开始就是这块没弄对,因为默认SPI调用一次是发8位,你必须在这8位完成以后立马再来8位时钟才能实现读写,而且中间__片选信号千万不能断__

Arduino上的写入数据例子如下:

  SPI.transfer(cs,addrToSend,SPI_CONTINUE);
  SPI.transfer(cs,thisValue);

也就是先送8位地址的信号出去addrToSend,然后立马写thisValue过去,注意这里面cs代表使用的片选端口,上面那句带的SPI_CONTINUE代表这两句中间片选不间断,到第二句完了以后才关片选。

读数据的例子是这样

  const byte READ = 0b10000000;   //  read command  这一句放在最开始,是全局变量
  byte addrToRead = thisRegister | READ; // 读的话,地址第一位必须是1,这个是一个读写输入输出的控制,一定要注意
  SPI.transfer(cs,addrToRead,SPI_CONTINUE); // 先送8位地址,注意片选不能断
  result=SPI.transfer(cs,0x00); //这个时候,sclk时钟继续着,送出0x00代表MOSI一直是低电平,result就是从SPI读出的数据

在Arduino里,我写了函数封装了基本的读写,比如像这样
void writeRegister(byte cs, byte thisRegister, byte thisValue)
unsigned int readRegister(byte cs, byte thisRegister)
直接告诉函数你用哪个线片选,要读写什么地址啥的就好,建议你也这么做。

最关键的还是读取ECG数据!!这里用了一个steming的操作,需要额外注意下,手册38页一定要好好看下

在Arduino里我是这么操作的

   while (SerialUSB.available() == 0) {
        SPI.transfer(4,0xD0,SPI_CONTINUE); //告诉ADS,我们要读0x50地址,注意这个0xD0地址是因为第一位是1,读写控制。紧接着一直打开片选,不能断SPI_CONTINUE,后面保持着片选,时钟一加,数据一直源源不断跟着你的时钟按顺序出来,这个不太方便封装,你一定要仔细看,看不懂问我。
        
        receivedUpper = SPI.transfer(4,0x00,SPI_CONTINUE);//0x37 
        receivedMiddle = SPI.transfer(4,0x00,SPI_CONTINUE);//0x38
        receivedLower = SPI.transfer(4,0x00,SPI_CONTINUE);//0x39
  
        CH1EcgData=64*receivedUpper+8*receivedMiddle+receivedLower;
        
        receivedUpper = SPI.transfer(4,0x00,SPI_CONTINUE);//0x3A
        receivedMiddle = SPI.transfer(4,0x00,SPI_CONTINUE);//0x3B
        receivedLower = SPI.transfer(4,0x00,SPI_CONTINUE);//0x3C
  
        CH2EcgData=64*receivedUpper+8*receivedMiddle+receivedLower;
  
        receivedUpper = SPI.transfer(4,0x00,SPI_CONTINUE);//0x3D
        receivedMiddle = SPI.transfer(4,0x00,SPI_CONTINUE);//0x3E
        receivedLower = SPI.transfer(4,0x00);//0x3F
  
        CH3EcgData=64*receivedUpper+8*receivedMiddle+receivedLower;
  
        SerialUSB.print("ECG Channel 1 Data: ");
        SerialUSB.print(CH1EcgData);
        SerialUSB.print(" ECG Channel 2 Data: ");
        SerialUSB.print(CH2EcgData);
        SerialUSB.print(" ECG Channel 3 Data: ");
        SerialUSB.print(CH3EcgData);
        SerialUSB.print(" \n");

        delay(100);
      
   }

对ADS的SPI操作主要是这么几大块了

初始化写各种控制字

      writeRegister(4,0x01,0x11);
      writeRegister(4,0x02,0x19);
      writeRegister(4,0x03,0x2E);
      writeRegister(4,0x0A,0x07);
      writeRegister(4,0x0C,0x04);

      writeRegister(4,0x0D,0x01);
      writeRegister(4,0x0E,0x02);
      writeRegister(4,0x0F,0x03);

      writeRegister(4,0x10,0x01);

      writeRegister(4,0x12,0x04);
      writeRegister(4,0x21,0x02);
      writeRegister(4,0x22,0x02);
      writeRegister(4,0x23,0x02);
      writeRegister(4,0x24,0x02);
      writeRegister(4,0x27,0x08);
      writeRegister(4,0x2F,0x70);

打开数据记录

writeRegister(4,0x00,0x01);//start conversion
这就是向0地址写一个

开始通过steming读ECG各channel的数据

见前面讲steming的部分

关闭数据记录

writeRegister(4,0x00,0x00)//stop conversion

滤波问题

就今天记录的一段数据来看,貌似50Hz工频干扰有很显著的影响,一定要在MSP或者手机APP上做一个FIR或者IIR滤波,吧50Hz陷掉

主要就是这样,有问题问我,我ADS结束了赶紧弄AFE了

Serial Code Receiving Testing

Now the code that receiving serial code while running has been updated,

The main idea is that I added a function read the state of the UART buffer in the UART library, and add a function to directly read content from the UART buffer without asking for UART RX state.

In the main function, for every loop, we have a loop quit flag. We asked for UART buffer state in every interruption pulse, if there is something, we quit the main loop, go to another running state based on what we read from the UART buffer.

Now what we should do is to test whether is work smoothly.

Basically, you should send a char 'M' to start the sampling, while sampling, you will see EEG and ECG wave form directly. In the running state, you will want to send a char 'T', to trigger a stage switching. You are expected to see the HRP LED flashing, and the UART will sent '0x00,0x01 to 0x07',you need to check what you received in your cellphone.

MSP Androide Communicate Protocol

Android Send Command:

M - Normal Mode- Mobile receiving data (5-Lead ECG)
N - Normal Mode(3-Lead ECG)
F - AFE Only Mode - Turnoff ADS and only receive AFE PPG data. Encoding Formant not change, ADS data fills zero.
A - ADS Only Mode (5-Leads)
B - ADS Only Mode (3-Leads)
T - Stop & Wait Mode

X - Select CH I
Y - Select CH II
Z - Select CH III

Abnormal Situation:

Receiving all 0 in ECG Data: Leads off
Receiving all 0 in PPG Data: SPO2 Probe off
Receiving all 1 in PPG Data: Fingers not in.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.