Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict when using PWM and Servo at the same time #27

Open
fcooper opened this issue Aug 5, 2019 · 3 comments
Open

Conflict when using PWM and Servo at the same time #27

fcooper opened this issue Aug 5, 2019 · 3 comments

Comments

@fcooper
Copy link

fcooper commented Aug 5, 2019

OS: Windows 10 64bit
IDE Version: Energia 1.8.7E21
Board: MSP_EXP432E401Y
Core: MSP432 EMT Red v5.25.0

Currently I'm having an issue when using both analogWrite and the Servo library. It appears that the Servo library isn't aware of what timers analogWrite is using. Therefore, the two can conflict which causes weird behavior on both the pwm and servo pins.

Pins I'm using for PWM
P2.7, P2.6, P2.4 and P5.7

Pins I'm using for Servo
P3.7 and P3.6

Base example I used for testing is below

// Sweep
// by BARRAGAN <http://barraganstudio.com> 
// Modified for Energia/Stellaris Launchpad by Kevin Balke <[email protected]>
// This example code is in the public domain.

#include <Servo.h> 

#define P2_4  38
#define P2_6  39
#define P2_7  40
#define P5_7  17

#define P3_6  11
#define P3_7  31

Servo myservo1;  // create servo object to control a servo 
Servo myservo2;             // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 

  myservo1.attach(P3_6);  // attaches the servo on Port F, pin 1 (Red LED pin) to the servo object
  myservo2.attach(P3_7);  // attaches the servo on Port F, pin 1 (Red LED pin) to the servo object

  analogWrite(P2_4,50);
  analogWrite(P2_6,100);
  analogWrite(P2_7,150);
  analogWrite(P5_7,200);      
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo1.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo2.write(pos);   
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo1.write(pos);   
    myservo2.write(pos);       // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
} 

Based on the above example
image

Based on the above example but I made P5_7 a servo pin and P3_7 a pwm pin.
image

Based on the above example but I made P5_7 a servo pin and P3_6 a pwm pin.
image

As you can see at times depending on the order that pwm and servo pins are first used the output can vary. All six pins should have some kind of output but that isn't the case with the above.

@fcooper
Copy link
Author

fcooper commented Aug 9, 2019

Based on conversations with Robert and looking at the code this issue is due to the way the PWM code is written. PWM uses port mapping to allow almost an pin to be used for PWM. This port mapped pwm uses Timer A. However, the PWM code does not "claim" the timer it is using. Therefore, when other code attempts to request a free timer it may grab the same timer A instance that PWM may already be using. The proper fix is to have the PWM to properly claim the timer it is using so no other code will accidentally grab it. Also PWM code needs to check to see if the timer a instance is claimed by someone else before port mapping.

@fcooper
Copy link
Author

fcooper commented Sep 4, 2019

Tested this again on the official 5.25.0 release. I'm still seeing this issue.

@ndroid
Copy link

ndroid commented Aug 12, 2023

I believe v5.29 correctly claims (and checks for availability) of timer for analogWrite, though there is still a potential limitation produced by the conflict for the Timer_A resources. I have updated the MSP432 core to work on Arduino and have modified the Servo library so that it uses Timer32 instead, thereby having no conflict with PWM outputs. It is thus theoretically possible to have 12 PWM and 8 servo outputs concurrently.

You can find the package index file, board package and source at msp432-core.

This core is also included with the broader Energia core maintenance effort provided by TI_Platform_Cores_For_Arduino.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants