// Variable for the angle of the servo motor, ranging from 0 to 180 degrees
int grade = 0;
int contor = 0;
void setup() {
// Set pin 9 (OC1A) as an output
DDRB |= (1 << PB1);
// Set up Timer 0 to count time at the interrupt frequency of 250Hz, every 0.004s
TCCR0A = (1 << WGM01) | (0 << WGM00);
OCR0A = 0xF9;
TIMSK0 |= (1 << OCIE0A);
TCCR0B = (1 << CS02) | (0 << CS01) | (0 << CS00);
// Set up Timer 1 to generate a PWM signal with a frequency of 50Hz, every 20ms
TCCR1A = (1 << COM1A1) | (1 << COM1B1); // Non-inverted Mode
TCCR1B = (1 << WGM13) | (1 << CS11); // Prescaler 8
ICR1 = 20000; // TOP = F_CPU/2*Prescaler*50Hz
OCR1A = 0; // PWM duty cycle register
// Enable global interrupts
SREG |= (1 << SREG_I);
}
void loop() {
// Set the PWM duty cycle
OCR1A = convertAngleToPWM(45);
}
ISR(TIMER0_COMPA_vect) {
// Disable global interrupts
SREG &= ~(1 << SREG_I);
++contor; // Increment the counter
if (contor >= 100000)
contor = 0;
// Enable global interrupts
SREG |= (1 << SREG_I);
}
// Function to convert angle to PWM value
int convertAngleToPWM(int angle) {
// The motor operates with pulses between 0.5ms and 2.5ms, so a 2ms interval corresponds to 2000 increments in OCR1A
// If we have 500 increments for angles from 0 to 45 degrees, to convert the angle to the corresponding register value
// we calculate 500/45, which results in multiplying each degree by 11.1111 and then adding the starting value of 500
float a = 11.1111;
float b = 500;
return int(a * angle + b);
}
Your picture does not compute. Why the black thing. What is the fan like thing? I highly recommend you go back and read a few posts on this forum and many others about connecting motors to an arduino. You should come across two important rules:
Rule #1 An Arduino is NOT a Power Supply!
Rule #2 Never connect anything inductive to an arduino!
Maybe rule 3 should be if you fail on rule 1 or 2 have a spare pile of Arduinos.
The code still freezes at the setup of TCCR1B in Tinkercad. Why does this happen? (I am now using pin 10 to control the servo motor, but when I connect pin 10 to the servo motor, Tinkercad freezes.)
You were not using the ISR at all, so I made a few changes to use the ISR to move the pulsewidth slowly from 500 >> 2500 us, as that was mentioned in the formula description.
Keep in mind that you need to adapt the formula if you want a 1000 - 2000 us PWM pulse, which is the default servo range.
500 - 2500 us has some servo overtravel at both ends. Not all servo's can deal with that, but that is a matter of testing
// Variable for the angle of the servo motor, ranging from 0 to 180 degrees
//int grade = 0; // not used
volatile int contor = 0; // needs volatile as changed inside ISR
void setup() {
// Set pin 9 (OC1A) as an output
DDRB |= (1 << PB1);
// Set up Timer 0 to count time at the interrupt frequency of 250Hz, every 0.004s
TCCR0A = (1 << WGM01) | (0 << WGM00);
OCR0A = 0xF9;
TIMSK0 |= (1 << OCIE0A);
TCCR0B = (1 << CS02) | (0 << CS01) | (0 << CS00);
// Set up Timer 1 to generate a PWM signal with a frequency of 50Hz, every 20ms
TCCR1A = (1 << COM1A1) | (1 << COM1B1); // Non-inverted Mode
TCCR1B = (1 << WGM13) | (1 << CS11); // Prescaler 8
ICR1 = 20000; // TOP = F_CPU/2*Prescaler*50Hz
OCR1A = 0; // PWM duty cycle register
// Enable global interrupts
SREG |= (1 << SREG_I);
}
void loop() {
// Set the PWM duty cycle
OCR1A = convertAngleToPWM(contor/100);
}
ISR(TIMER0_COMPA_vect) {
// Disable global interrupts
SREG &= ~(1 << SREG_I);
++contor; // Increment the counter
if (contor >= 18000)
contor = 0;
// Enable global interrupts
SREG |= (1 << SREG_I);
}
// Function to convert angle to PWM value
int convertAngleToPWM(int angle) {
// The motor operates with pulses between 0.5ms and 2.5ms, so a 2ms interval corresponds to 2000 increments in OCR1A
// If we have 500 increments for angles from 0 to 45 degrees, to convert the angle to the corresponding register value
// we calculate 500/45, which results in multiplying each degree by 11.1111 and then adding the starting value of 500
float a = 11.1111;
float b = 500;
return int(a * angle + b);
}
Thank you for all your help, but I need to complete the project in Tinkercad, and the frustrating issue with WGM13 is causing the entire debugging process to freeze, which is driving me crazy!
Ok. In that case you can better change the topic of this discussion into: "Problem with WGM13 in Tinkercad" as your problem is not with Arduino nor the code itself.
Yes, I use it a lot as most of my projects have to do with some form of RC. No more testing with real servo's which often require their own powersource, and I can see the frequency or plain wrong pulses right away.
It is based on a super simple PCB that piggybacks straight on a 1602 display
I think so, tinkercad doesn’t offer me details of the servo motor name/serial number, but the problem is that at the 1 << WGM13 tinkercad freeze and I don’t understand why
Do you have a UNO or NANO and a SG-90 type Servo Motor? If yes, then I can provide you two different kinds of sketches -- Servo.h Library based and Registers based.