TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: amyver en 27 de Enero de 2012, 14:42:44

Título: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 27 de Enero de 2012, 14:42:44
Muy buenas amigos...bueno esta es mi primera consulta en el foro.. :P :P :P :P
La consulta es la siguiente:

Deseo implementar un circuito que sea capaz de controlar la velocidad de giro de un motor DC ante cambios bruscos de carga,
es decir que conserve una velocidad previamente programada ante distintos tipos de carga acoplada a su eje..

Bueno el detalle y lo mas crucial del proyecto es que no es posible hacer uso de un sensor externo, como por ejemplo un
encoder o algun sensor de otro tipo que se acople al eje del motor....


Bueno vi un circuito bastante interesante una vez en la cual se hacia el control de velocidad ante cambios bruscos de carga sin el uso de
sensores externos solo tomando los armonicos que se generaban al energizar el motor DC, mi objetivo es realizar un circuito de este tipo...acudo a ustedes para resolver esto...porfa ante cualquier duda acerca del planteamiento del problema con gusto respondere....

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: darck_khronos en 27 de Enero de 2012, 16:31:05
Podrias usar un convertidor de Corriente a Voltaje, en base al consumo de este lo mandas al ADC del Micro y con el puedes incrementar o decrementar la velocidad mediante el PWM o lo que se te ocurra utilizar como tecnica para esta variacion, pudes usar cualquier tipo de control, PI PD PID Fuzzy etc.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 27 de Enero de 2012, 16:49:20
Podrias usar un convertidor de Corriente a Voltaje, en base al consumo de este lo mandas al ADC del Micro y con el puedes incrementar o decrementar la velocidad mediante el PWM o lo que se te ocurra utilizar como tecnica para esta variacion, pudes usar cualquier tipo de control, PI PD PID Fuzzy etc.

Bueno en principio gracias por tu aporte darck_khronos...

Pero se me ocurre la siguiente ipotesis: ante un cambio de carga, efectivamente la corriente que atravieza el motor aumentaria
pero como podria saber si dicho motor entro en paro con esa corriente??? bueno la idea basica es que si en algun momento el motor
intenta parar por una carga exesiva, se incremente la tension de alimentacion del motor a fin de que no pare, y al mismo tiempo hacer un control de velocidad para que no se sobrepase la programada inicialmente..
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: darck_khronos en 27 de Enero de 2012, 16:55:16
Ya que no puedes acoplar ningun tipo de sensor lo unico que se me ocurre es ademas del convertidor de corriente-voltaje, agregar un otro opam, para medir la tencion que le estaras enviando al motor ya sea en incremento de esta o biceversa, y en base a eso mediante una tabla comparativa podrias ajustar tus marjenes a lo que necesitas, eso creo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 27 de Enero de 2012, 17:21:07
Bueno gracias nuevamente por tu aporte darck_khronos.

Te cuento que se me ocurrio algo similar a lo que me acabas de aconsejar, paso lo siguiente:

Inicialmente programaba una velocidad cualquiera al motor, por ejemplo una velocidad de 2500 RPM (el control de velocidad lo hago con el modulo ccp trabajando en PWM del pic 16F877A, claro que con un circuito de potencia para los motores el L6203), y efectivamente
estando el motor en vacio funcionaba correctamente y cuando se le ponia una carga exesiva el motor paraba y la tension de alimentacion al motor reducia, y como te decia se me ocurrio arreglar que pase lo que pase el circuito conserve constante la tension que inicialmente le habia dado al  motor, pero no resulto como queria :( :( :( :(  ya que el torque del motor se incremento solo un poco y el motor seguia parando con la tension inicial.. :( :( :(

Bueno alguna de las caracteristicas del motor que estoy utilizando
-Se trata de un motor DC de 30V y velocidad maxima de 30.000RPM
-es el tipo de motor utilizado para implantologia dental.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 27 de Enero de 2012, 18:06:09
Hay dos métodos que funcionan bastante bien:

A - Método por compensación de corriente:
1º  Mides la corriente del motor
2º Aumentas la tensión de alimentación del motor dV = I · Rmotor
La Rmotor tienes que conocerla antes(se puede medir con un polímetro, midiendo Ohmios con el motor parado)


B - Método por medición de la tensión generada (back-emf)
1º Apagas la tensión de alimentación del motor
2º Esperas a que la corriente de las bobinas llegue a cero
3º Mides la tensión que está generando el motor
4º Vuelves a alimentar el motor
(todo el ciclo debe durar poco tiempo, p.ejemplo 10ms)

La tensión que genera el motor es proporcional a la velocidad de giro

Error de los métodos: <1% si los ajustas bien

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 27 de Enero de 2012, 18:19:01
Hay dos métodos que funcionan bastante bien:

A - Método por compensación de corriente:
1º  Mides la corriente del motor
2º Aumentas la tensión de alimentación del motor dV = I · Rmotor
La Rmotor tienes que conocerla antes(se puede medir con un polímetro, midiendo Ohmios con el motor parado)


B - Método por medición de la tensión generada (back-emf)
1º Apagas la tensión de alimentación del motor
2º Esperas a que la corriente de las bobinas llegue a cero
3º Mides la tensión que está generando el motor
4º Vuelves a alimentar el motor
(todo el ciclo debe durar poco tiempo, p.ejemplo 10ms)

La tensión que genera el motor es proporcional a la velocidad de giro

Error de los métodos: <1% si los ajustas bien

Saludos.


muchas gracias amigo picuino, la verdad los dos metodos me parecen de lo mas interesantes
no las conocia y te pediria porfa si tienes alguna informacion adicional, paginas de internet o algun pdf te lo agradeceria
infinitamente
saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 06:25:31
Googleando puedes conseguir mucha información (sobre todo en inglés).
También tienes información en las notas de aplicación de microchip:
  AN847 – “RC Model Aircraft Motor Control” (DS00847)
  AN893 – “Low-cost Bidirectional Brushed DC Motor Control Using the PIC16F684” (DS00893)
  AN905 – “Brushed DC Motor Fundamentals” (DS00905)

Si no tienes experiencia, yo te recomendaría el primer método (del que ya estábais hablando) y respecto a saber la velocidad del motor, una vez regulada la velocidad permanece constante.
El motor sólo se para cuando dejas de aumentar la tensión de alimentación o cuando se quema.

Ejemplo:

Motor con R = 1 ohmio.
velocidad regulada = 10000 rpm

carga = vacío
I = 1 Amperio
Vmotor = 14 + 1A·1 Ohm = 15v

carga = máxima
I = 6 Amperios
Vmotor = 14 + 6*1 = 20v

carga = 3 veces la carga máxima
I = 16 Amperios
Vmotor = 14 + 16*1 = 30v

(en este último caso, la velocidad se mantiene en 10000rpm a costa de consumir 16Amperios y en pocos segundos el motor se quema)

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 28 de Enero de 2012, 09:56:43
Gracias mil una vez mas " picuino ", bueno pues entonces a googlear se a dicho  8) 8) 8) 8)
buscare informacion este fin de semana y publicare los avances de este proyecto...
Pero claro si alguien mas quiere aportar con sus conocimientos bienvenido seran chauu chauu amigos foreros    :-/ :-/ :-/ :-/ :-/ :-/
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Nocturno en 28 de Enero de 2012, 10:24:47
Muy interesante el hilo.
Picuino, de tus dos métodos, me gusta especialmente le segundo.

En el primero entiendo que generas corriente constante, ¿pero cómo sabes que la velocidad también lo es?
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 10:38:26
El modelo de un motor de corriente continua pequeño (con imanes en el estator) es símple: una resistencia en serie con un generador de tensión:

(http://www.globalspec.com/RefArticleImages/2E7925ABC41B09A0B5EEC3EC31C13BF3_9_1_1_9_1_1-IMGS-14.jpg)

El generador de tensión (también llamado fem, fuerza electromotriz o Electro Motriz Force)  tiene una tensión proporcional a la velocidad de giro:

   Eg = w · Km

con Eg en voltios y la velocidad de giro 'w' en rpm

En el caso de un motor de 33000rpm y 30 voltios  Km = 30/33000 = 0.00091 v/rpm

Si mantenemos constante la tensión Eg, la velocidad del motor se mantendrá constante. ¿Cómo se hace eso? Pues compensando la caída de tensión en las resistencias del devanado y de las escobillas (Ra y Rb).

Lo que mantenemos constante en los dos métodos es la tensión Eg interna del motor (que no es la tensión externa de alimentación V).

En varias pruebas que he hecho con motores pequeños (2vatios) con reductora de 1/50 resulta muy difícil mover el eje con la mano cuando se fija la velocidad a cero rpm. El motor se 'clava' en su lugar.

También es curioso ver el motor girando a 30rpm (una revolución en 2 segundos!) sin que se pare, aunque le pongas una pequeña carga.


Saludos.

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 10:39:15
Gracias mil una vez mas " picuino ", bueno pues entonces a googlear se a dicho  8) 8) 8) 8)
buscare informacion este fin de semana y publicare los avances de este proyecto...
Pero claro si alguien mas quiere aportar con sus conocimientos bienvenido seran chauu chauu amigos foreros    :-/ :-/ :-/ :-/ :-/ :-/
Si tienes dudas concretas no dudes en preguntar.
Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 10:54:38
Si hay más foreros interesados, se podría hacer un proyecto colaborando para hacer una placa que regule la velocidad de un motor DC pequeño (serviría para controlar la velocidad de un taladro tipo dremel).

Saludos.

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: sander en 28 de Enero de 2012, 11:41:03
Si hay más foreros interesados, se podría hacer un proyecto colaborando para hacer una placa que regule la velocidad de un motor DC pequeño (serviría para controlar la velocidad de un taladro tipo dremel).

Saludos.



A mi me interesa, donde me anoto  :)

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 11:49:48
Saludos sander,
Gracias por sumarte. Creo que podemos apuntarnos en este mismo hilo y de paso resolveremos dudas a amyver, que lo inició.

Por ahora podemos ir pensando si el regulador debería ser de un sólo sentido o de dos sentidos, es decir con marcha atrás  (el doble de dificil).

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 28 de Enero de 2012, 11:58:07
Saludos sander,
Gracias por sumarte. Creo que podemos apuntarnos en este mismo hilo y de paso resolveremos dudas a amyver, que lo inició.

Por ahora podemos ir pensando si el regulador debería ser de un sólo sentido o de dos sentidos, es decir con marcha atrás  (el doble de dificil).

Saludos.

En hora buena Sander  8) 8) 8) 8)

