Skip to main content
Arduino

Return to Question

replaced http://arduino.stackexchange.com/ with https://arduino.stackexchange.com/
Source Link

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 here.

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.

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.

Just solved the problem and I'd like to point a related question to it.
Source Link
bpinhosilva
  • 486
  • 3
  • 12

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 .

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;
 }
}

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 code indented
Source Link
bpinhosilva
  • 486
  • 3
  • 12

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;
 }
}

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.

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;
 }
}
Source Link
bpinhosilva
  • 486
  • 3
  • 12
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /