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

Thread: Audio shield and accelstepper

  1. #1

    Audio shield and accelstepper

    I have spent countless hours trying to get Teensy 3.5 with the audio shield to work together with accelstepper. i get the most bizarre results. the following sketch shows what would be expected in the serial monitor but stepper motion has nothing to do with the audio input. i have the following pins connected between the audio shield and the teensy, i do not have all pins connected because other things are going on another shield that connects the stepper motor. 3.3 volts from the teensy to the audio shield. gnd, and pins 23, 22 13 11 and 9 sending audio in from a ascam recorder playing an MP3 file. serial monitor shows detection of peaks and 0 when no signal input but all i get is an oscillation of the motor even with the signal off the onboard LED flickers all the time which also seems strange. not sure shy pin 13 was used for RX since it is connected to the LED?

    i have tried different ordering of the includes but this does not seem to matter. Is there some conflict between accelstepper and the audio library? i have not tried yet but can try running the stepper directly without the accelstepper library.


    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <AccelStepper.h>
    
    const int myInput = AUDIO_INPUT_LINEIN;
    
    AudioInputI2S        audioInput;         // audio shield: mic or line-in
    AudioAnalyzePeak     peak_L;
    AudioAnalyzePeak     peak_R;
    AudioAnalyzeRMS      rms_L;
    AudioAnalyzeRMS      rms_R;
    AudioOutputI2S       audioOutput;        // audio shield: headphones & line-out
    
    AudioConnection c1(audioInput, 0, peak_L, 0);
    AudioConnection c2(audioInput, 1, peak_R, 0);
    AudioConnection c3(audioInput, 0, rms_L, 0);
    AudioConnection c4(audioInput, 1, rms_R, 0);
    //AudioConnection c5(audioInput, 0, audioOutput, 0);
    //AudioConnection c6(audioInput, 1, audioOutput, 1);
    
    AudioControlSGTL5000 audioShield;
    
    AccelStepper stepper(AccelStepper::DRIVER,3,4);
    
    void setup()
    {  
        Serial.begin(57600);
    
        Serial.println("begin setup");
        AudioMemory(6);
        audioShield.enable();
        audioShield.inputSelect(myInput);
        audioShield.volume(1);  
        stepper.setPinsInverted(true,true,true);  
        
        stepper.setMinPulseWidth(20);
        stepper.setCurrentPosition(0)  ;
        stepper.setMaxSpeed(1000.0);
        stepper.setAcceleration(1000.0);
        while(!Serial && millis() < 2000 );
            
    }
    elapsedMillis fps;
    uint8_t cnt=0;
    int stroke;
    int totalPeak;
    
    void loop() {
      if(fps > 4) {
        if (peak_L.available() && peak_R.available() && rms_L.available() && rms_R.available()) {
          fps=0;
          float leftPeak = peak_L.read() * 30.0;
          float rightPeak = peak_R.read() * 30.0;
          float leftRMS = rms_L.read() * 30.0;
          float rightRMS = rms_R.read() * 30.0;     
          float totalRms = (leftRMS + rightRMS);
          totalPeak = leftPeak + rightPeak;
    //          stroke = totalRms;
          stroke = totalPeak * 5;
          Serial.print("stroke ");
          Serial.println(stroke);  
          if (stroke > 20){
            stepper.runToNewPosition(stroke);
          }
        }   
      }
    }

  2. #2
    i think i have it working. it seems that i did not understand peakavailable and rms available. still not sure what they are and would like some more precise explanations. i changed teh main loop to the following, using totalRms instead of totalPeak

    Code:
    void loop() {
      if(fps > 4) {
        if (peak_L.available() && peak_R.available() && rms_L.available() && rms_R.available()) {
          fps=0;
          float leftPeak = peak_L.read() * 30.0;
          float rightPeak = peak_R.read() * 30.0;
          float leftRMS = rms_L.read() * 30.0;
          float rightRMS = rms_R.read() * 30.0;     
          float totalRms = (leftRMS + rightRMS);
          totalPeak = leftPeak + rightPeak;
              stroke = totalRms * 5;
    //      stroke = totalPeak * 5;
          Serial.print("stroke ");
          Serial.println(stroke);  
          if (stroke > 20){
    //        for (int i=0; i < stroke; i++){
    //          cwpulse();
    //          delay(2);    
    //        }  
    //         for (int i=0; i < stroke; i++){
    //          ccwpulse();
    //          delay(2);    
    //        }         
            stepper.runToNewPosition(stroke);
          }
        }   
      }
    }

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    13,324
    Quote Originally Posted by spencoid View Post
    it seems that i did not understand peakavailable and rms available. still not sure what they are and would like some more precise explanations.
    Peak looks for maximum and minimum numbers of every sample. It's useful for know the "worst case" or "most case" that occurs. In practice with real audio signals, it's very sensitive to extremely short duration events that may or may not actually have much sonic significance to human hearing.

    RMS is about equivalent power. Imagine DC voltage into a resistor load. The power voltage times current, and since you can compute the current from the voltage and resistance, Power = V*V / R. Simple to calculate with DC voltage.

    But what happens when a rapidly varying AC voltage drives a resistor? Power is still dissipated in the resistor of course. Extremely short duration peaks have very little effect on the amount of actual power. It's still related to the square of the voltage, with an average effect over time.

    RMS is a calculation that gives you a number representing the voltage related to the amount of power is can deliver to a load. If you have a perfect square wave, the RMS is the same as the peak, because it's always driving the load with the peak voltage, half the time positive and half the time negative. But if the waveform isn't a perfect square wave, RMS gives you a voltage that is the same number as a DC voltage that would have caused the same amount of actual power into the resistive load.

    RMS is actually calculated by taking the square on each sample. A large group of those squares are averaged together, and then the square root is computed to give you the RMS number. Engineering textbooks are filled with complicated formal mathematical language about this, but the essential concept is RMS gives you a number for the overall voltage that's equivalent to the DC voltage in terms of how much power the signal will actually deliver if used to drive a resistive load.

Posting Permissions

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