Seria genial si logramos hacer que el circuito tenga la posibilidad de girar en un sentido u otro...bueno esperamos a mas foreros para realizar este proyecto...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 12:19:33
Para hacer que gire en los dos sentidos es necesario un puente en H (cuatro transistores) con dos transistores en el lado alto que necesitarían dos driver para excitarles parecidos al  IR2101 (http://www.irf.com/product-info/datasheets/data/ir2101.pdf). Esto complica mucho el circuito de potencia. A cambio el circuito de medición de corriente o la medición de tensión Back-emf se simplifica.

Por otra parte un controlador de un solo sentido de giro tiene la ventaja de necesitar un solo transistor y un diodo de potencia. El transistor puede estar en el lado bajo y se excita con facilidad. El problema en este caso consiste en que la medición hay que realizarla referida a Vcc (lado alto).

Para controlar un motor de taladrado no es necesario el giro en sentido inverso, aunque podría utilizarse para desbloquear las brocas de forma automática si se detecta mucha corriente (si el motor se para)

El sentido inverso de giro se puede utilizar para bloquear el motor parado o para impedir que gire a más velocidad de la que se desea (para frenar el motor de forma regulada).


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 28 de Enero de 2012, 12:26:40
para la inversion de giro seria mejor usar un integrado como el L6203 (puente H), ya que aguanta una buena cantidad de corriente, me parece que superior a los 4 amperios, y el motor que pretendo controlar es uno que consume un maximo de 4 Amp
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Enero de 2012, 12:32:09
Había olvidado que hace tiempo que compré un L6203 (http://www.datasheetcatalog.org/datasheet/stmicroelectronics/1373.pdf) con la intención de utilizarlo en algún proyecto y lo tengo por ahí acumulando polvo.
No es muy caro y se encuentra con facilidad.

Por otra parte sería suficiente para mi taladro de 3Amperios y 18voltios.

¿Que opinas Sander?

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: sander en 29 de Enero de 2012, 01:04:45
Yo opino que es mejor hacerlo con inversion de giro, me parece mas general, tambien me parece adecuado usar el L6203 , de esta forma nos centramos mas en los dos metodos que picuino para controlar la velocidad, y no en parte del diseño del puente y el driver. Despues se podria ver esa parte para motores mas grandes.

Por mi parte voy a estudiar la hoja de datos del L6203, y ver algunas opciones para el circuito que comande el L6203

Saludos

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Enero de 2012, 06:37:44
Ahora hay que encontrar un método de medir la tensión del motor con el puente desconectado.

El integrado L6203 se desconecta por completo (todos los transistores off) y no se puede conectar sólo un transistor para llevar a masa uno de los terminales del motor.
Debido a esto la tensión del motor queda 'flotante' y no se puede medir bien.

Un método que se puede utilizar es colocar un transistor externo para la medición. Por ahora he encontrado esto:

http://www.siliconchip.com.au/cms/A_112702/article.html


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Enero de 2012, 06:40:35
He abierto otra entrada sin querer, porque no veía la anterior (estaba en la página siguiente)
Saludos.

P.D.:
Aprovecho para comentar que el circuito anterior tiene una 'zona muerta' en la que no mide tensión del motor.
Las tensiones de motor por debajo de 0.6v (tensión en directo del diodo) no se pueden medir.
Esto hace que en este rango el motor se mueva sin control.
Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Enero de 2012, 15:31:42
He preparado una placa que sirva de zócalo para el integrado L6203 y con una salida de pines con espaciado estandar 2.54mm y así poder insertarle en una protoboard.

Página web con las fuentes:
https://sites.google.com/site/picuino/dc_motor_regulator

Esquema y placa:

(https://sites.google.com/site/picuino/dc_motor_regulator/L6203_Zocalo_Esquema_v10.png)

(https://sites.google.com/site/picuino/_/rsrc/1327860979064/dc_motor_regulator/L6203_Zocalo_Pistas_v10.png)

(https://sites.google.com/site/picuino/_/rsrc/1327860998996/dc_motor_regulator/L6203_Zocalo_Componentes_v10.png)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Enero de 2012, 17:34:02
(https://sites.google.com/site/picuino/dc_motor_regulator/L6203_zocalo.jpg)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: sander en 29 de Enero de 2012, 18:47:41
He abierto otra entrada sin querer, porque no veía la anterior (estaba en la página siguiente)
Saludos.

P.D.:
Aprovecho para comentar que el circuito anterior tiene una 'zona muerta' en la que no mide tensión del motor.
Las tensiones de motor por debajo de 0.6v (tensión en directo del diodo) no se pueden medir.
Esto hace que en este rango el motor se mueva sin control.
Saludos.


Hola Picuino, he revisado el circuito para medir  la tension del motor y sobre la zona muerta de la que hablas, los 0.6 V se deben al diodo schoktty o al transistor Q1?.

Aunque ahora que lo pienso ......, creo que ambos componentes tienen su influencia, a la del diodo no hay mucho que hacerle, para la del transistor podrias pensar en poner un
Mosfet en lugar de un BJT, asi podriamos reducir ese voltaje. que opinas?

PD : A la placa que te preparaste talvez se le podria aumentar los diodos externos y la red snnuber que se sugieren en la hoja de datos, asi evitas de ponerlas externamente.

Saludos

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Enero de 2012, 19:22:29
Me he equivocado, la zona muerta es de 2*Vd es decir 1.2 voltios.

La zona muerta se debe a que la resistencia de 10k que está en la parte baja del motor está conectada a tierra a través de un diodo.
Por lo tanto su tensión es de -0.6v

Un motor con 1.2 voltios va ha tener sus bornas a -0.6v y +0.6v y en el punto medio se miden 0 voltios.

http://www.siliconchip.com.au/cms/gallery/article.html?slideshow=0&a=112702&i=3

Por ahora se puede probar el funcionamiento con tensiones grandes y ya se corregirá el problema de las pequeñas tensiones cuando lo demás funcione.
(También creo que habrá que corregirlo con un MOSFET)


Diodos externos:
Creo que no hacen falta (ya tiene diodos el L6203)

Red snnubber:
Quiero hacer pruebas con varios valores a ver que pasa. Puede afectar a la medición de la back-emf, de manera que habrá que afinarla.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 31 de Enero de 2012, 14:54:34
Bueno luego de analizar el circuito que muestras picuino, se me quedan algunas dudas...

- La primera:  Entiendo que los diodos que salen de los terminales del motor son para aterrarlo y asi tener una lectura confiable
                     de la Back-emf cuando se pare el motor por un instante de tiempo verdad???.
- La segunda: Cual es la funcionalidad del Diodo D5, pues si no me equivoco es por el catodo de este diodo por donde se haran las lecturas
                     de la Back-Back-emf....
- La Tercera:   Las lecturas de la Back-emf deberan ser pasadas al modulo CAD del micro que se usa, pero para esta lectura no hara falta limitar
                     el voltaje de entrada a dicho conversor???, bueno normalmente yo uso los micros de Microchip y su conversor analogico digital tiene
                     un voltaje max analog de In de 5V.
- Y la Ultima:  Segun entiendo la funcionalidad del transistor BC337 es para habilitar las lecturas de la Back-emf cuando se necesite..

Bueno son algunas dudas que tube y confiando en la amabilidad y tolerancia si es necesario de los amigos foreros en especial de picuino seguiremos adelante... :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 31 de Enero de 2012, 17:43:36
Bueno luego de analizar el circuito que muestras picuino, se me quedan algunas dudas...

- La primera:  Entiendo que los diodos que salen de los terminales del motor son para aterrarlo y asi tener una lectura confiable
                     de la Back-emf cuando se pare el motor por un instante de tiempo verdad???.
- La segunda: Cual es la funcionalidad del Diodo D5, pues si no me equivoco es por el catodo de este diodo por donde se haran las lecturas
                     de la Back-Back-emf....
- La Tercera:   Las lecturas de la Back-emf deberan ser pasadas al modulo CAD del micro que se usa, pero para esta lectura no hara falta limitar
                     el voltaje de entrada a dicho conversor???, bueno normalmente yo uso los micros de Microchip y su conversor analogico digital tiene
                     un voltaje max analog de In de 5V.
- Y la Ultima:  Segun entiendo la funcionalidad del transistor BC337 es para habilitar las lecturas de la Back-emf cuando se necesite..

Bueno son algunas dudas que tube y confiando en la amabilidad y tolerancia si es necesario de los amigos foreros en especial de picuino seguiremos adelante... :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/


Saludos de nuevo Gente del Foro...
Bueno pues dedicandole su tiempo al circuito que muy amablemente nos mostro picuino logre disolver algunas dudas y quiero compartirlas...

*En cuanto a la Primera:
     Los diodos D3 y D4 (Schottky) están conectados paralelamente a los diodos internos del integrado L6203, su conmutación es mas rápida y   
     hace el circuito más eficiente.

*La Segunda:
    El diodo D5 (Schottky), el condensador 10nF y el resistor 10MΩ en su cátodo forman peak-hold. Entonces un Back-EMF positivo polariza D5
    hacia adelante y carga el condensador que entonces descarga a través de su resistor en paralelo.

*La Tercera:
    Bueno para ser sincero aun no logre deducir cuales seran los rangos maximos y minimos de las lecturas que tendre (con el motor que
    pretendo utilizar) para incertarlas en el CAD, pero bueno, se forma un filtro pasa bajo usando el condensador 10nF y su resistor en paralelo
    22kΩ para descargarlo (también se reduce la amplitud detectada del Back-EMF)

*Y la Ultima:
    Bueno en esta no me equivoque, pues efectivamente el transistor BC337 sirve para abilitar las lecturas de la Back-EMF. :mrgreen:

bueno esperamos mas comentarios y aportes saludos....... ;-) ;-)
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 31 de Enero de 2012, 17:52:33
He quemado el integrado L6203. :?

Las primeras pruebas con un motor de 2W empezaban a funcionar bien (cuando intentaba frenar su velocidad con la mano, la potencia aumentaba hasta 6W antes de empezar a frenar)

Después probé con el taladro y en pocos segundos se quemó el integrado. No lo entiendo, porque la intensidad no subió de 3 amperios (la fuente no permite más) y el integrado está protegido contra sobrecalentamientos.

El caso es que voy a continuar las pruebas con un puente en H que tengo a base de 4 mosfet BUZ11, con un driver que se apaga cuando la tensión de puerta es muy baja.

Cuando tenga el puente funcionando OK y con protección, volveré a intentarlo con el L6203.

Dejo un esquema que quizás sea más sencillo de entender (es con el que voy a trabajar). Su lectura de tensión de motor está limitada por ahora a 10 voltios (suficiente para realizar pruebas):

(https://sites.google.com/site/picuino/dc_motor_regulator/Schematic_v01.png)

Ya se que no estoy utilizando el módulo PWM... todo llegará.

Saludos.



Editado:
Habría que colocar dos condensadores (o dos RC) de filtro entre las entradas analógicas y tierra.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Nocturno en 31 de Enero de 2012, 18:04:55
No se ve el esquema, picuino
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 31 de Enero de 2012, 18:51:32
El circuito anterior necesita un pequeño condensador a la entrada de RA0 y RA1 (las entradas analógicas)

Código que funcionó con el motor pequeño:
(es muuy simple, sin interrupciones ni PWM ni nada)

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.  
  4.    C18 COMPILER
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9. #include <delays.h>
  10.  
  11. #define  FOSC 20000000
  12. #define  BAUD 57600
  13.  
  14.  
  15. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  16. #define DCMOT_TRIS_AN1     TRISAbits.TRISA1
  17.  
  18. #define DCMOT_TRIS_BEMF    TRISAbits.TRISA2
  19. #define DCMOT_BEMF         PORTAbits.RA2
  20.  
  21. #define DCMOT_TRIS_ENABLE  TRISAbits.TRISA3
  22. #define DCMOT_ENABLE       PORTAbits.RA3
  23.  
  24. #define DCMOT_TRIS_IN1     TRISAbits.TRISA4
  25. #define DCMOT_IN1          PORTAbits.RA4
  26.  
  27. #define DCMOT_TRIS_IN2     TRISAbits.TRISA5
  28. #define DCMOT_IN2          PORTAbits.RA5
  29.  
  30.  
  31. /****************************************************************************
  32.     ADC FUNCTIONS
  33.  ****************************************************************************/
  34. /*
  35.   Read Analog Input AN0 or AN1
  36. */
  37. unsigned short adc_read(unsigned char channel) {
  38.    union {
  39.       struct {
  40.           unsigned char lob;
  41.           unsigned char hib;
  42.       };
  43.       unsigned short word;
  44.    } adc_val;
  45.  
  46.    // Configure ADC
  47.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  48.    ADCON1 = 0b00001101;   // Analog inputs = AN0, AN1
  49.    ADCON2 = 0b10010101;   // TAD
  50.  
  51.    // GO ADC conversion
  52.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  53.    while (ADCON0bits.GO==1); // Conversion
  54.  
  55.    // Configure ADC
  56.    ADCON0 = 0b00000000;   // ADC off
  57.    ADCON1 = 0b00001111;   // All pins to digital inputs
  58.  
  59.    // Return ADC conversion
  60.    adc_val.lob = ADRESL;
  61.    adc_val.hib = ADRESH;
  62.    return adc_val.word;
  63. }
  64.  
  65.  
  66. /****************************************************************************
  67.       RS232 FUNCTIONS
  68.  ****************************************************************************/
  69. #pragma code
  70.  
  71. /*
  72.   Initialize USART for RS232 comunications
  73. */
  74. void rs232_init(void) {
  75.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  76.    SPBRGH = 0;
  77.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  78.  
  79.    TXSTA = (char)
  80.            (0<<7)    // CSRC:  1 = Syncronous Master mode
  81.          + (0<<6)    // TX9:   1 = Selects 9-bit transmission
  82.          + (1<<5)    // TXEN:  1 = Transmit enabled
  83.          + (0<<4)    // SYNC:  1 = Synchronous mode
  84.          + (0<<3)    // SENDB: 1 = Asynchronous mode: Send Sync Break on next transmission (cleared by hardware upon completion)
  85.          + (1<<2)    // BRGH:  1 = Asynchronous mode: High speed
  86.          + (1<<1)    // TRMT:  1 = TSR empty
  87.          + (0<<0);   // TX9D:  Ninth bit of Transmit Data
  88.  
  89.    RCSTA = (char)
  90.            (1<<7)    // SPEN:  1 = Serial port enabled
  91.          + (0<<6)    // RX9:   1 = Selects 9-bit reception
  92.          + (0<<5)    // SREN:  1 = Enables single receive in Master Synchronous mode
  93.          + (1<<4)    // CREN:  1 = Enables Continuous Receive
  94.          + (0<<3)    // ADDEN: 1 = Enables address detection (RX9 = 1)
  95.          + (0<<2)    // FERR:  1 = Framing error
  96.          + (0<<1)    // OERR:  1 = Overrun error (can be cleared by clearing bit CREN)
  97.          + (0<<0);   // RX9D:  Ninth bit of Received Data
  98.  
  99.    TRISCbits.TRISC6 = 0;      // Enable TX output
  100.    PIE1bits.TXIE = 0;         // Disable RS232 interrupts
  101. }
  102.  
  103.  
  104. /****************************************************************************
  105.     PWM OUTPUT
  106.  ****************************************************************************/
  107. void dcmot_pwm(int Vo) {
  108.    char i;
  109.    if (Vo<1)  Vo = 1;
  110.    if (Vo>99) Vo = 99;
  111.    DCMOT_ENABLE = 1;        // Switch on H-bridge
  112.    for(i=0; i<50; i++) {
  113.       DCMOT_IN1 = 1;
  114.       Delay10TCYx(Vo);
  115.       DCMOT_IN1 = 0;
  116.       Delay10TCYx(100-Vo);
  117.    }
  118.    DCMOT_ENABLE = 0;        // Switch off H-bridge
  119. }
  120.  
  121.  
  122. /****************************************************************************
  123.       MAIN PROGRAM
  124.  ****************************************************************************/
  125. void main(void) {
  126.    int Vref, Vmot, Err, Integ, Vo;
  127.  
  128.    // Initialize
  129.    rs232_init();
  130.    CMCON = 0b00000111;
  131.    ADCON1 = 0b00001111;
  132.    
  133.    DCMOT_BEMF = 0;
  134.    DCMOT_IN1 = 0;
  135.    DCMOT_IN2 = 0;
  136.    DCMOT_ENABLE = 0;
  137.  
  138.    DCMOT_TRIS_BEMF = 0;
  139.    DCMOT_TRIS_IN1 = 0;
  140.    DCMOT_TRIS_IN2 = 0;
  141.    DCMOT_TRIS_ENABLE = 0;
  142.  
  143.    DCMOT_TRIS_AN0 = 1;
  144.    DCMOT_TRIS_AN1 = 1;
  145.  
  146.    fprintf(_H_USART, (const rom far char *)"\r\nSystem OK.\r\n");
  147.  
  148.    // DC MOTOR SPEED CONTROL
  149.    Vo = 1;
  150.    Integ = 0;
  151.    while(1) {
  152.        dcmot_pwm(Vo);
  153.  
  154.       //*********************************
  155.       // BACK EMF SENSE
  156.       //*********************************
  157.  
  158.       // printf control values while I_motor decrease to 0
  159.       fprintf(_H_USART, (const rom far char *)"Vm=%d   Err=%d   Intg=%d   Vo=%d\r\n", Vmot, Err, Integ, Vo);
  160.       Delay10TCYx(200);
  161.  
  162.       DCMOT_BEMF = 1;          // Ground motor terminal
  163.       Delay10TCYx(100);
  164.       Vmot = adc_read(0);
  165.       DCMOT_BEMF = 0;
  166.  
  167.  
  168.       //*********************************
  169.       // PI Speed control
  170.       //*********************************
  171.       Vref = 100;
  172.       Err = Vref - Vmot;        
  173.       Integ += Err;
  174.       if (Integ>20000) Integ = 20000;
  175.       if (Integ<-20000) Integ = -20000;
  176.  
  177.       Vo = Err/8 + Integ/16;
  178.    }
  179. }


Saludos.


Editado:
He añadido una linea muy importante:
      DCMOT_BEMF = 0;
Sin ella, el transistor Q1 se funde al comenzar el puente a dar tensión.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 31 de Enero de 2012, 18:53:42
No se ve el esquema, picuino
Gracias Nocturno, creo que google sites da problemas a veces mientras lo edito. (sólo lo veo yo)
Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 01 de Febrero de 2012, 16:19:46
Creo que ya se porqué se ha quemado el driver.
El problema está en el motor de mi taladro, que consume mucha corriente en la conmutación. Creo que tiene muy poca inductancia.

Para evitar este problema he cambiado el circuito de prueba añadiendo una inductancia de filtro.

También he añadido filtros a las entradas de tensión analógicas y una resistencia al transistor Q1 para que no se queme por error:

(https://sites.google.com/site/picuino/_/rsrc/1328122976723/dc_motor_regulator/Schematic_v02.png)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: LeugimZerO en 01 de Febrero de 2012, 23:20:12
muy interesante picuino  :-/ sigo atento al hilo, termino un proyecto pendiente y hago pruebas... suerte a todos  :mrgreen:
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Febrero de 2012, 08:23:59
He vuelto a medir la corriente por el motor de mi taladro y cuando lo paro con la mano, llega a picos de 8 amperios alimentando el puente a 16v.
No me extraña que el L6203 se quemara.
Para prevenirlo, el esquema final debería tener una limitación rápida por corriente excesiva. Creo que muchos micros tienen unido el comparador con el módulo PWM para apagar el PWM ante corrientes excesivas.

Por ahora lo estoy probando con un 18F2550, pero el micro final debería ser un 16F88 ¿Que opinais?

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Febrero de 2012, 08:39:50
muy interesante picuino  :-/ sigo atento al hilo, termino un proyecto pendiente y hago pruebas... suerte a todos  :mrgreen:

Gracias LeugimZerO, cualquier aporte será bienvenido.

Veo que has publicado sobre drivers para motores PAP.

Una de las aplicaciones de este proyecto puede ser sustituir un motor PAP. En el peor de los casos un motor regulado por Back-emf puede tener un error del 5% en su velocidad.
Este error de velocidad se puede corregir con facilidad con un encoder.

La ventaja de utilizar motores DC en vez de PAP es que estás seguro de no perder pulsos y el par motor es mucho mayor.
La mayoría de las impresoras se mueven con motores DC y encoders muy baratos construídos con una lámina transparente con rayas impresas y un fotodetector:

(http://www.indoor.flyer.co.uk/printer/encoder.JPG)

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Febrero de 2012, 10:54:00
Otro circuito más para hacer pruebas (y van 3):

Ya funcionan los circuitos anteriores con motores pequeños. Además he comprado otro L6203 (a ver si este me dura más :D)

Con este tercer circuito voy a probar:
   Conmutación con el módulo PWM del micro a frecuencias más altas (25Khz)
   Tensión de alimentación mayor (30v)
   Limitación de corriente de pico para proteger al integrado.
   Regulación PID más fina (por ahora el motor se acelera al aumentar la carga mecánica en el eje y la velocidad de giro oscila mucho)

(https://sites.google.com/site/picuino/dc_motor_regulator/Schematic_v03.png)

   
Faltaría por desarrollar:
   Control del motor en los dos sentidos.
   Sensado de Back-emf en los dos sentidos.
   Sensado de corriente media por el motor.
   Regulación de par motor.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 03 de Febrero de 2012, 11:22:07
Buenisimo PICUINO... :!: :!: :!: :!: sera posible escribir el codigo del micro en "C" :?: :?: :?: :?:
saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Febrero de 2012, 12:46:41
El código en el que me baso está unos mensajes más arriba y ya funciona (sin módulo PWM)

Sólo hay que mejorarle.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Febrero de 2012, 13:12:33
Ahora creo que hace falta tratar el tema de los motores DC con más detalle.

He creado un nuevo hilo donde explico el funcionamiento de los motores de corriente continua (dentro del foro técnico) y he desplazado todo el contenido que tenía en este mensaje:

GUIA: Motores de corriente continua (http://www.todopic.com.ar/foros/index.php?topic=37484.0)


Saludos

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 03 de Febrero de 2012, 14:31:55
El código en el que me baso está unos mensajes más arriba y ya funciona (sin módulo PWM)

Sólo hay que mejorarle.

Saludos.

En realidad me referia al lenguaje de programacion del CCS.... :mrgreen: :mrgreen:
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Febrero de 2012, 14:45:27
No tengo instalado CSS ni lo conozco, pero no creo que sea difícil.
De hecho casi no he utilizado librerias para que sea más portable.

De todas formas el programa aun no está terminado.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Febrero de 2012, 14:55:22
Cómo funciona un motor DC de imanes permanentes:
=======================================

1.7 Ejemplos prácticos:

Motor de 33000 rpm 30 voltios y 4 amperios:

   w = 33000 rpm = 3456 rad/s
   Pe = I · V = 4 · 30 = 120w
   Pm = Pe · n = 120 · 0.85 = 102 w     (El rendimiento n vale aproximadamente 0.85 para un motor típico de 100w)
   N = Pm / w = 102 / 3456 = 0.0295 Nm = 29.5 mNm = 301 grf·cm     (par máximo)
   Km = I / N = 4 / 0.0295 = 136 rad/s·v


Pequeño motor de 6v y 1A
    Rm = 2 ohm     (medido con polímetro)

    V = 3v   I = 0.06 A   w = 790 rpm
    Km = w / (V - Rm · I) = 790 / (3 - 2 · 0.06) = 274 rad/s·v
    N = I / Km = 1 / 274 = 0.0036 Nm = 3.6 mNm = 36.7 grf·cm    (par máximo)
    Máxima velocidad w = Eg · Km = 6 · 274 = 1644 rad/s = 15700 rpm

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 04 de Febrero de 2012, 10:47:49
Las pruebas que voy realizando dan buenos resultados.
He modificado el código para que tenga menos librerías del compilador.

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=37404.0;attach=17762;image)

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10. #define  FOSC 20000000
  11. #define  BAUD 57600
  12.  
  13.  
  14. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  15. #define DCMOT_TRIS_AN1     TRISAbits.TRISA1
  16.  
  17. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC1
  18. #define DCMOT_ENABLE       LATCbits.LATC1
  19.  
  20. #define DCMOT_TRIS_IN1     TRISAbits.TRISA4
  21. #define DCMOT_IN1          LATAbits.LATA4
  22.  
  23. #define DCMOT_TRIS_IN2     TRISAbits.TRISA5
  24. #define DCMOT_IN2          LATAbits.LATA5
  25.  
  26.  
  27.  
  28. /****************************************************************************
  29.       DELAY FUNCTIONS
  30.  ****************************************************************************/
  31. void Delay_10us(unsigned int t) {
  32.     unsigned char i;
  33.     do {
  34.       i = 11;
  35.       while(--i);
  36.    } while(--t);
  37. }
  38.  
  39.  
  40. /****************************************************************************
  41.     ADC FUNCTIONS
  42.  ****************************************************************************/
  43. /*
  44.   Read Analog Input AN0 or AN1
  45. */
  46. unsigned short adc_read(unsigned char channel) {
  47.    union {
  48.       struct {
  49.           unsigned char lob;
  50.           unsigned char hib;
  51.       };
  52.       unsigned short word;
  53.    } adc_val;
  54.  
  55.    // Configure ADC
  56.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  57.    ADCON1 = 0b00001101;   // Analog inputs = AN0, AN1
  58.    ADCON2 = 0b10010101;   // TAD
  59.  
  60.    // Make an ADC conversion
  61.    Delay_10us(1);
  62.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  63.    while (ADCON0bits.GO==1); // Conversion
  64.  
  65.    // Configure ADC
  66.    ADCON0 = 0b00000000;   // ADC off
  67.    ADCON1 = 0b00001111;   // All pins to digital inputs
  68.  
  69.    // Return ADC conversion
  70.    adc_val.lob = ADRESL;
  71.    adc_val.hib = ADRESH;
  72.    return adc_val.word;
  73. }
  74.  
  75.  
  76. /****************************************************************************
  77.       PWM FUNCTIONS
  78.  ****************************************************************************/
  79. /*
  80.   Initialize and configure PWM module
  81.   D = Duty cycle in range 0 .. 200
  82. */
  83. void pwm1_init(unsigned char D) {
  84.    CCP1CON = 0b00001100;
  85.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  86.    PR2 = 200;             // PWM Period = [(PR2) + 1] &#8226; TCY &#8226;(TMR2 Prescale Value)]
  87.    CCPR1L = D;
  88.    TRISCbits.TRISC2 = 0;
  89. }
  90.  
  91.  
  92.  
  93. /****************************************************************************
  94.       RS232 FUNCTIONS
  95.  ****************************************************************************/
  96.  
  97. /*
  98.   Initialize USART for RS232 comunications
  99. */
  100. void rs232_init(void) {
  101.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  102.    SPBRGH = 0;
  103.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  104.  
  105.    TXSTA = (char)
  106.            (0<<7)    // CSRC:  1 = Syncronous Master mode
  107.          + (0<<6)    // TX9:   1 = Selects 9-bit transmission
  108.          + (1<<5)    // TXEN:  1 = Transmit enabled
  109.          + (0<<4)    // SYNC:  1 = Synchronous mode
  110.          + (0<<3)    // SENDB: 1 = Asynchronous mode: Send Sync Break on next transmission (cleared by hardware upon completion)
  111.          + (1<<2)    // BRGH:  1 = Asynchronous mode: High speed
  112.          + (1<<1)    // TRMT:  1 = TSR empty
  113.          + (0<<0);   // TX9D:  Ninth bit of Transmit Data
  114.  
  115.    RCSTA = (char)
  116.            (1<<7)    // SPEN:  1 = Serial port enabled
  117.          + (0<<6)    // RX9:   1 = Selects 9-bit reception
  118.          + (0<<5)    // SREN:  1 = Enables single receive in Master Synchronous mode
  119.          + (1<<4)    // CREN:  1 = Enables Continuous Receive
  120.          + (0<<3)    // ADDEN: 1 = Enables address detection (RX9 = 1)
  121.          + (0<<2)    // FERR:  1 = Framing error
  122.          + (0<<1)    // OERR:  1 = Overrun error (can be cleared by clearing bit CREN)
  123.          + (0<<0);   // RX9D:  Ninth bit of Received Data
  124.  
  125.    TRISCbits.TRISC6 = 0;      // Enable TX output
  126.    PIE1bits.TXIE = 0;         // Disable RS232 interrupts
  127. }
  128.  
  129.  
  130. /****************************************************************************
  131.       MAIN PROGRAM
  132.  ****************************************************************************/
  133. void main(void) {
  134.    int Vref, Vmot, Err, Integ, Vo;
  135.    int _Vref, _Vmot, _Err, _Integ, _Vo;
  136.    char st1;
  137.  
  138.    //*********************************
  139.    // Initialize
  140.    //*********************************
  141.    rs232_init();
  142.    CMCON = 0b00000111;
  143.    ADCON1 = 0b00001111;
  144.    
  145.    DCMOT_IN1 = 0;
  146.    DCMOT_IN2 = 0;
  147.    DCMOT_ENABLE = 0;
  148.  
  149.    DCMOT_TRIS_IN1 = 0;
  150.    DCMOT_TRIS_IN2 = 0;
  151.    DCMOT_TRIS_ENABLE = 0;
  152.  
  153.    DCMOT_TRIS_AN0 = 1;
  154.    DCMOT_TRIS_AN1 = 1;
  155.  
  156.    fprintf(_H_USART, (const rom far char *)"\r\nSystem OK.\r\n");
  157.  
  158.    //*********************************
  159.    // DC MOTOR SPEED CONTROL
  160.    //*********************************
  161.    Integ = 0;
  162.    st1 = 0;
  163.    while(1) {
  164.  
  165.       //*********************************
  166.       // PID Speed control
  167.       //*********************************
  168.       Vref = 50;
  169.       Err = Vref - Vmot;        
  170.       Integ += Err;
  171.       if (Integ>30000) Integ = 30000;
  172.       if (Integ<-30000) Integ = -30000;
  173.  
  174.       Vo = Vref/5 + Err/5 + Integ/16;
  175.  
  176.       //*********************************
  177.       // Debug PID values
  178.       //*********************************
  179.       switch (st1++) {  
  180.          case 1: _Vref = Vref;
  181.                  _Vmot = Vmot;
  182.                  _Err = Err;
  183.                  _Integ = Integ;
  184.                  _Vo = Vo;
  185.                  break;
  186.          case 2: fprintf(_H_USART, "Vm=%3d   ", _Vmot);
  187.                  break;
  188.          case 3: fprintf(_H_USART, "Err=%3d   ", _Err);
  189.                  break;
  190.          case 4: fprintf(_H_USART, "Intg=%5d   ", _Integ);
  191.                  break;
  192.          case 5: fprintf(_H_USART, "Vo=%-3d", _Vo);
  193.                  break;
  194.          case 6: fprintf(_H_USART, "\r\n");
  195.                  st1 = 0;
  196.                  break;
  197.       }
  198.    
  199.  
  200.       //*********************************
  201.       // PWM driver output
  202.       //*********************************
  203.       if (Vo>100) pwm1_init(100);
  204.       else if (Vo<0) pwm1_init(0);
  205.       else pwm1_init(Vo);
  206.       Delay_10us(800);
  207.  
  208.  
  209.       //*********************************
  210.       // BACK EMF SENSE
  211.       //*********************************
  212.       DCMOT_ENABLE = 0;
  213.       Delay_10us(80);
  214.       Vmot = adc_read(0);
  215.       DCMOT_ENABLE = 1;
  216.    }
  217. }


Si alguien lo quiere probar puede escribir sus resultados y aportar su opinión, que será bien recibida.
Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 04 de Febrero de 2012, 13:06:04
Para tomar las lecturas de la Back-emf con inversion de giro, progongo usar el integrado 4053, que es un muliplexor/demultiplexor analogico..

tube problemas al subir la imagen del circuito :roll: :roll: :roll:...pero en fin el  integrado 4053 es muy simple de ser utilizado... :cheesy: :cheesy:

bueno el circuito habla por si mismo, cualquier aporte o comentario bien venido... :-/ :-/ :-/ :-/

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 04 de Febrero de 2012, 14:43:28
El problema está en llevar el terminal negativo del motor a masa (dependiendo del sentido de giro el terminal negativo es distinto)

En los circuitos que hemos publicado hasta ahora, una resistencia lleva a masa un terminal, pero eso no es suficiente con dos sentidos de giro.

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Febrero de 2012, 14:31:38
El problema está en llevar el terminal negativo del motor a masa (dependiendo del sentido de giro el terminal negativo es distinto)

En los circuitos que hemos publicado hasta ahora, una resistencia lleva a masa un terminal, pero eso no es suficiente con dos sentidos de giro.

Saludos

mil disculpas habia olvidado que el micro tiene muchos canales analogicos por los cuales se puede tomar las lecturas de la Back-emf...se que el problema principal ahora es el aterramiento del motor...pero me surge la inquietud de por que no usar los transistores que se estaban usando en los circuitos anteriores????

Ha otra cosa, bueno estube analizando tu codigo y tienes funciones escritas, pero que no las llamas en ningun momento (ej. dcmot_pwm() ), asi como tambien usas variables que no estan declaradas (ej. DCMOT_BEMF)... bueno en realidad no programo en C18, asi que si me equivoco en algunas de las observaciones mil disculpas... :mrgreen: :mrgreen: :mrgreen:

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Febrero de 2012, 16:48:15
Tienes toda la razón con las funciones c ...
Ya las he 'limpiado'. Cuando pasé a utilizar el módulo PWM del micro olvidé quitar las funciones con las que simulaba por soft el PWM.

Ahora mismo tengo parado la parte hardware porque estoy modelando el motor y escribiendo un manual que explica cómo funcionan los motores cc:

   GUIA: Motores de corriente continua (http://www.todopic.com.ar/foros/index.php?topic=37484.0)

Cuando termine, se podrá controlar mucho mejor la velocidad del motor.

Te adelanto que el PID responde cada 10ms (cada muestreo de Back-emf) y durante este tiempo el motor puede acelerarse o frenarse casi un 60%.
Por eso la regulación actual tiene oscilaciones excesivas de velocidad. Para evitarlo es necesario realizar una compensación del ciclo PWM con la corriente del motor.

Para hacer una regulación de corriente es necesario sensar los picos de corriente en la resistencia de sensado.

Hay que diseñar un cto que detecte y amplifique las corrientes de pico.

Después habrá que modificar el ciclo PWM en función de la corriente. Esto dará una velocidad de respuesta menor de 1ms, mucho mejor que la del PID, con la que se evitarán las oscilaciones de velocidad.

En cuanto a la medición de los dos sentidos de giro: hay que llevar el motor a tierra con 2 mosfet.

Por ahora puedes probar el cto que he publicado y me cuentas cómo te funciona: http://www.todopic.com.ar/foros/index.php?topic=37404.msg311512#msg311512

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Febrero de 2012, 18:50:09
Necesitamos ayuda:

¿Alguien sabría  "traducir" el programa de 5 mensajes atrás de C18 al compilador CCS?

http://www.todopic.com.ar/foros/index.php?topic=37404.msg311512#msg311512


Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: sander en 06 de Febrero de 2012, 19:22:46
Yo lo puedo hacer, aunque talvez demore un poco, por cuestiones de tiempo.

Solo necesito saber para que micro es y la frecuencia de operacion

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Febrero de 2012, 19:31:09
Yo estoy trabajando con el PIC18F2550 a 20Mhz

amyver ¿Qué micro vas a utilizar?

A propósito Sander, el programa ya funciona para un sentido de giro ¿Te animas a probarlo sobre protoboard?

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: sander en 06 de Febrero de 2012, 19:42:18
yo me animo  :-/ ,  lo que pasa es que no encontre el L6203 por mi ciudad, asi que pense en armar un puente H con MOSFETs discretos, pero luego me di cuenta que iba a necesitar algun driver para los MOSFETS para poder manejarlos de forma mas eficiente, y tampoco consegui esos drivers, asi que para probarlo voy a usar el  L293, que es parecido al L6203 pero para motores mas pequeños.

Voy a tratar de probarlo con el mismo micro, o talvez pruebe otro sin USB

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 07 de Febrero de 2012, 12:19:38
yo me animo  :-/ ,  lo que pasa es que no encontre el L6203 por mi ciudad, asi que pense en armar un puente H con MOSFETs discretos, pero luego me di cuenta que iba a necesitar algun driver para los MOSFETS para poder manejarlos de forma mas eficiente, y tampoco consegui esos drivers, asi que para probarlo voy a usar el  L293, que es parecido al L6203 pero para motores mas pequeños.

Voy a tratar de probarlo con el mismo micro, o talvez pruebe otro sin USB

Saludos

Hola sander me parece genial que te animes a traducir el codigo de los programas de c18 a C... bueno con respecto al micro que usaras
yo la verdad pienso que no habria un gran problema entre uno u otro, puedes escojer uno que maneje PWM, ADC y usart ... bueno yo propongo usar el PIC16F877A..

Ha y con respecto al driver que pretendes usar, te sugeriria el L298, que maneja mayores corrientes que el L293, pero menores corrientes que el L6203...

Saludos. :-) :-) :-)
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Febrero de 2012, 13:57:55
El L293 sólo vale si quieres controlar un motor pequeño. (Yo lo he utilizado en ocasiones)

En teoría llega hasta 2 amperios, pero consumiendo mucha potencia y con mucha caída de tensión (más de 3 voltios)

Otras desventajas:
   No permite medir bien la corriente por el motor.
   No tiene diodos rectificadores y hay que añadirles. (4 por motor)
   Es relativamente caro y sólo llega a 2 Amperios.

Creo que no es adecuado para este proyecto.
Puedes esperar a que publique un sencillo driver para MOSFET en el lado alto. Eso te servirá para controlar el motor en un sentido de giro.
Si quieres luego ampliar a 2 sentidos de giro, tendrás que poner 4 mosfet.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Febrero de 2012, 20:08:08
Driver discreto (con transistores) para Mosfet lado alto y lado bajo:

(https://sites.google.com/site/picuino/dc_motor_regulator/Driver_Mosfet.png) (https://sites.google.com/site/picuino/dc_motor_regulator/Driver_Mosfet.png)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 08 de Febrero de 2012, 20:56:46
Ya he terminado de modelar el motor de corriente continua y he publicado el manual en mi web y en el foro:

Modelo equivalente del motor eléctrico:
https://sites.google.com/site/picuino/motor_equivalent_model


GUIA: Motores de corriente continua
http://www.todopic.com.ar/foros/index.php?topic=37484.0


Ahora vamos a por la regulación de corriente del motor.


Saludos,
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 10 de Febrero de 2012, 16:57:57
Ya he terminado de modelar el motor de corriente continua y he publicado el manual en mi web y en el foro:

Modelo equivalente del motor eléctrico:
https://sites.google.com/site/picuino/motor_equivalent_model


GUIA: Motores de corriente continua
http://www.todopic.com.ar/foros/index.php?topic=37484.0


Ahora vamos a por la regulación de corriente del motor.


Saludos,

Muy bueno picuino, te comento que estos dias estube realizando pruebas con un motor de 30V y 30000RPM y los resultados fueron buenos.... aun no implemente el control PID, y la estabilizacion del motor se demora un poco, bueno ya me pongo en la tarea de realizar un mejor control, pero bueno tengo algunas dudas en las cuales requiero tu ayuda:

*Lo que hago es enviar al driver L6203 del motor una señal PWM de 4Khz.
*Cada 10ms quito la energia al motor y testeo la Back-emf (bueno le doy 1ms para que la señal se estabilice, y otro milisegundo para tomar el  valor de tension.)

La duda es la siguiente, con respecto a la frecuencia del motor te parece razonable??? y lo segundo te parece razonable el tiempo entre muestro y muestreo de la Back-emf???
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 10 de Febrero de 2012, 18:00:58
Tiempo de muestreo
1ms para que baje la corriente: OK
El tiempo para que la corriente baje a 0 es muy pequeño, del orden de 0.5ms para la mayoría de los motores pequeños. De forma que 1ms puede estar bien.
De todas formas deberías comprobarlo con un osciloscopio. Si no tienes osciloscopio puedes esperar menos de 1ms a medir back-emf y enviar la lectura por rs232 a ver que pasa.

1ms para tomar el valor de la tensión: ???
Me parece excesivo. En cuanto se estabilice la tensión, la conversión se realiza en 20us como mucho.

Ten en cuenta que cuanto más tiempo esté el motor apagado, más se reduce su potencia y vibra. Cuanto menos dure el tiempo de sensado mejor.


Frecuencia de 4khz PWM para el motor
4khz puede estar bien, pero si utilizas el módulo PWM a 20kHz la conmutación no se oye (no hace ruido audible).
Además el motor se calentará menos y las corrientes de pico serán menores.


PID
Las ecuaciones del PID son sencillas:
/*
    Vref   = tensión que quiero tener en la back-emf (es equivalente a la velocidad del motor)
    Vemf = tensión de back-emf medida en el motor
    Vo     = tensión de alimentación al motor
    PWM  = valor de la señal PWM enviada al motor
    Vdd   = tensión de alimentación del puente PWM
    PWM_max = máximo valor de la señal PWM
*/

    Vref  = 50;                                    // valor deseado de tensión en el motor
    Verr  =  Vref - Vemf;                     // Error
    Intg  = Intg + Verr;                       // Valor integral
    Vo    = Vref + Verr*Kp + Intg/Ki;        // Alimentación del motor
    PWM = Vo * (PWM_max/Vdd);

Esta rutina se repite cada 10ms
Las constantes que funcionan bien para muchos motores son:
   Kp = 1
   Ki = 30
Depende de como responda tu motor al escalón.


La parte Derivativa del PID no se añade porque no hace falta en la mayoría de motores sin carga.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 10 de Febrero de 2012, 18:21:23
Último programa que funciona correctamente para controlar un motor por back-emf.

Utiliza módulo PWM
Utiliza interrupciones para que los intervalos de tiempo sean exactos a la hora de calcular back-emf y PID.


Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10. #define  FOSC 20000000
  11. #define  BAUD 57600
  12.  
  13.  
  14. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  15. #define DCMOT_AN0          LATAbits.LATA0
  16.  
  17. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC0
  18. #define DCMOT_ENABLE       LATCbits.LATC0
  19.  
  20. #define DCMOT_TRIS_MOT1    TRISCbits.TRISC1
  21. #define DCMOT_MOT1         LATCbits.LATC1
  22.  
  23. #define DCMOT_TRIS_MOT2    TRISCbits.TRISC2
  24. #define DCMOT_MOT2         LATCbits.LATC2
  25.  
  26.  
  27. /****************************************************************************
  28.       INTERRUPTS
  29.  ****************************************************************************/
  30. #define TMR0_COUNT      (FOSC/((unsigned long)4*4*250*1000))      // Number of carrys per second
  31.  
  32. unsigned char milli_second, sys_clk;
  33.  
  34. void isr_main(void);
  35.  
  36. #pragma code HIGH_INTERRUPT_VECTOR = 0x0008
  37. void High_ISR (void) {
  38.    _asm goto isr_main _endasm
  39. }
  40.  
  41. #pragma interrupt isr_main
  42. void isr_main(void) {
  43.    if (INTCONbits.TMR0IF==1)  {        // if TIMER0 overflow interrupt
  44.       INTCONbits.TMR0IF = 0;           // Clear Timer0 interrupt flag
  45.       TMR0L += 6+3;
  46.       sys_clk--;
  47.       if (sys_clk==0) {
  48.          sys_clk = TMR0_COUNT;
  49.          milli_second++;
  50.       }
  51.    }
  52. }
  53.  
  54.  
  55. /*
  56.    Initialize isr routine and Timer0
  57. */
  58. void isr_init(void) {
  59.    INTCON = 0b11100000;  // Enable interrupts
  60.    T0CON =  0b11000001;  // Prescaler = 4  
  61.    TMR0L = 6+3;
  62.    sys_clk = TMR0_COUNT;
  63.    milli_second = 0;
  64. }
  65.  
  66.  
  67. /****************************************************************************
  68.     ADC FUNCTIONS
  69.  ****************************************************************************/
  70. /*
  71.   Read Analog Input AN0 or AN1
  72. */
  73. unsigned short adc_read(unsigned char channel) {
  74.    union {
  75.       struct {
  76.           unsigned char lob;
  77.           unsigned char hib;
  78.       };
  79.       unsigned short word;
  80.    } adc_val;
  81.  
  82.    // Configure ADC
  83.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  84.    ADCON1 = 0b00001101;   // Analog inputs = AN0, AN1
  85.    ADCON2 = 0b10010101;   // TAD
  86.  
  87.    // Make an ADC conversion
  88.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  89.    while (ADCON0bits.GO==1); // Conversion
  90.  
  91.    // Configure ADC
  92.    ADCON0 = 0b00000000;   // ADC off
  93.    ADCON1 = 0b00001111;   // All pins to digital inputs
  94.  
  95.    // Return ADC conversion
  96.    adc_val.lob = ADRESL;
  97.    adc_val.hib = ADRESH;
  98.    return adc_val.word;
  99. }
  100.  
  101.  
  102. /****************************************************************************
  103.       PWM FUNCTIONS
  104.  ****************************************************************************/
  105. /*
  106.   Initialize and configure PWM module
  107.   D = Duty cycle in range 0 .. 200
  108. */
  109. void pwm1_init(int D) {
  110.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  111.    PR2 = 250;             // PWM Period = [(PR2) + 1] &#8226; TCY &#8226;(TMR2 Prescale Value)]
  112.  
  113.    if (D > 1000) D = 1000;
  114.    if (D<0)   D = 0;
  115.    DCMOT_MOT1 = 0;
  116.    CCP1CON = 0b00001100;
  117.    if (D & 1) CCP1CON |= (1<<4);
  118.    if (D & 2) CCP1CON |= (1<<5);
  119.    D = D>>2;
  120.    CCPR1L = D;
  121. }
  122.  
  123.  
  124. /****************************************************************************
  125.       RS232 FUNCTIONS
  126.  ****************************************************************************/
  127.  
  128. /*
  129.   Initialize USART for RS232 comunications
  130. */
  131. void rs232_init(void) {
  132.    PIE1bits.TXIE = 0;               // Disable RS232 interrupts
  133.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  134.    SPBRGH = 0;
  135.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  136.    TXSTA = 0b00100110;
  137.    RCSTA = 0b10010000;
  138.    TRISCbits.TRISC6 = 0;            // Enable TX output
  139. }
  140.  
  141.  
  142. /*
  143.    Send char to USART with pooling
  144. */
  145. int rs232_puts(char *buff, char pos) {
  146.    if (buff[pos] == 0)
  147.       return -1;
  148.    if (PIR1bits.TXIF == 1) {
  149.       TXREG = buff[pos];
  150.       return pos+1;
  151.    }
  152.    else
  153.       return pos;
  154. }
  155.  
  156.  
  157. /****************************************************************************
  158.       PID CONTROL
  159.  ****************************************************************************/
  160. #define KP  1.0
  161. #define KI  3.3
  162.  
  163. signed int Vref, Vmot, Err, Integ, Vo;
  164.  
  165. void pid_control(int Vref) {
  166.    char sample;
  167.    if (milli_second == 10) {
  168.        milli_second = 0;
  169.    }
  170.  
  171.    //*********************************
  172.    // BACK EMF SENSE
  173.    //*********************************
  174.    while (milli_second == 0) {
  175.       DCMOT_ENABLE = 0;
  176.       sample = 0;
  177.    }
  178.    if (milli_second == 1 && sample == 0) {
  179.       Vmot = adc_read(0);
  180.       DCMOT_ENABLE = 1;
  181.       sample = 1;
  182.    }
  183.  
  184.    //*********************************
  185.    // PID Speed control
  186.    //*********************************
  187.    if (sample==1) {
  188.       sample = 2;
  189.  
  190.       Err = Vref - Vmot;        
  191.       Integ += Err;
  192.       if (Integ>30000) Integ = 30000;
  193.       if (Integ<-30000) Integ = -30000;
  194.  
  195.       Vo = Vref + Err*KP + Integ/((int)(100.0/KI));
  196.  
  197.       pwm1_init(Vo);
  198.    }
  199. }
  200.  
  201.  
  202. /****************************************************************************
  203.       MAIN PROGRAM
  204.  ****************************************************************************/
  205. void main(void) {
  206.    char buff[80], buff_p;
  207.    char send;
  208.  
  209.    //*********************************
  210.    // Initialize
  211.    //*********************************
  212.    CMCON = 0b00000111;
  213.    ADCON1 = 0b00001111;
  214.    rs232_init();
  215.    isr_init();
  216.    
  217.    DCMOT_MOT1 = 0;
  218.    DCMOT_MOT2 = 0;
  219.    DCMOT_ENABLE = 0;
  220.  
  221.    DCMOT_TRIS_MOT1 = 0;
  222.    DCMOT_TRIS_MOT2 = 0;
  223.    DCMOT_TRIS_ENABLE = 0;
  224.  
  225.    DCMOT_TRIS_AN0 = 1;
  226.  
  227.    fprintf (_H_USART, "\r\nSystem OK.\r\n");
  228.  
  229.    //*********************************
  230.    // DC MOTOR SPEED CONTROL
  231.    //*********************************
  232.    Integ = 0;
  233.    send = 0;
  234.    while(1) {
  235.       pid_control(10);
  236.    
  237.       //*********************************
  238.       // Print PID values
  239.       //*********************************
  240.       TRISBbits.TRISB5 = 0;
  241.       if (milli_second==3 && send == 0) {
  242.          sprintf (buff, "Vm=%4d\tInteg=%5d\tVo=%4d\r\n", Vmot, Integ, Vo);
  243.          buff_p = 0;
  244.          send = 1;
  245.       }
  246.       if (send) {
  247.          buff_p = rs232_puts(buff, buff_p);
  248.          if (buff_p == -1)
  249.             send = 0;
  250.       }    
  251.    }
  252. }

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 10 de Febrero de 2012, 18:31:37
¿Alguien conoce técnicas para medir corriente de pico por una resistencia pequeña (0.1 ohmio)?

Para mejorar el control back-emf,  hay que incluir compensación de la corriente del motor.

Estoy intentando medir la corriente del motor con una resistencia a la salida del L6203
y no lo consigo por ahora.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 11 de Febrero de 2012, 09:21:41
OK picuino... hare las modificaciones en el codigo de mi programa y comentare resultados  :-/ :-/ :-/

saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 11 de Febrero de 2012, 10:33:41
Hola amyver.
El programa que he publicado y que estás probando tiene un problema:

oscila mucho

El problema viene de lo siguiente:

   El muestreo back-emf se realiza cada 10ms (100 veces por segundo)
   El motor tiene una constante de tiempo de 10ms.

Como resultado este programa no puede responder suficientemente rápido a las modificaciones de velocidad del motor y da "saltos"

Se recomienda que como mínimo un sistema digital tome muestras 5 o 10 veces más rápido que la constante de tiempo del sistema controlado.
Esto es imposible en este caso porque estaríamos todo el tiempo muestreando y el motor estaría todo el tiempo apagado.


Una solución es controlar el motor con compensación de corriente:
La corriente se puede medir cada 1ms sin apagar el motor y se puede corregir el ciclo PWM para que el motor no oscile.


Otra solución es hacer el control mucho más lento:
con una constante integral KI muy pequeña, por ejemplo cambiando la línea:

212.      Vo = Vref + Integ/64;


El motor responderá lento pero sin 'saltos'.
Te dejo el código modificado:

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10. #define  FOSC 20000000
  11. #define  BAUD 57600
  12.  
  13.  
  14. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  15.  
  16. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC0
  17. #define DCMOT_ENABLE       LATCbits.LATC0
  18.  
  19. #define DCMOT_TRIS_MOT1    TRISCbits.TRISC1
  20. #define DCMOT_MOT1         LATCbits.LATC1
  21.  
  22. #define DCMOT_TRIS_MOT2    TRISCbits.TRISC2
  23. #define DCMOT_MOT2         LATCbits.LATC2
  24.  
  25.  
  26. /****************************************************************************
  27.       INTERRUPTS
  28.  ****************************************************************************/
  29. #define TMR0_COUNT      (FOSC/((unsigned long)4*4*250*1000))      // Number of carrys per second
  30.  
  31. unsigned char milli_second, sys_clk;
  32.  
  33. void isr_main(void);
  34.  
  35. #pragma code HIGH_INTERRUPT_VECTOR = 0x0008
  36. void High_ISR (void) {
  37.    _asm goto isr_main _endasm
  38. }
  39.  
  40. #pragma interrupt isr_main
  41. void isr_main(void) {
  42.    if (INTCONbits.TMR0IF==1)  {        // if TIMER0 overflow interrupt
  43.       INTCONbits.TMR0IF = 0;           // Clear Timer0 interrupt flag
  44.       TMR0L += 6+3;
  45.       sys_clk--;
  46.       if (sys_clk==0) {
  47.          sys_clk = TMR0_COUNT;
  48.          milli_second++;
  49.       }
  50.    }
  51. }
  52.  
  53.  
  54. /*
  55.    Initialize isr routine and Timer0
  56. */
  57. void isr_init(void) {
  58.    INTCON = 0b11100000;  // Enable interrupts
  59.    T0CON =  0b11000001;  // Prescaler = 4  
  60.    TMR0L = 6+3;
  61.    sys_clk = TMR0_COUNT;
  62.    milli_second = 0;
  63. }
  64.  
  65.  
  66. /****************************************************************************
  67.     ADC FUNCTIONS
  68.  ****************************************************************************/
  69. /*
  70.   Read Analog Input AN0 or AN1
  71. */
  72. unsigned short adc_read(unsigned char channel) {
  73.    union {
  74.       struct {
  75.           unsigned char lob;
  76.           unsigned char hib;
  77.       };
  78.       unsigned short word;
  79.    } adc_val;
  80.  
  81.    // Configure ADC
  82.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  83.    ADCON1 = 0b00001101;   // Analog inputs = AN0, AN1
  84.    ADCON2 = 0b10010101;   // TAD
  85.  
  86.    // Make an ADC conversion
  87.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  88.    while (ADCON0bits.GO==1); // Conversion
  89.  
  90.    // Configure ADC
  91.    ADCON0 = 0b00000000;   // ADC off
  92.    ADCON1 = 0b00001111;   // All pins to digital inputs
  93.  
  94.    // Return ADC conversion
  95.    adc_val.lob = ADRESL;
  96.    adc_val.hib = ADRESH;
  97.    return adc_val.word;
  98. }
  99.  
  100.  
  101. /****************************************************************************
  102.       RS232 FUNCTIONS
  103.  ****************************************************************************/
  104.  
  105. /*
  106.   Initialize USART for RS232 comunications
  107. */
  108. void rs232_init(void) {
  109.    PIE1bits.TXIE = 0;               // Disable RS232 interrupts
  110.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  111.    SPBRGH = 0;
  112.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  113.    TXSTA = 0b00100110;
  114.    RCSTA = 0b10010000;
  115.    TRISCbits.TRISC6 = 0;            // Enable TX output
  116. }
  117.  
  118.  
  119. /*
  120.    Send char to USART with pooling
  121. */
  122. int rs232_puts(char *buff, char pos) {
  123.    if (buff[pos] == 0)
  124.       return -1;
  125.    if (PIR1bits.TXIF == 1) {
  126.       TXREG = buff[pos];
  127.       return pos+1;
  128.    }
  129.    else
  130.       return pos;
  131. }
  132.  
  133.  
  134. /****************************************************************************
  135.       PWM FUNCTIONS
  136.  ****************************************************************************/
  137.  
  138. /*
  139.   Sets PWM module
  140.   D = Duty cycle in range 0 .. 1000
  141. */
  142. void pwm1_set(int D) {
  143.    if (D > 1000) D = 1000;
  144.    if (D<0) {
  145.       D = 0;
  146.    }
  147.    DCMOT_MOT1 = 1;
  148.    CCP1CON = 0b00001100;
  149.    if (D & 1) CCP1CON |= (1<<4);
  150.    if (D & 2) CCP1CON |= (1<<5);
  151.    D = D>>2;
  152.    CCPR1L = D;
  153. }
  154.  
  155.  
  156. /*
  157.   Initialize and configure PWM module
  158. */
  159. void pwm1_init(void) {
  160.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  161.    PR2 = 250;             // PWM Period = [(PR2) + 1] &#8226; TCY &#8226;(TMR2 Prescale Value)]
  162.  
  163.    DCMOT_MOT1 = 0;
  164.    DCMOT_MOT2 = 0;
  165.    DCMOT_ENABLE = 0;
  166.  
  167.    DCMOT_TRIS_MOT1 = 0;
  168.    DCMOT_TRIS_MOT2 = 0;
  169.    DCMOT_TRIS_ENABLE = 0;
  170. }
  171.  
  172.  
  173. /****************************************************************************
  174.       PID CONTROL
  175.  ****************************************************************************/
  176. #define KP  1.0
  177. #define KI  0.2
  178.  
  179. signed int Vref, Vmot, Err, Err_old, Integ, Vo;
  180.  
  181. void pid_control(void) {
  182.    char sample;
  183.    if (milli_second == 10) {
  184.        milli_second = 0;
  185.    }
  186.  
  187.    //*********************************
  188.    // BACK EMF SENSE
  189.    //*********************************
  190.    while (milli_second == 0) {
  191.       DCMOT_ENABLE = 0;
  192.       sample = 0;
  193.    }
  194.    if (milli_second == 1 && sample == 0) {
  195.       Vmot = adc_read(0);
  196.       DCMOT_ENABLE = 1;
  197.       sample = 1;
  198.    }
  199.  
  200.    //*********************************
  201.    // PID Speed control
  202.    //*********************************
  203.    if (sample==1) {
  204.       sample = 2;
  205.  
  206.       Vref = 20;
  207.  
  208.       Err_old = Err;
  209.       Err = Vref - Vmot;    
  210.       Integ += (Err + Err_old)/2;
  211.       if (Integ>30000) Integ = 30000;
  212.       if (Integ<-30000) Integ = -30000;
  213.  
  214.       Vo = Vref + Integ/128;      //   Err*(int)KP +   ((int)(100.0/KI));
  215.  
  216.       pwm1_set(Vo);
  217.    }
  218. }
  219.  
  220.  
  221. void pid_init() {
  222.    // PID inputs
  223.    CMCON = 0b00000111;
  224.    ADCON1 = 0b00001111;
  225.    DCMOT_TRIS_AN0 = 1;
  226.  
  227.    // PID values
  228.    Err_old = 0;
  229. }
  230.  
  231. /****************************************************************************
  232.       MAIN PROGRAM
  233.  ****************************************************************************/
  234. void main(void) {
  235.    char buff[80], buff_p;
  236.    char send;
  237.  
  238.    //*********************************
  239.    // Initialize
  240.    //*********************************
  241.    rs232_init();
  242.    isr_init();
  243.    pwm1_init();
  244.    pid_init();
  245.  
  246.    fprintf (_H_USART, "\r\nSystem OK.\r\n");
  247.  
  248.    //*********************************
  249.    // DC MOTOR SPEED CONTROL
  250.    //*********************************
  251.    send = 0;
  252.    while(1) {
  253.  
  254.       //*********************************
  255.       // PID control
  256.       //*********************************
  257.       pid_control();
  258.    
  259.       //*********************************
  260.       // Print PID values
  261.       //*********************************
  262.       TRISBbits.TRISB5 = 0;
  263.       if (milli_second==3 && send == 0) {
  264.          sprintf (buff, "Vm=%4d\tInteg=%5d\tVo=%4d\r\n", Vmot, Integ, Vo);
  265.          buff_p = 0;
  266.          send = 1;
  267.       }
  268.       if (send) {
  269.          buff_p = rs232_puts(buff, buff_p);
  270.          if (buff_p == -1)
  271.             send = 0;
  272.       }    
  273.    }
  274. }

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 11 de Febrero de 2012, 11:14:06
Ok...lo tendre muy encuenta picuino..

saludos... :-/ :-/ :-/
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 12 de Febrero de 2012, 09:57:44
Código: [Seleccionar]
Estoy probando un método para medir la velocidad del motor y 'obsevar'  como varía la velocidad.

Añadiendo un led al PIC que se encienda durante 1ms cada 10ms se consigue una luz estroboscópica.
Iluminando el eje del motor con la luz se observa el eje del motor "quieto" cuando gira a 6000rpm

Si añadimos al eje motor 3 marcas negras (por ejemplo las 3 pinzas en un motor de taladro), podemos dejarlas "quietas" a 2000rpm

El código es sencillo. He modificado la rutina de interrupción para que encienda un led en el puerto RB5:

[code = c]
      if (sys_clk==0) {
         sys_clk = TMR0_COUNT;
         LATBbits.LATB5 = 1;                        // Luz estroboscópica off
         if (++milli_second == 10) {
            LATBbits.LATB5 = 0;                     // Luz estroboscópica on
            milli_second = 0;
         }
      }


Luego se conecta el led:

                Led          R              | PIC 18F2550
     (+)-----|>|-----[ 220 ]--------| Pin RB5
                  \\                          |

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 13 de Febrero de 2012, 17:54:35
Estoy probando diferentes métodos para medir la intensidad del motor.
La resistencia de sensado de corriente de 0.1 ohmio da una señal muy pequeña, de forma que estoy intentando amplificar su señal sin introducir ruido.

Por otra parte he probado el control de velocidad en varios motores y creo que con algunos el circuito oscila porque la back-emf está llena de ruido.
Las señales de tensión emf y de corriente están llenas de pulsos y oscilaciones debido a la conmutación de las escobillas.
En algunos motores casi no se nota y en otros llega a ser demasiado grande.
Tengo que encontrar alguna técnica para corregir el ruido sin perder precisión y rapidez.


También he encontrado una forma de controlar la corriente cada 1ms a la vez que mantengo las comunicaciones RS232 (imprescindible si quiero saber cómo está funcionando el regulador).
Por ahora lo consigo convirtiendo y enviando los caracteres uno a uno por el rs232 de forma cooperativa con el control de corriente.
Para facilitar las cosas envío los datos en hexadecimal (así la conversión es más rápida)

En cuanto tenga un resultado claro lo posteo.

Saludos.

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: LeugimZerO en 14 de Febrero de 2012, 20:17:52
sigue asi picuino falta poco ya estas cerca  :-/
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 22 de Febrero de 2012, 19:14:40
He conseguido que el motor gire despacio (30rpm) y que se adapte a los cambios de carga.

El problema está en que hay mucho ruido en el sensado de corriente. Si compenso poco, el motor no responde lo suficiente y si compenso más, el motor responde bien a los cambios de carga pero vibra mucho.

Sigo con ello. Por ahora adjunto el programa con el que voy haciendo pruebas con compensación de corriente.

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10.  
  11. /****************************************************************************
  12.       HARDWARE DEFINITIONS
  13.  ****************************************************************************/
  14. #define  FOSC 20000000
  15. #define  BAUD 57600
  16.  
  17.  
  18. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  19. #define DCMOT_TRIS_AN1     TRISAbits.TRISA1
  20. #define DCMOT_TRIS_AN2     TRISAbits.TRISA2
  21.  
  22. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC0
  23. #define DCMOT_ENABLE       LATCbits.LATC0
  24.  
  25. #define DCMOT_TRIS_MOT1    TRISCbits.TRISC1
  26. #define DCMOT_MOT1         LATCbits.LATC1
  27.  
  28. #define DCMOT_TRIS_MOT2    TRISCbits.TRISC2
  29. #define DCMOT_MOT2         LATCbits.LATC2
  30.  
  31. #define DCMOT_TRIS_LED1    TRISBbits.TRISB7
  32. #define DCMOT_LED1         LATBbits.LATB7
  33.  
  34.  
  35. /****************************************************************************
  36.       INTERRUPTS
  37.  ****************************************************************************/
  38. #define TMR0_COUNT      (FOSC/((unsigned long)4*4*250*1000))      // Number of carrys per second
  39.  
  40. unsigned char milli_second, sys_clk;
  41.  
  42. void isr_main(void);
  43.  
  44. #pragma code HIGH_INTERRUPT_VECTOR = 0x0008
  45. void High_ISR (void) {
  46.    _asm goto isr_main _endasm
  47. }
  48.  
  49. #pragma interrupt isr_main
  50. void isr_main(void) {
  51.    if (INTCONbits.TMR0IF==1)  {        // if TIMER0 overflow interrupt
  52.       INTCONbits.TMR0IF = 0;           // Clear Timer0 interrupt flag
  53.       TMR0L += 6+3;
  54.       sys_clk--;
  55.       if (sys_clk==0) {
  56.          sys_clk = TMR0_COUNT;
  57.          if (++milli_second == 10) {
  58.             milli_second = 0;
  59.          }
  60.       }
  61.    }
  62. }
  63.  
  64.  
  65. /*
  66.    Initialize isr routine and Timer0
  67. */
  68. void isr_init(void) {
  69.    INTCON = 0b11100000;  // Enable interrupts
  70.    T0CON =  0b11000001;  // Prescaler = 4  
  71.    TMR0L = 6+3;
  72.    sys_clk = TMR0_COUNT;
  73.    milli_second = 0;
  74. }
  75.  
  76.  
  77. /****************************************************************************
  78.     ADC FUNCTIONS
  79.  ****************************************************************************/
  80. /*
  81.   Read Analog Input AN0 or AN1
  82. */
  83. unsigned short adc_read(unsigned char channel) {
  84.    union {
  85.       struct {
  86.           unsigned char lob;
  87.           unsigned char hib;
  88.       };
  89.       unsigned short word;
  90.    } adc_val;
  91.  
  92.    // Configure ADC
  93.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  94.    ADCON1 = 0b00001100;   // Analog inputs = AN0, AN1, AN2
  95.    ADCON2 = 0b10010101;   // TAD
  96.  
  97.    // Make an ADC conversion
  98.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  99.    while (ADCON0bits.GO==1); // Conversion
  100.  
  101.    // Configure ADC
  102.    ADCON0 = 0b00000000;   // ADC off
  103.    ADCON1 = 0b00001111;   // All pins to digital inputs
  104.  
  105.    // Return ADC conversion
  106.    adc_val.lob = ADRESL;
  107.    adc_val.hib = ADRESH;
  108.    return adc_val.word;
  109. }
  110.  
  111.  
  112. /****************************************************************************
  113.       RS232 FUNCTIONS
  114.  ****************************************************************************/
  115.  
  116. /*
  117.   Initialize USART for RS232 comunications
  118. */
  119. void rs232_init(void) {
  120.    PIE1bits.TXIE = 0;               // Disable RS232 interrupts
  121.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  122.    SPBRGH = 0;
  123.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  124.    TXSTA = 0b00100110;
  125.    RCSTA = 0b10010000;
  126.    TRISCbits.TRISC6 = 0;            // Enable TX output
  127. }
  128.  
  129.  
  130. /*
  131.    Send char to USART
  132. */
  133. void rs232_putc(char c) {
  134.    TXREG = c;
  135. }
  136.  
  137.  
  138. /*
  139.    Return Hexadecimal value of a nibble
  140. */
  141. char Hexdec(char nibble) {
  142.    nibble &= 0x0F;
  143.    if (nibble>9)
  144.       return ('A'-10) + nibble;
  145.    return '0' + nibble;
  146. }
  147.  
  148.  
  149. /****************************************************************************
  150.       PWM FUNCTIONS
  151.  ****************************************************************************/
  152. /*
  153.   Initialize and configure PWM module
  154.   D = Duty cycle in range 0 .. 200
  155. */
  156. void pwm1_set(int D) {
  157.    if (D > 1000) D = 1000;
  158.    if (D<0) {
  159.       D = 0;
  160.    }
  161.    DCMOT_MOT1 = 1;
  162.    CCP1CON = 0b00001100;
  163.    if (D & 1) CCP1CON |= (1<<4);
  164.    if (D & 2) CCP1CON |= (1<<5);
  165.    D = D>>2;
  166.    CCPR1L = D;
  167. }
  168.  
  169.  
  170. void pwm1_init(void) {
  171.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  172.    PR2 = 250;             // PWM Period = [(PR2) + 1] • TCY •(TMR2 Prescale Value)]
  173.  
  174.    DCMOT_MOT1 = 0;
  175.    DCMOT_MOT2 = 0;
  176.    DCMOT_ENABLE = 0;
  177.  
  178.    DCMOT_TRIS_MOT1 = 0;
  179.    DCMOT_TRIS_MOT2 = 0;
  180.    DCMOT_TRIS_ENABLE = 0;
  181. }
  182.  
  183.  
  184. /****************************************************************************
  185.       PID CONTROL
  186.  ****************************************************************************/
  187. #define DCMOT_RM   8        // Motor resistance in ohm
  188. #define DCMOT_RS   100      // I sense resistance in milliohm
  189. #define DCMOT_IMAX 2000     // Max motor current in milliamp
  190. #define VDD        12
  191.  
  192. #define KI          100
  193. #define PWM_STEPS   1000
  194.  
  195. #define INTEG_MAX  30000
  196.  
  197. signed int Vref, Vmot, Err, Err_old, Integ, Vo, Vo2, Imot, Imot_old;
  198.  
  199. void pid_control(void) {
  200.    char sample;
  201.  
  202.    //*********************************
  203.    // BACK EMF SENSE
  204.    //*********************************
  205.    while (milli_second == 0) {
  206.       DCMOT_ENABLE = 0;
  207.       sample = 0;
  208.    }
  209.    if (milli_second == 1 && sample == 0) {
  210.       Vmot = adc_read(0);
  211.       DCMOT_ENABLE = 1;
  212.       sample = 1;
  213.    }
  214.  
  215.    //*********************************
  216.    // PID Speed control
  217.    //*********************************
  218.    if (sample==1) {
  219.       sample = 1;
  220.  
  221.       Vref = adc_read(2)/2;  // External pot
  222.  
  223.       Err = Vref - Vmot;
  224.       Integ += (Err + Err_old)/2;
  225.       Err_old = Err;
  226.       if (Integ>INTEG_MAX) Integ = INTEG_MAX;
  227.       if (Integ<-INTEG_MAX) Integ = -INTEG_MAX;
  228.  
  229.       Vo = Vref + Integ/KI;      // Integral control
  230.    }
  231.  
  232.    //*********************************
  233.    // Current Control
  234.    //*********************************
  235.    Imot = adc_read(1);
  236.    Imot += adc_read(1);        
  237.    Imot = Imot*250/DCMOT_RS;   // Imot in milliamp
  238.    if (Imot > DCMOT_IMAX) {
  239.       DCMOT_LED1 = 1;          // Max current led = 1
  240.       if (Vmot>Vref)
  241.          pwm1_set(Vmot);
  242.       else
  243.          pwm1_set(Vmot + ((long)DCMOT_IMAX*DCMOT_RM*PWM_STEPS/((long)VDD*1000)));
  244.    }
  245.    else {
  246.       DCMOT_LED1 = 0;        
  247.       Vo2 = Vo + (long)Imot*DCMOT_RM*PWM_STEPS/(1000*VDD);
  248.       pwm1_set(Vo2);
  249.    }  
  250.    Imot_old = Imot;
  251. }
  252.  
  253.  
  254. void pid_init() {
  255.    // PID inputs
  256.    CMCON = 0b00000111;
  257.    ADCON1 = 0b00001111;
  258.    DCMOT_TRIS_AN0 = 1;
  259.    DCMOT_TRIS_AN1 = 1;
  260.    DCMOT_TRIS_AN2 = 1;
  261.  
  262.    // PID values
  263.    Integ = 0;
  264.    Err_old = 0;
  265. }
  266.  
  267. /****************************************************************************
  268.       MAIN PROGRAM
  269.  ****************************************************************************/
  270. void main(void) {
  271.    char send;
  272.  
  273.    //*********************************
  274.    // Initialize
  275.    //*********************************
  276.    rs232_init();
  277.    isr_init();
  278.    pwm1_init();
  279.    pid_init();
  280.    TRISB &= 0x0F;
  281.    fprintf (_H_USART, "\r\nSystem OK.\r\n");
  282.  
  283.  
  284.    //*********************************
  285.    // DC MOTOR SPEED CONTROL
  286.    //*********************************
  287.    send = 0;
  288.    while(1) {
  289.  
  290.       //*********************************
  291.       // PID control
  292.       //*********************************
  293.       pid_control();
  294.  
  295.       //continue;
  296.      
  297.       //*********************************
  298.       // Print PID values
  299.       //*********************************
  300.       #define PUTC(A, B) case A: rs232_putc(B); break;
  301.    
  302.       if (PIR1bits.TXIF == 1) {
  303.          LATBbits.LATB6 = 1;
  304.          switch(send++) {
  305.             PUTC(1, '\r')
  306.             PUTC(2, '\n')
  307.             PUTC(3, 'V')
  308.             PUTC(4, 'm')
  309.             PUTC(5, '=')
  310.             PUTC(6, Hexdec(Vmot>>12))
  311.             PUTC(7, Hexdec(Vmot>>8))
  312.             PUTC(8, Hexdec(Vmot>>4))
  313.             PUTC(9, Hexdec(Vmot))
  314.             PUTC(10, '\t')
  315.  
  316.             PUTC(11, 'I')
  317.             PUTC(12, 'm')
  318.             PUTC(13, '=')
  319.             PUTC(14, Hexdec(Imot>>12))
  320.             PUTC(15, Hexdec(Imot>>8))
  321.             PUTC(16, Hexdec(Imot>>4))
  322.             PUTC(17, Hexdec(Imot))
  323.             PUTC(18, '\t')
  324.  
  325.             PUTC(19, 'I')
  326.             PUTC(20, 'n')
  327.             PUTC(21, 't')
  328.             PUTC(22, 'e')
  329.             PUTC(23, 'g')
  330.             PUTC(24, '=')
  331.             PUTC(25, Hexdec(Integ>>12))
  332.             PUTC(26, Hexdec(Integ>>8))
  333.             PUTC(27, Hexdec(Integ>>4))
  334.             PUTC(28, Hexdec(Integ))
  335.             PUTC(29, '\t')
  336.  
  337.             PUTC(30, 'V')
  338.             PUTC(31, 'o')
  339.             PUTC(32, '=')
  340.             PUTC(33, Hexdec(Vo2>>12))
  341.             PUTC(34, Hexdec(Vo2>>8))
  342.             PUTC(35, Hexdec(Vo2>>4))
  343.             PUTC(36, Hexdec(Vo2))
  344.             PUTC(37, '\t')
  345.  
  346.             default: send = 1;
  347.          } //End switch
  348.          LATBbits.LATB6 = 0;
  349.       } //End if
  350.    } //End while
  351.  
  352. }

Saludos.

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 23 de Febrero de 2012, 14:39:09
Hoy he probado la compensación de corriente con un circuito analógico (operacional + transistor bipolar) y funciona perfectamente.
Sin embargo, cuando intento realizar el mismo control con el PIC, la corriente comienza a oscilar y no aumenta lo necesario. El motor se para y no regula la velocidad.
No se qué ocurre. Voy a intentar comenzar de cero sólo con compensación de corriente y sin control back-emf para poder ver sólo un efecto y que las formas de onda sean más sencillas. Así podré ver algo con el osciloscopio.

También intentaré cambiar la frecuencia PWM para que no interfiera tanto en las formas de onda de corriente.

Espero que merezca la pena porque llevo muchas horas dedicadas al proyecto y no avanza.
A veces me siento algo desalentado.

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Nocturno en 23 de Febrero de 2012, 16:43:53
Ánimo, picuino, no te desanimos. Los mejores premios vienen tras los mayores esfuerzos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 23 de Febrero de 2012, 17:05:34
Saludos PICUINO..

Estoy seguro que al igual que yo hay muchisimos mas pendientes de este hilo asi que ANIMO!!!! :-/ :-/ :-/ ;-) ;-) ;-) :-/ :-/ :-/

Bueno comentarte tambien que por mi parte sigo avanzando en este proyecto, y hasta ahora ya tengo una respuesta modesta con respecto a la respuesta del motor ante cambios bruscos de carga (Tambien es cierto que el motor si vibra un poco ante distintas cargas,.....y bueno deje este tema aparte para una revision posterior).... bueno me dedique ha ver la parte de la inversion de giro y la toma de lectura...y esto fueron los resultados:

* probe la inversion con distintos componentes por separado y tube al final una buena respuesta..

* tambien fue satisfactorio la toma de lectura de la back-emf tanto en giro Derecho como Izquierdo

Ahora me hallo implementando el programa en el micro para controlar todos los componentes (es decir los controlare via RS-232)

Bueno dejo el esquema con el cual estoy trabajando...
(http://s2.subirimagenes.com/imagen/previo/thump_74700881backemf.gif)
Saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 23 de Febrero de 2012, 18:56:24
Muchas gracias por los ánimos Nocturno y amyver. Sigo con ello.

El esquema está fenomenal. Es ingeniosa la solución para utilizar una sola salida PWM para las dos entradas del driver.
De todas formas te recomiendo pasar al PIC16F886. Totalmente compatible con el 16F877 y con 4 salidas PWM. Incluso puede controlar a la vez los 4 transistores de un puente en H.
Habría que plantearse utilizar un puente en H con transistores discretos. Tendríamos más potencia y, total, ya se están utilizando 2 mosfet discretos para llevar a tierra la tensión.

La ventaja de un puente en H es la medida de corriente. En el esquema no detallas como medir corriente. A mi me está dando muchos problemas.
El L6203 sólo deja pasar corriente durante el tiempo de ciclo de trabajo, con lo que la forma de la corriente es a pulsos, tiene mucho ruido y es difícil calcular su valor medio.

Me alegro de que te funcione la medida de la back-emf. A mi también me funciona bien, aunque dependiendo del motor tiene más o menos ruido.

Una cosa que no entiendo del esquema es para qué sirve la TensionMux.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 23 de Febrero de 2012, 19:21:13
Ya sé para qué sirve la tensión mux.
Se me ha ocurrido una solución mejor para el sensado back-emf.

¿Qué te parece si quitas R8 y colocas un divisor de tensión que salga de la unión R3 y R4 ?

El mismo cable serviría para medir tensión positiva o negativa dependiendo del transistor mosfet que lleve a tierra el terminal del motor.
La tensión siempre sería positiva entre 0 y 5 voltios.

Dejo una imagen:

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=37404.0;attach=17949)

Saludos

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 24 de Febrero de 2012, 15:09:18
Saludos PICUINO...en hora buena por continuar en este proyecto  :mrgreen: :mrgreen: :mrgreen:

Primeramente y con respecto al circuito para la toma de la Back-emf tanto negativa como positiva me parece genial... ((:-)) ((:-)) ((:-))

Segundo, tambien me parecio una buena alternativa el micro PIC16f887 en lugar del 16F877A, lo buscare en la tiendas de electronica de mi ciudad

Por ultimo  sobre la medida de la corriente, no la estoy realizando (la verdad no le entiendo mucho, asi como tampoco  se influencia en el circuito.. :lol: :lol:)

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 24 de Febrero de 2012, 16:31:30
Bueno tambien aprovecho para consultar una duda acerca del funcionamiento del motor, es la siguiente:

*Sucede que cuando el motor esta funcionando a una velocidad programada con el control Back-emf
  al aplicarle una carga y retirarla rapidamente...el microcontrolador se reinicia o tiene un mal funcionamiento...
  utilizo para energizar todo el circuito un solo trafo con el cual saco todas las tensiones de alimentacion...
  
bueno como podria solucionar este problemilla???  :lol: :lol:

Por ultimo consultar tambien si alguno conoce que micro de 40 pines tiene mas de DOS salidas PWM y mayor memoria que los 16F877A..

saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 24 de Febrero de 2012, 18:45:50
No se si puede tener algo que ver, pero aprovecho para comentar un efecto del control de velocidad.

Cuando el puente de potencia intenta frenar al motor (reducir su velocidad) absorbe energía del motor y carga el condensador de alimentación.
Si no se tiene cuidado, el condensador puede llegar a aumentar mucho su velocidad. Para que el controlador pueda frenar al motor hace falta que una resistencia consuma la corriente absorbida del motor.


El 16F886 tiene la misma memoria de programa y tiene 1 pwm con 4 salidas para poder controlar un puente en H.
Si quieres más creo que tendrías que ir a la serie 18F

También puedes intentar optimizar el tamaño del programa (el compilador CC5X no es una maravilla, pero crea código muy compacto y la versión gratuita funciona muy bien)
y se puede simular PWM a baja frecuencia por programa.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 25 de Febrero de 2012, 09:26:30
Ya he encontrado el problema :-/
Ahora no sé cómo resolverlo. :?

Creía que tenía problemas con el ruido a la hora de medir la corriente, pero el problema está en la regulación (en la rutina de regulación).
Es verdad que hay ruido en las señales, pero no es el principal problema.

Pruebas controlando el motor sólo con compensación de corriente (sin control back-emf):
El muestreo de corriente es rápido, pero la respuesta es lenta y no sé cómo solucionarlo.
Cada ciclo lee la corriente del motor y aumenta un poco la tensión del motor para compensarlo.
Poco a poco va aumentando la corriente y tarda varios ciclos (demasiados) hasta que se compensa la corriente.

En el caso de utilizar también muestreo back-emf, cada vez que se muestrea se debe apagar la corriente del motor. Cuando termina el muestreo back-emf hay que volver a aumentar la corriente del motor otra vez como estaba antes y el control de corriente es tán lento que apenas le da tiempo de volver a aumentar la corriente del motor antes del siguiente muestreo back-emf.



Control del motor con back-emf:
La cuestión está en que el sistema de regulación responde con mucha lentitud. El motor tiene una constante de tiempo tan rápida como el muestreo del sistema digital.
Lo recomendable es que se tomen muestras del sistema 10 veces más rápido que el tiempo de respuesta del sistema.
Para un motor que tiene una constante de tiempo de 10ms, debería tomar muestras back-emf cada 1ms. Pero esto es imposible porque tendría todo el tiempo al motor apagado.


Todo esto puede parecer un poco confuso. Lo estoy contando en parte para ayudarme a aclarar las ideas. Más adelante postearé gráficas para que se vea con más facilidad.
Por ahora voy a seguir buscando por internet, pero hay poco material publicado. Incluso en inglés es difícil encontrar textos sobre el asunto.
Si alguien encuentra material interesante sobre control digital de motores dc por favor que lo postee.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 29 de Febrero de 2012, 11:51:33
Reportando avances...

Bueno gracias al circuito propuesto por el amigo PICUINO (El circuito para tomar la Back-emf en ambos sentidos de giro del motor) logre realizar que el motor tenga una velocidad relativamente constante ante cambios bruscos de carga tanto en derecha como en izquierda...

Ahora se me ha presentado otro problemilla en el cual necesito ayuda, resulta lo siguiente:

*Cuando el circuito es energizado la tensiones tanto de la alimentacion logica (5Vdc) como la alimentacion del motor (30 Vdc) permanecen constantes, esto lo pude evidenciar con un osciloscopio...

*Pero sucede que en cuanto el motor entra en funcionamiento este introduce ruido a la fuente de alimentacion logica (5Vdc) (tambien pude evidenciar esto con ayuda del osciloscopio), pero bueno el circuito sigue funcionando...

*El problema ocurre en cuanto se le agrega una carga al motor, con una carga "libiana" al eje del motor este funciona bien (es decir cumple con su cometido, conserva la velocidad constante), pero en cuanto se da al motor una carga "mas pesada" el microcontrolador tiende a resetearce...

**Bueno como el control del motor se lo realiza con tres pines del micro, se me ocurre aislar estos pines con un amplificador operacional trabajando en configuracion de SEGUIDOR DE VOLTAJE, bueno hare las pruebas y comentare como me fue...


De cualquier forma si a alguno le ocurrio este problema de ruido controlando motores DC agradeceria sus comentarios acerca de como poder solucionarlo...


Saludos..
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 29 de Febrero de 2012, 12:13:22
Se me olvido mencionar un detalle sobre el ruido en la alimentacion logica cuando el motor esta en funcionamiento....

Bueno hice dos pruebas.

*La primera con una sola fuente de poder (es decir que con esta fuente alimentaba tanto al motor como a la parte logica)
*La segunda prueba con dos fuentes (una para la alimentacion del motor, y otra para la alimentacion de la parte logica)

Pero el problema seguia......en cuanto se acciona el motor este seguia introduciendo ruido a la alimentacion de la circuiteria logica.... :? :? :?



Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Febrero de 2012, 16:03:52
Yo también tengo problemas de ruido a la hora de medir corrientes porque la tensión en la resistencia de sensado es pequeña y el ruido se nota mucho.

En mi caso noto ruido en torno a 20mV. Como estoy utilizando placa de prototipos de inserción rápida (protoboard) esto es normal con las corrientes de hasta 1 amperio con las que trabajo.

En mi caso ya he conseguido que funcione bien el sensado de corriente con un operacional cmos y la parte de potencia trabajando con medio puente (un sólo sentido de giro).
Sólo me falta conseguirlo con un puente en H completo.

Creo que va siendo hora de hacer una placa PCB para que el ruido afecte menos.


Si en tu caso el ruido es mucho mayor que 20mV y el microcontrolador llega a resetearse, el problema es otro.
¿Has colocado un condensador entre Vdd y Gnd?
¿Has unido bien las masas de los dos circuitos? PIC_____Puente H
¿Has colocado resistencias de 100 ohm en los cables de señal para asegurarte de que no conducen grandes corrientes?

Si envías una foto podemos opinar otros posibles problemas.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 29 de Febrero de 2012, 17:56:30
Yo también tengo problemas de ruido a la hora de medir corrientes porque la tensión en la resistencia de sensado es pequeña y el ruido se nota mucho.

En mi caso noto ruido en torno a 20mV. Como estoy utilizando placa de prototipos de inserción rápida (protoboard) esto es normal con las corrientes de hasta 1 amperio con las que trabajo.

En mi caso ya he conseguido que funcione bien el sensado de corriente con un operacional cmos y la parte de potencia trabajando con medio puente (un sólo sentido de giro).
Sólo me falta conseguirlo con un puente en H completo.

Creo que va siendo hora de hacer una placa PCB para que el ruido afecte menos.


Si en tu caso el ruido es mucho mayor que 20mV y el microcontrolador llega a resetearse, el problema es otro.
¿Has colocado un condensador entre Vdd y Gnd?
¿Has unido bien las masas de los dos circuitos? PIC_____Puente H
¿Has colocado resistencias de 100 ohm en los cables de señal para asegurarte de que no conducen grandes corrientes?

Si envías una foto podemos opinar otros posibles problemas.

Saludos.

Si, el ruido que se produce cuando el motor esta en funcionamiento y es mayor que 20mV....y con respecto a las preguntas:

1).- Si coloque capacitores entre Vcc y Gnd
2).- Las tierras de la parte logica y de potencia son las mismas
3).- Sobre las resistencias de 100 ohm a las que te refieres......deben estar situadas entre el Micro y el Puente H???
      si es asi...me falta ese punto bueno ahora me pongo en la tarea de revisar eso...


Por otra parte comentar tambien que probe con los operacionales configurados en SEGUIDOR DE VOLTAJE, y el circuito funciono bien aunque el ruido permanecia en la alimentacion (claro que con menor amplitud)....

Saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 29 de Febrero de 2012, 18:02:19
Si, las resistencias deben estar entre el microcontrolador y el puente en H.

Estas resistencias NO SON NECESARIAS, pero te pueden dar una pista de dónde está el problema.

Si se producen sobretensiones o cortocircuitos en los cables de señal, con las resistencias no se debería resetear el micro.

Con un polímetro puedes comprobar la tensión en las resistencias, que debería ser cero o muy cercano a cero. En caso contrario ahí está el problema.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 01 de Marzo de 2012, 09:42:24
Si, las resistencias deben estar entre el microcontrolador y el puente en H.

Estas resistencias NO SON NECESARIAS, pero te pueden dar una pista de dónde está el problema.

Si se producen sobretensiones o cortocircuitos en los cables de señal, con las resistencias no se debería resetear el micro.

Con un polímetro puedes comprobar la tensión en las resistencias, que debería ser cero o muy cercano a cero. En caso contrario ahí está el problema.

Saludos.

Exito en las pruebas que realice, gracias una vez mas a las muy acertadas sugerencias del amigo PICUINO  ((:-)) ((:-)) ((:-)) ((:-))
pues comentarte picuino que una vez colocadas las resitencias el ruido disminuyo de manera considerable...con lo cual el micro ya no se resetea  :-/ :-/ :-/ :-/

seguire puliendo detalles y comentando avances o dudas

saludos...

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 01 de Marzo de 2012, 14:09:27
Hola amyver,
Me alegro mucho de que hayas solucionado el problema.
Por mi parte, estoy probando una modificación para medir pulsos de corriente en vez de corriente continua.
Si lo consigo voy a preparar una PCB para montar el puente en H.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 01 de Marzo de 2012, 16:43:26
Las pruebas de medición de corriente de pico han salido OK con un LM358 alimentado a 12v y dos diodos BAT42.
El circuito es similar al siguiente:

(http://photos1.hi5.com/0139/623/716/mFmfHy623716-02.png)

con Ei = 0 y con la entrada de señal por el terminal positivo para que el amplificador sea no inversor.

Estoy preparando el esquema definitivo del puente en H.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 01 de Marzo de 2012, 18:48:25
Ya tengo un esquema provisional.

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=37404.0;attach=18002;image)

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 02 de Marzo de 2012, 14:34:09
bueno creo que ha llegado el momento de implementar un control PID en el codigo de mi programa, hasta ahora el control de velocidad que realizo es bastante basico....

entonces primeramente mostrare el esquema actual con el que estoy trabajando...

a continuacion mostrare mi codigo fuente actual:
Código: [Seleccionar]
/****************************************************************************
By: Amyver - Foro TODOPIC
*****VERSION 1B*****
Funciones:
*Modulo controlado atravez del interface USART
 ****************************************************************************/
#include <16F877A.h>
#device adc=10             //Definimos un Conversor Analogo/Digital con resolucion de 10 bits
#Fuses XT, NOWDT, NOPROTECT, NOLVP, PUT, BROWNOUT, NOCPD, NOWRT//palabra de configuracion
#Use delay(clock=4000000)  //usando un oscilador de 4MHz
#Use RS232(Baud=9600, Xmit=Pin_C6, Rcv= Pin_C7, Parity=N, Bits=8)

#Use Fast_io(B)
#Use Fast_io(C)

#Byte PortB=0x06
#Byte PortC=0x07

//declaracion de variables globales que seran usados en el programa
char var;
signed int16 senialError=0;
signed int16 lecturaBackEmf=0,fijarVelocidad=0,valorPWM=0;
////////////////////////////////////////////////////////////////////////////////
void incrementarVelocidad()
{
 OutPut_High(Pin_C5);       //Habilitamos el driver L6203

 fijarVelocidad+=25;       //incrementamos la velocidad en 25
 
 if(fijarVelocidad>=1000)  //pregutamos si se llego a la velocidad tope hacia adelante
 {
  fijarVelocidad=1000;     //se fija una velocidad tope
 }
 if(fijarVelocidad>=0)     //Preguntamos si la velocidad es positiva (motor con giro hacia adelante)
 {
  OutPut_Low(Pin_C4);      //Habilitamos driver L6203 para el giro a la derecha 
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);   
 }
 else
 {
  OutPut_High(Pin_C4);     //Habilitamos driver L6203 para el giro a la izquierda
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);     
 }
}
void decrementarVelocidad()
{
 OutPut_High(Pin_C5);       //Habilitamos el driver L6203
 
 fijarVelocidad-=25;       //decrementamos la velocidad en 25
 
 if(fijarVelocidad<-1000)  //pregutamos si se llego a la velocidad tope hacia atras
 {
  fijarVelocidad=-1000;    //se fija una velocidad tope
 }
 if(fijarVelocidad>=0)     //Preguntamos si la velocidad es positiva (motor con giro hacia adelante)
 {
  OutPut_Low(Pin_C4);      //Habilitamos driver L6203 para el giro a la derecha 
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);
 }
 else
 {
  OutPut_High(Pin_C4);     //Habilitamos driver L6203 para el giro a la izquierda
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);     
 }
}
void pararMotor()          //paramos el motor
{
 fijarVelocidad=0;         //Establecemos la velocidad en cero
 OutPut_Low(Pin_C5);       //Deshabilitamos el driver L6203
 
 set_pwm1_duty((int16)0);  //se establece el PWM1 en Cero   
 printf("\r\n\r\nPARAR MOTOR=%Ld\r\n   ",fijarVelocidad);
}
////////////////////////////////////////////////////////////////////////////////
void verificarRS232()      //Funcion encargada de verificar si existen datos en buffer
{                          //del USART
  if(kbhit())              //Preguntamos si existen datos pendientes a ser procesados
  {                        //Si, hay algo pendiente de recibir ...         
   var=getc();             //tomamos el dato ingresado por el usuario y lo almacenamos en
                           //una variable
   if(var==0x0D)           //preguntamos si se presiono Enter
   {
    incrementarVelocidad();//llamamos a la funcion incrementar velocidad
   }
   if(var==0x08)           //preguntamos si se presiono retroceso
   {
    decrementarVelocidad();//llamamos a la funcion decrementar velocidad
   }
   if(var==0x20)           //preguntamos si se presiono la barra espaciadora
   {
    pararMotor();          //funcion que para los motores
   }
  }
}
void testearBackEmf()      //Funcion que tomara el valor de la Back-emf
{
 delay_ms(10);             //tiempo que se enviara la señal PWM
 
 OutPut_Low(Pin_C5);       //Enable Motor OFF
 delay_ms(1);              //tiempo de espera para que la señal Back-emf se estabilice
 
 Set_adc_channel(1);       //selecion de canal 1 del modulo ADC
 delay_us(50);             //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();//Se toma el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 printf("\r\nLectura BACK-EMF=%Ld",lecturaBackEmf);   //imprimimos un dato por pantalla
 OutPut_High(Pin_C5);      //Enable Motor ON
}
void ajustarVelocidad()    //funcion encargada de realizar el control de velocidad(ES LA QUE PRETENDO MEJORAR)
{
 signed int16 auxiliar=0;  //Definimos una variable de tipo entero con signo de 16 bits

 if(fijarVelocidad>=0)     //preguntamos si la velocidad es positiva (Giro Derecho)
 {
  senialError= fijarVelocidad-lecturaBackEmf;   //sacamos el error
 }
 else                      //si la velocidad es negativa (Giro Izquierdo)
 {
  auxiliar=(int16)ABS(fijarVelocidad);    //tomamos el valor absoluto de la variable
  senialError= auxiliar-lecturaBackEmf;   //la almacenamos en una variable para despues usarla
 }

 printf("\r\nSenial de Error=%Ld",senialError); //Imprimimos por pantalla el valor de la señal de error
 
 if(senialError>5)                        //Establecemos un desplazamiento maximo de 5 unidades
 {
  valorPWM+=senialError;                  //ajustamos el valor del PWM
 
  if(valorPWM>=1000)                      //preguntamos si se llego al limite maximo del PWM1
   valorPWM=1000;                     

  set_pwm1_duty((int16)valorPWM);         //establecemos el nuevo valor del PWM1
  printf("\r\n\r\nValor del PWM=%Ld\r\n   ",valorPWM);   //imprimimos el valor del PWM1
 }
 if(senialError<-5)                       //Establecemos un desplazamiento maximo de -5 unidades
 {
  valorPWM+=senialError;                  //ajustamos el valor del PWM
 
  if(valorPWM<25)                         //si el valor del PWM1 es menor que 25, apagamos el CCP1
   valorPWM=0;
   
  set_pwm1_duty((int16)valorPWM);         //establecemos el nuevo valor del PWM1
  printf("\r\n\r\nValor del PWM=%Ld\r\n   ",valorPWM);   //imprimimos el valor del PWM1
 }
}

void main()
{
 Set_Tris_B(0b11111110);            //Configuramos el pin RB0 como salida, los restantes como entradas
 Set_Tris_C(0b10001011);            //Configuramos los pines RC0,RC1,RC3 y RC7 como entradas, los restantes como salidas

 PortB=0x00;                        //limpiamos el puertoB
 PortC=0x00;                        //limpiamos el puertoC

 OutPut_High(Pin_B0);               //senializacion de pic ON

////////////////////////////////////Configuracion de CCPx(PWM)/////////////////////////////////////////////////
 setup_timer_2(T2_DIV_BY_1,249,1);  //configuramos el timer2, Prescaler=1,Periodo=249,Postcaler=1
                                    //con lo que se conseguira: T=250us o f=4Khz
                                    //"setup_timer_2(Prescaler,Periodo,Postcaler)"
 setup_CCP1(CCP_PWM);               //Escogemos el modo de trabajo de CCP1, lo escojemos como modulacion por ancho de pulso
                                    //NOTA.- Tanto para PWM1 y PWM2 el periodo es establecido por el timer2
                                    //NOTA2.-la resolucion maxima esta dada por: Tpwm=2exp(n) * 1/Fosc
                                    //                                           250us=2exp(n) * 1/(4exp(6))
                                    //                                           2exp(n)= 1000
                                    //Entonces el maximo valor que podemos cargar al "value" es de 1000 con lo que se
                                    //conseguira un ciclo de trabajo de 100% "set_pwm1_duty(value)"
////////////////////////////////////Configuracion de CAD////////////////////////////////////////////////////
 setup_adc(ADC_CLOCK_INTERNAL);     //Se usara un reloj interno
 Setup_adc_Ports(AN0_AN1_AN3);      //se configuran lo pines: RA0,RA1,RA2 como entradas analogicas
////////////////////////////////////////////////////////////////////////////////////////////////////////////
 set_pwm1_duty((int16)0);           //se inicializa el PWM en cero

 OutPut_High(Pin_C5);               //Enable Motor ON
 
 printf("\r\nSystem OK.\r\n");      //Sistema en linea y listo para transmitir

 while(true)                        //ciclo infinito
 {
  verificarRS232();                 //llamamos a la funcion que se encargara de verificar la tecla que se pulso
  testearBackEmf();                 //funcion que determinara el valor de la Back-emf
  ajustarVelocidad();               //FUNCION QUE REALIZA EL CONTROL DE VELOCIDAD (es la que pretendo mejorar)!!!!
 }
}

