Go Down

Topic: myservo.detach() not releasing PWM on Digital pins 9 & 10 (Read 2247 times) previous topic - next topic

GunnerGunner

Jan 11, 2017, 10:44 am Last Edit: Jan 14, 2017, 07:43 am by GunnerGunner
According to servo.Detach() - Reference  Use of this command should release the PWM feature of Pins 9 & 10.  However, it does not.

I have been Googling this issue for about an hour and found many references over the years, but no apparent resolution... just a lot of advice to  "use different pins".

UPDATE: Yes, technically just another dreaded "workaround", but I was able to cobble up a simple servo control method that works just as well and without need of a library.  I posted it further on in this topic, but here it is for those who don't wish to read all the fluff.
Code: [Select]

// Manual servo control
// Smooth and minimal jitters - NO library needed.
//
// Currently using a potentiometer, but could be fed a number from
// 0-1023 that then gets mapped to microsecond pulses for the servo.
// My servo worked best with 690-2350 (0.69ms - 2.35ms) for a 180 deg range.
// Adjust accordingly to fit your servo.
//
// Gunner.

#define SERVO_PIN 5
#define POT_PIN A2
int ServoPOS;

void setup()
{
  pinMode(SERVO_PIN, OUTPUT);
}

void PotTurn()
{
  ServoPOS = map(analogRead(POT_PIN), 0, 1023, 2350, 690);  // Map to microsecond pulse (i.e. 2.35*1000=2350)
  digitalWrite(SERVO_PIN, HIGH);  // Activate servo pin, send servo to 0.
  delayMicroseconds(ServoPOS);  // Delay for the length of the pulse.
  digitalWrite(SERVO_PIN, LOW);  // Deactivate to servo pin.
  delay(5);  // Just a little extra delay seemed necessary to stabilize everything.
}

void loop()
{
  PotTurn();
}



Now for my project, I am using a UNO R3 with a Diyode CodeShield.  The shield has a fixed pin arrangement,  and the RGB LED utilizes pins 11, 10 & 9 respectively.  All other PWM pins are also utilized by something (including a single servo), and I am running all of the other devices anyhow, so switching pins is NOT an option in this case.  The RGB will work fine until I call the servo into action with the attach(x) command, then I loose all PWM control on the Green and Blue part of my RGB... and it just doesn't look the same without them :)

So my question is;  After all these years and updates, had this issue been looked into?  If so, what is the resolution?  If not... couldn't someone at least change the reference info ;)

manor_royal

The shield has a fixed pin arrangement
That's exactly why I hate the use of shields

Presumably you servo.detach()'ed all the servos?

I must say I had never read the part that says servo.detach() gives pin 9 and 10 their PWM back, but that (to me anyway) conflicts with the main servo page, where it says...

Quote
On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10
I always took that to mean that the mere presence of the line...

Code: [Select]

#include <Servo.h>


... meant you were using the library, so that took away the PWM from pins 9 and 10.


If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

GunnerGunner

#2
Jan 11, 2017, 11:05 am Last Edit: Jan 11, 2017, 11:22 am by GunnerGunner
With the project I am currently working on, only the one servo and all other PWW pins are in use anyhow, so being "fixed" is not really an issue. 

The PWM function of pins 9 & 10 do not get disabled until actually calling the attach(x) command, which I don't do until actually moving the servo.

Took me hours to even realize the whole, "servo library shares timer with pins 9 & 10 issue" in the first place... then when I found the 'detach() solution', I was happy... until, wha, wha, wha... solution failed :)

manor_royal

The PWM function of pins 9 & 10 do not get disabled until actually calling the myservo.attach(x) command.
Yeah I just verified that, and also verified the problem that you don't get PWM back on 9 and 10 if you detach all the servos. I just used the IDE's fade sketch to fade an LED on 9, 10 and 11. Works fine until I attached a servo to pin 7, then only the fade on 11 worked, as expected. Detaching the only servo didn't fix 9 and 10.

Maybe you need a Mega? Or think of some kind of distributed processing?

If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

manor_royal

Afterthought: The Analog pins are actually digital, and can run servos. You using them?

If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

GunnerGunner

#5
Jan 11, 2017, 11:34 am Last Edit: Jan 11, 2017, 11:51 am by GunnerGunner
I have a Mega, but for my latest project I only want to use the UNO (so I can optimize my code as much as I can into it's limited memory).  Basically I am teaching myself Arduino code by utilizing Blynk and was mashing as much into my initial project as I could (that one used the Mega); both because it is fun :) and because I must then learn to successfully mesh all the different code snippits, that I find or develop, into one functioning sketch. 

Really makes me think this way, as opposed to one little snippit at a time.  I was originally just using basic PWM to control the servo... which just doesn't work very well, so I figured I would merge in the servo library... and here I am.

And besides... I just want the detach() function to work the way 'they' say it should! ;)

GunnerGunner

