No funciona servo con atmega 328p

Buenas noches!
Estoy intentando manejar un servomotor con un atmega328p. y no consigo hacerlo.
Lo que hago: Por el PIn de pwm del micro emito una señal de de T = 20m y 1,5 ms de tiempo de trabajo; y la recibe el servo por el pin de pulso.

Entre el microControlador y el servo, hay un uln2803 para obtener una mayor corriente.

Problema: no funciona. Algo estaré haciendo mal?

Adjunto imagen del circuito.
 

Adjuntos

  • foro.jpg
    foro.jpg
    38.8 KB · Visitas: 17
Sería buen o una foto de tu montaje y que publiques tu código para examinarlo.
Cuantos más datos nos de más rápido y mejores respuestas recibiras.
Si te fijas en el diagrama interno del ULN2803 las salidas on invertidas con respecto a la entrada
S3x9DW1397835883.jpg

Por otro lado la alimentación del servo debería ser independiente del micro
En general no hace falta ese circuito ya que lo que necesita es muy poco y puede tranquilamente ser controlado por el micro
 
Última edición:
Como te han comentado, no es necesario el Driver ULN 2803, ya que el servo-motor no requiere una alta corriente para ser controlado siendo suficiente la señal generada por el micro-controlador.

Por otro lado seria bueno conocer el código que utilizas en el micro-controlador y si cuentas con un frecuenciometro para verificar la salida generada.

Saludos.
 
No tiene ningún sentido aumentar la corriente de la señal de control, además ese driver es de colector abierto y seguramente el servicio no lo entiende. Quitalo.
Lo que sí que tiene sentido es aumentar la corriente de alimentación que la que da la placa de Arduino es mínima. Yo nunca alimento nada de ese regulador, no tan siquiera al propio Arduino.
 
No tiene ningún sentido aumentar la corriente de la señal de control, además ese driver es de colector abierto y seguramente el servicio no lo entiende. Quitalo.
Lo que sí que tiene sentido es aumentar la corriente de alimentación que la que da la placa de Arduino es mínima. Yo nunca alimento nada de ese regulador, no tan siquiera al propio Arduino.
No leí que fuera un Arduino, pero si recomiendo que uses alimentación independiente del MCU y cargas elevadas sobre todo inductivas como motores y relevadores por que puede producir reinicios.
 
Muchas gracias por las respuestas.

Como dice Nuyel, no estoy usando un arduino.
También estoy alimentando el microcontrolador con una fuente de 5 v y 2A. Además probé por separado alimentar el servo y el micro, pero tampoco funcionó.

Por otro lado seria bueno conocer el código que utilizas en el micro-controlador y si cuentas con un frecuenciometro para verificar la salida generada.
Saludos.
Medí la señal que sale del micro con un osciloscopio y está todo ok!

Pero mi duda es: no necesito amplificar la corriente de la señal que sale del micro? Porque tenía entendido que el servo consumía aproximadamente unos 400mA, la cual, el micro no puede entregar.
 
Confundes los conceptos
La corriente no viene del pin, viene de la alimentación.
La señal es señal de control y "no gasta"

Y la alimentación de un Arduino no da para eso.
 
Solo conecta el pin del micro directo el pin del PWM del servo y se acabo se ve que no lees hojas de datos y miras muchas paginas basura de internet
No, he leido la hoja de datos del micro, por eso me pareció correcto aumentar la mínima corriente que viene del micro. Y la hoja de datos del servo que uso, SG90, no tiene consideraciones eléctricas. Por eso opté por lo que decían "las páginas basuras" jeje.

Confundes los conceptos
La corriente no viene del pin, viene de la alimentación.
La señal es señal de control y "no gasta"

Y la alimentación de un Arduino no da para eso.
Ya entendí ahora. Conecto la entrada de señal de control del servo, directo al pin del micro. Pero cual será el problema de que no me funciona? Porque la señal está medida con un osciloscopio, y es la deseada.
 
La señal de control no gasta y la alimentación si, si fuera al revés sería absurdo
Al poner ese buffer inviertes la señal
Al poner ese driver se queda en colector abierto
Al no poner mas alimentación no llega bastante

Llevamos desde el principio con lo mismo.
 
Si, entendí perfectamente el porqué de no poner el uln2803. Pero al conectar el servo y el micro directo,como me han indicado, no me funciona. Voy a comprar otro servo y ver si el problema es ahí.
 
Si lo has conectado como ya te hemos indicado y no funciona o el servo no sirve o tu código esta mal
Si te fijas te pedí que publicarás el código, en el post #2 y no veo que lo hayas publicado.
Con información a medias es imposible ayudar.
Si te interesa que te ayudemos danos todos los datos, no nos has mostrado una foto de tu montaje, tal vez hay algo que esta mal allí, tu no logras verlo y nosotros menos porque no podemos verlo.
Te vuelvo a repetir, si queres recibir ayuda proporciona toda la información que se te solicita, por que si no estamos suponiendo cosas que es posible que no sean porque no estamos viendo nada......
 
Perdón por la tardanza. Si, es verdad lo del código; solo que no lo subía porque la señal que me daba en el osciloscopio era la correcta.
Pero a lo mejor hay algún error. Está en assembler:

Código:
.INCLUDE "m328Pdef.inc"

.DSEG
.ORG 0x100
.DEF init = R18
.DEF led = R20
.DEF pwm = R19; me proporciona el tiempo que el pwm está con nivel bajo.


.ORG 0x130
vector_RAM: .BYTE 4



.CSEG
.EQU PWM_CERO = 110
.EQU PWM_IZQ = 106
.EQU PWM_DER = 114

.EQU DDR_LED = DDRB
.EQU PORT_LED = PORTB
.EQU PINES_LED = PINB
.EQU PIN_LED_ROJO = 0

.EQU DDR_PRUEBA = DDRD
.EQU PORT_PRUEBA = PORTD
.EQU PINES_PRUEBA = PIND
.EQU PIN_PRUEBA = 7

.EQU DDR_PWM0 = DDRD
.EQU PORT_PWM0 = PORTD
.EQU PINES_PWM0 = PIND
.EQU PIN_PWM0A = 6


.ORG 0x00
    JMP MAIN
.ORG 0x0020
    JMP INTERRUP_DESBORD_TIMER0
.ORG 0x0024
    JMP INTERRUP_RECEP_UART_COMPLETA


.ORG 0x50
MAIN:
INICIA_PROGRAMA:
    LDI R16,HIGH(RAMEND)
    OUT SPH,R16
    LDI R16, LOW(RAMEND)
    OUT SPL,R16

    ;----CONFIGURACIÓN DE PUERTOS----

    SBI DDR_LED,PIN_LED_ROJO; Pone como salida el pin del led rojo.
    SBI DDR_PRUEBA,PIN_PRUEBA; Pone como salida el pin de prueba.

        ;....TIMER0....
    LDI R16,99
    OUT TCNT0,R16; acorto la cuenta para que el periodo del PWM sea de 20ms.
    SBI DDR_PWM0, PIN_PWM0A; Activo como salida el pin del pwm.
    CBI PORT_PWM0, PIN_PWM0A; Pongo en bajo el pin del PWM.
    LDI pwm,PWM_DER
    OUT OCR0A, pwm; comparador.
    LDI R16,0b11000011
    OUT TCCR0A, R16; modo rápido PWM, señal por pin OC0A de forma no invertida.
    LDI R16,0b00000101;
    OUT TCCR0B, R16; preescaler 1024: 0,128ms por pulso de clock.
    LDI R16,0b00000001;
    STS TIMSK0, R16; habilito interrupción por desbordamiento (cuando la cuenta llega a 255).
    SEI
   
   

;----INICIO PROGRAMA----
    INICIO_PROGRAMA:
        SBI PORT_LED,PIN_LED_ROJO; enciendo el LED
        SBI PORT_PRUEBA,PIN_PRUEBA; pongo en  alto el pin de prueba.
        ;SBI PORT_PWM0,PIN_PWM0A; enciendo el LED
        ;JMP FIN
        LDI pwm,PWM_DER
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
        LDI pwm,PWM_IZQ
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
        LDI pwm,PWM_CERO
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
    FIN: JMP INICIO_PROGRAMA


;----FUNCIONES----








;----RETARDOS----


;Uso clock de 8MHz. Un pulso de clock equivale a 125nseg.
SDELAY: ;call=4pulso
    NOP    ;=1pulso
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
RET; =4pulsos    TOTAL SDELAY: 16Pulsos=2us


DELAY_100us:
    PUSH R17
    LDI R17, 41
    DR0:
    CALL SDELAY
    DEC R17
    BRNE DR0
    POP R17
RET

DELAY_10ms:  ;
    PUSH R17
    LDI R17, 100
    DR1:
    CALL DELAY_100us
    DEC R17
    BRNE DR1
    POP R17
RET

DELAY_1s:  ; 1s en realidad
    PUSH R17
    LDI R17, 100
    DR2:
    CALL DELAY_10ms
    DEC R17
    BRNE DR2
    POP R17
RET


;----INTERRUPCIONES----

INTERRUP_DESBORD_TIMER0:
    LDI R16,99
    OUT TCNT0,R16; acorto la cuenta para que el periodo del PWM sea de 20ms.
    CBI PORT_PWM0, PIN_PWM0A; Pongo en bajo el pin del PWM.
RETI

Y aquí la conexión:
Micro y servo.jpg
Ya lo solucioné. Básicamente tenían razón ustedes: error en el código y la conexión del servo directo al micro.