bueno es un codigo bastante sencillo y le puse comentarios para un mejor entendimiento, ojo que la funcion a la cual pretendo mejorar es la llamada "ajustarVelocidad()"

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 02 de Marzo de 2012, 14:41:20
Tal vez sea conveniente mostrar el cableado en proteus (version: 7.7SP2) y el codigo en fuente (en PCWHD 4.084) ya compilado bueno los adjunto a continuacion...

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Marzo de 2012, 17:48:22
Hola amyver,
He leído el código y veo que por ahora tienes un control Integral:

   Error = Referencia - BackEmf
   Control = Control + Error
   set_pwm(Control)

Vamos a analizar el bucle de control.


1. Entrada de señal Back-Emf:
El rango de entrada es de 0 a 1023 puntos del ADC
El rango de lectura es de 0 a 23.4 voltios con el divisor de tensión que has puesto
Por lo tanto la señal BackEmf está multiplicada por 1023/23.4 = 43.7 puntos/voltio

Así cuando haya un voltio en el motor se leerá como:  1v · 43.7 = 43 puntos


2. Salida de señal PWM:
El rango de salida pwm es de 0 a 1000 puntos en el CCP1
El rango de salida es de 0 a 30 voltios en el puente.
Por lo tanto la señal pwm está multiplicada por 30/1000 = 0.030 voltios/punto