Well, Google some more and ye shall find, but ask and nothing shall be done about it :(

Even the author of the servo library states that this issue requires something done to the timer core? I dunno.

Bug in servo library with detach()

Guess it is just not worth fixing  :-\

manor_royal

My question remains though: what about the analog pins A0-A5 as digital?- you doing that, or are they used as analog input already?

If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

GunnerGunner

#8
Jan 12, 2017, 09:32 am Last Edit: Jan 14, 2017, 07:44 am by GunnerGunner
My question remains though: what about the analog pins A0-A5 as digital?- you doing that, or are they used as analog input already?
Oh, sorry... I thought you had noted that I was using the Diyode CodeShield... it is chock full of devices, so ALL pins are in use (well except 4, 7 and 8 but I had to manually break them out)... so, no, Analog pins are all full up.

Besides the whole post was concerning the fault in the bleepin detach() function, as described in the reference... NOT how to find an alternate PWM pin ;)

That said... I scoured Google for alternative libraries and such... (that did not block the darn timers or PWM pins).  Not much I could find, except a reference to something called PWM sweeping (If I remember correctly). 

So I just dug into the example, tore it apart to basic elements, and wrote my own subroutine that works absolutely great for me!!  I just feed it a range from 0-1023 and the servo smoothly moves accordingly... and NO jitters.  I have even merged it into my chock full Blynk project... all happy camper like am I :D

Code: [Select]

// Manual servo control
// Smooth and minimal jitters - NO library needed.
//
// Currently using a potentiometer, but could be fed a number from
// 0-1023 that then gets mapped to microsecond pulses for the servo.
// My servo worked best with 690-2350 (0.69ms - 2.35ms) for a 180 deg range.
// Adjust accordingly to fit your servo.
//
// Gunner.

#define SERVO_PIN 5
#define POT_PIN A2
int ServoPOS;

void setup()
{
  pinMode(SERVO_PIN, OUTPUT);
}

void PotTurn()
{
  ServoPOS = map(analogRead(POT_PIN), 0, 1023, 2350, 690);  // Map to microsecond pulse (i.e. 2.35*1000=2350)
  digitalWrite(SERVO_PIN, HIGH);  // Activate servo pin, send servo to 0.
  delayMicroseconds(ServoPOS);  // Delay for the length of the pulse.
  digitalWrite(SERVO_PIN, LOW);  // Deactivate to servo pin.
  delay(5);  // Just a little extra delay seemed necessary to stabilize everything.
}

void loop()
{
  PotTurn();
}

manor_royal

Oh, sorry... I thought you had noted that I was using the Diyode CodeShield... it is chock full of devices, so ALL pins are in use (well except 4, 7 and 8 but I had to manually break them out)... so, no, Analog pins are all full up.
I'm not sure from its product page what the analog pins are used for though- and notwithstanding what you said about the thread being about that glitch, it's worth remembering that pins A0-A5 are digital.

As a matter of interest are you sure the analog pins are used? Apart from the pot and the ldr, that is.

In the pic on the page you linked there are no headers, so how do you attach anything to the unused pins?

I would like that product a zillion times more if it wasn't a shield, and could be wired in any way the user likes. I actually made a strip board with a small display, RTC and EEPROM (all I2C), and a couple of leds and buttons, and buzzer and couple of pots, but all with wires so I can attach it how I like.

Presumably that servo is hardwired for power to the Arduino 5V?- that's not wise, if it is.

If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

GunnerGunner

#10
Jan 12, 2017, 10:47 am Last Edit: Jan 12, 2017, 10:57 am by GunnerGunner
I'm not sure from its product page what the analog pins are used for though- and notwithstanding what you said about the thread being about that glitch, it's worth remembering that pins A0-A5 are digital.
Yes, I was aware of the dual uses of the analog pins, but thank you! 

As far as the CodeShield, it uses all the analog pins for the Rotary Encoder (x2), Potentiometer, Thermistor, LDR and Hall Effect sensor.

I purchased mine (years ago) as a kit, and had used extra long headers to keep better clearances... but I only really started fully using it in the last month... so I soldered some headers onto the open pins, as well and the power and ground on the other side.  I put them at right angles to the existing pins, just under the PCB, so as not to block the silkscreen as they would have if added on top.

No issues with the servo's current draw (it is only a tiny 9g), even when powered by USB; But as I am using everything concurrently, I add external power just because I can :)  This is a shield for programming and education use; More of a "Focus on the software debugging, not the hardware debugging", type thing.

I would like that product a zillion times more if it wasn't a shield, and could be wired in any way the user likes
Just order the kit and use jumper wires instead of the header pins.

manor_royal

This is a shield for programming and education use; Focus on the software debugging, not the hardware debugging, type thing.
Yep I get that, it's quite nice.
If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

manor_royal

Just order the kit and use jumper wires instead of the header pins.
I'm actually planning a bigger "general purpose control panel" because I keep losing stuff.

It will likely have:

I2C LCD with buttons built in and managed by the adafruit library
I2C RTC
LEDs of various colours and a couple of RGBs
A couple of 7-segs
An xy joystick
A micro servo
Loads of 3V, 5V and Gnd connections
Loads of buttons and switches
Breadboard glued down so I don't take it somewhere else
Some permanently mounted logic level mosfets (so they don't get lost)

.... and who knows what else will be a good idea?
If this was a Civil Engineering forum would there be posts like "I need to build a bridge. Someone send me drawings."

Go Up