Error del código fué que luego de tantas pruebas, había cambiado el tipo de pulso 19ms en alto y 1ms en bajo.

Código corregido:
Código:
.INCLUDE "m328Pdef.inc"

.DSEG
.ORG 0x100
.DEF init = R18
.DEF led = R20
.DEF pwm = R19; me proporciona el tiempo que el pwm está con nivel bajo.


.ORG 0x130
vector_RAM: .BYTE 4



.CSEG
.EQU PWM_CERO = 110
.EQU PWM_IZQ = 106
.EQU PWM_DER = 114

.EQU DDR_LED = DDRB
.EQU PORT_LED = PORTB
.EQU PINES_LED = PINB
.EQU PIN_LED_ROJO = 0

.EQU DDR_PRUEBA = DDRD
.EQU PORT_PRUEBA = PORTD
.EQU PINES_PRUEBA = PIND
.EQU PIN_PRUEBA = 7

.EQU DDR_PWM0 = DDRD
.EQU PORT_PWM0 = PORTD
.EQU PINES_PWM0 = PIND
.EQU PIN_PWM0A = 6


.ORG 0x00
    JMP MAIN
.ORG 0x0020
    JMP INTERRUP_DESBORD_TIMER0
.ORG 0x0024
    JMP INTERRUP_RECEP_UART_COMPLETA


.ORG 0x50
MAIN:
INICIA_PROGRAMA:
    LDI R16,HIGH(RAMEND)
    OUT SPH,R16
    LDI R16, LOW(RAMEND)
    OUT SPL,R16

    ;----CONFIGURACIÓN DE PUERTOS----

    SBI DDR_LED,PIN_LED_ROJO; Pone como salida el pin del led rojo.
    SBI DDR_PRUEBA,PIN_PRUEBA; Pone como salida el pin de prueba.

        ;....TIMER0....
    LDI R16,99
    OUT TCNT0,R16; acorto la cuenta para que el periodo del PWM sea de 20ms.
    SBI DDR_PWM0, PIN_PWM0A; Activo como salida el pin del pwm.
    SBI PORT_PWM0, PIN_PWM0A; Pongo en bajo el pin del PWM.
    LDI pwm,PWM_DER
    OUT OCR0A, pwm; comparador.
    LDI R16,0b10000011
    OUT TCCR0A, R16; modo rápido PWM, señal por pin OC0A de forma no invertida.
    LDI R16,0b00000101;
    OUT TCCR0B, R16; preescaler 1024: 0,128ms por pulso de clock.
    LDI R16,0b00000001;
    STS TIMSK0, R16; habilito interrupción por desbordamiento (cuando la cuenta llega a 255).
    SEI
   
   

;----INICIO PROGRAMA----
    INICIO_PROGRAMA:
        SBI PORT_LED,PIN_LED_ROJO; enciendo el LED
        SBI PORT_PRUEBA,PIN_PRUEBA; pongo en  alto el pin de prueba.
        ;SBI PORT_PWM0,PIN_PWM0A; enciendo el LED
        ;JMP FIN
        LDI pwm,PWM_DER
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
        LDI pwm,PWM_IZQ
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
        LDI pwm,PWM_CERO
        OUT OCR0A, pwm; comparador.
        CALL DELAY_1s
        CALL DELAY_1s
    FIN: JMP INICIO_PROGRAMA


;----FUNCIONES----








;----RETARDOS----


;Uso clock de 8MHz. Un pulso de clock equivale a 125nseg.
SDELAY: ;call=4pulso
    NOP    ;=1pulso
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
RET; =4pulsos    TOTAL SDELAY: 16Pulsos=2us


DELAY_100us:
    PUSH R17
    LDI R17, 41
    DR0:
    CALL SDELAY
    DEC R17
    BRNE DR0
    POP R17
RET

DELAY_10ms:  ;
    PUSH R17
    LDI R17, 100
    DR1:
    CALL DELAY_100us
    DEC R17
    BRNE DR1
    POP R17
RET

DELAY_1s:  ; 1s en realidad
    PUSH R17
    LDI R17, 100
    DR2:
    CALL DELAY_10ms
    DEC R17
    BRNE DR2
    POP R17
RET


;----INTERRUPCIONES----

INTERRUP_DESBORD_TIMER0:
    LDI R16,99
    OUT TCNT0,R16; acorto la cuenta para que el periodo del PWM sea de 20ms.
    SBI PORT_PWM0, PIN_PWM0A; Pongo en alto el pin del PWM.
RETI

Las lineas en negrita son las modificadas, para invertir el pulso que generaba antes:
en vez de CBI, cambié a SBI.
En vez de LDI R16,0b11000011, cambié a 0b10000011 para que el pwm no me salga invertido.

Muchas a gracias a todos por las respuestas.
:)

Saludos.
 
Última edición:
Atrás
Arriba