Artemis ATP - HardFault when using with SX1509 and CD74HC4067

Hello,

I have a problem when using the Artemis ATP together with a SX1509 and CD74HC4067 (both breakout boards from Sparkfun). This is part of a larger project were I am monitoring 13 potentiometers via the CD74HC4067 and several active low switches using the SX1509. I can read the pot values but as soon as I am doing anything with the SX1509 I get a HardFault crash. If I don’t check the pots and only do the SX1509 things, it works. I also tried another CD74HC4067 library (light_ CD74HC4067) with same effect.

My code

#include <Wire.h>
#include <SparkFunSX1509.h>
#include <CD74HC4067.h>

CD74HC4067 mux(10, 9, 26, 15);  // create a new CD74HC4067 object with its four select lines
const int signal_pin = A31; // Pin Connected to Sig pin of CD74HC4067
const byte BTN_ADDRESS = 0x3E;
int myvalues[13] = {0};
int master = 0;
SX1509 io; 



void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Lets go");
  Wire.begin();

  pinMode(14, INPUT_PULLUP);
  pinMode(signal_pin, INPUT);
  
  if (io.begin(BTN_ADDRESS) == false)
  {
    Serial.println("Failed to communicate. Check wiring and address of SX1509.");
    while (1)
      ; // If we fail to communicate, loop forever.
  }
  for (int i=0; i<16; i++){
    io.pinMode(i, INPUT_PULLUP);
    io.enableInterrupt(i, CHANGE);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  check_potis();

  if(digitalRead(14) == 0){
    Serial.println("Change!");
    io.interruptSource();
  }
}

void check_potis(){
  for (int i = 15; i >= 3; i--) {
    mux.channel(i);
    int val = analogRead(signal_pin);
    int dif = abs(myvalues[i]-val);
    if(dif > 30){
      myvalues[i] = val; 
      Serial.println("Channel "+String(i)+": "+String(val));
    }
  }
}

The Error:

Lets go
Channel 15: 485
ChanneLets go
Channel 15: 487
Channel 14: 1023
Channel 13: 830
Channel 12: 556
Channel 11: 340
Channel 9: 552
Channel 8: 487
Channel 6: 859
Channel 5: 964
Channel 4: 864
Channel 3: 389
Change!

++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0: 100010C4
R1: 18
R2: 1
R3: 33E
R4: 1000107C
R5: 18
R6: 1
R7: 0
R8: 0
R9: 0
R10: 0
R11: 0
R12: 1C
SP   : 10007188
LR   : 11691
PC   : 1122A
xPSR : 21000000
PSP  : 10007120
MSP  : 1005FF70
CPUID: 410FC241
HFSR : 40000000
MMFSR: 0
BFSR : 82
UFSR : 0
DFSR : 0
AFSR : 0
BFAR : 36A
Mode : Thread
Priv : Privileged
Stack: PSP

-- MbedOS Fault Handler --



++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0x1122A
Error Value: 0x10006150
Current Thread: main Id: 0x10004558 Entry: 0x24075 StackSize: 0x1000 StackMem: 0x100061B0 SP: 0x10007188 
For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=SFE_ARTEMIS_ATP
-- MbedOS Error Info --

I could narrow it down to calling ```
io.interruptSource();


When I try to drive LEDs with following code, it crashes immediately when arriving at the for loop:

#include <Wire.h>
#include <SparkFunSX1509.h>
#include <CD74HC4067.h>

CD74HC4067 mux(10, 9, 26, 15); // create a new CD74HC4067 object with its four select lines
const int signal_pin = A31; // Pin Connected to Sig pin of CD74HC4067
const byte BTN_ADDRESS = 0x3F;
int myvalues[13] = {0};
int master = 0;
SX1509 io;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(“Lets go”);
Wire.begin();

pinMode(14, INPUT_PULLUP);
pinMode(signal_pin, INPUT);

if (io.begin(BTN_ADDRESS) == false)
{
Serial.println(“Failed to communicate. Check wiring and address of SX1509.”);
while (1)
; // If we fail to communicate, loop forever.
}
for (int i=0; i<16; i++){
io.pinMode(i, ANALOG_OUTPUT);
}
}

void loop() {
// put your main code here, to run repeatedly:
check_potis();

Serial.println(“Starting LEDs”);
for (int i=0; i<12; i++){
io.analogWrite(i, 0);
delay(100);
io.analogWrite(i, 255);
}
}

void check_potis(){
for (int i = 15; i >= 3; i–) {
mux.channel(i);
int val = analogRead(signal_pin);
int dif = abs(myvalues[i]-val);
if(dif > 30){
myvalues[i] = val;
Serial.println("Channel “+String(i)+”: "+String(val));
}
}
}


Error:

Lets go
Channel 15: 487
ChanneLets go
Channel 15: 484
Channel 14: 1023
Channel 13: 831
Channel 12: 545
Channel 11: 342
Channel 9: 562
Channel 8: 485
Channel 6: 865
Channel 5: 968
Channel 4: 850
Channel 3: 393
Starting LEDs

++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0: 100010E4
R1: 2A
R2: 0
R3: 33F
R4: 0
R5: 1000109C
R6: 2A
R7: 0
R8: 0
R9: 0
R10: 0
R11: 0
R12: 24CB9
SP : 100071A8
LR : 10E8F
PC : 1127C
xPSR : 61000000
PSP : 10007140
MSP : 1005FF70
CPUID: 410FC241
HFSR : 40000000
MMFSR: 0
BFSR : 82
UFSR : 0
DFSR : 0
AFSR : 0
BFAR : 36B
Mode : Thread
Priv : Privileged
Stack: PSP

– MbedOS Fault Handler –
++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0x1127C
Error Value: 0x10006170
Current Thread: main Id: 0x10004578 Entry: 0x23FA5 StackSize: 0x1000 StackMem: 0x100061D0 SP: 0x100071A8
For more info, visit: mbedos-error
– MbedOS Error Info –


The SX1509 parts do work if I don't check the pot values with the CD74HC4067 (i.e. comment out the check_potis() call).

Hooking up an individual pot to an Analog Input of the Artemis ATP and reading it works fine. I tried different pins for the CD74HC4067 and this didn't make a difference. 

I am using the SV Bootloader Version 5 and newest Arduino IDE and Board Manager. Any one got an idea what might be causing it? Any alternative to the CD74HC4067 that works with the SX1509 and Artemis ATP?

Thank you!

I think the problem could related to the definition of ‘myvalues[13]’. It allocates 13 places ( 0 - 12) to store a value.

In the routine check_potis() you try to store in myvalues on places 15 to 3. So you write on 3 places (15, 14, 13) a value that was NOT allocated for myvalues. As a result, you can get memory corruption and a hard fault.

Try to define with more entries: ‘myvalues[16] = {0};’ and/or adjust your program.

paulvha:
I think the problem could related to the definition of ‘myvalues[13]’. It allocates 13 places ( 0 - 12) to store a value.

In the routine check_potis() you try to store in myvalues on places 15 to 3. So you write on 3 places (15, 14, 13) a value that was NOT allocated for myvalues. As a result, you can get memory corruption and a hard fault.

Try to define with more entries: ‘myvalues[16] = {0};’ and/or adjust your program.

Bingo! Adjusting it to 16 solved it. Very well spotted, thank you so much - literally saved the project! :smiley: (This is what happens while putting the thing together one puts the lead wires of the pots to pins 16 to 3 of the CD74HC4067 instead of 0 to 13 as originally planned…)