Autor Tema: Tener varios pwm en un pic?  (Leído 4378 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Tener varios pwm en un pic?
« en: 03 de Mayo de 2015, 14:58:02 »
Es posible crear o tener varios pwm en un solo pic?? no encuentro ninguna forma de hacerlo partiendo de la idea que necesito entre 8 y 12, tambien imaginé mandar algunos 555 desde el pic para que me generen el pwm cada uno de los 555 pero tampoco creo poder... entonces acá estoy pidiendo ayuda para intentar tener varios pwm en un solo pic

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: Tener varios pwm en un pic?
« Respuesta #1 en: 03 de Mayo de 2015, 15:10:29 »
Hola mindfield,

puedes tener mas de un PWM en un solo pic, utilizando los timer, tu puedes jugar con sus cargas de tiempo y mantener un pin en alto o bajo en tiempo que desees,

por ejemplo, si lo quieres para 1 servo motor tipico de 20mseg de frecuencia, con un solo timer de 16 bits puedes manejar hasta 8 servomotores, haciendo ventanas de 20 mseg.

tengo un programa por hay guardado que lo hace, pero creo que lo tengo en CCS de hace ya mucho tiempo.

resumiendo, si, puedes tener mas de un PWM en un solo pic usando los timer  y dependiendo de la frecuencia de esos PWM puedes hacer varios usando un solo timer.


un saludo
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Re: Tener varios pwm en un pic?
« Respuesta #2 en: 03 de Mayo de 2015, 15:23:41 »
Hola! gracias por responder! quiero que el micro al recibir ciertos datos via serial (esta parate ya esta andando) el micro entregue en sus salidas el pwm a modo de dimmer ya que es para controlar varias lamparas, lo que no entiendo es que si tengo timer0, timer1, timer2 como voy a hacer para que funcionen 8 dimer o salidas con pwm con solo 3 timer?; Tambien estoy usando CCS..
« Última modificación: 03 de Mayo de 2015, 15:33:24 por MINDFIELD »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: Tener varios pwm en un pic?
« Respuesta #3 en: 03 de Mayo de 2015, 15:40:30 »


de esta manera (esto es para servos pero la idea es la misma), dependiendo de la frecuencia que le quieras dar a tu pwm (en el caso del ejemplo 20 mseg) y lo divides por el numero de ventanas que quieras usar (en el ejemplo 8 de 2,5 ms), nada mas empezar el timer pones un pin a 1 y lo mantienes el tiempo que quieras en alto, digamos 1 mseg por ejemplo, y luego lo apagas, calculas lo que resta de ventana, 2,5-1 = 1,5 mseg, despues de ese tiempo pones en alto el segundo pin el tiempo que desees y lo bajas de nuevo, y asi las 8 ventanas, cuando se completan los 20mseg comienzas de nuevo con el primero y asi todo el rato.

tu debes calcular tus frecuencias y tus ventanas y cambiar los calculos para tu aplicación, y mucho cuidado de no usar delay en ningun lado.

Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                    //
//    multi.c                                                                                           //
//    Descripcion:   programa fuente de optimizacion de codigo para mover 8 sevos von 1 solo timer    //
//    Autor: Juan Jose Perales Serrano                                                                //
//                                                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////////////



#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

/////////////////////////////////////////////////////////////////////////////
//
// Definicion de espacio para la carga del bootloader
//
/////////////////////////////////////////////////////////////////////////////

#build (reset=0x1000,interrupt=0x1008)
#org 0x0000,0x0FFF{}

//////////////////////////////////////////////////////////////////////////////
     
#priority timer1//,demas interrupciones, para dar prioridad a los servos

#use standard_io(A)                          //habilitamos los puertos como entrada salida
#use standard_io(B)
#use standard_io(C)

#define LED PIN_C1
#define SW1 PIN_C2

///////////////////////////DEFINICION DE TODOS LOS SERVOS///////////////////////
#define SERVO1 PIN_B7
#define SERVO2 PIN_B6
#define SERVO3 PIN_B5
#define SERVO4 PIN_B4
#define SERVO5 PIN_B3
#define SERVO6 PIN_B2
#define SERVO7 PIN_B1
#define SERVO8 PIN_B0
////////////////////////////////////////////////////////////////////////////////



const int16  TicksVENTANA=7500;                                              // PWM para un servo = 2.5 ms x 8 = 20 ms
const int16  TicksMINIMA=2100;                                               // PWM Position 0 = 0.7 ms 
const int16  TicksCENTRO= 4500;                                              // PWM Position 90= 1.5 ms 
const int16  TicksMAXIMA=6300;                                               // PWM Position 180= 2.1 ms

static int16 Servo_PWM[8]={TicksMINIMA,TicksMINIMA,TicksMINIMA,0,0,0,0,0};   //en este vector cargamos las posiciones de cada uno de los servos

static int8  SERVO_N=0;                                                      //variable para seleccionar el servo
static int1  SERVO1_ON=1;                                                    //variables para activar los servos
static int1  SERVO2_ON=1;
static int1  SERVO3_ON=1;
static int1  SERVO4_ON=0;
static int1  SERVO5_ON=0;
static int1  SERVO6_ON=0;
static int1  SERVO7_ON=0;
static int1  SERVO8_ON=0;
static int1  flag_Phase;
static int16 TicksPROXIMAINTERRUPCION=53036;                                    //cuenta para la proxima interrupcion, VALOR ALEATORIO PARA LA PRIMERA INTERRUPCION

int8 bandera=0;



#int_timer1
void timer1_isr(void){
 
   if(flag_Phase==0){
   
      if(SERVO_N==0 && SERVO1_ON) {output_high(SERVO1);}                         //activacion de los servos en interrupciones impares
      if(SERVO_N==1 && SERVO2_ON) {output_high(SERVO2);}
      if(SERVO_N==2 && SERVO3_ON) {output_high(SERVO3);}
      if(SERVO_N==3 && SERVO4_ON) {output_high(SERVO4);}
      if(SERVO_N==4 && SERVO5_ON) {output_high(SERVO5);}
      if(SERVO_N==5 && SERVO6_ON) {output_high(SERVO6);}
      if(SERVO_N==6 && SERVO7_ON) {output_high(SERVO7);}
      if(SERVO_N==7 && SERVO8_ON) {output_high(SERVO8);}
      TicksPROXIMAINTERRUPCION = 65535 - Servo_PWM[SERVO_N];                     //cargamos el timer con el valor en alto del servo
      set_timer1(TicksPROXIMAINTERRUPCION);
   }
   if(flag_Phase==1){
   
      if(SERVO_N==0 && SERVO1_ON) {output_low(SERVO1);}                         //desactivacion de los servos en posiciones pares
      if(SERVO_N==1 && SERVO2_ON) {output_low(SERVO2);}
      if(SERVO_N==2 && SERVO3_ON) {output_low(SERVO3);}
      if(SERVO_N==3 && SERVO4_ON) {output_low(SERVO4);}
      if(SERVO_N==4 && SERVO5_ON) {output_low(SERVO5);}
      if(SERVO_N==5 && SERVO6_ON) {output_low(SERVO6);}
      if(SERVO_N==6 && SERVO7_ON) {output_low(SERVO7);}
      if(SERVO_N==7 && SERVO8_ON) {output_low(SERVO8);}
      TicksPROXIMAINTERRUPCION = 65535 - TicksVENTANA - Servo_PWM[SERVO_N];      //cargamos el timer con el valor asta completar una ventana
      set_timer1(TicksPROXIMAINTERRUPCION);
     
     
      if(++SERVO_N>7) SERVO_N=0;
   }
   ++flag_Phase;
}

void main(void)
{
   int8 i=0,u=0;
   disable_interrupts(GLOBAL);                          //CONFIGURACIÓN INICIAL
 

   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
   enable_interrupts(INT_TIMER1);
 
   enable_interrupts(GLOBAL);
 
   delay_ms(50);
   
      output_low(SERVO1);
      output_low(SERVO2);
      output_low(SERVO3);
      output_low(SERVO4);
      output_low(SERVO5);
      output_low(SERVO6);
      output_low(SERVO7);
      output_low(SERVO8);
     
   set_timer1(TicksPROXIMAINTERRUPCION);
   
   while(TRUE)
   {
      //tu codigo
   }
   
   
}


te dejo el programa para que te hagas una idea y a ver si lo puedes utilizar, cuidado con el por que es de hace mucho y yo era un novatillo jeje.

al principio le dices cuantos servos vas a tener y cargando el vector "static int16 Servo_PWM[8]={TicksMINIMA,TicksMINIMA,TicksMINIMA,0,0,0,0,0}; " los tiempos de los servos para su posición y el programa lo hace todo.

para variar la posicion vas variando los valores de ese vector y ya esta.

ojala te sirva para tu aplicacion  ;-) ;-) un saludo
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Re: Tener varios pwm en un pic?
« Respuesta #4 en: 03 de Mayo de 2015, 15:48:04 »
Gracias genio! lo voy a probar, a lo unico que le tengo miedo es a que si el pwm tiene q estar apagado me genere un pequeño pulso que exitaria minimamente las lamparas que quiero controlar... es solo una corazonada porque todavia no lo probe pero seguro me va a servir, muy agradecido juaperser1!!

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: Tener varios pwm en un pic?
« Respuesta #5 en: 03 de Mayo de 2015, 16:12:08 »
bueno ten en cuenta que eso esta hecho para servomotores a 20 mseg de frecuencia, ya modificalo como tu necesites, te lo he pasado para que veas como hacer varios PWM con 1 solo timer y pueda ayudarte, pero no creo que te funcione solo con meterselo al pic, tienes que poner tu reloj, tu micro, tu base de tiempo etc etc. de todas formas espero que si te sirva  ;-)

