Audio and PWM motor control at the same time

Status
Not open for further replies.

jasch

New member
Hello,

I'm wondering if anyone has encountered the issue that PWM motor control is not working on the normal PWM pins when also using the audio library at the same time.
I believe it's to do with timers being used for audio that would normally drive the PWM generation.

I'm using a servo and an H-bridge-driven DC-motor controlled by an incoming audio-signal.

Any hints, pointers, help is greatly appreciated

thanks

/*j

here's a MWE:

Code:
#include <Servo.h>

#define AUDIOTHRESH 455
#define AUDIOMAX 505
#define RUNNINGSPEED 255 
#define TIMEINTERVAL 250 // should be 1000 for one second inervals if tables are 60 elements long

#define motorCtrl1 6 // analog side PWM
#define motorCtrl2 7 // analog side PWM
#define    analogIn1 8 // analog side
#define    analogIn2 9 // analog side 

#define servoCtrl 5 // digital pin PWM

int startDuration = 8; // seconds
int stopDuration = 8; // seconds

Servo myservo;
int sensorValueL;
int sensorValueR;

int audioValue;
boolean audioState;
int maximum;
int prevMaximum;
unsigned long t0, t1, t2;
unsigned long time1, time2;

int memory[500];
int counter = 0;

boolean motorCounter = 0;
int motorState = 0; // 0 stopped, 1 starting, 2 running, 3 stopping, 4 serching endposition
bool searchStop = false;

void setup()
{
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    myservo.attach(6);
    myservo.write(110);
}

void loop()
{   
    int audioSensingValue;
    float accum;
    audioSensingValue = analogRead(A0);
    audioValue = abs(512 - audioSensingValue);

// --- windowed audio, collecting maximum value
    memory[counter++] = audioValue;
    if(counter >= 500 ) {
        counter = 0;
    }
    maximum = -10000;
    for(int i = 0; i < 500; i++) 
    {
        if(memory[i] >= maximum) { maximum =  memory[i]; }
    }

    // logic for audio sync
    if(maximum > AUDIOTHRESH) 
    {
        if(maximum >= AUDIOMAX){
            motorState = 2;
        }else{
            motorState = 1;
            if(audioState == 0)
            {
                myservo.write(110);
                audioState = 1;
            }
        }
    }
    if(maximum <= AUDIOTHRESH)
    {
        if(audioState == 1)    // transition to low
        {        
            motorState = 4; // search locking position
        }
    }
  
// --- motor control
    time1 = millis();
    if(time1 >= time2 + TIMEINTERVAL ) // do everything here in 1 second intervals
    { 
        if(motorState == 1)    // starting 
        {
            analogWrite(motorCtrl, maximum );
            myservo.write(110);
            searchStop = false;

        } 
        else if (motorState == 2)  // running
        { 
            analogWrite(motorCtrl, 255);
        } 
        else if (motorState == 3) // stopping
        {  

        } 
        else if(motorState == 0) // stopped
        {      
            analogWrite(motorCtrl, 0);
            motorCounter = 0;
        }        
        time2 = time1;
    }
}
 
Last edited:
In the attached picture taken from https://www.pjrc.com/store/teensy3_audio.html you can see that the audio shield is "monopolizing" several Teensy pins. Thus, even when not using that shield, it is highly probable that the corresponding pins are reconfigured by the audio library.

Thus I'd suggest that you use the PWM pins attached to FTM1 (3 and 4) and FTM2 (25 and 32) when using a Teensy 3.2, or the FTM3 pins on Teensy 3.5 and 3.6 to prevent any "interference".
Capture d’écran 2017-10-24 à 13.08.30.png
 
Thank you for the quick reply,

What would the pins be for FTM3 on T3.5/3.6?
And how do I activate Timer3 for the Servo.h library and the built in PWM functions?

meilleures salutations

/*j
 
What would the pins be for FTM3 on T3.5/3.6?

Details here. Scroll down to "PWM Frequency" to find the table.

https://www.pjrc.com/teensy/td_pulse.html

And how do I activate Timer3 for the Servo.h library

You don't. Servo.h never uses any of the FTM timers, so no conflict. :)

The Servo library uses the PDB timer. It has an option in its code to alternately use LPTMR, which is the default on Teensy LC because LC does not have the PDB timer.

PWMServo does use the FTM timers. Simply use its attach() to a pin from FTM3 (from the table on the PWM page).

and the built in PWM functions?

Use analogWrite.
 
Thank you for the quick reply,
What would the pins be for FTM3 on T3.5/3.6?
Can be found in core_pins.h, thus pins 35 to 38 are convenient:
Code:
#define CORE_FTM3_CH0_PIN	 2
#define CORE_FTM3_CH1_PIN	14
#define CORE_FTM3_CH2_PIN	 7
#define CORE_FTM3_CH3_PIN	 8
#define CORE_FTM3_CH4_PIN	35
#define CORE_FTM3_CH5_PIN	36
#define CORE_FTM3_CH6_PIN	37
#define CORE_FTM3_CH7_PIN	38
And how do I activate Timer3 for the Servo.h library and the built in PWM functions?

meilleures salutations

/*j

As I just discover by looking at the source code, the servo library uses none of the FTM timers, but the PDB (programmable delay block) on T 3.x, thus it should work on any digital pin without modifications. But: The audio library uses the PDB, too, for generating the audio master clock. Thus, this might be another source of conflicts.
 
Status
Not open for further replies.
Back
Top