T4.0 GPIO expanders don't respond without USB Serial

Frukost

Well-known member
So, I have a problem i fail to work out on my own. I have two MCP23S17's connected to a T4 for reading buttons/encoders.

The MCP23S17's behaves as expected, provided that the USB connector is hooked up to my computer, and Serial.begin(115200) is called in setup(). If I remove either the USB cable, or the Serial.begin(115200) line, the MCP's will not initialize at startup.

Some observations:
loop() runs as expected, even if the MCP's don't.
No while (!Serial) statements are used.
VUSB is separated from VIN.

I am really tired right now, so maybe I'm missing something obvious. I'd appreciate I someone could point me in the right direction. Will post more code if needed!
 
It's a big project consisting of a lot of files, but I can start with the stuff below.

I also noticed that experimenting with putting a delay(1500) first in setup() fixes the problem. Could this be a power up issue?

Code:
void setup() {
    GenerateNoteData generateNoteData;
    GenerateSequencerData generateSequencerData;
    AssignSequencerData assignSequencerData;
    Sequencer sequencer;
    AssignVoiceData assignVoiceData;
    ProcessGPIOExpanders processGPIOExpanders;
    MIDI MIDI;
    DisplayBaseClass display;
    LED LED;
    RGBLED RGBLED;

    // Debugging
    // Serial.begin(115200);

    attachInterrupt(digitalPinToInterrupt(interruptPin1), ISR1, FALLING);
    attachInterrupt(digitalPinToInterrupt(interruptPin2), ISR2, FALLING);

    // Randomization
    Entropy.Initialize();  // Used only as a seed below, since the Entropy class is slower than the standard random() function
    randomSeed(Entropy.random());

    // Input
    processGPIOExpanders.setup();

    // Generate stuff
    generateNoteData.setup();                         // Randomizes voice data
    generateSequencerData.randomizeOctaveModifier();  //

    // Assign stuff
    assignVoiceData.setup();                     // Voice data is initialized
    assignSequencerData.defineAmbitus();         // Defines lowest/highest note of the loop
    assignSequencerData.assignRandomArpNOSPB();  // assign arp values
    sequencer.bpm = 100;                         // Start value

    // Output
    MIDI.setup();     // MIDI Serial port is initialized
    display.setup();  // Initializes oled display object, and displays main menu
    LED.setup();
    RGBLED.setBrightness(0);
}

void loop() {
    ProcessGPIOExpanders processGPIOExpanders;
    ProcessTimeEvents processTimeEvents;
    RGBLED RGBLED;

    processGPIOExpanders.processInterrupts();  // Input events
    processTimeEvents.processTimeEvents();
    RGBLED.processRGBLED();
}
 
It may be that the Teensy is starting up Too Quickly for the MCP23S17's when you start to initialise them.
The chips may simple be not ready to be initialised.
This is born out by putting a delay at the head of the setup code.
 
Yes, I'm beginning to suspect this, hence my experiment with delaying the setup code. I put decoupling caps on all IC's (can't remember the values, and the schematics is not available here right now), is it possible they delay startup to the point that initializing data is lost?

Also, does this mean that the initializing delay for the USB connection emulates the delay needed for a proper startup? I'm struggling to understand it's role here, haha...
 
Yes, I'm beginning to suspect this, hence my experiment with delaying the setup code. I put decoupling caps on all IC's (can't remember the values, and the schematics is not available here right now), is it possible they delay startup to the point that initializing data is lost?

Also, does this mean that the initializing delay for the USB connection emulates the delay needed for a proper startup? I'm struggling to understand it's role here, haha...

Or just that initializing USB takes long enough that the MCP 23017 is up and running (i.e. to do the handshake with the computer).
 
Hmm, I use two of them in my sequencer, and they work without Serial connection running, and I have have them setup right after I setup the display. As I started working with them, I had a sketch with just the Adafruit_MCP23X17 library and debugging via usbMIDI and I had no issues with startup time either. There should be no "too fast", if you that in setup, as everything is done until then (thats called right before the while(1) in the main() function.
I do see however, that you are attaching 2 interrupts to 2 pins. Are those the pins coming from the MCP? Have you tried to setup the interrupts after you initialize the MCP, because they might be triggered and do something that messes up your initialization?
 
Or just that initializing USB takes long enough that the MCP 23017 is up and running (i.e. to do the handshake with the computer).
Agreed, I believe we mean the same thing.

Have you tried to setup the interrupts after you initialize the MCP, because they might be triggered and do something that messes up your initialization?
Thanks for your advice. I use 2 MCP's, each utilizing an interrupt pin. I've tried your advice now, and the problem persists.

At this point, delaying running setup() works, and I'm fine with that. However, if someone could corroborate previous theories, or explain why this works I'd be happy to learn more.
 
Last edited:
It's a big project consisting of a lot of files, but I can start with the stuff below.

I also noticed that experimenting with putting a delay(1500) first in setup() fixes the problem. Could this be a power up issue?

Code:
void setup() {
[COLOR="#FF0000"]    GenerateNoteData generateNoteData;
    GenerateSequencerData generateSequencerData;
    AssignSequencerData assignSequencerData;
    Sequencer sequencer;
    AssignVoiceData assignVoiceData;
    ProcessGPIOExpanders processGPIOExpanders;
    MIDI MIDI;
    DisplayBaseClass display;
    LED LED;
    RGBLED RGBLED;[/COLOR]

    // Debugging
    // Serial.begin(115200);

    attachInterrupt(digitalPinToInterrupt(interruptPin1), ISR1, FALLING);
    attachInterrupt(digitalPinToInterrupt(interruptPin2), ISR2, FALLING);

    // Randomization
    Entropy.Initialize();  // Used only as a seed below, since the Entropy class is slower than the standard random() function
    randomSeed(Entropy.random());

    // Input
    processGPIOExpanders.setup();

    // Generate stuff
    generateNoteData.setup();                         // Randomizes voice data
    generateSequencerData.randomizeOctaveModifier();  //

    // Assign stuff
    assignVoiceData.setup();                     // Voice data is initialized
    assignSequencerData.defineAmbitus();         // Defines lowest/highest note of the loop
    assignSequencerData.assignRandomArpNOSPB();  // assign arp values
    sequencer.bpm = 100;                         // Start value

    // Output
    MIDI.setup();     // MIDI Serial port is initialized
    display.setup();  // Initializes oled display object, and displays main menu
    LED.setup();
    RGBLED.setBrightness(0);
}

void loop() {
    ProcessGPIOExpanders 
;
    ProcessTimeEvents processTimeEvents;
    RGBLED RGBLED;

    processGPIOExpanders.processInterrupts();  // Input events
    processTimeEvents.processTimeEvents();
    RGBLED.processRGBLED();
}

Sorry, maybe I am missing something here...
But with this code, it looks like a lot of the classes are on the stack as part of setup?
So they disappear once setup completes?

What do you mean by not responding? Is anything working?

Now if, the stuff was on the stack, then things can get exciting, like maybe the USB INIT code and/or delays causes the code to change such that maybe the memory is still OK enough in some cases and in others, maybe something overwrote it...

Or maybe I am barking up the wrong tree ;)
 
I interpreted that "It's a big project consisting of a lot of files, but I can start with the stuff below." as that he just threw together what he thought is important but its not really the code he is working with (what makes finding the issue from our perspective quite hard).
 
Back
Top