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

Thread: Teensy 3.1 freeze troubleshooting

  1. #1
    Senior Member
    Join Date
    Feb 2015
    Posts
    162

    SOLVED: Teensy 3.1 crash troubleshooting

    Hello,

    I am building an open source sequencer with the Teensy 3.1. The prototype I am working with currently has two hardware debounced rotary encoders, 4 momentary switches, 8 Neopixel LEDs, and one 128x64 OLED display using the Adafruit_SSD1306 library.

    Code is here: https://github.com/cosmikwolf/afx-01a

    I wrote a small library for a sequencer object, which contains all step information (midi notes, gate lengths, velocity etc for each step).
    The code has 4 iterations of this sequencer.

    Only one sequence can be selected at any one time, and the LCD displays some information that is taken directly from the Sequence object (using public variables)

    When I press a button to change the selected sequence, which changes what is displayed, OCCASIONALLY the whole thing locks up. I have printed out things to the serial console and it seems to be happening sometime during the display rendering part of the code. That code works just fine most of the time, except occasionally when the selected sequence variable is changed. One clue is that if I link this variable to a rotary encoder, and change the value with it instead of using a button, it freezes much more frequently. I can usually get it to freeze within 10 seconds.

    This is the end of the serial output when I am running the program and it freezes:

    Code:
    interrupt start
    interrupt end
    display debug 7
    display debug 8
    diinterrupt start
    interrupt end
    lay debug 7
    display debug 8
    di
    This is the section of code where the last debug line (number 8) is printed out. This displayLoop() is called within the main loop. You can see the rest of the code in the github linked above.

    Code:
    void displayLoop() {
      Serial.println("displayStart");
      display.clearDisplay();   // clears the screen and buffer
    
        display.drawTriangle( 120,0,
                              113,9,
                              127,9, WHITE);
      if (tempoBool == true) {
        display.fillTriangle( 120,0,
                              113,9,
                              127,9, WHITE);
      }
    Serial.println("displaydebug1");
    
      display.setTextSize(1);
    
      display.setTextColor(WHITE);
    Serial.println("displaydebug2");
    
      display.setCursor(0,0);
      display.println(String(instrumentNames[sequence[selectedSequence].instrument+1]));
      display.println("tempo:" + String(sequence[selectedSequence]._tempo));
      display.println("as: " + String(sequence[selectedSequence].activeStep) + " ct: " + String(sequence[selectedSequence].clockTracker));
      display.println("sequenceLength: " + String(sequence[selectedSequence]._sequenceLength));
    Serial.println("displaydebug3");
    
      display.println("lastActiveStep: " + String(lastActiveStep));
     
      if (stepLength[selectedStep] == 1) {
        display.println("Step: " + String(selectedStep) + " -  " + sequence[selectedSequence]._gateLength[selectedStep] + " beat");
      } else {
        display.println("Step: " + String(selectedStep) + " " + sequence[selectedSequence]._gateLength[selectedStep] + " beats");
      }
    Serial.println("displaydebug4");
    
      if (stepActive[selectedStep] == true){
        display.println("Pitch: " + String(midiNotes[sequence[selectedSequence]._stepPitch[selectedStep]]) + " Vel: " + String(sequence[selectedSequence]._stepVelocity[selectedStep]));
      } else {
        display.println("Rest Step");
      }
    Serial.println("displaydebug5");
    
      display.println("avgPeriod:" + String(avgPeriod));
    Serial.println("display debug 6");
    
      display.println("avgLoopTime:" + String(avgLoopTime));
      display.println("avgRuntime:" + String(avgRuntime));
      display.setTextSize(2);
      display.setCursor(100,0);
    Serial.println("display debug 7");
    
      display.print(String(selectedSequence));
    Serial.println("display debug 8");
      
      display.display();
    Serial.println("display debug 9");
    Serial.println("displayLoopEnd");
    }
    I should also mention that I have an IntervalTimer object that runs an interrupt every 700 microseconds. The crash still happens even when the IntervalTimer is completely disabled.

    SO my question is... How do I troubleshoot this? Any suggestions? It would be really helpful to figure out WHY the teensy is crashing, some kind of stack trace.

    Thank you!
    tk
    Last edited by tenkai; 02-10-2015 at 07:23 AM.

  2. #2
    Senior Member
    Join Date
    Feb 2015
    Posts
    162
    Solved!

    I was setting the selected Sequence with a modulo operator:

    Code:
        selectedSequence = knob2Buffer % 3;
    What i did not account for was the negative value of a modulo operation. I always assumed that a modulo would return a positive value, and so when it would return a negative value for the selectedSequence, it would be looking up sequence[selectedSequence] which was a null pointer (I think thats what it is?)

    Anywho, anyone who is experiencing hard crashes of Teensy 3.1 might want to make sure that they are not looking up invalid array references.

  3. #3
    Senior Member
    Join Date
    Nov 2013
    Posts
    720
    I was mildly curious about your problem but when I saw that you did not
    Quote Originally Posted by Forum Rule
    Always post complete source code & details to reproduce any issue!
    I decided to look the other way - certainly not enough to work from with what you have posted.

    When I saw you marked this thread solved I thought I would have a squiz again.

    I've never checked how modulo is 'catered' in (GNU) C/C++ but if the numerator/dividend is negative I will definitely prefer a negative result; funny things about the divisor, arguments could probably abound as to whether or not the divisor's sign should influence the result but your divisor is clearly positive making that line of thought moot here.


    Having not seen how you derive 'knob2buffer' (or even how you declare it, whether signed or unsigned) I assume that it can (and does) reach negative values in the usual course of program operation?

  4. #4
    Senior Member
    Join Date
    Feb 2015
    Posts
    162
    It would be nice if you read my post before pointing out that I failed to follow the rules. I included a link to the full source code at the top.

    There are two ways of calculating modulo, one provides a positive result every time:

    https://www.google.com/webhp?sourcei...-8#q=-4+%25+12

    and the other, which is what is used in C and can be tried in OS X Spotlight sometimes does return a negative result:

    Code:
    -4 %12 = -4
    Last edited by tenkai; 02-11-2015 at 02:13 AM.

  5. #5
    Senior Member
    Join Date
    Jan 2015
    Location
    frisia
    Posts
    285
    Purely speaking, the % is a remainder operator and not a modulo operator.
    The % is defined so that the result of "(a/b) * b + a%b" results in a again.
    The fact that a/b always rounds towards zero, causes the remainder to be negative for negative input numbers.
    For positive numbers, there is nothing to worry about.

  6. #6
    Senior Member
    Join Date
    Nov 2013
    Posts
    720
    Quote Originally Posted by tenkai View Post
    You should read my post before pointing out that I failed to follow the rules. I included a link to the full source code at the top.


    ...
    Quote Originally Posted by tenkai View Post
    Hello,

    I am building an open source sequencer with the Teensy 3.1. The prototype I am working with currently has two hardware debounced rotary encoders, 4 momentary switches, 8 Neopixel LEDs, and one 128x64 OLED display using the Adafruit_SSD1306 library.

    Code is here: https://github.com/cosmikwolf/afx-01a

    ...
    I read your post mate, the bit I quoted from your OP didn't look like a link to YOUR full code to me so I ignored it (looked like it might be a link to your 'small library for sequencer' or perhaps a fork/alternative of Adafruit_SSD1306 library) and looked at what you put in between the [code][/code] tags which clearly wasn't enough to reproduce your problem.

    Had you 'juxtaposition'ed your link to YOUR full code nearer the snippet that I now realise comes from it I would have made a different assumption about it fairly surely.


    Modulo is not the best way to achieve what you were doing with it;
    Code:
    uint8_t result=input_value & 3;
    executes quicker and just will not return a negative result because it cannot.

  7. #7
    Senior Member
    Join Date
    Dec 2014
    Posts
    134
    Quote Originally Posted by robsoles View Post
    Modulo is not the best way to achieve what you were doing with it;
    Code:
    uint8_t result=input_value & 3;
    executes quicker and just will not return a negative result because it cannot.
    would using & 3 reliably cycle an accumulator? Usually in my sequencers and oscillators the core is an increasing value using:
    Code:
    "phase = (phase +1)%length"
    I am wondering if & would work as a drop in replacement for % in these? Seems like & would be a huge potential performance gain overall.

Posting Permissions

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