[Help Please] Atmega328p, converting a PWM servo code from pin9 to pin6

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I found a working code that uses pin9 (PB1) on my Arduino for controlling a Servo, but in my project, an ultrasonic sensor is already using that pin/timer. I want to convert the code to use pin6 (PD6), changed the registers according to the atmega's datasheet, but it doesn't work. Need help :/

 

The code should allow me to turn a servo using a potentiometer.

 

 

#define F_CPU 16000000 //16MHz

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#include <stdlib.h>



//#include <stdio.h>

//#include "uart/uart.h"





#define PWM_PRESCALLER 64

#define ICR_MAX (long double)F_CPU/PWM_PRESCALLER/50

#define OCR_MIN (float)ICR_MAX/37.5 // /8.75

#define OCR_MAX (float)ICR_MAX/8.7 // 37.5



//char uart_s[150];

volatile unsigned long adc_val=0;

volatile unsigned long counter=0;

unsigned long curr_adc=0;



ISR (ADC_vect)

{

adc_val += ADC;

counter++;

}



int main(void)

{



DDRD |= (1<<DDD6);

ICR1 = ICR_MAX;

OCR0A = OCR_MIN;

TCCR0A = (1 << COM1A1) | (1<<WGM00) | (1<<WGM01);

TCCR0B = (1<<WGM02) | (1<<CS01) | (1<<CS00);

ADMUX = (1 << REFS0);

ADCSRA = (1 << ADEN)|(1 << ADATE)|(1 << ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);

sei();

ADCSRA |= (1<<ADSC);





while(1)

{

if(counter >= 1000)

{

cli();

unsigned long round_val = round(adc_val / counter);

adc_val=0;

counter=0;

if(abs(round_val - curr_adc) > 1)

{

curr_adc = round_val;

}

long double ocr = OCR_MIN + ((long double)curr_adc * (OCR_MAX - OCR_MIN)/1024);



OCR0A = (int)round(ocr);

sei();

}

}

}

 

 

Formatted Code - JGM

Last Edited: Wed. Jun 13, 2018 - 01:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello.  Welcome to AVRfreaks.

 

Peti wrote:
I found a working code

 

Are you sure?  Did you try the 'working' code as is with your ultrasonic sensor removed to confirm the code works?

 

Is the code you posted the original 'working' code, or your modified version?

 

Why do you need "float" values?  Your servo is not that precise.

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
Peti wrote: I found a working code Are you sure?

+1.  Or more.

 

Many confusing things in the posted code.  To start with, how can an 8-bit timer on an AVR8 reach a 20ms period?  What does ICR1 have to do with tis?  Was this code really converted from timer1?

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
To start with, how can an 8-bit timer on an AVR8 reach a 20ms period?
Just guessing but is there some HUGE value for CLKPR (and/or perhaps very low value for external clock source) that would get you there eventually ?

 

BTW as an 8 bit timer only has 256 steps then if 256 = 20ms then the active 1ms to 2ms period is 13 to 26. So you have 13 positions for the servo - that's a pretty coarse granularity.

 

Oh and there's an ICR1= line in there which maybe supports the timer1 -> timer0 theory.

Last Edited: Wed. Jun 13, 2018 - 02:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see any reference in the original post about "ultrasonic sensor". Instead, the desire seems to be to run a servo that turns a potentiometer.

 

Agree with the comments about floating point values. Everything inside the micro is 8 or 16 bit integer. Sure, you may want to round properly after a division but using floats is a bit like using an 8-pound (4 kilo) sledge hammer to attach a picture hanger to a wall. 

 

Really, this is a simple task, and there are loads of (much better) examples out there on the net. But, better yet, write your own code and learn something along the way!

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Wed. Jun 13, 2018 - 04:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
which maybe supports the timer1 -> timer0 theory.
So does this:

Peti wrote:
working code that uses pin9 (PB1)
PB1 is OC1A.

Peti wrote:
I want to convert the code to use pin6 (PD6)
PD6 is OC0A.

Peti wrote:
changed the registers according to the atmega's datasheet, but it doesn't work

So it is quite obvious that the working code was for Timer 1, and the code shown above is his attempt to port it to Timer 0.

Stefan Ernst

Last Edited: Wed. Jun 13, 2018 - 04:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
I don't see any reference in the original post about "ultrasonic sensor".

 

First Sentence:

Peti wrote:
I found a working code that uses pin9 (PB1) on my Arduino for controlling a Servo, but in my project, an ultrasonic sensor is already using that pin/timer.

 

ECJ

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user