Así una señal pwm de 100 puntos se verá en el motor como 100 · 0.030 = 3 voltios


3. Periodo del control y ganancia integral:
Aquí es muy importante conocer cada cuánto tiempo se repite el control. Imagino que en tu caso será cada 12ms más o menos.
La ganancia del control integral es igual a la frecuencia de repetición del ciclo de control.
Ki = 1/0.012 = 83       (más o menos)


4. Ganancia total:

Multiplicamos las tres ganancias:
43.7 · 83 · 0.030 = 109

La ganancia integral total será de 109




Luego sigo con el control.
Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Marzo de 2012, 18:42:10
Me faltan datos del modelo dinámico del motor para poder decir si la ganancia integral es correcta.

He simulado el programa con mi motor y parece que puede funcionar bien.

En cualquier caso lo que falta en el programa es poder variar la ganancia integral. Cambia esta línea:

Código: C
  1. valorPWM+=senialError;

Por lo siguiente:

Código: C
  1. signed int16 Control_I, KI;
  2.  
  3.  
  4.    KI = 16;                                       // Ganancia integral
  5.    Control_I = (senialError * KI) / 8;
  6.  
  7.    valorPWM += Control_I;

El valor de KI tendrás que variarlo de 2 a 31 hasta que el lazo funcione OK.
   Si el valor de KI es grande, el motor responderá más rápido y la velocidad oscilará más.
   Si el valor de KI es pequeño, el motor responderá más lento y la velocidad oscilará menos.

   Si necesitas dar un valor de KI mayor que 31, entonces en vez de dividir entre 8 divide entre 4: Control_I = (senialError * KI) / 4;

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 03 de Marzo de 2012, 10:50:05
1. Entrada de señal Back-Emf:
El rango de entrada es de 0 a 1023 puntos del ADC
El rango de lectura es de 0 a 23.4 voltios con el divisor de tensión que has puesto
Por lo tanto la señal BackEmf está multiplicada por 1023/23.4 = 43.7 puntos/voltio

Así cuando haya un voltio en el motor se leerá como:  1v · 43.7 = 43 puntos

Hola PICUINO, algunas aclaraciones con respecto al analisis que hiciste:

El rango de entrada es de 0 a 1023 puntos del ADC -----> OK, es correcto
El rango de lectura es de 0 a 23.4 voltios con el divisor de tensión que has puesto

*Bueno en teoria tendria una señal analogica (por la union de los pines de las resistencias R9 y R10) que varia entre 0 y 6.41 V aproximadamente (suponiendo que el motor se comporta como una fuente ideal de 30Vdc)

Pero luego de algunas pruebas pude evidenciar que con el divisor de tension tenia una entrada de señal por el CAD de aprox. 1000 "puntos" lo que es equivalente a una entrada de tension de aprox 5 V cuando  insertaba un PWM señal con un ciclo de trabajo de 100% o 1000"puntos"

Por lo tanto la señal BackEmf está multiplicada por 1023/23.4 = 43.7 puntos/voltio--> Entonces si no me equivoco la correccion seria de la siguiente manera:
Por lo tanto la señal BackEmf está multiplicada por 1023/5 = 204 puntos/voltio

Así cuando haya un voltio en el motor se leerá como:  1v · 204 = 204 puntos


Bueno pues todo el analisis que hiciste esta muy bien explicado como siempre.... (((:-))) (((:-))) (((:-)))
y una duda mas... sobre el control que se esta realizando ahora.... sera necesario implementar un proporcional y un derivativo... o solo nos quedamos con el integral????

Saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Marzo de 2012, 12:28:00
En los motores se suele implementar una forma especial de PID que se llama I-PD

Esto significa que el control directo es integral y el proporcional y derivativo se colocan en el lazo de realimentación.
Se hace así para evitar que el motor sufra cambios repentinos de tensión y de corriente.

En nuestro caso, para hacer el control derivativo hay un problema: el motor es muy rápido comparado con la velocidad de toma de datos.
El control derivativo consigue hacer que el sistema sea más estable. Si el motor comienza a aumentar muy rápido la velocidad el control derivativo le va a frenar.
El problema es que nuestros motores pueden aumentar de 0% a 60% su velocidad entre dos intervalos de toma de datos back-emf.
En estas condiciones el control derivativo puede hacer poco para evitar que el motor se embale.

Para conseguir estabilidad, por ahora lo mejor será afinar bien el integral.


Más adelante se puede intentar un método más avanzado de control por simulación del motor:
Consiste en simular el funcionamiento del motor dentro del micro. Para eso debemos conocer los parámetros dinámicos del motor (inductancia, resistencia, inercia) y resolver las ecuaciones como lo haría un simulador de circuitos.
Al simular el motor se puede controlar la velocidad del motor simulado, en vez del motor real.
Esto permite aumentar la frecuencia de muestreo del bucle de control y controlar con un PID completo.
Cada cierto tiempo se deben medir los valores del motor real y ajustar los valores del motor simulado para que no se aparten mucho de la realidad.
Pero esto es otra historia mucho más compleja. Por ahora vamos a ver si funciona nuestro control Integral.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Marzo de 2012, 12:31:16

Pero luego de algunas pruebas pude evidenciar que con el divisor de tension tenia una entrada de señal por el CAD de aprox. 1000 "puntos" lo que es equivalente a una entrada de tension de aprox 5 V cuando  insertaba un PWM señal con un ciclo de trabajo de 100% o 1000"puntos"


Eso es porque el ADC estaba saturado y por encima de 5 voltios de entrada siempre te dá una lectura de 1023.

Prueba lo siguiente:
Alimenta con 23.4 voltios la resistencia R7
Mide la tensión en el punto "analog" y dará 5 voltios (fondo de escala)


(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=37404.0;attach=18013;image)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Marzo de 2012, 12:39:01

Por lo tanto la señal BackEmf está multiplicada por 1023/23.4 = 43.7 puntos/voltio--> Entonces si no me equivoco la correccion seria de la siguiente manera:
Por lo tanto la señal BackEmf está multiplicada por 1023/5 = 204 puntos/voltio


Se debe comenzar en el mismo punto donde se termina (en este caso la unión de R7 con el motor)

   La señal medida por el micro comienza en R7
   La señal generada por el PWM temina en R7 (0 - 30 voltios)


Si divides 1023/5 estás comenzando a analizar en la señal "analog" que vale 5 voltios y estás olvidando la ganancia del divisor de tensión. (que baja de 30v a 5v)

De manera que si el divisor de tensión funciona OK y te da 5 voltios en analog cuando el motor tiene 30 voltios, la corrección debería ser:

   Por lo tanto la señal BackEmf está multiplicada por 1023/30 = 34.1 puntos/voltio

Pero insisto en que las pruebas que has hecho saturan al DAC.



De todas formas todo esto sólo vale si también tenemos los valores del motor.

¿Podrías medir los parámetros del motor?
  1. Resistencia equivalente
  2. Inductancia
  3. Inercia mecánica

Manual y hojas excel para medir los parámetros:
   https://sites.google.com/site/picuino/motor_equivalent_model#TOC-MODELADO-DE-UN-MOTOR-DE-CORRIENTE-C

  

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 05 de Marzo de 2012, 09:16:12
Ok.... PICUINO comprendido..... :grin: :grin: :grin:

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Marzo de 2012, 10:28:57
Muy buenas a todos.... bueno comentar que el dia de ayer estube realizando algunas pruebas con el control Integral propuesto por el amigo PICUINO y la pruebas fueron muy alentadoras... :-/ :-/ :-/ :-/ :-/

efectivamente el control funcionaba bastante bien a bajas velocidades, el problema estaba ahora a velocidades elevadas....pero bueno se me ocurio darle otra ganancia integral a partir de cierta velocidad....y bueno los resultados fueron otra vez bastante buenos....

A continuacion adjunto el circuito del Proteus 7.7sp2 asi como el codigo fuente compilado en PCWHD 4.084

Código: [Seleccionar]
/****************************************************************************
By: Amyver - Foro TODOPIC
*****VERSION 2B*****
Funciones:
*Modulo controlado atravez del interface USART
*Modulo usado CCP1
*El programa controla velocidad de un motor DC
 en dos sentido de giro, con la particularidad
 de mantener la velocidad constante ante cambios bruscos de carga
 
*Se soluciono el problema del reseteo del Micro usando
 amplificadores operacionales configurados como seguidores de voltaje
 dichos amplificadores fueron conectados a las salidas de los pines
 de -CCP1- -Control de Giro- y -Enable-
 ****************************************************************************/
#include <16F877A.h>
#device adc=10             //Definimos un Conversor Analogo/Digital con resolucion de 10 bits
#Fuses XT, NOWDT, NOPROTECT, NOLVP, PUT, BROWNOUT, NOCPD, NOWRT//palabra de configuracion
#Use delay(clock=4000000)  //usando un oscilador de 4MHz
#Use RS232(Baud=9600, Xmit=Pin_C6, Rcv= Pin_C7, Parity=N, Bits=8)

#Use Fast_io(B)
#Use Fast_io(C)

#Byte PortB=0x06
#Byte PortC=0x07

char var;
signed int16 senialError=0;
signed int16 lecturaBackEmf=0,fijarVelocidad=0,valorPWM=0;

void incrementarVelocidad()
{
 OutPut_High(Pin_C5);       //Habilitamos el driver L6203

 fijarVelocidad+=20;       //incrementamos la velocidad en 300
 
 if(fijarVelocidad>=1000)  //pregutamos si se llego a la velocidad tope hacia adelante
 {
  fijarVelocidad=1000;     //se fija una velocidad tope
 }
 if(fijarVelocidad>=0)     //Preguntamos si la velocidad es positiva (motor con giro hacia adelante)
 {
  OutPut_Low(Pin_C4);      //Habilitamos driver L6203 para el giro a la derecha 
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);   
 }
 else
 {
  OutPut_High(Pin_C4);     //Habilitamos driver L6203 para el giro a la izquierda
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);     
 }
}
void decrementarVelocidad()
{
 OutPut_High(Pin_C5);       //Habilitamos el driver L6203
 
 fijarVelocidad-=20;       //decrementamos la velocidad en 300
 
 if(fijarVelocidad<-1000)  //pregutamos si se llego a la velocidad tope hacia atras
 {
  fijarVelocidad=-1000;    //se fija una velocidad tope
 }
 if(fijarVelocidad>=0)     //Preguntamos si la velocidad es positiva (motor con giro hacia adelante)
 {
  OutPut_Low(Pin_C4);      //Habilitamos driver L6203 para el giro a la derecha 
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);
 }
 else
 {
  OutPut_High(Pin_C4);     //Habilitamos driver L6203 para el giro a la izquierda
  printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);     
 }
}
void pararMotor()          //paramos el motor
{
 fijarVelocidad=0;         //Establecemos la velocidad en cero
 OutPut_Low(Pin_C5);       //Deshabilitamos el driver L6203
 
 set_pwm1_duty((int16)0);  //se inicializa el PWM en Cero   
 printf("\r\n\r\nPARAR MOTOR=%Ld\r\n   ",fijarVelocidad);
}

void verificarRS232()      //Funcion encargada de verificar si existen datos en buffer
{                          //del USART
  if(kbhit())              //Preguntamos si existen datos pendientes a ser procesados
  {                        //Si, hay algo pendiente de recibir ...         
   var=getc();             //tomamos el dato ingresado por el usuario y lo almacenamos en
                           //una variable
   if(var==0x0D)           //preguntamos si se presiono Enter
   {
    incrementarVelocidad();//llamamos a la funcion incrementar velocidad
   }
   if(var==0x08)           //preguntamos si se presiono retroceso
   {
    decrementarVelocidad();//llamamos a la funcion decrementar velocidad
   }
   if(var==0x20)           //preguntamos si se presiono la barra espaciadora
   {
    pararMotor();          //funcion que para los motores
   }
  }
}
void testearBackEmf()
{
 delay_ms(7);         //tiempo que se enviara la señal PWM
 
 OutPut_Low(Pin_C5);   //Enable Motor OFF
 delay_ms(1);          //tiempo de espera para que la señal Back-emf se estabilice
 
 Set_adc_channel(1);   //selecion de canal 1
 delay_us(50);         //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();  //lee el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 printf("\r\nLectura BACK-EMF=%Ld",lecturaBackEmf);
 OutPut_High(Pin_C5);  //Enable Motor ON
}
void ajustarVelocidad()
{
 signed int16 Control_I, KI;                 //Definimos variables enteras con signo
 signed int16 auxiliar=0,fijarVelocidadAux=0;//de 16 bits..

 if(fijarVelocidad>=0)                       //Preguntamos si se tiene una velocidad
 {                                           //positiva (Giro del motor en derecha)
  senialError= fijarVelocidad-lecturaBackEmf;//Tomamos la señal de error
  fijarVelocidadAux=fijarVelocidad;          //Guardamos el valor de la velocidad programada
 }                                           //puesto que sera usada despues
 else                                        //si la velocidad es Negativa(Giro del motor en Izquierda)
 {
  auxiliar=(int16)ABS(fijarVelocidad);       //Tomamos el valor ABSOLUTO de la variable "fijarVelocidad"
  senialError= auxiliar-lecturaBackEmf;      //la combertimos en una variable de 16 bits y la almacenamos.
  fijarVelocidadAux=auxiliar;                //Guardamos el valor de la velocidad programada
 }
 
 printf("\r\nSenial de Error=%Ld",senialError);

//////////////CONTROL INTEGRAL (propuesto por PICUINO)//////////////////////////
 if((fijarVelocidadAux>=0)&&(fijarVelocidadAux<=200)) //nos aseguramos de que la velocidad se
 {                                                    //encuentre entre estos dos rangos.
  KI =10;          // Ganancia integral
 }
 else                                                 //Si la velocidad programada es mayor a (PWM1->200)
 {                                                    //le daremos otra ganancia para que responda lento
  KI = 2;         // Ganancia integral                //con lo cual se lograra que el motor Oscile menos
 }                                                    //a altas velocidades.

 Control_I = (senialError * KI) / 8;                  //ecuaciones para el CONTROL INTEGRAL
 valorPWM += Control_I;                               //se almacena el la variable "valorPWM" el resultado del
                                                      //resultado arrojado por el control Integral
 if(valorPWM>=1000)                 //fijamos limites para la velocidad
  valorPWM=1000;     
 if((valorPWM<20))           
  valorPWM=0;
 
 set_pwm1_duty((int16)valorPWM);    //se da el nuevo valor al PWM
 printf("\r\n\r\nValor del PWM=%Ld\r\n   ",valorPWM);
}

void main()
{
 Set_Tris_B(0b11111110);            //Configuramos el pin RB0 como salida, los restantes como entradas
 Set_Tris_C(0b10001011);            //Configuramos los pines RC0,RC1,RC3 y RC7 como entradas, los restantes como salidas

 PortB=0x00;                        //limpiamos el puertoB
 PortC=0x00;                        //limpiamos el puertoC

 OutPut_High(Pin_B0);               //senializacion de pic ON

 setup_timer_2(T2_DIV_BY_1,249,1);  //configuramos el timer2, Prescaler=1,Periodo=249,Postcaler=1
                                    //con lo que se conseguira: T=250us o f=4Khz
                                    //"setup_timer_2(Prescaler,Periodo,Postcaler)"
 setup_CCP1(CCP_PWM);               //Escogemos el modo de trabajo de CCP1, lo escojemos como modulacion por ancho de pulso
                                    //NOTA.- Tanto para PWM1 y PWM2 el periodo es establecido por el timer2
                                    //NOTA2.-la resolucion maxima esta dada por: Tpwm=2exp(n) * 1/Fosc
                                    //                                           250us=2exp(n) * 1/(4exp(6))
                                    //                                           2exp(n)= 1000
                                    //Entonces el maximo valor que podemos cargar al "value" es de 1000 con lo que se
                                    //conseguira un ciclo de trabajo de 100% "set_pwm1_duty(value)"
////////////////////////////////////Configuracion de CAD////////////////////////////////////////////////////
 setup_adc(ADC_CLOCK_INTERNAL);     //Se usara un reloj interno
 Setup_adc_Ports(AN0_AN1_AN3);      //se configuran lo pines: RA0,RA1,RA2 como entradas analogicas
////////////////////////////////////////////////////////////////////////////////////////////////////////////
 set_pwm1_duty((int16)0);           //se inicializa el PWM en cero

 OutPut_High(Pin_C5);               //Enable Motor ON
 
 printf("\r\nSystem OK.\r\n");      //Sistema en linea y listo para transmitir

 while(true)
 {
  verificarRS232();
  testearBackEmf();
  ajustarVelocidad();
 }
}

Entonces estoy a la espera de criticas constructivas para mejorar el funcionamiento actual... :P :P :P

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 10:33:04
Hola amyver.
¿Puedes decirme que resistencia de inducido tiene tu motor?

La puedes medir con un polímetro (igual que si midieses una resistencia)

Otra forma de medir la resistencia es:
   Alimentar al motor con una tensión baja, por ejemplo con 1 voltio
   frenar el eje con la mano para que no se mueva
   Medir la intensidad que atraviesa el motor.
   Medir la tensión en bornes del motor

   Rm = V / I


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Marzo de 2012, 10:35:36
Ah... olvidaba comentar que se opto por una solucion basada en AmpOp (Lm324) para solucionar el problema del reseteo del pic que aun persistia en cuanto el motor era sometido a cargas pesadas, los AmpOp fueron configurados como seguidores de voltaje y alimentados con 24Vdc y fueron puestos entre micro y L6203...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Marzo de 2012, 10:40:42
Lo medi con un multimetro de alta presicion y me arrojo un valor de 17 Ohm...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Marzo de 2012, 10:45:14
Una consulta PICUINO, te sirve la medida que realice??? o prefieres que la realice con el metodo de la tension y corriente??? :? :? :?
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 11:20:23
En principio valdrá con esa medida.

Se me olvidó comentarte que en algunos motores la medida varía dependiendo de la posición del eje, de forma que hay que medir la resistencia en varias posiciones del eje motor para asegurarse de que no varía.

El valor es muy alto. ¿Cuanto valen la corriente, la tensión y la potencia nominal?

Saludos.



Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 11:24:47
He leído en otro mensaje que tu motor tiene:

  U = 30v
  I  = 4 Amperios
  w = 30000 rpm

A lo que añadimos:

  Rm = 17 Ohmios

¿Es así?

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 06 de Marzo de 2012, 11:58:25
Si, es correcto....

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 13:52:45
Los datos no concuerdan.

Piensa que si alimento al motor con 30 voltios, como máximo van a pasar unos dos amperios.

   I = V / R = 30 / 17 = 1.76 Amperios.

Creo que la resistencia es muy grande.

¿Puedes hacer la prueba de resistencia alimentando con 1 voltio?
Si la resistencia está bien medida, deberían pasar 59 mA.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 13:57:33
Estoy probando una placa que he diseñado para hacer pruebas sobre PCB.
Por ahora no funciona. No se que le pasa.
Cuando alimento a 12 voltios parece que todo está bien.

Luego conecto el microcontrolador y aparece un cortocircuito que se mantiene aunque desconecte el microcontrolador.
Si apago la alimentación y vuelvo a conectar la placa con el L6203, otra vez está en corto (0.3voltios a 0.3Amperios)

Al día siguiente, parece que la placa vuelve en sí.
Conecto la alimentación y puedo subir a 12voltios con un consumo de 0.01Amperios.
Vuelvo a conectar el PIC y la placa vuelve al cortocircuito.


Es el fallo más raro que me he encontrado nunca.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Nocturno en 06 de Marzo de 2012, 14:30:02
¿Puedes poner el diseño a ver si vemos algo?

¿Se calienta el L6203 al hacer corto?
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Marzo de 2012, 15:14:10
Muchas gracias Nocturno.
Llevo un día buscando el fallo.
Cuando por fin publico la duda, a continuación encuentro el problema.
El problema consistía en que he colocado dos diodos a tierra al revés (hay que ser bruto)
Ya les he cambiado y todo funciona OK.
Lo que no me explico es el fallo intermitente.
Dejo el circuito para que no le pase a otro.

El circuito está ya corregido. Antes de corregir D1 y D2 estaban al revés.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Nocturno en 06 de Marzo de 2012, 15:19:21
Estupendo, me alegro que lo tengas.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 07 de Marzo de 2012, 10:19:39
Hola Picuino, bueno hice el calculo que me pediste y al corriente que medi fue de 66 mA...bueno entonces creo que el dato de la corriente nominal del motor que me dieron no era la correcta verdad???
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 11:46:03
Puede que esté mal el dato de corriente o el dato de tensión:

Si con 1 voltio circulan 0.066 Amperios
con 30 voltios circularán 1.98 Amperios de corriente máxima
con 60 voltios circularán 3.96 Amperios de corriente máxima

Una de dos, o el motor tiene 2Amperios de corriente máxima o tiene 60voltios de tensión máxima.


La resistencia del motor es de:

   Rm = 1v /0.066 A = 15 ohmios


El motor es muy "blando" y por lo tanto más difícil de controlar.


La potencia mecánica máxima será:

               V^2
   Pm = -----------   (Máxima potencia mecánica)
              4 · Rm

   Para 30v ->  Pm = (30v ^ 2) / (4· 15 ohm) = 15 vatios

   Para 60v ->  Pm = (60v ^ 2) / (4 · 15 ohm) = 60 vatios


Si pones una foto del motor al lado de una regla (para saber el tamaño) se puede estimar su potencia.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 12:12:01
También puede ser util conocer las pérdidas mecánicas.

¿Podrías hacer un ensayo para conocer las pérdidas de tu motor?

Consiste en alimentar al motor con diferentes tensiones y medir la corriente que consume.
Las tensiones pueden ser por ejemplo 2v, 5v, 10v, 20v y 30v
El rotor se deja girar libremente (sin freno).

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 07 de Marzo de 2012, 12:43:38
Hola PICUINO, pude encontrar datos acerca del motor que utilizo son estos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 12:57:17
Hola amyver,
Parece que el archivo RAR tiene un error porque no puedo abrirlo.

Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 07 de Marzo de 2012, 13:05:18
Hola amyver,
Parece que el archivo RAR tiene un error porque no puedo abrirlo.

Saludos

Bueno aqui va otra vez.. busco la forma de enviarte las imagenes
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 16:07:55
Ya puedo verlos.
No aparecen las características eléctricas. Solo veo el tamaño y velocidad de giro.

Por el tamaño se parece a esta serie de motores Maxon:
http://docs-europe.electrocomponents.com/webdocs/0111/0900766b80111e3b.pdf

Los modelos más parecidos son los de 30 y 36 voltios.
El de 36 voltios tiene estas características:
   R motor = 16.6 ohmios
   Corriente de arranque = 2.17 A
   Corriente máxima en continuo = 0.67 A
   Corriente sin carga = 50mA
   Potencia mecánica nominal = 15 vatios
   Potencia mecánica máxima = 18.6 vatios
   Constante de tiempo mecánica = 20 ms
   Inductancia = 2.44mH


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 16:12:55
El problema de control que tienes a altas velocidades puede que esté relacionado con la resistencia del motor y la tensión máxima de alimentación.
Deberías poner un led que se encienda cuando el ciclo PWM llege al límite máximo para comprobarlo.

Si quieres que el motor funcione a 25000rpm, la tensión back-emf (Eg) deberá ser de unos 21.4 voltios la corriente de alimentación sin carga será de unos 50 mA y la tensión de alimentación del motor (Vm) será:

   Vm = Eg + Rm·I = 21.4 + 15 · 0.050 = 22.2 v

(http://sites.google.com/site/picuino/_/rsrc/1328708571225/motor_speed_control/Modelo_simplificado_motor_cc.png?height=224&width=400)

Si ahora el motor pasa a tener carga nominal, la corriente aumentará a 0.7 Amperios:

   Vm =  Eg + Rm · I = 21.4 + 15 · 0.7 = 31.9 v

Como la tensión máxima de alimentación es de 30 voltios, el motor no se puede mantener a 25000 rpm con carga nominal y bajará su velocidad.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 16:47:13
Hola de nuevo amyver,

Otro tema es el par máximo de tu motor. Al tener mucha velocidad, el par debe ser pequeño.


La constante del motor es aproximadamente:

  w = 35000rpm = 3665 rad/s

  Km  = w / Eg = 3665 / 30v = 122 rad / (s·v)


El par nominal es:
La corriente máxima debe estar en torno a los 0.7 amperios

   N = I / Km = 0.7  / 122 = 0.0057 N·m = 5.7 mN·m = 58 grf·cm

Este es un par pequeño. El motor tiene una fuerza de unos 290gramos en el borde de una fresa de 4mm de diámetro.


El par máximo es:
En el arranque la corriente puede llegar a 2 amperios y el par se multiplica por tres.

   N = I / Km  = 2 / 122 = 0.016 N·m = 16 mN·m = 167 grf·cm


Fórmulas:

Modelo equivalente del motor de corriente continua (http://sites.google.com/site/picuino/motor_equivalent_model)


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 07 de Marzo de 2012, 16:59:39
Gracias de nuevo PICUINO muy explicativo   ((:-)) ((:-)) ((:-))

saludos..
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 07 de Marzo de 2012, 18:00:56
Mejoras en el programa de control:

1.- Estimar la corriente del motor
Con el valor del PWM se puede estimar Vm, la tensión de alimentación motor
Con el valor  back-emf se puede estimar la tensión interna del motor
La diferencia de tensiones dividido entre la resistencia del motor es la corriente del motor.

  I = (Vm - Eg) / Rm = (Vm - back_emf) / 15


2.- Limitar la corriente del motor
La corriente no debería pasar de 0.7 amperios en régimen continuo.
La corriente puede ser mayor, pero durante un periodo corto de tiempo (10 - 15 segundos)


3.- Aumentar la tensión de alimentación del puente a 40 voltios.
La tensión back-emf nunca debe superar los 30 voltios para que el motor no gire demasiado deprisa.
Pero en el caso de tener carga nominal, la alimentación puede estar en 40v y la tensión interna back-emf en 30v. Así puedes conseguir mantener la velocidad máxima con carga nominal.

El motor no se calienta por la tensión que recibe, sólo se calienta con la corriente. De forma que mientras la corriente esté limitada, el motor no se va a quemar.


Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 08 de Marzo de 2012, 17:24:26
Estoy probando el hardware de la placa PCB que he montado con un L6203.
Voy a hacer algunos cambios para mejorarla y corregir errores.
Después la publicaré.

Cuando acabe con el Hardware me voy a meter con el software de control del motor.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 11 de Marzo de 2012, 10:02:16
He publicado el circuito y PCB del regulador de velocidad de motores dc:

   https://sites.google.com/site/picuino/dc_motor_regulator

Por ahora tengo un problema con el detector de corriente de pico:

El operacional tiene una respuesta muy lenta para empezar a conducir.

Si monto el LM358 como seguidor de tensión, la salida es muy rápida, casi igual a los pulsos de corriente
Pero el montaje detector de pico hace que la salida del operacional esté a cero la mayor parte del tiempo.
Cuando tiene que volver a subir la tensión de salida, el operacional casi tarda ¡ 10us en comenzar a conducir !.

¿Alguien conoce un operacional rápido con entrada y salida referidas a masa?

¿Algún circuito detector de pico que funcione?


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 14 de Marzo de 2012, 13:18:51
Buenas a todos, bueno pues comentarles que logre que el motor funcione decentemente   :mrgreen: :mrgreen: :mrgreen: :mrgreen:

bueno es un poco de codigo adicional por ahi que funciono bastante bien, claro que sin el sensado de corriente, bueno incluyo el codigo abajo.
Código: [Seleccionar]
/****************************************************************************
By: Amyver - Foro TODOPIC
*****VERSION 2_1B*****
Funciones:
*Modulo controlado atravez del interface USART
*Modulo usado CCP1
*El programa controla velocidad de un motor DC
 en dos sentido de giro, con la particularidad
 de mantener la velocidad constante ante cambios bruscos de carga
 
*Se soluciono el problema del reseteo del Micro usando
 amplificadores operacionales configurados como seguidores de voltaje
 dichos amplificadores fueron conectados a las salidas de los pines
 de -CCP1- -Control de Giro- y -Enable-
 ****************************************************************************/
#include <16F877A.h>
#device adc=10             //Definimos un Conversor Analogo/Digital con resolucion de 10 bits
#Fuses XT, NOWDT, NOPROTECT, NOLVP, PUT, BROWNOUT, NOCPD, NOWRT//palabra de configuracion
#Use delay(clock=4000000)  //usando un oscilador de 4MHz
#Use RS232(Baud=9600, Xmit=Pin_C6, Rcv= Pin_C7, Parity=N, Bits=8)

#Use Fast_io(B)
#Use Fast_io(C)

#Byte PortB=0x06
#Byte PortC=0x07

char var;
signed int16 senialError=0;
signed int16 lecturaBackEmf=0,fijarVelocidad=0,valorPWM=0;

int1 flagReversa=0,flagMicroMotor=0;
////////////////////////////////////////////////////////////////////////////////
void incrementarVelocidad()
{
 flagMicroMotor=1;         //bandera de señalizacion de motor ON

 OutPut_High(Pin_C5);      //Habilitamos el driver L6203

 fijarVelocidad+=20;       //incrementamos la velocidad en 300
 
 if(fijarVelocidad>=1000)  //pregutamos si se llego a la velocidad tope hacia adelante
 {
  fijarVelocidad=1000;     //se fija una velocidad tope
 }
printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);    
}
void cambiarGiroMotor()       //preguntamos si se pulsa el boton reversa en PANEL o PEDAL
{
 flagReversa++;
  
 if(flagReversa)                   //si hay Reversa
 {
  printf("\r\n\r\nGIRO IZQUIERDO MOTOR\r\n   ");
  if(flagMicroMotor==1)            //preguntamos si el MicroMotor esta en funcionamiento
  {
   OutPut_Low(Pin_C5);             //Deshabilitamos el motor (PARADA)
   delay_ms(2000);                 //tiempo prudente para el frenado del motor
   OutPut_High(Pin_C5);            //Habilitamos el motor (GIRO)
    
   set_pwm1_duty((int16)0);        //se inicializa el PWM en Cero      
  }
  OutPut_High(Pin_C4);             //Cambiamos el sentido de giro del Micro Motor
 }
 else
 {
  printf("\r\n\r\nGIRO DERECHA MOTOR\r\n   ");
  if(flagMicroMotor==1)             //preguntamos si el MicroMotor esta en funcionamiento
  {
   OutPut_Low(Pin_C5);              //Deshabilitamos el motor (PARADA)
   delay_ms(2000);                  //tiempo prudente para el frenado del motor
   OutPut_High(Pin_C5);             //Habilitamos el motor (GIRO)
    
   set_pwm1_duty((int16)0);         //se inicializa el PWM en Cero          
  }
  OutPut_Low(Pin_C4);               //Cambiamos el sentido de giro del Micro Motor
 }
}
void pararMotor()                   //Funcion que recudira a cero la velocidad del Auto IR
{
 flagMicroMotor=0;                  //señalizamos motor Apagado

 OutPut_Low(Pin_C5);                //Deshabilitamos el motor (PARADA)
 delay_ms(2500);
 valorPWM=0;                        //actualizamos la variable
 set_pwm1_duty(valorPWM);           //se inicializa el PWM en Cero  
 fijarVelocidad=0;                  //Establecemos la velocidad en cero
 
 printf("\r\n\r\nPARAR MOTOR=%Ld\r\n   ",fijarVelocidad);
}
////////////////////////////////////////////////////////////////////////////////
void verificarRS232()
{
  if(kbhit())
  {                  // Si hay algo pendiente de recibir ...        
   var=getc();
        
   if(var==0x0D)     //preguntamos si se presiono Enter
   {
    incrementarVelocidad();    
   }
   if(var==0x08)     //preguntamos si se presiono retroceso
   {
      cambiarGiroMotor();
   }
   if(var==0x20)     //preguntamos si se presiono retroceso
   {
    pararMotor();
   }
  }
}
void testearBackEmf()
{
 delay_ms(7);         //tiempo que se enviara la señal PWM
  
 OutPut_Low(Pin_C5);   //Enable Motor OFF
 delay_ms(1);          //tiempo de espera para que la señal Back-emf se estabilice
  
 Set_adc_channel(1);   //selecion de canal 0
 delay_us(50);         //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();  //lee el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 printf("\r\nLectura BACK-EMF=%Ld",lecturaBackEmf);
 OutPut_High(Pin_C5);  //Enable Motor ON
}
void ajustarVelocidad()
{
 signed int16 Control_I, KI;
 signed int16 fijarVelocidadAux=0;

 senialError= fijarVelocidad-lecturaBackEmf;
 fijarVelocidadAux=fijarVelocidad;

 printf("\r\nSenial de Error=%Ld",senialError);

 if((fijarVelocidadAux>=0)&&(fijarVelocidadAux<=100))//Estabelecemos una Ganancia alta para bajas velocidades
 {                                                   //para lograr una respuesta Rapida
  KI =10;          // Ganancia integral
 }
 else if((fijarVelocidadAux>100)&&(fijarVelocidadAux<=600))
 {                                                   //para lograr una respuesta Lenta
  KI = 2;         // Ganancia integral
 }
 else
 {
  KI = 1;         // Ganancia integral
 }

 Control_I = (senialError * KI) / 8;
 valorPWM += Control_I;

 if(valorPWM>=1000)
  valorPWM=1000;
 if((valorPWM<20))
  valorPWM=0;
  
 set_pwm1_duty((int16)valorPWM);                  //se inicializa el PWM en Cero  
 printf("\r\n\r\nValor del PWM=%Ld\r\n   ",valorPWM);
}

void main()
{
 Set_Tris_B(0b11111110);
 Set_Tris_C(0b10001011);

 PortB=0x00;                        //limpiamos el puertoB
 PortC=0x00;                        //limpiamos el puertoC

 OutPut_High(Pin_B0);               //senializacion de pic ON

////////////////////////////////////Configuracion de CCPx(PWM)/////////////////////////////////////////////////
 setup_timer_2(T2_DIV_BY_1,249,1); //configuramos el timer2, Prescaler=1,Periodo=249,Postcaler=1
                                   //con lo que se conseguira: T=50us o f=20Khz
                                   //"setup_timer_2(Prescaler,Periodo,Postcaler)"
 setup_CCP1(CCP_PWM);               //Escogemos el modo de trabajo de CCP1, lo escojemos como modulacion por ancho de pulso
//setup_CCP2(CCP_PWM);               //Escogemos el modo de trabajo de CCP2, lo escojemos como modulacion por ancho de pulso
                                    //NOTA.- Tanto para PWM1 y PWM2 el periodo es establecido por el timer2
// set_pwm2_duty((int16)value);     //NOTA2.-la resolucion maxima esta dada por: Tpwm=2´(n) * 1/Fosc
                                    //                                           50us=2´(n) * 1/4´(6)
                                    //                                           2´(n)= 200
                                    //Entonces el maximo valor que podemos cargar a "value" es de 200, con lo que se
                                    //conseguira un ciclo de trabajo de 100%
////////////////////////////////////Configuracion de CAD////////////////////////////////////////////////////
 setup_adc(ADC_CLOCK_INTERNAL);     //Se usara un reloj interno
 Setup_adc_Ports(AN0_AN1_AN3);              //A0
////////////////////////////////////////////////////////////////////////////////////////////////////////////
 set_pwm1_duty((int16)0);         //se inicializa el PWM en

 OutPut_High(Pin_C5);             //Enable Motor ON
 
 printf("\r\nSystem OK.\r\n");    //Sistema en linea y listo para transmitir

 while(true)
 {
  verificarRS232();
  testearBackEmf();
  ajustarVelocidad();
 }
}

Tambien incluyo el archivo de simulacion y el .hex....

Bueno ahora tengo otra inquietud en la cual quisiera un poco de ayuda....es la siguiente:

* Resulta que el motor efectivamente intenta conservar una velocidad constante ante cambios bruscos de carga.....hasta ahi OK..
* Pero como podria implementar una alarma o un pitido que me indique que el motor llego al tope de su fuerza y pararlo para que no se dañe dicho motor???

Bueno sobre este punto estaba pensando usar la lectura de corriente del integrado L6203, pero como dije antes no tengo muy claro su funcionamiento :(  

Saludos....

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 14 de Marzo de 2012, 15:10:02
Hola amyver.
Estos días atrás he estado ocupado con el hardware, fabricando una placa con el L6203:

http://sites.google.com/site/picuino/dc_motor_regulator

También he estado dando vueltas al circuito de sensado de corriente porque me daba problemas.

El caso es que ahora voy a meterme a fondo con el software y el control.

El sensado de corriente del que me hablas se puede realizar sin resistencia de sensado en el L6203:

   1º   Medir la tensión de alimentación del puente Vdd (midiendo la tensión del motor mientras está conectado a Vdd)

   2º   Calcular la tensión de alimentación al motor  Vmotor
         Vmotor = Vdd · D
         D =  ciclo de trabajo del PWM de 0 a 100%

   3º   Medir la tensión interna del motor Eg o back-emf

   4º   Estimar la corriente que circula por el motor:

         Imotor = (Vmotor - Eg) / Rmotor

         Rmotor =  Resistencia del motor en ohmios


Ejemplo de estimación de la corriente del motor con aritmetica de enteros:
En este caso hay que ajustar las unidades para que entren en un número de 0 a 65536:

Código: [Seleccionar]
   Rmotor = 156;                                 // (Rmotor + Rtransistores) · 10 = (15 + 0.6) · 10 = 156
    Vdd = 950;                                    // Vdd = 950 · 32v / 1023ptos = 29.7 voltios.  Cuando ADC=1023 el puente está a 32 voltios.
    D = 325;                                      // Ciclo de trabajo de 0 a 1000

    Vmotor = (Vdd/4) * (D/4);                    // Vmotor = 19197  = 9.65 voltios
    Eg  = 150;                                   // Eg = 150 · 32v / 1023ptos = 4.69 voltios.
    Vrm  = Vmot - Eg*62;                         // Vrm = 19197 - 9300 = 9897 = 4.96 voltios.  (caída de tensión en la resistencia del motor)
    Imotor = (Vrm / Rmotor)*81/16;              // Imotor = (9897 / 156)*81/16 = 318 = 0.318 Amperios

El último número que multiplica (81) es un factor de conversión para obtener la intensidad del motor en miliamperios. Depende de la aritmetica de enteros utilizada y del divisor de tensión del puente. Quizá lo más práctico es afinar ese número midiendo con un polímetro la corriente por el motor y ajustando hasta que Imotor coincida con el polímetro.

También se puede sustituir la ecuación por un valor de Rmotor ajustado:

    Imotor = (Vrm / Rmotor);         (en este caso Rmotor debe valer 31 y no se parece en nada a la verdadera resistencia del motor)

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 21 de Marzo de 2012, 11:10:03
Hola PICUINO...

Aqui a la espera de tus avances....seguro nos sorprenderas :-/ :-/ :-/ :-/

Saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 21 de Marzo de 2012, 11:23:14
Hola amyver,
Estos días he estado fuera y un poco ocupado, de manera que no me he puesto con el control del motor.
Este fin de semana estoy pensando en dedicarle unas horas y terminar algo que se pueda presentar.

Estoy poniendo en marcha también una placa de desarrollo con un dsPIC que creo que será perfecta para controlar motores y experimentar.
El micro tiene conversor ADC con un millón de muestras por segundo  :shock: y módulo DSP con el que se puede hacer simulación e identificación de sistemas en tiempo real (para control avanzado).

También estoy pensando cómo se podría identificar la resistencia del motor para no tener que meterla como parámetro y que el controlador se adapte después de cada reset al motor que esté conectado en cada momento. No consigo encontrar una solución sin utilizar el sensor de corriente.

Se me ha ocurrido también otra forma de rectificar la señal de pico de la resistencia sensora de corriente. Es muy sencilla, sin amplificadores operacionales, y podrías ponerla en marcha en tu proyecto.

Mientras tanteo si quieres te puedo echar una mano con el limitador de corriente para tu motor.

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 21 de Marzo de 2012, 11:38:41
Magnifico PICUINO, todas las ideas que tienes superan por mucho las que se me ocurren a mi  ((:-)) ((:-)) ((:-)) ((:-))

y si... porfa dame una mano con el limitador de corriente para mi motor. :)

saludos..
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 21 de Marzo de 2012, 11:46:05
Bien puedes empezar midiendo la tensión del puente con el PIC.

¿Cómo es el esquema que utilizas?

¿Cuantos puntos mide tu ADC cuando mides tensión mientras el puente está conectado?

Puedes conectar el puente durante 20us (Enable = 1)
comenzar la conversión ADC
Desconectar el puente (Enable = 0)
Leer la conversión ADC cuando termine.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 21 de Marzo de 2012, 12:53:31
Hola picuino, bueno con respecto al punto
Citar
Bien puedes empezar midiendo la tensión del puente con el PIC.

Te refieres a la medida de tension luego del divisor de  tension con resistencias que puse en mi esquema???

(http://s2.subirimagenes.com/otros/previo/thump_7552505divisortension.jpg)

y sobre el esquema que utilizo, quieres decir el esquema para la toma de corriente????
bueno si es asi, por el momento no hago ninguna lectura de corriente...

y sobre:
Citar
¿Cuantos puntos mide tu ADC cuando mides tensión mientras el puente está conectado?

Código: [Seleccionar]
void testearBackEmf()
{
 delay_ms(10);         //tiempo que se enviara la señal PWM
 
 OutPut_Low(Pin_C3);   //Enable Motor OFF
 delay_ms(1);          //tiempo de espera para que la señal Back-emf se estabilice
 
 Set_adc_channel(0);   //selecion de canal 0
 delay_us(50);         //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();  //lee el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 OutPut_High(Pin_C3);  //Enable Motor ON
}

Voy llamando a la funcion de manera continua, pero solo hago el control cuando el usuario asi lo requiera (cuando el usuario pulsa un pulsador)

y sobre.
Citar
Puedes conectar el puente durante 20us (Enable = 1)
comenzar la conversión ADC
Desconectar el puente (Enable = 0)
Leer la conversión ADC cuando termine.

armare el circuito y te comentare resultados...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 21 de Marzo de 2012, 17:43:50
Si, me refiero a leer la entrada Analog cuando el puente está conectado:

Código: [Seleccionar]
signed int16 Analog;

void ADC_Analog_read(void)
{
   // Conectar el puente
   Set_adc_channel(0);               // selecion de canal 0
   set_pwm1_duty((int16)1001);  // PWM siempre a uno
   OutPut_High(Pin_C3);             // Enable Motor ON

   // Medir el valor de tensión
   delay_us(5);                          // Retardo para que se carge la senial analogica
   Analog = read_adc();             // Lee el resultado de la conversion y se guarda en nuestra variable de 16bits 


   // Dejar el puente en los valores originales
   OutPut_LowHigh(Pin_C3);       // Enable Motor OFF
   set_pwm1_duty((int16)valorPWM);
}


Saludos
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 26 de Marzo de 2012, 10:22:37
Estoy haciendo los cambios en el programa para controlar la corriente a partir de la back-emf
Me está llevando más trabajo del que pensaba.
Como tenía problemas para interpretar los valores enteros, he modificado el programa para que utilice números en coma flotante.

También he tenido que modificar el esquema eléctrico y reducir el condensador C8 para que la medida de tensión varíe con rapidez. En caso contrario había que conectar la alimentación durante mucho tiempo para medir la tensión del puente y la corriente por el motor subía demasiado.

Cuando tenga resultados los posteo.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 28 de Marzo de 2012, 15:40:21
Bueno, por fin solucioné el problema que tenía con la detección de corriente. Si hubiese un smiley sudando lo pondría.
Me ha costado bastantes pruebas, pero al final ha merecido la pena.
Cambiando el operacional a un CA3240 el circuito detector de pico de corriente funciona a la perfección.

Es bastante importante que funcione Ok el detector de pico para poder contrastar los resultados de cálculo de corriente por back-emf con la corriente verdadera.

Ahora puedo seguir con las pruebas.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 01 de Abril de 2012, 17:49:04
Hola amyver, estoy estudiando el regulador del motor.
Ahora el problema que tengo es el ruido de la señal back-emf.
Si la filtro, la respuesta es lenta y si no la filtro, la respuesta oscila mucho.

Espero tener un controlador dentro de poco y publico el programa.

¿Que tal vas tú con el proyecto?

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 02 de Abril de 2012, 10:38:55
Hola master PICUINO...  :mrgreen: (espero no te moleste lo de master, lo dije con mucho respeto y admiracion por tus aportes)
En cuanto al ruido de la señal back-emf, trabajando con mi motor era considerable  :angry:, pero me di cuenta que trabajando con el ultimo programa que publique (con el control que me sugeriste) los valores que tomaba de dicha señal mantenian una velocidad en el motor relativamente constante.... :grin:

asi que como funcionaba relativamente bien :laugh: decidi dejarlo en un version 1.0....no quise meterle mas mano hasta que mis conocimientos sobre motores y control superen un poco mas mientras tanto dedicandome a hacer otros proyectos e ir con calma en esto de los motores..

saludos....

Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Abril de 2012, 12:12:50
Me alegro de que estés contento con los resultados.
Recuerdo que querías limitar la corriente del motor. Yo estoy detras de ello y ya he conseguido resultados. Cuando lo pula un poco (el problema está en el ruido que ya he comentado) lo publicaré para que lo puedas utilizar.

Si con master te refieres a que has aprendido de mis aportes, me alegro mucho que para eso estamos en el foro.

Un saludo.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 02 de Abril de 2012, 12:22:42
Me alegro de que estés contento con los resultados.
Recuerdo que querías limitar la corriente del motor. Yo estoy detras de ello y ya he conseguido resultados. Cuando lo pula un poco (el problema está en el ruido que ya he comentado) lo publicaré para que lo puedas utilizar.

Si con master te refieres a que has aprendido de mis aportes, me alegro mucho que para eso estamos en el foro.

Un saludo.

Pues si PICUINO, en el foro y con tu ayuda me entere de que existia una Back-Emf, y que existia una forma de controlar la velocidad de un motor ademas de los encoders...

saludos..
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 02 de Abril de 2012, 14:34:34
Hola amyver
Me gustaría ayudarte para que consigas limitar la corriente máxima del motor.

Yo lo he conseguido ya y funciona bien. Si intentas frenar el motor la corriente no sube de 2 amperios, el motor no se quema y la placa tampoco.

Un saludo.
  
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 03 de Abril de 2012, 09:21:26
Oh, que bien picuino lo lograste exito!!!!  :-/ :-/ :-/

Claro que acepto tu ayuda gracias  :-) :-)

Bueno me parece que lo que hay que hacer es tomar las lecturas de corriente del integrado L6203 transformarlas a voltaje con un circuito adicional y posteriormente tomar dichas lecturas con el modulo ADC del pic verdad???

Leyendo tus post anteriores me pude dar cuenta que se estaba utilizando un AmpOp para tomar las señales del L6203 y amplificarlas hasta un nivel adecuado verdad??

Y una vez teniendo dichas lecturas sera tarea del pic procesar la informacion y tomar las acciones que se desee....

bueno dime si lo que entendi es lo correcto....

saludos...
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 03 de Abril de 2012, 09:31:05
No es necesario tomar lecturas de corriente, es mucho más sencillo si lo que quieres hacer es sólo limitar la corriente máxima.

La base de todo es que la tensión de alimentación del motor (Vm) sea sólo un poco mayor que la lectura de back-emf (en la figura Eg) para que la corriente no sea muy alta:


   Vm = Eg + Rm · I


por ejemplo para limitar a  1 amperio con una resistencia de motor de 5 ohmios que devuelve una back-emf de 10voltios:

   Vm = 10 volt + 1 Amperio · 5 ohm = 15 volt


   En este caso con una back-emf de 10 voltios, si alimento con 15 voltios como máximo, la corriente no aumentará más de 1 amperio.
   Hay que calcularlo en cada ciclo.


(http://sites.google.com/site/picuino/motor_speed_control/Modelo_simplificado_motor_cc.png)


Lo de medir la corriente es para hacer otro tipo de control con el que estoy experimentando y que es distinto del control back-emf.

Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: amyver en 04 de Abril de 2012, 11:15:04
Hola PICUINO, muy buena la tecnica que describes....

Entonces puedo realizar el calculo de  Vm = Eg + Rm · I  cada vez que tome una lectura de la Back-Emf???
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 04 de Abril de 2012, 12:36:08
Si, eso es.

De esta forma la corriente se limita en una centésima de segundo. No da tiempo a que se queme el puente en H ni el motor.


Saludos.
Título: Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
Publicado por: Picuino en 06 de Abril de 2012, 11:29:32
He encontrado un método que elimina casi todo el ruido de la medición de tensión back-emf  :-/ :-/ :-/

Es muy sencillo. Consiste en realizar mediciones de tensión back-emf continuamente durante el apagado del motor y quedarse con la mayor de todas:

Código: [Seleccionar]
  for (i=0; i<100; i++);          // Esperar un tiempo a que la tensión se estabilice

   Vmax = 0;
   for (i=0; i<10; i++) {          // Realizar diez mediciones de back-emf
      V = medir_back_emf():
      if (V>Vmax)  Vmax = V;       // memorizar la medición mayor
   }
   return Vmax;

El número de mediciones (entre 10 y 20) se debe escoger para que dure en torno a un milisegundo. Si este tiempo es mayor que la duración de una conmutación de escobilla (unos 0.2 milisegundos) entonces el ruido de conmutación de escobilla desaparece.


Saludos.