工具与软件:
大家好! 我有一个问题一直困扰着我一个星期,我不知道如何解决它。 我想征求每个人的建议。 谢谢!
我基于 OpenBCI PCB 设计使用 ADS1299芯片设计了一个 PCB、并尝试使用 Adafruit nRF52832开发板读取数据。 我主要修改了 master·chipaudette/OpenBCI (github.com)上基于 OpenBCI/Arduino/Librarys/ADS1299的代码 、以将适用于 AVR 控制器的 SPI 信号读取代码替换为适用于与 Adafruit nRF52832进行 SPI 通信的代码。 在实际测试中、我使用代码来打印 ADS1299数据、该数据已从3字节2补码转换为4字节2补码。
代码确实如此处所示。 这和主功能代码一样、我打印了转换后的数据8个通道用于验证
void loop(){ if (is_running) { //is data ready? while(!(ADSManager.isDataAvailable())){ // watch the DRDY pin delayMicroseconds(10); } unsigned long start_micros = micros(); //get the data // analogVal = analogRead(PIN_ANALOGINPUT); // get analog value ADSManager.updateChannelData(); // update the channelData array sampleCounter++; // increment my sample counter //Apply filers to the data if (useFilters) applyFilters(); ADSManager.printChannelDataAsText(MAX_N_CHANNELS,sampleCounter); //print all channels, whether active or not } } // end of loop void ADS1299::updateChannelData(){ byte inByte; int nchan=8; //assume 8 channel. If needed, it automatically changes to 16 automatically in a later block. digitalWrite(CS, LOW); // open SPI // READ CHANNEL DATA FROM FIRST ADS IN DAISY LINE for(int i=0; i<3; i++){ // read 3 byte status register from ADS 1 (1100+LOFF_STATP+LOFF_STATN+GPIO[7:4]) inByte = transfer(0x00); stat_1 = (stat_1<<8) | inByte; } for(int i = 0; i<8; i++){ for(int j=0; j<3; j++){ // read 24 bits of channel data from 1st ADS in 8 3 byte chunks inByte = transfer(0x00); channelData[i] = (channelData[i]<<8) | inByte; } } digitalWrite(CS, HIGH); // close SPI //reformat the numbers for(int i=0; i<nchan; i++){ // convert 3 byte 2's compliment to 4 byte 2's compliment if(bitRead(channelData[i],23) == 1){ channelData[i] |= 0xFF000000; }else{ channelData[i] &= 0x00FFFFFF; } } }
我发现大多数数据都是正常的、但突然发生了突变;信号应该是连续的、但显然存在错误的数据点。 我发现转换3字节二进制补码数据不是问题。 相反、问题似乎出在数据读取过程本身。
以下是 ADS1299 8通道数据在不同情况下的数据:1)悬空2)内部测试信号:短接3)内部测试信号:1mV 方波 4)内部测试信号:2mV 方波。 最左边只是一个计数器、后面是8个通道数据。 正如您所看到的、幅度似乎是正确的、但读数有突变、我将其称为异常值。 这种噪声让我感到疯狂。
为了帮助进行调试、我会尽可能详细地列出信息。
首先是我的寄存器设置:
第二、 我怀疑问题在于 SPI 通信、因此我使用了逻辑分析仪和示波器捕获信号以进行分析。 但是、由于这是我第一次使用这些仪器来捕获信号、我发现我捕获的信号有点矛盾、很难解释。
这是逻辑分析仪显示的内容:此 SPI 通信信号是否存在任何问题? 我注意到 SCLK 信号看起来不像预期的那样;它应该看起来不像这样。
为了进一步研究、我使用示波器来测量 SCLK 和 DRDY 信号的波形。 黄色迹线为 SCLK、蓝色迹线为 DRDY 信号。
1.
在示波器上、SCLK 信号看起来相对正常、但 DRDY 信号在变为高电平之前未按预期行为。 在下图中、我主要观察 DRDY 信号。 我将采样率设置为1000Hz、因此间隔为1ms、并使用自动设置成功采集此间隔。 但是、我注意到 DRDY 信号非常不稳定;当我将时间间隔调整为1ms 时、信号看起来不一致。 如您所见、除了每1ms DRDY 信号外、还有一些噪声。
这是我到目前为止已经尝试过的步骤、但我不确定是我的电路、代码问题还是我选择了错误的 MCU。 我还尝试使用 ESP32读取数据。 这种情况真的令人沮丧。 如果有人可以提出可能的问题、我会尝试收集更多信息并努力找到解决方案。 非常感谢!
附录:这里是我使用 nRF52832设置 SPI 所用的代码、这也是与原始代码的主要区别。"
#include "ADS1299.h" void ADS1299::initialize(int _DRDY, int _RST, int _CS, int _FREQ, boolean _isDaisy){ isDaisy = _isDaisy; DRDY = _DRDY; CS = _CS; int FREQ = _FREQ; int RST = _RST; delay(250); // recommended power up sequence requiers Tpor (~32mS) pinMode(RST,OUTPUT); digitalWrite(RST,LOW); delayMicroseconds(4); // toggle reset pin digitalWrite(RST,HIGH); delayMicroseconds(20); // recommended to wait 18 Tclk before using device (~8uS); // **** ----- SPI Setup ----- **** // SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE1); // clock polarity = 0; clock phase = 1 (pg. 8) switch (FREQ){ case 8: SPI.setClockDivider(SPI_CLOCK_DIV8); break; case 4: SPI.setClockDivider(SPI_CLOCK_DIV16); break; case 2: SPI.setClockDivider(SPI_CLOCK_DIV32); break; case 1: SPI.setClockDivider(SPI_CLOCK_DIV64); break; default: break; } // **** ----- End of SPI Setup ----- **** // // initalize the data ready chip select and reset pins: pinMode(DRDY, INPUT); pinMode(CS, OUTPUT); digitalWrite(CS,HIGH); digitalWrite(RST,HIGH); } //SPI communication methods byte ADS1299::transfer(byte _data) { return SPI.transfer(_data); }