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

Thread: Read controls while sound is playing

  1. #1
    Senior Member
    Join Date
    Nov 2015
    Posts
    188

    Read controls while sound is playing

    Hello! It's time to ask for advice
    i have a project that include: teensy3.6, 5 encoders with MCP23017, audio board and other stuff..

    Now, i have tested the single parts: audio ok, encoders ok
    but if i put all the parts together, i can ear the audio but the encoders stop working.

    I need an advice to put the pieces together, with the encoders I want to control the audio parameters while the audio keeps playing.

    the encoders are read with this library and the pollAll function inside the loop() function

    https://github.com/maxgerhardt/rotar...-over-mcp23017

    this is the complete loop()

    Code:
    void loop() {
        pollAll();
    
        float w;
        for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          delay(800);
          envelope1.noteOff();
          delay(600);    
        }
      }

  2. #2
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,915
    You have delays in there so things halt for a second and a half. Suggest using something like
    https://www.pjrc.com/teensy/td_timin...pedMillis.html
    or more complex timing to trigger when to turn on and off the note, and visit the pollAll() function as often as possible.

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    Indeed something with elapsedMillis … and delay is 1.4 seconds TIMES 19?

  4. #4
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    Hi, i have my code on github now
    without hardware is difficult to understand but is an early stage.
    can someone help me?

    i have added

    Code:
    elapsedMillis updateUI;
    before the setup()

    and in loop()

    Code:
    if (updateUI > 250) {      // poll every 250ms
          updateUI = 0;
          pollAll();
        }
    but the encoders are not read

  5. #5
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,551
    I’d check the I2C communication with a logic analyzer to be sure that the PollAll works correctly.

  6. #6
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    yes, I tested the circuit piece by piece and it works everything, leds, encoders, audio ...
    the problem arises when I try to put everything together

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    It is these delay()'s that are keeping it from polling:
    Code:
        for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          delay(800);
          envelope1.noteOff();
          delay(600);    
        }
    Those delays and that it does that 19 times before exiting to poll again.

    A first quick hack would be:
    Code:
        for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          delay(800);
          pollAll();
          envelope1.noteOff();
          delay(600);    
          pollAll();
        }
    But that will still not poll for 800 or 600 ms. if 250 ms fast enough to poll? They could be broken up or rewritten with an elapsedMillis variable in some fashion.

  8. #8
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    the goal is to read continuosly or at least as fast as possible the interface (buttons and encoders)
    then update the sound parameters, the leds and the oled (at least the sound parameters)

  9. #9
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    tried this

    Code:
    for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          delay(800);
          pollAll();
          envelope1.noteOff();
          delay(600);    
          pollAll();
        }
    but the pollAll() stop working...

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    perhaps:
    Code:
    #define MS_INC 50 // polling delay step increment
    // this will overshoot by the time it takes to complete the pollAll()
    void PollingDelay() ( uint16_t msDel ) {
    uint16_t track=0
      while ( track<msDel ) {
        track += MS_INC;
        delay( MS_INC );
        pollAll();
      }
    }
    
    loop() {
    // …
    
        for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          PollingDelay(800);
          envelope1.noteOff();
          PollingDelay(600);    
        }

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    If pollAll() stops - then it has some issue with being call too fast?

    The one in the outer loop will be called immediately before and after that for - so two may be back to back

  12. #12
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    even with this last solution, it does not work.
    it's a pity because the prototype itself works, I'm sure it's just a code problem

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    Bummer - did you try with :: #define MS_INC 200

    Perhaps that will let it run? You can make it higher but will miss the marks of 600 and 800 ms as wtirren.

    Also comment out the one in loop() outside the "for" so it run any back-to-back.

  14. #14
    Senior Member
    Join Date
    Nov 2015
    Posts
    188
    nope, also with 200 doesn't work

    main.cpp (i'm on atom and platformio)

    Code:
    #include <Arduino.h>
    #include <ht16k33.h> //0x77
    #include <U8g2lib.h> //oled display
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <Audio.h>
    #include <SerialFlash.h>
    
    
    #include <Leds.h>
    #include <Buttons.h>
    #include <Encoders.h>
    #include <Display.h>
    #include <User_functions.h> //user functions
    
    // GUItool: begin automatically generated code
    AudioSynthWaveform       waveform1;      //xy=188,240
    AudioEffectEnvelope      envelope1;      //xy=371,237
    AudioOutputI2S           i2s1;           //xy=565,241
    AudioConnection          patchCord1(waveform1, envelope1);
    AudioConnection          patchCord2(envelope1, 0, i2s1, 0);
    AudioConnection          patchCord3(envelope1, 0, i2s1, 1);
    AudioControlSGTL5000     audioShield;     //xy=586,175
    // GUItool: end automatically generated code
    
    //timer
    elapsedMillis updateUI;
    #define MS_INC 200 // polling delay step increment
    // this will overshoot by the time it takes to complete the pollAll()
    void PollingDelay ( uint16_t msDel ) {
    uint16_t track=0;
      while ( track<msDel ) {
        track += MS_INC;
        delay( MS_INC );
        pollAll();
      }
    }
    void setup() {
        //led and buttons
        lb.begin(0x77); //ht16k33 i2c address
        lb.setBrightness(0); //0-15
    
        //SPI and display
        SPI.setMOSI(28);
        SPI.setSCK(27);
        pinMode(29, OUTPUT);
        pinMode(30, OUTPUT);
        SPI.begin();
        display.begin();
    
        //Encoder
        enc.begin(5);
    
        //serial monitor
        Serial.begin(57600);
        Serial.println("via");
    
        //audio
        AudioMemory(8);
        audioShield.enable();
        audioShield.volume(0.45);
        //
        waveform1.pulseWidth(0.5);
        waveform1.begin(0.4, 220, WAVEFORM_PULSE);
    
        envelope1.attack(50);
        envelope1.decay(50);
        envelope1.release(250);
    }
    
    void loop() {
      float w;
      for (uint32_t i =1; i<20; i++) {
          w = i / 20.0;
          waveform1.pulseWidth(w);
          envelope1.noteOn();
          PollingDelay(800);
          envelope1.noteOff();
          PollingDelay(600);
        }
    }
    encoders.h

    Code:
    #include <RotaryEncOverMCP.h>
    //encoder port expander
    Adafruit_MCP23017 enc;
    
    /* function prototypes */
    void RotaryEncoderChanged(bool clockwise, int id);
    Adafruit_MCP23017* allMCPs[] = { &enc };
    
    /* Array of all rotary encoders and their pins */
    RotaryEncOverMCP rotaryEncoders[] = {
      RotaryEncOverMCP(&enc, 9, 8, &RotaryEncoderChanged, 1),
      RotaryEncOverMCP(&enc, 11, 10, &RotaryEncoderChanged, 2),
      RotaryEncOverMCP(&enc, 13, 12, &RotaryEncoderChanged, 3),
      RotaryEncOverMCP(&enc, 15, 14, &RotaryEncoderChanged, 4),
      RotaryEncOverMCP(&enc, 1, 0, &RotaryEncoderChanged, 5)
    };
    
    void RotaryEncoderChanged(bool clockwise, int id) {
      Serial.println("Encoder " + String(id) + ": "
        + (clockwise ? String("clockwise") : String("counter-clock-wise")));
    }
    
    void pollAll() {
      uint16_t gpioAB = allMCPs[0]->readGPIOAB();
        for (int i=0; i < 5; i++) {
          if(rotaryEncoders[i].getMCP() == allMCPs[0])
            rotaryEncoders[i].feedInput(gpioAB);
        }
    }

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,587
    looking at added code nothing jumps out at me.

    Make a bare example with just the needed encoder calls perhaps. I don't have any to test … but paring that down might show or the issue to resolve

  16. #16
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,518
    I just looked into the referenced encoder library
    I may be wrong, but it seems to me it is using I2C bitbang and no wire library
    for bitbang it tries to use GPIOA, GPIOB. is that not conflicting with I2S that uses PTA and PTB?

    I would try a library that uses a proper I2C library instead of bitbang

Posting Permissions

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