Hey everyone. I am trying to write a fairly basic synthesizer sketch for the Teensy 4.1 w/ Audio Shield but I've run into a hurdle that I would really appreciate some help with.
In the code (pasted below), I am receiving a byte of data, 'buttonStates' from a slave Arduino over I2C. The data received from the slave Arduino contains information about the binary states of several buttons. Currently, for testing, there are only 7 buttons so all this data fits into a single byte, but in the future i intend to have 40+ buttons/input devices. This receiving of this data is done inside a pin ISR (connected to a digital output on the slave Arduino), so that the Teensy can only request data from the slave Arduino when that Arduino has new set of data. This part of the code works fine by itself and I have tested it in a separate sketch.
Once this is received by the Teensy, I am trying to use that button information to control a simple string synthesizer created with the Audio System Design tool. Basically, If a button is pressed, (i.e. a 1 bit), I turn the corresponding string and envelope on, and once the button is release (i.e. a 0 bit) the corresponding envelope is turned off.
Also, I have an I2C OLED (SSD1306) connected which is working fine regardless.
This seems simple enough, but I'm having a lot of trouble getting it to all work together. Running the code below as it is causes the Teensy to crash (by crash, I mean no serial prints and not responding USB-based requests to enter program mode).
Here's what I've tried so far in terms of trying to debug it:
-If I just comment out the ISR stuff, I get the same crash result and no output.
-If I comment out the entire for loop containing the audio stuff, the program works fine and prints out the data received over I2C
-If I comment out the ISR stuff AND the lines
then the program works fine and prints out an output. Its pretty weird that this would have an effect because since all the bits in buttonStates are zero, the program shouldnt even enter the if statement where these functions are called.
-If I comment those lines out but leave in the pin_ISR() function with the attachInteerupt commented out I get the crash and no output. This is also really weird because in this case, pin_ISR() is never even getting called
-Interestingly, the OLED, whose text is only set in void setup(), works fine regardless of crashing. So I think that in the cases that the code is crashing, the program executes void setup() just fine but for some reason, gets held up at void loop().
So naturally I'm kinda perplexed and I would appreciate if anyone could offer any insight or suggestions to try out. Also this is my first forum post so i apologise in advance for any formatting/other mistakes. Thanks a lot!
Here's my code:
In the code (pasted below), I am receiving a byte of data, 'buttonStates' from a slave Arduino over I2C. The data received from the slave Arduino contains information about the binary states of several buttons. Currently, for testing, there are only 7 buttons so all this data fits into a single byte, but in the future i intend to have 40+ buttons/input devices. This receiving of this data is done inside a pin ISR (connected to a digital output on the slave Arduino), so that the Teensy can only request data from the slave Arduino when that Arduino has new set of data. This part of the code works fine by itself and I have tested it in a separate sketch.
Once this is received by the Teensy, I am trying to use that button information to control a simple string synthesizer created with the Audio System Design tool. Basically, If a button is pressed, (i.e. a 1 bit), I turn the corresponding string and envelope on, and once the button is release (i.e. a 0 bit) the corresponding envelope is turned off.
Also, I have an I2C OLED (SSD1306) connected which is working fine regardless.
This seems simple enough, but I'm having a lot of trouble getting it to all work together. Running the code below as it is causes the Teensy to crash (by crash, I mean no serial prints and not responding USB-based requests to enter program mode).
Here's what I've tried so far in terms of trying to debug it:
-If I just comment out the ISR stuff, I get the same crash result and no output.
-If I comment out the entire for loop containing the audio stuff, the program works fine and prints out the data received over I2C
-If I comment out the ISR stuff AND the lines
Code:
strs[i]->noteOn(keys[i],0.1);
if (!(envs[i]->isActive())){
envs[i]->noteOn();
}
-If I comment those lines out but leave in the pin_ISR() function with the attachInteerupt commented out I get the crash and no output. This is also really weird because in this case, pin_ISR() is never even getting called
-Interestingly, the OLED, whose text is only set in void setup(), works fine regardless of crashing. So I think that in the cases that the code is crashing, the program executes void setup() just fine but for some reason, gets held up at void loop().
So naturally I'm kinda perplexed and I would appreciate if anyone could offer any insight or suggestions to try out. Also this is my first forum post so i apologise in advance for any formatting/other mistakes. Thanks a lot!
Here's my code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET -1
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
// GUItool: begin automatically generated code
AudioSynthKarplusStrong string2; //xy=430.0000228881836,176.14286422729492
AudioSynthKarplusStrong string3; //xy=435.0000228881836,228.1428680419922
AudioSynthKarplusStrong string7; //xy=435.0000228881836,447.14287853240967
AudioSynthKarplusStrong string5; //xy=436.00005531311035,336.14290618896484
AudioSynthKarplusStrong string1; //xy=437.00004959106445,114.14286231994629
AudioSynthKarplusStrong string4; //xy=438.0000228881836,279.1428699493408
AudioSynthKarplusStrong string6; //xy=440.00005626678467,396.1429080963135
AudioEffectEnvelope envelope6; //xy=585,399
AudioEffectEnvelope envelope7; //xy=589,451
AudioEffectEnvelope envelope2; //xy=593,172
AudioEffectEnvelope envelope4; //xy=593,280
AudioEffectEnvelope envelope1; //xy=595.0000228881836,110.99999618530273
AudioEffectEnvelope envelope3; //xy=596,227
AudioEffectEnvelope envelope5; //xy=601.0000228881836,335.00001430511475
AudioMixer4 mixer1; //xy=909.0000190734863,201.00000762939453
AudioMixer4 mixer2; //xy=909.000072479248,360.2857360839844
AudioMixer4 mixer3; //xy=1071.0000076293945,277.2857246398926
AudioOutputI2S i2s1; //xy=1461.0006675720215,278.2859001159668
AudioAnalyzePeak peak1; //xy=1465.428825378418,187.14288234710693
AudioConnection patchCord1(string2, envelope2);
AudioConnection patchCord2(string3, envelope3);
AudioConnection patchCord3(string7, envelope7);
AudioConnection patchCord4(string5, envelope5);
AudioConnection patchCord5(string1, envelope1);
AudioConnection patchCord6(string4, envelope4);
AudioConnection patchCord7(string6, envelope6);
AudioConnection patchCord8(envelope6, 0, mixer2, 1);
AudioConnection patchCord9(envelope7, 0, mixer2, 2);
AudioConnection patchCord10(envelope2, 0, mixer1, 1);
AudioConnection patchCord11(envelope4, 0, mixer1, 3);
AudioConnection patchCord12(envelope1, 0, mixer1, 0);
AudioConnection patchCord13(envelope3, 0, mixer1, 2);
AudioConnection patchCord14(envelope5, 0, mixer2, 0);
AudioConnection patchCord15(mixer1, 0, mixer3, 0);
AudioConnection patchCord16(mixer2, 0, mixer3, 1);
AudioConnection patchCord17(mixer3, peak1);
AudioConnection patchCord18(mixer3, 0, i2s1, 0);
AudioConnection patchCord19(mixer3, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=64.5,20
// GUItool: end automatically generated code
AudioEffectEnvelope *envs[7] = {&envelope1, &envelope2, &envelope3, &envelope4, &envelope5, &envelope6, &envelope7};
AudioSynthKarplusStrong *strs[7] = {&string1, &string2, &string3, &string4, &string5, &string6, &string7};
float keys[7] = {27.50*3,30.87*3,32.70*3,36.71*3,41.20*3,43.65*3,49.00*3};
int numButtons = 7;
byte buttonStates = 0;
void setup() {
attachInterrupt(34, pin_ISR, RISING);
Wire.begin();
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(3); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(20, 25); // Start at top-left corner
display.println(F("HELLO"));
display.drawRect(15, 20, 96, 30, SSD1306_WHITE);
display.display();
AudioMemory(18);
sgtl5000_1.enable();
sgtl5000_1.volume(1.0);
for (int i=0; i<7; i++) {
envs[i]->attack(90.2);
envs[i]->hold(0);
envs[i]->decay(31.4);
envs[i]->sustain(0.6);
envs[i]->release(440.5);
}
AudioInterrupts();
display.clearDisplay();
}
void loop() {
for (int i = 0; i <= numButtons; i++){
if (bitRead(buttonStates, i)){
Serial.print(i);
Serial.println(": on");
AudioNoInterrupts();
strs[i]->noteOn(keys[i],0.1);
if (!(envs[i]->isActive())){
envs[i]->noteOn();
}
AudioInterrupts();
}
else{
Serial.print(i);
Serial.println(": off");
envs[i]->noteOff();
}
}
if (peak1.available()){
float pk = peak1.read();
pk=map(pk,0.01,0.1,0,128);
display.clearDisplay();
display.fillRect(0, 30, pk, 10, SSD1306_WHITE);
display.display();
}
}
void pin_ISR(){
Wire.requestFrom(8, 1);
while(Wire.available()) {
Serial.print("read: ");
buttonStates = Wire.read();
Serial.print(buttonStates,BIN);
}
Serial.println();
}