Arduino HUZZAH32 -ADS1256 issue while reading array in interruption event

Hello eveyone,

This is my first post and my first arduino project. I am student and I hope i’m posting in the right section. My project for my last year is about retrieving sounds signals from microphones and doing some treatments on them to show their position on a 2D map.

The first step i’m trying to do is acquiring sounds data. For that I have 3 microphones connected to an ADS1256 and this ADS connected to a HUZZAH32 card.
Based on some libraries I found on github and the documentations, I built my own library.
To do so, I’m doing as follow :

// project.ino
int  PIN_CS = 15;
int  PIN_DRDY = 27;
int  PIN_POWER_DOWN = 33;

void setup() {
  Serial.begin(9600);                                         // starting serial port on port 9600
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(BOUTON, INPUT_PULLUP);
  while (!Serial) {

  }
  Serial.println("[INFO] Serial online");
  ADS.init(PIN_CS, PIN_DRDY, PIN_POWER_DOWN);
  ADS.setChannel(0);
}
void loop() { }

And my library is built like that

// ADS1256.cpp

long datas[DATA_ARRAY_SIZE] = {};
unsigned int iterator = 0;
int _CS;
int _POWER_DOWN;

// init ADS
void ADS1256::init(int CS, int DRDY, int POWER_DOWN) {

  _CS = CS;
  _DRDY = DRDY;
  _POWER_DOWN = POWER_DOWN;


  for (int i = 0 ; i < DATA_ARRAY_SIZE ; i++) {
    datas[i] = 0;
  }

  pinMode(_CS, OUTPUT);                                          // set CS as output pin
  CSON();                                        // activate CS (0 is enabled, 1 is disabled)

  pinMode(_POWER_DOWN, OUTPUT);                                       // set POWER_DOWN as output pin
  digitalWrite(_POWER_DOWN, HIGH);                                    // activate POWER_DOWN (1 is enabled, 0 is disabled)

  delay(30);                                                    // wait 30ms; time to wake for ADS
  SPI.begin();                                                  // start SPI
  SPI.beginTransaction(SPISettings(7.68 * 1000000 / 4, MSBFIRST, SPI_MODE1));

  delayMicroseconds(10);
  SPI.transfer(_POWER_DOWN);
  delayMicroseconds(100);

  byte status_reg = 0 ;  // address (datasheet p. 30)
  byte status_data = 0x01; //status: Most Significant Bit First, Auto-Calibration Disabled, Analog Input Buffer Disabled

  SPI.transfer(0x50 | status_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(status_data);   // write the databyte to the register
  delayMicroseconds(10);

  CSOFF();                                        // activate CS (0 is enabled, 1 is disabled)
  delayMicroseconds(50);

  attachInterrupt(digitalPinToInterrupt(_DRDY), readData, FALLING);
  attachInterrupt(digitalPinToInterrupt(_POWER_DOWN), showDatas, FALLING);
}

void ADS1256::CSON() {
  digitalWrite(_CS, LOW);                   // activate CS
}

void ADS1256::CSOFF() {
  digitalWrite(_CS, HIGH);                  // deactivate CS
}

void ADS1256::readData() {
  if (iterator < DATA_ARRAY_SIZE) {
    CSON();
    delayMicroseconds(10);  // t6 delay       // wait 60 micros to read
    SPI.transfer(RDATA);                      // Send command to read data

    long adc_val = 0;

    adc_val = SPI.transfer(0);
    adc_val <<= 8; //shift to left
    adc_val |= SPI.transfer(0);
    adc_val <<= 8;
    adc_val |= SPI.transfer(0);

    if (adc_val > 0x7fffff) { //if MSB == 1
      adc_val = 16777216ul - adc_val; //do 2's complement, discard sign
    }

    CSOFF();
    datas[iterator] = adc_val;
    Serial.println(adc_val);
    iterator++;
  }
  else {
    digitalWrite(_POWER_DOWN, LOW);
  }
}

void ADS1256::showDatas() { <---- PROBLEM APPEND HERE
  Serial.println("interrupt");
  for (int i = 0 ; i < DATA_ARRAY_SIZE ; i++) {
    Serial.print(i);
    Serial.print(" == ");
    Serial.println(datas[i]);
  }
}

The problem is that when POWER_DOWN interruption launch showDatas() function, Serial.print() seems to cause this error :

Guru Meditation Error: Core 1 panic’ed (Interrupt wdt timeout on CPU1)
11:16:08.267 → Core 1 register dump:
11:16:08.302 → PC : 0x400d230d PS : 0x00060034 A0 : 0x800d10c8 A1 : 0x3ffbe6e0
11:16:08.404 → A2 : 0x3ffbec1c A3 : 0x3f400f63 A4 : 0x3f400f65 A5 : 0x0000ff00
11:16:08.507 → A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x677fc000 A9 : 0x3ff40000
11:16:08.576 → A10 : 0x0000007f A11 : 0x00000000 A12 : 0x3ffb8214 A13 : 0x00000000
11:16:08.679 → A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001f EXCCAUSE: 0x00000006
11:16:08.784 → EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
11:16:08.853 → Core 1 was running in ISR context:
11:16:08.886 → EPC1 : 0x40088bce EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d230d
11:16:08.991 →
11:16:08.991 → Backtrace: 0x400d230d:0x3ffbe6e0 0x400d10c5:0x3ffbe700 0x400d127a:0x3ffbe720 0x400d128d:0x3ffbe740 0x400d13ab:0x3ffbe760 0x400d0c1e:0x3ffbe780

I read it’s a common error but for different problem but I can relate it to my code. Can someone can explain why I get this error and how to solve this ?

Thanks in advance.

PS: I put the code related to my problem.

Hello,

I resolved the issue by putting all my code inside the .ino file as follow :

// Arduino Code with use of ADS 1256 library
// API to read from 3 microphone & map sound received on 2D plan
// Written by Garcia Jérôme, Jean-Félix, Samir

#include <Arduino.h>
#include <SPI.h>

#define RED_LED 4
#define GREEN_LED 25
#define BUTTON 26

#define PIN_CS 16
#define PIN_DRDY 27
#define PIN_POWER_DOWN 33

// REGISTERS
#define    MUX     0x01 //Multiplexer Control Register 0

// CHANELS
// positives
#define AIN0 0x08 //(default)
#define AIN1 0x18
#define AIN2 0x28

// negatives
#define N_AINCOM B00001000

// SPI COMMAND DEFINITION
/*SYSTEM CONTROL */
#define   WAKEUP    0x00  //Exit Sleep Mode
#define   STANDBY   0xFD  //Enter Sleep Mode
#define   SYNC    0xFC    //Synchornize the A/D Conversion
#define   POWER_DOWN_VAL    0xFE  //Reset To Power UP values
#define   NOP     0xFF  //No operation
/*DATA READ*/
#define   RDATA   0x01  //Read data once
/*READ REGISTER */
#define   RREG    0x10  //Read From Register
#define   WREG    0x50  //Write To Register

#define DATA_ARRAY_SIZE 3000


unsigned char datas[DATA_ARRAY_SIZE] = {};
int iterator = 0;

void readData();

void setup()
{
  Serial.begin(9600);                                                 // starting serial comm on port 9600
  while (!Serial);
  Serial.println("[INFO] Serial port started");

  // declare all pins
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_POWER_DOWN, OUTPUT);
  pinMode(PIN_DRDY, INPUT);

  // ADS power ON
  digitalWrite(PIN_CS, LOW);
  digitalWrite(PIN_POWER_DOWN, HIGH);
  delay(30);

  SPI.begin();
  SPI.beginTransaction(SPISettings(1250000, MSBFIRST, SPI_MODE1));
  delayMicroseconds(10);

  SPI.transfer(PIN_POWER_DOWN);
  delayMicroseconds(100);

  digitalWrite(PIN_CS, HIGH);                                       // deactivate CS (0 is enabled, 1 is disabled)
  delayMicroseconds(50);

  iterator = 0;
  // Declare interruption on pin DRDY
  attachInterrupt(digitalPinToInterrupt(PIN_DRDY), readData, FALLING);
  delayMicroseconds(50);

}


