Go Down

Topic: Creating your own PWM to control a servo. (Read 2752 times) previous topic - next topic

mixania

Nov 16, 2012, 04:45 pm Last Edit: Nov 16, 2012, 04:47 pm by mixania Reason: 1
Huy guys, I just got a package from Hobby King with servo's and they are HEXTRONIC HXT500 5gr minis'.

Iv'e tested them out with the Servo Library and they worked Perfetto! However i bought such little ones (they almost fit on your thumb!) for a special purpose. I want to make a light weight and little insect robot. If i want to build it and make it light then I have no option but remove the Arduino Uno from the project and use it only for prototyping. Instead, the robot's brain will be a Attiny 85.

The Attiny has a problem however, it doesn't support the Servo library for the Arduino. I know that there are Servo libraries for little Attinie's but I prefer to do the code by myself.

I wrote a code to control my servo by pulsing a pulse of between 1ms and 2ms and then a stop period of 19- 18ms (20 - 1 = 19 ms; 20 - 2 = 18 ms). The standard stop period is 20ms, which is 50HZ exactly suitable for the servo's. But the servo just sits still when i upload my sketch to my Arduino Uno. :(

I have no idea how to alter the PWM signal from 500HZ (default) to 50HZ, so instead i decided to do it with the help of digitalWrite() and delay() functions.  

Please suggest me how to create a suitable PWM signal for controlling a servo.

Here is the code:
Code: [Select]

int servo = 14;

void setup() {
 
 pinMode(servo, OUTPUT); //OUTPUT setup
 
 for ( int i = 0; i > 5; i++){ // Set the possition to 90 degrees
  digitalWrite(servo, HIGH);
   delayMicroseconds(1500);
   digitalWrite(servo, LOW);
 }
 delay(2000);
}


void loop() {
 for ( int i = 0; i > 50; i++){
   digitalWrite(servo, HIGH);
   delayMicroseconds(1000); // Set the possition to 0 degrees
   digitalWrite(servo, LOW);
   delay(19);
 }
 for ( int i = 0; i > 50; i++){
   digitalWrite(servo, HIGH);
   delayMicroseconds(2000); //Set the possition to 180 degrees
   digitalWrite(servo, LOW);
   delay(18);
 }
}

 


Thank you guys.
Arduino Uno R3
Mac OSX Lion

justone

  ? int servo = 14;

Have not looked at the pin def's for the tiny85 which is a 8 pin device but pin 14 sounds wrong.

johnwasser

I don't think he 50Hz rate is a requirement, particularly not a lower limit.  I'd try just sending a pulse to each servo each time through loop().  If your servos don't like that you could use the BlinkWithoutDelay example to send pulses only every 20 ms.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

robtillaart

Quote
for ( int i = 0; i > 5; i++){ // Set the possition to 90 degrees
  digitalWrite(servo, HIGH);
   delayMicroseconds(1500);
   digitalWrite(servo, LOW);
 }

this loop has no delay after digitalWrite(servo, LOW); so it is effectively a high for 7.5 ms ?

Are you familiar with the blink without delay sketch?
It is a way to do timing more precise and it removes the blocking delays.
You need several extra variables to hold state.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

DuaneB

Hi,
  If you decide to follow this approach, for each servo that you add, you will use up 10% of your processing power, it  also means that you will not be able to respond to inputs while your timing code is running. For a small robot that moves slowly and has few sensors to respond to, it should be fine, but its worth mentioning these limitations.

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

Erni

There is this servo library made specific for the Attiny 45/85

http://www.cunningturtle.com/servo8bit-library-version-0-6-released/

mixania

Thank you for your responses guys! there were many helpful ones! :))
Arduino Uno R3
Mac OSX Lion

mcapurso

I succeded to control a servo on an attiny 84 and attiny 85  with the following code

//Tested on attiny 84 with servo towerpro microservo 90 SG90
// 08/jan/2014   servo data on www.servodatabase.com
int servoPin = 6;   // servo connected to digital pin 6
      
void setup()    
{   
         pinMode(servoPin, OUTPUT);   // sets the servoPin to be an output
}    
      
void loop()    // run over and over again
{    
       servowrite(servoPin, 0, 500, 2400); 
       servowrite(servoPin, 90, 500, 2400); 
       servowrite(servoPin, 180, 500, 2400); 
       // servotest();
}     

void servowrite(int pin, int angle, int microzero, int micro180)
{
  // pin for servo, angle to move, microseconds for zero degrees, microseconds for 180 degrees
  int microvalue= map(angle, 0, 180, microzero, micro180); //map angle to microseconds
  int i;
  for (i = 0; i < 50; i++)   //Send 50 pwm pulses with width microvalue uS
      {
        analogWrite(servoPin,255);              //Pulse high for microvalue uS     
        delayMicroseconds(microvalue);
        analogWrite(servoPin,0);                //Pulse low for 15mS
        delay(15);
       }
   delay(10);            //Pause
}

void servotest()
// test servo
{
   int i;

    for (i = 0; i < 50; i++)   //Send 50 pulses with width 500 uS
      {
        analogWrite(servoPin,255);                //Pulse high for 500uS     
        delayMicroseconds(500);
        analogWrite(servoPin,0);                //Pulse low for 15mS
        delay(15);
       }
      delay(100);            //Pause for 100mS
     
    for (i = 0; i < 50; i++)   //Send 50 pulses with width 1.25mS
     {
        analogWrite(servoPin,255);
        //Pulse high for 1.4 mS
        delayMicroseconds(1400); 
        analogWrite(servoPin,0);
        delay(15);
      }
      delay(100);

     for (i = 0; i < 50; i++) //Send 50 pulses with width 2.4ms
     {
        analogWrite(servoPin,255);
        delayMicroseconds(2400); 
        analogWrite(servoPin,0);
        delay(15);
      }
      delay(100);
   
                 
}

Go Up