un saludo
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Re: Tener varios pwm en un pic?
« Respuesta #6 en: 03 de Mayo de 2015, 18:54:58 »
Si Gracias por tu ayuda! cual es la base de tiempo aconsejable para controlar un foco? debe ser como de no menos de 150 ciclos por segundo?!

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: Tener varios pwm en un pic?
« Respuesta #7 en: 04 de Mayo de 2015, 10:38:43 »
Perdona por tardar estaba en el curro, pues veras nunca he trabajado con dimmer así que en ese tema es mejor que te ayude algún compañero del foro. Siento no poder ayudarte en ese tema

Un saludo.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Tener varios pwm en un pic?
« Respuesta #8 en: 04 de Mayo de 2015, 11:08:58 »
Que tension estas trabajando, decis la red publica? 220V?

Si es asi deberias ver el cruce por cero de la señal alterna, lo cual esto quiere decir que vas a trabajar con tensiones altas.
Al momento del cruce, mientras mas esperes menos brillo va a tener tu lampara. obviamente el maximo esta dado por la mitad de un ciclo de esos 50Hz

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Re: Tener varios pwm en un pic?
« Respuesta #9 en: 04 de Mayo de 2015, 19:37:29 »
si es de 220vac y 50hz, entonces que debo hacer? o podria poner un optoacoplador con cruce por cero? o estoy muy errado  :?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Tener varios pwm en un pic?
« Respuesta #10 en: 04 de Mayo de 2015, 23:52:32 »
Un opto sin cruce por cero + un triac, seguro hay muchos circuitos dando vueltas.

