主题中讨论的其他器件: ADS1298、 ADS1294、 ADS1296、 ADS1299
我在 MATLAB 中从 ADS1198获得了8通道测试信号、下面是这些信号的图片。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
用于获取8通道测试信号的 Arduino 主代码
// ADS129n 系列连接的最小 sketch。 加载此脚本并打开 Tools/SerialMonitor。
//您应该看到类似这样的文本
//设备类型(ID 控制寄存器):62个通道:8.
//如果您看到“通道:0”,请检查您的接线
#include "ADS1298.h"
#include "adsCMD.h"
#include "base64.h"
#include //包括 SPI 库:
int gMaxChan = 0;// ads129n 支持的最大通道数= 4、6、8
int gIDval = 0;//设备 ID:ID 控制寄存器的低5位
int activeSerialPort = 0;//数据将被发送到最后发送命令的串行端口。 例如蓝牙或 USB 端口
const int kPIN_LED = 13;//具有内置光的引脚-对于 teensy 2.0通常为13、11。
int numActiveChannels = 0;
布尔 gActiveChan [9];//报告通道1.0.9是否处于活动状态
布尔 isRdataac = false;
布尔 base64Mode = false;
int sampleCount=0;
布尔 isLimit=false;
hexchar Digits[]="0123456789ABCDEF";
uint8_t serialBytes[200];
char sampleBuffer[1000];
uint8_t chan1[2];
const char * hardwareType ="未知";
const char * boardName ="HackEEG";
const char * makerName ="Hamid、Mujahid、Abdul Hamede";
const char * driverVersion ="ADS1298 driver v0.1";
#if define(__SAM3X8E__)
#define isDUE //检测 Arduino 到期
//#define WiredSerial SerialUSB //使用 Due 的本机端口
//#define nserial SerialUSB
#define nserial Serial1.(定义 nserial Serial1)
#define WiredSerial
其他
#define WiredSerial
#endif
void setup(){
使用命名空间 ADS1298;
//PREPARE 引脚为输出或输入
//pinMode (PIN_SCLK、输出);//可选- SPI 库将为我们执行此操作
//pinMode (PIN_DIN、输出);//可选- SPI 库将为我们执行此操作
//pinMode (PIN_DOUT、输入);//可选- SPI 库将为我们执行此操作
PinMode (IPIn_CS、输出);
引脚模式(PIN_START、输出);
引脚模式(IPIn_DRDY、输入);
PinMode (PIN_CLKSEL,输出);//*可选
PinMode (IPIn_RESET、输出);//*可选
PinMode (IPIn_PWDN、输出);//*可选
digitalWrite (PIN_CLKSEL、高电平);//外部时钟
//启动串行外设接口
SPI.begin();
SPI.setBitOrder(MSBFIRST);
#ifndef isDUE
SPI.setClockDivider(SPI_CLOCK_DIV4);//forum.pjrc.com/.../1156-Teensy-3-SPI-Basic-Clock-Questions
#endif
SPI.setDataMode(SPI_MODE1);
//启动 ADS1298
delay (500);//等待 ads129n 准备就绪-可能需要一段时间为电容器充电
digitalWrite (PIN_CLKSEL、高电平);//外部时钟
延迟(10);//等待振荡器唤醒
延迟(1);
digitalWrite (IPIn_PWDN,高电平);//*可选-关闭断电模式
digitalWrite (IPIn_RESET、HIGH);
延迟(1000);//*可选
digitalWrite (IPIn_RESET、LOW);
延迟(1);//*可选
digitalWrite (IPIn_RESET、HIGH);
delay (1500);//*可选等待18个 tCLK AKA 9微秒,我们使用1毫秒
ADC_SEND_COMMAND (SDATAC);//发送 SDATAC 命令(停止连续读取数据模式)
// delayMicroseconds (2);
延迟(100);
//确定可用通道的型号和数量
gIDval = ADC_rreg (ID);//寄存器0的低5位显示芯片类型
switch (gIDval & B00011111){//最低有效位报告通道
案件 B10000://16
HardwareType ="ADS1294";
gMaxChan = 4;//ads1294
中断;
案例 B10001://17
HardwareType ="ADS1296";
gMaxChan = 6;//ads1296
中断;
B10010号案件://18
HardwareType ="ADS1298";
gMaxChan = 8;//ADS1298
中断;
B11110案://30
HardwareType ="ADS1299";
gMaxChan = 8;//ads1299
中断;
B10110案:/22
HardwareType ="ADS119198";
gMaxChan = 8;//ads1198
中断;
默认值:
gMaxChan = 0;
}
//启动串行端口
NSerial.begin(115200);
WiredSerial.begin(115200);//在到期时使用本机端口
while (WiredSerial.read()>=0){}//forum.arduino.cc/index.php
//while (!WiredSerial);// Leonardo Arduino.cc/.../IfSerial 要求 (ads129n 需要3.3V 信号、Leonardo 需要5V 信号)
延迟(200);//获取由于复位问题而导致的
PinMode (kPIN_LED、输出);
WiredSerial.print ("设备类型(ID 控制寄存器):");WiredSerial.print (gIDval);WiredSerial.print ("设备名称:");WiredSerial.print (hardwareType);WiredSerial.print ("通道:");WiredSerial.println (gMaxChan);
digitalWrite (kPIN_LED、LOW);//打开 LED (HIGH 是电压电平)
detectActiveChannels();
WiredSerial.print ("活动信道数:");
WiredSerial.println (numActiveChannels);
ADC_wreg (GPIO、0);
adc_wreg (CONFIG3、PD_REFBUF | CONFIG3_CONST);
//对于 RLD:为内部基准加电并等待其稳定
//ADC_wreg (CONFIG3、RLDREF_INT | PD_RLD | PD_REFBUF | VREF_4V | CONFIG3_CONST);
//延迟(150);
//ADC_wreg (RLD_SENSP、0x01);//仅使用通道 IN1P 和 IN1N
//ADC_wreg (RLD_SENSN、0x01);//用于 RLD 测量
// Serial.println (high_Res_500_sps);
adc_wreg (CONFIG1、HIGH_RES_500_SPS);
ADC_wreg (CONFIG2、INT_TEST);//生成内部测试信号
//将前两个通道设置为输入信号
//将前两个通道设置为输入信号
对于(int i = 1;i <= 8;++I){
//ADC_wreg (CHnSET + I、FITER_INPUT | GAIN_6X);//使用 x12增益报告此通道
//ADC_wreg (CHnSET + I、FITER_INPUT | Gain_1X);//使用 x12增益报告此通道
ADC_wreg (CHnSET + I、TEST_SIGNAL | GAIN_6X);//创建方波
//ADC_wreg (CHnSET + I、0x65);
//adc_wreg (CHnSET + I、短接);//禁用此通道
}
//* for (int i = 2;i <= 2;++i){
//ADC_wreg (CHnSET + I、FITER_INPUT | Gain_1X);//使用 x12增益报告此通道
//ADC_wreg (CHnSET + I、FITER_INPUT | GAIN_12X);//使用 x12增益报告此通道
ADC_wreg (CHnSET + I、TEST_SIGNAL | GAIN_12X);//创建方波
//adc_wreg (CHnSET + I、短接);//禁用此通道
}
对于(int i = 3;i <= 6;+i){
//ADC_wreg (CHnSET + I、短接);//禁用此通道
ADC_wreg (CHnSET + I、FITER_INPUT | GAIN_12X);//使用 x12增益报告此通道
}
对于(int i = 7;i <= 8;++I){
ADC_wreg (CHnSET + I、FITER_INPUT | Gain_1X);//使用 x12增益报告此通道
//ADC_wreg (CHnSET + I、FITER_INPUT | GAIN_12X);//使用 x12增益报告此通道
//adc_wreg (CHnSET + I、test_signal | gain_12X);//创建方波
//adc_wreg (CHnSET + I、短接);//禁用此通道
}
*
// WiredSerial.println (“就绪”);
}
void loop()
{
if (WiredSerial.available ()){
nserial.println (WiredSerial.readString());
}
if (nserial.available ())
{使用命名空间 ADS1298;
string iDATA=nserial.readString();
WiredSerial.println ("reciped Command="+iDATA);
if (iDATA="1001"){
stopads();
}
否则(iDATA="1111")
{startads();
isLimit=false;}
否则、如果(iDATA="1010"){
startads();
WiredSerial.println ("连续2秒采样") 信号");
isLimit=true;
}
}
if (isRdatac){
if (samplpleCount<1000){
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
sendSamples();
}
否则{
isLimit=false;
WiredSerial.println ("1000个样本已发送");
stopads();
sampleCount=0;
}
}
}
void RDATA_COMMAND(){
使用命名空间 ADS1298;
while (digitalRead (IPIn_DRDY)=高电平);
ADC_SEND_COMMAND_LEASE_CS_ACTIVE (RDATA);
WiredSerial.println ("200 OK ");
sendSample();
WiredSerial.println();
}
void rdataac_command(){
使用命名空间 ADS1298;
detectActiveChannels();
if (numActiveChannels > 0){
isRdataac = true;
ADC_SEND_COMMAND (RDATAC);
WiredSerial.println ("500SPS OK");
WiredSerial.println ("RDATAC 模式打开。");
}否则{
WiredSerial.println ("405 Error:no active channel.");
}
WiredSerial.println();
}
内联 void sendSamples (void){
如果((!isRdatac)||(numActiveChannels<1))返回;
if (digitalRead (IPIn_DRDY)= HIGH) return;
sendSample();
}
//使用 SAM3X DMA
内联 void sendSample (void){
digitalWrite (IPIn_CS、低电平);
寄存器 int numSerialBytes =(2 *gMaxChan)+ 3;// 24位标头加上每个通道24位
uint8_t returnCode = spiRec (serialBytes、numSerialBytes);
digitalWrite (IPIn_CS、高电平);
寄存器 unsigned int count = 0;
if (base64Mode = true){
Base64_encode (samplpleBuffer、(char *) serialBytes、numSerialBytes);
}
否则{
encodeHex (samplpleBuffer、(char *) serialBytes、numSerialBytes);
}
nserial.println (samplpleBuffer);
if (isLimit){
SampleCount++;
}
}
void encodeHex (char*输出、char*输入、int inputLen){
寄存器 int count = 0;
对于(寄存器 int i=0;i < inputLen;i++){
寄存器 uint8_t lowNyble = input[i]& 0x0F;
寄存器 uint8_t highNybble = input[i]>> 4;
output[count++]= hexDigits [高 Nyble];
output[count++]= hexDigits [低 Nyble];
}
output[count]= 0;
}
uint8_t spiRec (uint8_t* buf、size_t len){
对于(size_t i = 0;i < len;i++){
buf[i]= SPI.transfer (0xFF);
}
返回0;
}
/*void reg_val (){
serial.print ("Config1:");
serial.println (adc_rreg (config1));
serial.print ("Config2:");
serial.println (adc_rreg (CONFIG2));
serial.print ("Config3:");
serial.println (adc_rreg (CONFIG3));
serial.print ("LOFF:");
serial.println (adc_rreg (LOFF));
serial.print ("RLD_SENSP:");
serial.println (adc_rreg (RLD_SENSP));
serial.print ("RLD_SENSN:");
serial.println (adc_rreg (RLD_SENSN));
serial.print ("CONFIG4:");
serial.println (adc_rreg (CONFIG4));
serial.print ("resp:");
serial.println (adc_rreg (resp));
serial.print ("WCT1:");
serial.println (adc_rreg (WCT1));
serial.print ("WCT2:");
serial.println (adc_rreg (WCT2));
}*/
void detectActiveChannels(){//将器件设置为 RDATAC (连续)模式-它将流式传输数据
如果((isRdatac)||(gMaxChan < 1)返回;//在 RDATAC 模式下无法读取寄存器
//Serial.println ("检测活动通道:");
使用命名空间 ADS1298;
numActiveChannels = 0;
对于(int i = 1;i <= gMaxChan;i++){
delayMicroseconds (1);
int chSet = ADC_rreg (CHnSET + I);
gActiveChan [i]=((chSet & 7)!=短接);
if ((chSet & 7)!=短接) numActiveChannels ++;
}
}
void startADS (){
WiredSerial.println ("连续读取数据...... ");
使用命名空间 ADS1298;
ADC_SEND_COMMAND (START);
rdataac_command();
isRdataac=true;
}
void stopads(){
使用命名空间 ADS1298;
WiredSerial.println ("停止连续读取数据模式");
ADC_SEND_COMMAND (SDATAC);//发送 SDATAC 命令(停止连续读取数据模式)
isRdataac=false;
// delayMicroseconds (2);
延迟(100);
}
您好、Ahmed、
当 Alex 度假时、我会尽力提供帮助。
我重新访问了您的初始帖子、看起来大多数数据都是正确的。 但是、偶尔会发生一些中断、这些中断可能由一些 SPI 时序问题引起。 请使用逻辑分析仪检查接口信号、并验证您是否正在开始和结束每个事务、而不会与/DRDY 中断重叠。
您能否提供每个通道的输出数据速率、基准电压和增益设置?
此外、我绘制了您共享的原始数据。 一个通道1似乎存在间歇性问题、这同样可以通过糟糕的 SPI 事务来解释。 您能否列出用于收集此数据的十六进制寄存器设置?
将来、请在单独的文本文件中共享代码和数据结果、并将其附加到您的帖子中、以便该主题更易于阅读。
此致、
以下是获取测试信号所需的设置
输出数据速率= 500sps
基准电压= 2.4V
增益设置= 6
CONFIG1=0xA6
CONFIG2=0x10
CONFIG3=0xC0
通道集= 0x05
我对电极输入还有一个问题、我将 ECG 仿真器 skx2000c 与 ADS1198的输入相连、 仿真器为我们提供滤波输出、因此我认为无需在前端添加模拟抗混叠滤波器、因此我将仿真器输出直接连接到 ADS1198的输入、但除了通道3外、输出看起来非常糟糕。
由于我之前布置了通道2-7的测试信号(通道1和通道8除外)看起来不错、那么电极输入的问题是什么、我将配置3多路复用器设置中的设置更改为 000 (正常电极输入) 但我不设置 RLD 和 WCT、因为我认为仿真器滤波输出不需要 WCT 和 RLD、因为 RLD 消除了共模噪声、WCT 是仿真器已经生成的胸导联的参考。
现在请告诉我、如果我错了、那么 RLD (8通道)和 WCT 以及电极输入的任何其他寄存器的设置是什么。
下面是8通道电极输出的附件
谢谢
您好、Ahmed、
感谢寄存器设置。 以下是有关这一点的一些评论:
您是否能够使用逻辑分析仪检查 SPI 事务并验证时序?
我在反转您应用的异或函数后重新绘制了您的数据。 信号振幅看起来正确。 您在 CH1上观察到的尖峰可能是由于数据传输与新的/DRDY 中断重叠而导致数据读取错误或数据损坏的原因。
请开始新主题、讨论您有关电极输入配置的其他问题。
此致、