Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Strange error when reconnecting Teensy (audio board not working on reboot)

  1. #1
    Junior Member
    Join Date
    Jun 2018
    Location
    Oxford, UK
    Posts
    15

    Strange error when reconnecting Teensy (audio board not working on reboot)

    Hi all,

    I've got some odd behaviour in a sketch I've written. It's a fairly complicated synthesizer sketch but it works fine on my Teensy 3.2 with the audio board, until I unplug the Teensy and plug it back in again. When I do this, the LED on the Teensy is no longer lit and no audio comes out of the headphone socket, even though the sketch appears to be running normally (the Serial.println() commands still work).

    This behaviour happens when I plug the Teensy back into my (Windows) computer, or if I just power it using a phone charger. Once the behaviour has happened, the only way I have found to get my sketch working again is to upload another audio board sketch (e.g. the PlaySynthMusic example). After uploading that sketch, I can then upload my sketch again and it works (until I unplug the Teensy!).

    My sketch is rather huge and sprawls across lots of files, but I've pasted the main .ino file contents just in case anyone can spot an obvious mistake. I'm also doing a lot of stuff with pointers and references in this sketch, which I'm fairly new to, so please do say if it looks like I'm doing something silly with those that could be causing this issue.

    Any help gratefully received!

    GitHub link here in case that helps, too (slightly older version, before I started bug-hunting, but same problem): https://github.com/mattybrad/modular...teensymodsynth

    Matt

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    #include "Module.h"
    #include "PatchCable.h"
    #include "Output.h"
    #include "VCO.h"
    //#include "Mixer.h"
    //#include "LFO.h"
    //#include "VCF.h"
    //#include "Noise.h"
    //#include "Envelope.h"
    //#include "VCA.h"
    
    #define EMPTY_MODULE 0
    #define OUTPUT_MODULE 1
    #define VCO_MODULE 2
    #define VCF_MODULE 3
    #define VCA_MODULE 4
    #define MIXER_MODULE 5
    #define LFO_MODULE 6
    #define NOISE_MODULE 7
    #define ENVELOPE_MODULE 8
    
    #define MODULE_SLOTS 8
    #define SOCKET_RECEIVE_DATA_PIN 27
    #define MODULE_ID_PIN 28
    #define ANALOG_DATA_PIN 33
    #define MAX_CABLES 100
    const int NUM_SOCKETS = MODULE_SLOTS * 8;
    const int SOCKET_SEND_ROOT_SELECT_PINS[] = {2,3,4};
    const int SOCKET_RECEIVE_ROOT_SELECT_PINS[] = {17,20,21};
    const int SOCKET_SEND_MODULE_SELECT_PINS[] = {5,8,16};
    const int SOCKET_RECEIVE_MODULE_SELECT_PINS[] = {24,25,26};
    
    Module *modules[MODULE_SLOTS]; // array of pointers to module instances
    PatchCable *patchCables[MAX_CABLES];
    byte moduleIdReadings[MODULE_SLOTS]; // readings of module IDs - changes will causes program to update module listing
    boolean patchCableConnections[NUM_SOCKETS][NUM_SOCKETS];
    
    AudioControlSGTL5000 sgtl;
    
    void setup() {
    
      Serial.begin(9600);
    
      // initialise audio board
      AudioMemory(80);
      sgtl.enable();
      sgtl.volume(0.5);
    
      // initialise mux/demux pins
      for(int i=0;i<3;i++) {
        pinMode(SOCKET_SEND_ROOT_SELECT_PINS[i], OUTPUT);
        pinMode(SOCKET_SEND_MODULE_SELECT_PINS[i], OUTPUT);
        pinMode(SOCKET_RECEIVE_ROOT_SELECT_PINS[i], OUTPUT);
        pinMode(SOCKET_RECEIVE_MODULE_SELECT_PINS[i], OUTPUT);
      }
      pinMode(SOCKET_RECEIVE_DATA_PIN, INPUT);
      pinMode(MODULE_ID_PIN, INPUT);
    
      // read module slots
      for(int a=0;a<MODULE_SLOTS;a++) {
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[0],bitRead(a,0));
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[1],bitRead(a,1));
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[2],bitRead(a,2));
        
        for(int b=0;b<8;b++) {
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[0],bitRead(b,0));
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[1],bitRead(b,1));
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[2],bitRead(b,2));
    
          bitWrite(moduleIdReadings[a],b,digitalRead(MODULE_ID_PIN));
        }
    
        // test code, overrides actual readings
        if(true) {
          moduleIdReadings[a] = EMPTY_MODULE;
          moduleIdReadings[0] = OUTPUT_MODULE;
          moduleIdReadings[1] = VCO_MODULE;
        }
    
        switch(moduleIdReadings[a]) {
          case EMPTY_MODULE:
          modules[a] = NULL;
          break;
    
          case OUTPUT_MODULE:
          modules[a] = new Output();
          break;
    
          case VCO_MODULE:
          modules[a] = new VCO();
          break;
    
          case MIXER_MODULE:
          //modules[a] = new Mixer();
          break;
    
          case LFO_MODULE:
          //modules[a] = new LFO();
          break;
    
          case VCF_MODULE:
          //modules[a] = new VCF();
          break;
    
          case VCA_MODULE:
          //modules[a] = new VCA();
          break;
    
          case NOISE_MODULE:
          //modules[a] = new Noise();
          break;
    
          case ENVELOPE_MODULE:
          //modules[a] = new Envelope();
          break;
    
          default:
          modules[a] = NULL;
        }
      }
    
      AudioProcessorUsageMaxReset();
      AudioMemoryUsageMaxReset();
    
      delay(5000);
    }
    
    void loop() {
    
      boolean newConnectionReading;
      for(int a=0;a<8;a++) {
        // switch the root socket send channel
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[0],bitRead(a,0));
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[1],bitRead(a,1));
        digitalWrite(SOCKET_SEND_ROOT_SELECT_PINS[2],bitRead(a,2));
        
        for(int b=0;b<8;b++) {
          // switch the module socket send channel
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[0],bitRead(b,0));
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[1],bitRead(b,1));
          digitalWrite(SOCKET_SEND_MODULE_SELECT_PINS[2],bitRead(b,2));
    
          for(int c=0;c<8;c++) {
            // switch the root socket receive channel
            digitalWrite(SOCKET_RECEIVE_ROOT_SELECT_PINS[0],bitRead(c,0));
            digitalWrite(SOCKET_RECEIVE_ROOT_SELECT_PINS[1],bitRead(c,1));
            digitalWrite(SOCKET_RECEIVE_ROOT_SELECT_PINS[2],bitRead(c,2));
    
            for(int d=0;d<8;d++) {
              // switch the module socket receive channel
              digitalWrite(SOCKET_RECEIVE_MODULE_SELECT_PINS[0],bitRead(d,0));
              digitalWrite(SOCKET_RECEIVE_MODULE_SELECT_PINS[1],bitRead(d,1));
              digitalWrite(SOCKET_RECEIVE_MODULE_SELECT_PINS[2],bitRead(d,2));
    
              int socket1 = a*8+b;
              int socket2 = c*8+d;
    
              if(modules[d]) modules[d]->update();
    
              if(socket1 > socket2) {
                newConnectionReading = false;
                if(digitalRead(SOCKET_RECEIVE_DATA_PIN)) {
                  newConnectionReading = true;
                }
    
                // testing code, overrides any actual connections
                if(true) {
                  if(fakeConnection(socket1,socket2,1,1,0,0)) newConnectionReading = true;
                }
          
                if(newConnectionReading != patchCableConnections[socket1][socket2]) {
                  if(newConnectionReading) {
                    // make connection
                    addPatchCable(socket1,socket2);
                  } else {
                    // break connection
                    removePatchCable(socket1,socket2);
                  }
                }
                patchCableConnections[socket1][socket2] = newConnectionReading;
              }
            }
          }
        }
      }
      Serial.println(AudioMemoryUsageMax());
      Serial.println(AudioProcessorUsageMax());
    }
    
    void addPatchCable(int highSocket, int lowSocket) {
      int foundIndex = -1;
      for(int i=0;i<MAX_CABLES&&foundIndex==-1;i++) {
        if(patchCables[i]==NULL) foundIndex = i;
      }
      if(foundIndex >= 0) {
        patchCables[foundIndex] = new PatchCable(highSocket, lowSocket, getSocket(highSocket), getSocket(lowSocket));
        Serial.println("ADDED CABLE");
      } else {
        Serial.println("CAN'T ADD NEW CABLE");
      }
    }
    
    void removePatchCable(int highSocket, int lowSocket) {
      for(int i=0;i<MAX_CABLES;i++) {
        if(patchCables[i]!=NULL) {
          // a cable exists in this slot
          if(highSocket==patchCables[i]->getHighSocket() && lowSocket==patchCables[i]->getLowSocket()) {
            // remove cable
            patchCables[i]->disconnect();
            delete patchCables[i];
            patchCables[i] = NULL;
            Serial.println("REMOVED CABLE");
          }
        }
      }
    }
    
    Socket &getSocket(int socketNumber) {
      int moduleNumber = socketNumber / 8;
      int moduleSocketNumber = socketNumber % 8;
      Serial.println(moduleNumber);
      Serial.println(moduleSocketNumber);
      return modules[moduleNumber]->getSocket(moduleSocketNumber);
    }
    
    boolean fakeConnection(int socket1, int socket2, int module1, int moduleSocket1, int module2, int moduleSocket2) {
      int testSocket1 = 8*module1 + moduleSocket1;
      int testSocket2 = 8*module2 + moduleSocket2;
      if(socket1==testSocket1 && socket2==testSocket2) return true;
      if(socket1==testSocket2 && socket2==testSocket1) return true;
      return false;
    }

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    1,912
    Quote Originally Posted by mattybrad View Post
    Hi all,

    I've got some odd behaviour in a sketch I've written. It's a fairly complicated synthesizer sketch but it works fine on my Teensy 3.2 with the audio board, until I unplug the Teensy and plug it back in again. When I do this, the LED on the Teensy is no longer lit and no audio comes out of the headphone socket, even though the sketch appears to be running normally (the Serial.println() commands still work).

    This behaviour happens when I plug the Teensy back into my (Windows) computer, or if I just power it using a phone charger. Once the behaviour has happened, the only way I have found to get my sketch working again is to upload another audio board sketch (e.g. the PlaySynthMusic example). After uploading that sketch, I can then upload my sketch again and it works (until I unplug the Teensy!).
    It seems that your sketch is missing a proper audio update functionality.
    (does the audiomemoryusagemax print indicate 0?)

    Initialization of the sgtl5000 requires stable I2S clocks.
    I cannot see any I2S audio object in your code, maybe you could simply add a dummy I2S_input/output object?

  3. #3
    Junior Member
    Join Date
    Jun 2018
    Location
    Oxford, UK
    Posts
    15
    Quote Originally Posted by WMXZ View Post
    It seems that your sketch is missing a proper audio update functionality.
    (does the audiomemoryusagemax print indicate 0?)

    Initialization of the sgtl5000 requires stable I2S clocks.
    I cannot see any I2S audio object in your code, maybe you could simply add a dummy I2S_input/output object?
    Thanks for taking a look. There is an I2S audio object but it's in the Output.h class. The code is a bit unusual in that I'm trying to make a modular synth, where you can add and remove various physical modules, each of which represents part of the signal chain, so all the audio objects which would normally be declared statically at the start of the sketch are actually added dynamically (the Teensy checks to see which modules are present using digitalRead then creates the audio objects accordingly).

    This sounds like a recipe for disaster, but the code does work as expected until the Teensy is unplugged. Audio is produced (a simple saw wave in the code I pasted) and AudioMemoryUsageMax is 4. Interestingly, even when I do disconnect and reconnect the Teensy, AudioMemoryUsageMax is still 4, even though audio is no longer audible.

    I'll keep stripping out more of the code to see if I can find the source of the problem...

  4. #4
    Junior Member
    Join Date
    Jun 2018
    Location
    Oxford, UK
    Posts
    15
    Quote Originally Posted by WMXZ View Post
    maybe you could simply add a dummy I2S_input/output object?
    Okay, looks like you were right! I declared the output object at the beginning of the sketch (since there'll only ever be one of them anyway) and it now works. Thank you!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •