TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: groundman en 14 de Mayo de 2017, 11:21:05
-
hola.estoy realizando un proyecto para el control de servos con el circuito Pca9685.he conseguido comunicarme con el circuito por i2c.
y queria explicar aqui su funcionamiento hasta donde mi entendimiento pueda llegar.
el circuito se controla con diferentes registros.
hay dos registros: MODE1 y MODE2 son registros de control.
otros tres SUBADR1,SUBADR2,SUBADR3 registros de direccionamiento programables.
otro ALLCALLADR es para programar todos los dispositivos que hayan en el bus i2c.
tambien estan los registros FAh,FBh,FCh,FDh para gestionar el PWM para todas las salidas a la vez.
(FEh) PRE_SCALE: registro para la frecuencia de salida.valor 0=650uS en un ciclo del 50%. valor 255=42mS en un ciclo del 50%.
otros registros independientes para cada salida.que van desde la direccion 06h hasta la 69h (LED0 a LED15)
los registros que van desde la 06h hasta la 69h son registros para gestionar los tiempos de cada salida individualmente.
gestionan desde el pin LED0 al LED15
los tiempos de cada salida son gestionados por cuatro registros.pondre el ejemplo del LED0
registro de 16bit para el control de estado de salida HI
06h LED0_ON_L
07h LED0_ON_H
registro de 16bit para el control de estado de salida LO
08h LED_OFF_L
09h LED_OFF_H
en estos registros podemos poner un valor entre 0 y 4095 decimal.LED_ON lo que hace es lo siguiente:
tenemos que imaginarnos que hay una linea de tiempo donde hay un principio y un final.esta linea de tiempo esta dividida en 4096 puntos.estos espacios
los numeraremos desde el 0 al 4095.
al meter en el registro LED_ON un valor entre 0 y 4095 lo que hacemos es indicarle al chip.en que espacio el led lo pondremos a estado alto.
lo contrario pasa con el registro LED_OFF.que desde que la salida se puso a nivel alto le indicaremos al chip cuantos espacios lo pondremos
a nivel bajo.
el problema radica en que tenemos que respetar los 4095 espacios.y el tiempo que valla a estar a nivel alto se lo tenemos que restar del que va a estar a
nivel bajo.si no se invertira la onda.
si queremos empezar en estado alto y modular desde ahi.el valor para LED_ON seria 0.y para LED_OFF seria entre 0 y 4095d
si queremos empezar en estado bajo.y modular desde ahi.el valor de LED_ON estaria entre 0 y 4095d y LED_OFF lo pondriamos a 4095d.
para una onda cuadrada de 50% empezando en alto seria 0 para LED_ON y 4095 para LED_OFF
por defecto el ciclo dura 5.08ms.si no configuramos el registro PRE_SCALE
COMUNICACION I2C:
ahora explicare algunos comandos que hay que enviar por el buss I2C.
S:start
A:acknowledge
P:stop
trama enviada: S 80 A 00 A 10
este comando envia al circuito el valor 80. '10000000' este valor es la direccion del dispositivo.en este caso los pin A0 a A5 deben de estar a masa.
FE ocupa el registro del comando.y pertenece al registro MODE1.
10 es el dato.en este caso le estamos dando el valor del reset.
trama enviada: S 80 A FE A 79 A P
este configura el registro (FE)PRESCALE con el valor 79h que son unos 200ms. bueno para el control de servos.
estos ponen todas las salidas a un valor PWM al 50%. por los valores ALL_LED_ON_L=00, ALL_LED_ON_H=00, ALL_LED_OFF_L=00, ALL_LED_OFF_H=08
S 80 A FA A 00 A P
S 80 A FB A 00 A P
S 80 A FC A 00 A P
S 80 A FD A 08 A P
Hay varias formas de escribir y leer por el buss I2C.hay otras formas de enviar los comandos y datos por el sistema de autoincremento.
pero estoy intentando leer el Pca9685 y no me sale.en el datasheet no esta muy claro.ya que en el diagrama cortan la trama y deben creer
que damos por sentado algo que no esta ahi.no explica si hay que escribir en todos los registros de control para recibir los datos
despues del Sr.
por ejemplo:
yo envio la sigueinte trama: 80 A 00 A 20 A Sr 81 A 11 N
80 es la direccion del dispositivo.00 es el registro al que le escribo el valor 20.que es el autoincremento.luesgo esta el restart.
envio 81 como direccion e indicando que voy a realiar una operacion de lectura.envio la rutina de lectura Read_I2C.y recivo el valor 11
pero en las siguentes rutinas de lectura solo recivo N FF N FF N FF....
no se que hago mal.y ya llevo un dia perdido.por no entender el datasheet o por no estar bien explicado.
-
me acabo de dar cuenta de algo.y es que aunque en el datasheet no se explica la secuencia de lectura de un registro especifico.puede hacerse asi:
escribimos el dato 08 en el reistro MODE1
"80 A 00 A 08 A P"
y lo leemos:
"80 A 00 A Sr 81 A 08 A P"
80= direccion escritura
00= registro MODE1
81= direccion lectura
08= dato leido
pero se me esta dando el caso de que tengo que leerlo dos veces para ver el valor 08. de momento no se lo que sera.he puesto varios delays pero nada.
respecto al autoincremento todabia estoy atrancado.
-
en la figura 22 del datasheet indicca esto: AI initially clear
creo que dice que inicialmente AI "bit de autoincremento" debe de esta a cero.y despues con la secuencia de lectura lo pondriamos a 1. asi:
S 80 A 00 A 20 A Sr 81 A xx A xx A xx A xx A....NAK P
pero es posible que por el problema que tengo con tener que leer dos veces los registros.el bit de autoincremento no se active.y esto no funcione.
haber como lo soluciono....
-
bueno.las pruebas que estoy realizando es en el proteus.y puedo leer y escribir.pero en registros de uno en uno.no he podido hacer que funcione el autoincremmento.
podria ser un fallo del proteus.por eso intentare hacerlo de forma fisica.haber si puedo controlar los servos con el autoincremento.esto es para agilizar la comunicacion.
no he visto librerias de arduino ni otras que pudiera ver como realizan esta comunicacion con el autoincremento.
aunas malas pues realizare el control escribiendo o leiendolos de uno en uno.
-
hola de nuevo.he podido realizar una simulacion con el proteus y funciona.pero solo en la simulacion.en la parte hardware no va.
la direccion que he tenido que meter es la 80 para escritura y 81 para lectura.los pin de direccion del pca9685 estan a masa.
ya que no me ha funcinado la parte de hardware.me he decidido a montar un arduino uno.y ejecura ell ejemplo de los servos.
he puesto un analizador logico en las lineas SDA y SCL.y he sacado esto:
Trafico I2C arduino
Write 40 A 0C A 0C N
Read 41 A EA A EA N
Read 49 A 1A A 1A N 01 02
Read 49 A 57 A 57 N 03
Write 40 A 10 A 10 N
Read 41 A F2 A F2 N 04
Read 49 A 20 A 20 N 05 06
Read 49 A 6E A 6E N 07
Write 40 A 14 A 14 N
Read 41 A ED A ED N
Read 49 A 0B A 0B N 08 09 0A
Read 49 A 37 A 37 N 0B
Write 40 A 18 A 18 N
Read 41 A EE A EE N
Read 49 A 3A A 3A N 0C 0D
Read 49 A 74 A 74 N 0E
Write 24 N
Write 40 A 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 38 A 38 N
Read 49 A 4F A 4F N 17 18
Read 49 A 52 A 52 N 19
Write 40 A 28 A 28 N
Read 41 A 17 A 17 N 1A
Read 49 A 43 A 43 N 1B 1C
Read 49 A 7A A 7A N 1D
por lo que veo en el codigo.parece que esta hecho para comunicarse con dos esclavos. de ahi las direcciones 40,41 y 49.
se reciben los acknowledge.lo que no entiendo es que no veo secuencias de STOP en las tramas.y no se porque salen los NAK.
en la simulacion solo salen cuando se envia un comando no reconocido.
tendre que hacer mas pruebas.
-
Por lo visto cometi un error con el analizador logico.esto es lo que realmente se recibe de las llineas SCL y SDA:
Write 40 A 0C A 0C N
Read 41 A EA A EA N
Read 49 A 1A A 1A N
Read 49 A 57 A 57 N
Write 40 A 10 A 10 N
Read 41 A F2 A F2 N
Read 49 A 20 A 20 N
Read 49 A 6E A 6E N
Write 40 A 14 A 14 N
Read 41 A ED A ED N
Read 49 A 0B A 0B N
Read 49 A 37 A 37 N
Write 40 A 18 A 18 N
Read 41 A EE A EE N
Read 49 A 3A A 3A N
Read 49 A 74 A 74 N
Write 24 N
Write 40 A 1C A 1C N
Read 41 A 28 A 28 N
Read 41 A 16 A 16 N
Read 49 A 5F A 5F N
Write 40 A 20 A 20 N
Read 41 A 4B A 4B N
Read 49 A 24 A 24 N
Read 49 A 71 A 71 N
Write 40 A 24 A 24 N
Read 41 A 38 A 38 N
Read 49 A 4F A 4F N
Read 49 A 52 A 52 N
Write 40 A 28 A 28 N
Read 41 A 17 A 17 N
Read 49 A 43 A 43 N
Read 49 A 7A A 7A N
he estando realizando pruebas con el proteus.resulta que sin conectar ningun pin A0..A5 del PCA9685 la direccion de escritura es la 80 y la de lectura la 81.
si cambio estos pin con varias combinaciones.este responde a diferentes direcciones.asi que la simulacion funciona.
pero no funciona con direcciiones con valor 40.supongo que en el circuito del arduino.previamente se ha configurado el PCA9685 para que funcine
con estas direcciones.
-
esta es otra secuencia que he sacado con el analizador logico.y es desde el principio.cuando se conecta por primera vez.
los datos son diferentes porque uso un direccionamiento de 8bit.en los ejemplos anterires eran de 7bit.un error que cometi con
el analizador logico por no saber usarlo.
S 80 A 00 A 00 P :normal mode
S 80 A 00 A 81 00 N P :lectura del registro MODE1
S 80 A 00 A 10 P :RESET
S 80 A FE A 03 P :configuracion del preescaler
S 80 A 00 A 00 P :normal mode
S 80 A 00 A A1 P :RESET,activar autoincremento,habilita ALLCALL
S 80 A 06 A 00 A 00 A 00 A 00 P :escribe en LED0 el valor 0.
S 80 A 0A A 00 A 00 A 00 A 01 P
S 80 A 0E A 00 A 00 A 00 A 02 P
S 80 A 12 A 00 A 00 A 00 A 03 P
los he introducido en el isis y funciona.incluso el autoincremento.ahora lo probare en el circuito real.haber si hace lo mismo.
-
pues ya consegui hacerlo funcionar.como siempre la insistencia da sus frutos.la verdad es que no he visto ningun codigo en asm para pic.
igual es que soy malo buscando en internet.
en este codigo lo que he hecho es usar el conversor AD de 12bit interno del pic.y pasar los datos al pca9685.como este tambien trabaja
con una modulacion PWM de 12bit.pues le meto los datos directamente por eso se ve en el video que el potenciometro tiene
muy poco rango de regulacion.aunque esto es facil de arreglar con un divisor de tension.
de todas formas la gestion de este circuito con un potenciometro es poco practico.mas que nada es para pruebas.a no ser que alguien quiera
gestionar algo a distancia con esto.pero bueno cada cual le puede sacar probecho de la forma que quiera.
ahora practicare con los registros de control para entender mejor el circuito.y cuando lo tenga ya pondre el codigo.
-
bueno.voy a explicar lo que por encima he entendido del funcionamiento de este circuito.
este circuito despues del envio del comando START.hay que direccionarlo con una direccion que se haya programado mediante el uso
de los pin A0..A5 en el circuito comprado por internet.estos pin estan conectados a masa mediante unas resistencias.y es posible ponerlos a
nivel 1.si soldamos los puentes.
si no soldamos nada,por defecto la direccion es 0x80 para la escritura y 0x81 para la lectura.esto nos da un tatal de 64 direcciones programables.
tambien tenemos 4 registros de direcciones programables.
SUBADR1 0x02
SUBADR2 0x03
SUBADR3 0x04
ALLCALLADR 0x05
estos registros pueden ser leidos y escritos.los valores por defecto son estos:
SUBADR1 =E2h escritura , E3h lectura
SUBADR2 =E4h escritura , E5h lectura
SUBADR3 =E8h escritura , E9h lectura
ALLCALLADR =E0h escritura , E1h lectura
por defecto esto registros estan deshabilitados.para habilitarls hay que poner a 1 los bit correspondientes del registro MODE1.
estos registros tambien pueden ser programados para cambiar sus direcciones.solo hay que escribir en ellos el valor deseado de direccion.
me he vuelto loco intentando hacer que funcionara esto de programar las direcciones.ya que lo intente con el proteus.y parece ser
que este no funciona en la simulacion.
una vez que se envie la direccion.se envia el comando que vallamos a gestionar.luego el dato que queramos ingresar en dicho registro.y Stop
esto seria para una secuencia de escritura.A(acknowledge) es un bit recibido del PCA.
Start,Direccion escritura,Comando,Dato,Stop S xx A xx A xx P
En el caso de querer leer un registro.seria:
Start,Direccion escritura,Registro a leer,Restart,Direccion lectura,Dato recibido,Nacknowledge,Stop S xx A xx A xx Sr xx A xx N P
En el caso anterior se refiere a la lectura de un registro.en el caso de leer o escribir en serie.habria que activar el bit AI(autoincremento)
esto seria una forma de escribir con el autoincremento activado:
S 80 A 00 A 20 A P
S 80 A 06 A 00 A 00 A 00 A 08 A 00 A 00 A 00 A 08......00 A 00 A 00 A 08 P
con la antreior secuencia.estariamos introduciendo los valores LED0_ON_L=00 , LED0_ON_H=00 ,LED0_OFF_L=00 ,LED_0_ON_L=08... a partir del registro
06(LED0) hasta donde paremos la transmision pon P(stop) el valor introducido 00 00 00 08 corresponde a un PWM del 50%
-
bueno.pues ya acabe el programa.lo que hace es gestionar las 16 salidas del Pca9685.mediante las entradas analogicas AN0 a AN15 del pic18f87k22
hace unas semanas encargue unas PCB a china para incluir este chip.y asi crear una placa de control que seria adaptable a cualquier
proyecto que quisieramos diseñar.y asi no tener que crear circuitos especificos que cuando quisieramos añadir alguna modificacion,
no nos sirviera la placa y tubieramos que desoldar el chip para pasarlo a otra placa.el diseño es de menos de 5x5cmt.eso hace que
salga muy varata.a 3€ la unidad.
cuando me llegen pondre el diseño por si a alguien le intersa.y com no,para mejorarla si es posible.
los pin utilizados del pic son:
;Entradas analogicas: remitirse al datasheet.desde AN0 a AN15
;I2C: RC3 SCL1 y RC4 SDA1.
;OE: RC2
en la conexion con la placa del PCA9685 ademas de conectar masa y SDA1,SCL1. he conectado la alimentacion de los motores a un cargador
de movil de 2A 5v
con V+ de la placa del PCA9685 alimentaremos el PIC18f87k22 y de la placa del pic.conectaremos la alimentacion de la logica de control VCC
a la placa PCA9685.tambien podemos alimentar al PIC independientemente.en ese caso no se usara el pin V+ de la placa PCA9685.
pero si tendremos que alimentar VCC desde la placa del PIC18f87k22.
esto seria la conexion de pruebas en proteus
(https://www.4shared.com/img/tklZDvVpca/s25/15c4eb8b1d0/pca9685) (https://www.4shared.com/photo/tklZDvVpca/pca9685.html)
este es el enlace de descarga:
ControlServos18F.X.zip (https://www.4shared.com/zip/L20beHsjca/ControlServos18FX.html)
-
Hola, me sirvió muchisimo en mi primer proyecto con el PCA9685.
Un abrazo y mil gracias por este tema. ((:-))
-
como se puede usar PCA9685 para el pic 16F877A en ccs?