Using timer in phase-correct mode, generate PWM signal for servo (Uno)

So I have to generate PWM signal for servo using timer in phase-correct mode. Plus, operating with potentiometer, turn the servo left-right.
I made a realisation of the second part of the task, but I have no idea what to add to my code to fullfil first part of the task.
Here is my code:

#include <Servo.h>
Servo myservo;  // create Servo object
int potpin = A0;  // analog pin A0 for potentiometer
int val;    // value from A0 pin

void setup() {
  myservo.attach(5);  // servo attached to the pin 5
}

void loop() {
  val = analogRead(potpin);            // get value from A0 potentiometer (0-1023)
  int newval = map(val, 0, 1023, 0, 180);     // mapping to (0-180)
  myservo.write(newval);                  // turn the servo according to the mapped value
  delay(15);                           // small delay for servo to  spin
}

And a tinkercad schematic:

Is this a class assignment? Standard hobby servos have no requirement for phase-correct PWM.

In any case, a number of tutorials on line cover the topic.

Can you read controller data sheets and deal with bits and registers?

Otherwise have a look at the TimerOne library or one of the many timer threads in the forum.

Yes it is. I did some researcing and came up with this:

  DDRD |= (1<<PD5); //port 0C0B for output phase-correct PWM
  OCR0A = 200;	// (ТОР) = 200
  OCR0B = 153;	// duty 40%
  TCCR0A |= (1<<COM0B1) | (1<<COM0B0) | (1<<WGM00);	//mode 5: inverted p-c pwm 
  TCCR0B |= (1<<WGM02) | (1<<CS02)| (0<<CS01)| (1<<CS00);	//prescaler 1024

So i have servo connected to pin 5 and working on 50 Hz and Fosc = 16 Mhz and finally i got wave frequency ~30Hz. Code above is written inside the setup function, but how do I translate the signal to the servo (I guess inside the loop function)?

The framework and libraries use timer 0 for all timing. Use a different timer.

I cannot use any other timer because teacher's servo is connected to pin5 (PD5) that is controlled by register OCR0B according to the pinout. All I need is to understand how do I send this OCR0B = map(analogRead(A0),0,1023,500,2480); to the servo MG90S (I guess of course). There is nothing in the servo or t/c datasheets.

but how do I translate the signal to the servo (I guess inside the loop function)?

how do I send this OCR0B = map(analogRead(A0),0,1023,500,2480); to the servo MG90S (I guess of course).

Your wiring diagram shows you connecting the pin 5 output to the servo. What happens when you put OCR0B = map(analogRead(A0),0,1023,500,2480); into loop()?

I'd ask my teacher whether I really shall invent a very new framework timing by abusing timer 0 for something else. Something is very strange with your project description.

f = 16000000/(2x1024x OCR0A(156)) ~= 50 Hz
void setup()
{ 
  pinMode(5, OUTPUT)
  OCR0A = 156;	// 
  OCR0B = 78;	// initial duty 50%
  TCCR0A |= (1<<COM0B1) | (1<<COM0B0); //inverted mode
  TCCR0B |= (1<<WGM02)|(1<<WGM00); //Mode-5 inverted phase correct
  TCCR0B |=  (1<<CS02)|(0<<CS01)|(1<<CS00);	//start TC0 wit prescaler 1024
}

void loop()
{
     byte y = map(ananlogRead(A0), 0, 1023, 0, 154);
     OCR0B = y;
     byte dc = map(OCR0B, 0, 154, 178, 0); //see Fig-1 below
     myservo.write(dc);
     delay(15);
}


Figure-1:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.