void loop()
{
  if (iterator == DATA_ARRAY_SIZE) {
    Serial.println("interrupt");
    for (int i = 0 ; i < DATA_ARRAY_SIZE ; i++) {
      Serial.print(" ");
      Serial.print(datas[i]);
      iterator++;
    }
  }
}


void readData() {
  if (iterator < DATA_ARRAY_SIZE) {
    
    digitalWrite(PIN_CS, LOW); 
    SPI.transfer(RDATA);                      // Send command to read data
    SPI.transfer(WAKEUP);
    delayMicroseconds(65);  // t6 delay       // wait 10 micros to read

    //unsigned long value;
    unsigned char adc_val = 0;

    // read datas
    adc_val = SPI.transfer(WAKEUP);
    adc_val <<= 8; //shift to left
    adc_val |= SPI.transfer(WAKEUP);
    adc_val <<= 8;
    adc_val |= SPI.transfer(WAKEUP);
    
    digitalWrite(PIN_DRDY, HIGH);
    digitalWrite(PIN_CS, HIGH);
    
    delayMicroseconds(65);
    
    datas[iterator] = adc_val;
    iterator++;
  } else {
    digitalWrite(PIN_POWER_DOWN, LOW);
  }
}

My though is that the Serial.print on an array take too much time to be executed inside an interruption.
If someone can confirm that is correct ?

Anyway I have another problem, reading datas from ADS1256. I’m trying to read data providing from 1 microphone so far but the array is always filled by 0 values.
I checked that my microphones are correctly connected to the ADS and verifyed that they are powered but still can’t obtain any result from them.

Maybe I did something wrong in my code, if anyone can help.

PS: Let me know if I need to open a new post since this is another kind of issue.

Thanks

Not sure it if applies to the Huzzah32, but on an arduino Serial cannot be used inside an interrupt routine, because it uses interrupts, and interrupts are disabled inside an interrupt routine. The same applies to delay.