Autor Tema: control secuencial de servos  (Leído 549 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado ulisescesaton

  • PIC10
  • *
  • Mensajes: 7
control secuencial de servos
« en: 13 de Noviembre de 2019, 00:27:23 »
que tal estoy haciendo un proyecto para tocar un instrumento musical con servos usando un pic 18f4550
 hice un programa  para controlar 8 servos usando un potenciometro y el timer 0  pero ahora me gustaría
mover los servos de forma secuencial para que toquen una melodía en un piano, alguna idea de como hacerlo ??

Código: [Seleccionar]
#include <18f4550.h>         
#device ADC = 10           //Bits del ADC
#Fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL2, CPUDIV1, VREGEN
#use delay (clock=48M)   
#DEFINE PWM1 PIN_B0
#DEFINE PWM2 PIN_B1
#DEFINE PWM3 PIN_B2
#DEFINE PWM4 PIN_B3
#DEFINE PWM5 PIN_B4
#DEFINE PWM6 PIN_B5
#DEFINE PWM7 PIN_B6
#DEFINE PWM8 PIN_B7
INT16 VOLT;
INT ANGULO[8];
STATIC INT1 FLAG;
INT16 CARGA1,CARGA2;
INT16 ADC_READ;
INT8 INDEX=0;
#INT_TIMER0
VOID TIMER0_ISR(VOID){

IF(FLAG==0){
SWITCH(INDEX){
CASE (0) : OUTPUT_HIGH(PWM1);SET_TIMER0(CARGA1);BREAK;
CASE (1) : OUTPUT_HIGH(PWM2);SET_TIMER0(CARGA1);BREAK;
CASE (2) : OUTPUT_HIGH(PWM3);SET_TIMER0(CARGA1);BREAK;
CASE (3) : OUTPUT_HIGH(PWM4);SET_TIMER0(CARGA1);BREAK;
CASE (4) : OUTPUT_HIGH(PWM5);SET_TIMER0(CARGA1);BREAK;
CASE (5) : OUTPUT_HIGH(PWM6);SET_TIMER0(CARGA1);BREAK;
CASE (6) : OUTPUT_HIGH(PWM7);SET_TIMER0(CARGA1);BREAK;
CASE (7) : OUTPUT_HIGH(PWM8);SET_TIMER0(CARGA1);BREAK;
SET_TIMER0(CARGA1);
}
}
ELSE{
SWITCH(INDEX){
CASE (0) : OUTPUT_LOW(PWM1);SET_TIMER0(CARGA2);BREAK;
CASE (1) : OUTPUT_LOW(PWM2);SET_TIMER0(CARGA2);BREAK;
CASE (2) : OUTPUT_LOW(PWM3);SET_TIMER0(CARGA2);BREAK;
CASE (3) : OUTPUT_LOW(PWM4);SET_TIMER0(CARGA2);BREAK;
CASE (4) : OUTPUT_LOW(PWM5);SET_TIMER0(CARGA2);BREAK;
CASE (5) : OUTPUT_LOW(PWM6);SET_TIMER0(CARGA2);BREAK;
CASE (6) : OUTPUT_LOW(PWM7);SET_TIMER0(CARGA2);BREAK;
CASE (7) : OUTPUT_LOW(PWM8);SET_TIMER0(CARGA2);BREAK;
SET_TIMER0(CARGA2);
}
INDEX=INDEX+1;
IF(INDEX>7){
INDEX=0;
}
}
FLAG=FLAG+1;
}
VOID MAIN(){
   setup_adc_ports(AN0);                  //Configura A0 como analógico
   setup_adc(ADC_CLOCK_INTERNAL);         //ADC con oscilador interno
   setup_timer_0(T0_INTERNAL|T0_DIV_256);   //Configura Timer0
   enable_interrupts(int_TIMER0);         //Habilita interrupciones
   enable_interrupts(GLOBAL);
   set_adc_channel(0);               
   DELAY_US(20);                 
   while(true){
    ADC_READ=READ_ADC();
    VOLT=5*ADC_READ/1023;
    ANGULO[0]= 180*VOLT/5;
    ANGULO[1]= 180*VOLT/5;
    ANGULO[2]= 180*VOLT/5;
    ANGULO[3]= 180*VOLT/5;
    ANGULO[4]= 180*VOLT/5;
    ANGULO[5]= 180*VOLT/5;
    ANGULO[6]= 180*VOLT/5;
    ANGULO[7]= 180*VOLT/5;
    CARGA1=65535-(47+ANGULO[INDEX]);
    CARGA2=65535-235+(47+ANGULO[INDEX]);
   }}



Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7426
Re:control secuencial de servos
« Respuesta #1 en: 13 de Noviembre de 2019, 16:08:57 »
Citar
que tal estoy haciendo un proyecto para tocar un instrumento musical con servos usando un pic 18f4550
 hice un programa  para controlar 8 servos usando un potenciometro y el timer 0  pero ahora me gustaría
mover los servos de forma secuencial para que toquen una melodía en un piano, alguna idea de como hacerlo ??

No utilizaria servos para eso, pero si vas por ello entonces adelante. Me refiero que tal ves sea preferible un embolo o algun actuador como un solenoide.

Respecto al programa si hay ideas de como hacerlo... las ideas que se me ocurren son:

- Usar un timer y que cada 0.5ms por ejemplo entre a la interrupcion, de alli cada servo posee un contador, en 0 siempre estan activos y desactivan en la entrada a la interrupcion que vos asignas a cada uno.
- Usar un integrado con varias salidas PWM y lo controlas por I2C.


Pero tu programa no va a funcionar tal y cual lo tenes, no con pocos cambios.

Desconectado remi04

  • PIC18
  • ****
  • Mensajes: 264
Re:control secuencial de servos
« Respuesta #2 en: 14 de Noviembre de 2019, 12:09:17 »
Yo también lo haría con solenoides con el positivo a común a todas y activadas independientemente cada una con transistores a emisor común.

  El positivo común lo alimentaría a través de un mosfet comandado por el pwm del micro. Así podrías no solo tocar las notas sino además elegir la fuerza con la que el solenoide va a golpear cada tecla.

La secuencia sería:

  - elijo la fuerza de la nota y la traduzco a un pwm con dutty positivo más amplio. A mayor dutty positivo más fuerte golpeará el solenoide.
  - ahora activo el solenoide mediante su transistor de gnd y listo.

   Siguiente nota.

  Además podrías incluso hacer acordes por que puedes activar varios solenoides a la vez.

   Eso en cuanto a la parte actuadora.

  Respecto a la parte orquestadora pues te haces una función a la que le envías tres argumentos por ejemplo:

tocar ( nota,duración,fuerza) ;

  La nota sería : c,d,e,f,g,a,b para (do, re, mi, fa, sol, la, si)
                        C#, d#, f#,g#,a#. ( para los sostenidos , teclas negras del piano)

  La duración expresada en tiempos de compás.  ( duración de las notas musicales)

Luego otra que sea:

 Acorde(nota1,nota2,nota3,duración,fuerza);   // tocar un acorde.

Luego la composición (secuencia de notas) la declaras en una tabla que contenga los tres argumentos (nota,duración,fuerza). Para la melodía

  Para los acordes otra tabla con lo mismo.

  Te creas una variable llamada tempo donde elijas la velocidad en BPM (beats por minuto)  será tu base de tiempo y por la que se guiará la función tocar y acorde para aplicarles las duraciones a las notas en ms o segundos.

  Una iteracción for(;;); será quien vaya leyendo las tablas y enviado a las funciones tocar() y acorde()

  Un saludo.
 

Desconectado ulisescesaton

  • PIC10
  • *
  • Mensajes: 7
Re:control secuencial de servos
« Respuesta #3 en: 14 de Noviembre de 2019, 23:31:42 »
la cuestion es que es necesario usar el timer 0 y servos para generar varios pwm's  parece  buena idea la de usar varios timers pero como haria para generar varias interrupciones con el timer 0 como para activar y desactivar los servos ??

Desconectado ulisescesaton

  • PIC10
  • *
  • Mensajes: 7
Re:control secuencial de servos
« Respuesta #4 en: 14 de Noviembre de 2019, 23:41:01 »
Yo también lo haría con solenoides con el positivo a común a todas y activadas independientemente cada una con transistores a emisor común.

  El positivo común lo alimentaría a través de un mosfet comandado por el pwm del micro. Así podrías no solo tocar las notas sino además elegir la fuerza con la que el solenoide va a golpear cada tecla.

La secuencia sería:

  - elijo la fuerza de la nota y la traduzco a un pwm con dutty positivo más amplio. A mayor dutty positivo más fuerte golpeará el solenoide.
  - ahora activo el solenoide mediante su transistor de gnd y listo.

   Siguiente nota.

  Además podrías incluso hacer acordes por que puedes activar varios solenoides a la vez.

   Eso en cuanto a la parte actuadora.

  Respecto a la parte orquestadora pues te haces una función a la que le envías tres argumentos por ejemplo:

tocar ( nota,duración,fuerza) ;

  La nota sería : c,d,e,f,g,a,b para (do, re, mi, fa, sol, la, si)
                        C#, d#, f#,g#,a#. ( para los sostenidos , teclas negras del piano)

  La duración expresada en tiempos de compás.  ( duración de las notas musicales)

Luego otra que sea:

 Acorde(nota1,nota2,nota3,duración,fuerza);   // tocar un acorde.

Luego la composición (secuencia de notas) la declaras en una tabla que contenga los tres argumentos (nota,duración,fuerza). Para la melodía

  Para los acordes otra tabla con lo mismo.

  Te creas una variable llamada tempo donde elijas la velocidad en BPM (beats por minuto)  será tu base de tiempo y por la que se guiará la función tocar y acorde para aplicarles las duraciones a las notas en ms o segundos.

  Una iteracción for(;;); será quien vaya leyendo las tablas y enviado a las funciones tocar() y acorde()

  Un saludo.
 
intente el ciclo for pero no hacia nada lo que me gustaría saber es como seleccionar un servo de forma independiente y asignarle un angulo especifico a dicho servo usando una interrupción por timer 0 para generar la señal pwm cada determinado tiempo como multiplexar las señales pwm algo asi como una secuencia de luces pero usando varios servos

Desconectado ulisescesaton

  • PIC10
  • *
  • Mensajes: 7
Re:control secuencial de servos
« Respuesta #5 en: 14 de Noviembre de 2019, 23:45:22 »
Citar
que tal estoy haciendo un proyecto para tocar un instrumento musical con servos usando un pic 18f4550
 hice un programa  para controlar 8 servos usando un potenciometro y el timer 0  pero ahora me gustaría
mover los servos de forma secuencial para que toquen una melodía en un piano, alguna idea de como hacerlo ??

No utilizaria servos para eso, pero si vas por ello entonces adelante. Me refiero que tal ves sea preferible un embolo o algun actuador como un solenoide.

Respecto al programa si hay ideas de como hacerlo... las ideas que se me ocurren son:

- Usar un timer y que cada 0.5ms por ejemplo entre a la interrupcion, de alli cada servo posee un contador, en 0 siempre estan activos y desactivan en la entrada a la interrupcion que vos asignas a cada uno.
- Usar un integrado con varias salidas PWM y lo controlas por I2C.


Pero tu programa no va a funcionar tal y cual lo tenes, no con pocos cambios.


la cuestion es que es necesario usar el timer 0 y servos para generar varios pwm's  parece  buena idea la de usar varios timers pero como haría para generar varias interrupciones con el timer 0 para activar y desactivar los servos algo así como una secuencia de luces pero usando varios servos  eso es lo que me interesa saber espero puedan asesorarme al respecto saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7426
Re:control secuencial de servos
« Respuesta #6 en: 14 de Noviembre de 2019, 23:48:06 »
la cuestion es que es necesario usar el timer 0 y servos para generar varios pwm's  parece  buena idea la de usar varios timers pero como haria para generar varias interrupciones con el timer 0 como para activar y desactivar los servos ??

No entendiste lo que se planteo... Nunca se hablo de varios timers. Pero si de 1 sola interrupcion que ocurra mucho mas seguido.
El servo lo controlas teniendo en alto un pin entre 1ms y 2ms, y repetirlo cada 20ms (periodo)

Entonces con un PIC lo suficientemente rapido podria hacer una interrupcion cada 0.1ms (Con el uso de un solo Timer)
Eso quiere decir que:
Si entra 10 veces a la interrupcion es el minimo tiempo (1ms),
Si entra 20 veces a la interrupcion es el maximo que debo tenerlo en 1 a la salida (2ms),
Al entrar 200 veces debo repetir todo de nuevo (20ms)

Cuando detectas que se cumplieron las 200 veces activas todos las salidas.
Luego tenes una variable para cada salida, la que guardas un numero desde el 10 al 20.
Por cada variable preguntas... Si el contador de entradas a la interrupciones es igual que la variable, entonces pones en 0 esa salida.
De esa forma podes controlar de forma independiente cada uno de los PWM, lo malo es la cantidad de "pasos" ya que esos 180º van a estar dividos en 10 pasos. Pero lo vas a poder controlar de forma separada a cada uno.


 

anything