El ciclo de la red de 50hz es de 20ms, es decir tenes como maximo 10ms
Tenes que detectar el cruce por 0 y apartir que detectas eso tener esa ventana para activar tu TRIAC

Como normalmente una imagen vale mas que mil palabras:

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re: Tener varios pwm en un pic?
« Respuesta #11 en: 05 de Mayo de 2015, 05:07:53 »
Debes de detectar el paso por cero para tener una referencia en la señal y entonces cortarla por donde quieras, puedes usar un opto transistor para el cruce por cero, y un optotriac para encender el triac, asi tendrás tu circuito aislado de la red y te evitaras problemas.

Por cierto KILLERJC:

Citar
Un opto sin cruce por cero + un triac, seguro hay muchos circuitos dando vueltas.

¿que quieres decir con un opto sin cruce por cero?

un saludo.
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Tener varios pwm en un pic?
« Respuesta #12 en: 05 de Mayo de 2015, 06:50:57 »
Si, si quisiera aislar el micro de todo lo que es la linea electrica deberia optoacoplar la entrada y la salida, pero igual si no se quiere tener una aislancion al menos en la entrada , se puede poner una resistencia grande + diodos de clamping. Por su parte la salida prefiero que sea aislada.

O Como bien dijiste con un optoacoplador se podria separar la entrada
http://www.vishay.com/docs/83725/4n25.pdf

Respecto a lo demas
Yo me referia a un opto triac SIN cruze por cero , no como este:
https://www.fairchildsemi.com/datasheets/MO/MOC3061M.pdf

En el que se activa cuando cruza por 0, para evitar picos de tension/corriente, interesante para un on/off. Pero no para su aplicacion

Mientras que un optotriac comun (este no funciona para 220V, pero da una idea )
http://pdf.datasheetcatalog.com/datasheet/motorola/MOC3010.pdf

Podrias controlar cuando activarlo, es decir en que angulo hacerlo, solo para ejemplo dejo un AN de ese opto, con los calculos necesarios para hacerlo funcionar.
http://www.soloelectronica.net/triac/AN_3003.PDF


PD: Los componentes que puse son unicamente para mostrar la diferencia, no es para que los uses en tu circuito, es lo primero que encontre por internet.
« Última modificación: 05 de Mayo de 2015, 06:53:04 por KILLERJC »

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Tener varios pwm en un pic?
« Respuesta #13 en: 05 de Mayo de 2015, 11:44:04 »
Si es de baja frecuencia (T>20ms) lo puedes hacer por sw utilizando dos TIMERS.

Un timer debe darte el período del PWM. Cada vez que entre esta interrupción deberás poner todas las salidas PWM al nivel de arranque (L o H) según decidas.
El otro TIMER debe interrumpir a intervalos regulares y el período debe ser múltiplo entero del período del PWM. Cada vez que entre la interrupción podrás cambiar el estado del PIN de cada salida en función de su ciclo útil. Para ello cada PWM debe tener un contador para contar los pulsos (interrupciones) del timer con período más corto.

Esto involucra un montón de programación y de tiempo de ejecución, así que no te quedará mucho tiempo para otras cosas, incluyendo que las otras cosas pueden afectar el desempeño de los PWM. Una olución más lógica es utilizar CI configurables externos  y listo. Hay varios, se pueden conectar por I2C o SPI y me parece que son una solución mucho más apropiada para la cantidad de PWM que necesitas.

Suerte
 Reinier

Desconectado MINDFIELD

  • PIC16
  • ***
  • Mensajes: 139
Re: Tener varios pwm en un pic?
« Respuesta #14 en: 05 de Mayo de 2015, 19:35:37 »
Hola y gracias por responder a todos! no pude leer las ultimas respuestas detenidamente pero las lei un poco rapido y entendi casi todo, lo unico que no entendi fue la respuesta de reiniertl (CI configurables externos) la verdad me quede con mucha duda a que se referia???  :shock: