I developed a PWM using timer1,using arduino uno and digital output, and identified that when I send a wave with duration of 0.6ms in High level, the motor goes to 0o. If I send 2.1ms, it goes to 180o. I tried to make a relationship between these scales to send the angle and change the time period in order to achieve that angle and it did not work.
I would like to move with a precision of 1 degree, is that possible? Just adjusting the time period.
The model of the motor is mg996r. Maybe I am missing something.
My code just generates an interrupt over 50 microsencods and I use this to set the frequency of 50Hz and the duty cycle in ms using digitalWrite associated with pin 9.
#include <TimerOne.h>
double t = 0.0;
double period = 0;
void setup()
{
t = 0;
Serial.begin(9600);
pinMode(9, OUTPUT);
Timer1.initialize(50);
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
void loop()
{
// Main code loop
// TODO: Put your regular (non-ISR) logic here
if (Serial.available() > 0) {
float grau = Serial.parseFloat();
// receive data as angle
if (grau > 180) grau = 180;
if (grau < 0) grau = 0;
// set period for that angle
// relationship developed between angle and period in ms
//set it to period
period = (0.00833*grau + 0.6)*1E-3;
}
}
/// --------------------------
/// Custom ISR Timer Routine
/// --------------------------
void timerIsr()
{
t += 50E-6;
if (t <= period) {
digitalWrite(9, HIGH);
}
else if (t < 20E-3) { // periodo max de 20ms -> 50Hz
digitalWrite(9, LOW);
}
else {
t = 0;
}
}
UPDATE:
I just got it working by creating a timer1 interrupt on CTC mode with a frequency of 100kHz and counting the necessary time to get increments (~ 10us each) of around 1 degree on my servo motor.
More info here.
-
The relationship is like a map between 0.6 ms -> 2.1ms and 0 -> 180 angle degrees. It works, but the problem is that it does not work for a precision of 1 angle degree as Arduino Servo Library does...bpinhosilva– bpinhosilva04/14/2015 22:12:36Commented Apr 14, 2015 at 22:12
-
For a precision of one degree, you need a minimum timer increment of 8.33us, which is optimistic. Your current 50us period gives you a resolution of ~6 degrees.Roger Rowland– Roger Rowland04/15/2015 04:43:24Commented Apr 15, 2015 at 4:43
-
I tried a resolution of 1us but it didn't work, the motor did not move. Can I achieve this using timer1?bpinhosilva– bpinhosilva04/15/2015 15:17:49Commented Apr 15, 2015 at 15:17
-
1I found that it has a dead band of 5us. So it won't move until the width changes by 5us.bpinhosilva– bpinhosilva04/15/2015 16:10:28Commented Apr 15, 2015 at 16:10
1 Answer 1
The best is to use 10us Period, instead of 50us.
That precision will be close to 1°
-
Thanks, @Mathsman, I got it working, you were right! Just created a timer1 interrupt using CTC mode and then generated an output signal with a frequency of 100kHz that I could increment the angle by approximately 1 degree.bpinhosilva– bpinhosilva04/28/2015 01:48:04Commented Apr 28, 2015 at 1:48
-
Your welcome. I recommended this as I have already tried it.Mathsman 100– Mathsman 10005/01/2015 08:46:51Commented May 1, 2015 at 8:46
-
It has precision of 1.1to 1.2 degrees.Mathsman 100– Mathsman 10005/01/2015 09:05:57Commented May 1, 2015 at 9:05