desktop

Curso de programación de PIC en PICBasic Pro

Hola a todos. Por favor me podrían ayudar a crear un pic que genere melodias y al mismo tiempo enciendan leds al ritmo de esa melodia ?,he creado por ejemplo la melodia de happy birthday y feliz navidad en el pic, pero no tengo idea como hacer para que por otro puerto enciendan algunos leds ,si yo quiero que enciendan los leds el programa primero ejecuta la melodia y luego recien enciende dichos leds y yo deseo que haga las dos cosas al mismo tiempo.Gracias.
Adjunto el archivo necesario en pic basic.:apreton:
 

Adjuntos

  • sonido.rar
    14.7 KB · Visitas: 34
Hola a todos. Por favor me podrían ayudar a crear un pic que genere melodias y al mismo tiempo enciendan leds al ritmo de esa melodia ?,he creado por ejemplo la melodia de happy birthday y feliz navidad en el pic, pero no tengo idea como hacer para que por otro puerto enciendan algunos leds ,si yo quiero que enciendan los leds el programa primero ejecuta la melodia y luego recien enciende dichos leds y yo deseo que haga las dos cosas al mismo tiempo.Gracias.
Adjunto el archivo necesario en pic basic.:apreton:

Hola...Una de las formas que se me ocurre ahora es que por cada nota llames a continuacion el cambio de nivel en donde esta los led. Ej:

Código:
....

music:

DelayMS 500 
Toggle PORTB.1
Sound PORTB.0,[90,50]
Toggle PORTB.1
Toggle PORTB.7
Sound PORTB.0,[94,50]
Toggle PORTB.1
Sound PORTB.0,[94,50]
Toggle PORTB.7
Sound PORTB.0,[90,50]
Toggle PORTB.1
Sound PORTB.0,[99,50]
......

O el orden de encendido apagado que quieras realizar.
Saludos.

Ric.
 
Gracias por responder,y si funciona lo que escribiste ,no se me había ocurrido usar "toggle".
No lo hace precisamente al ritmo de la música pero es una buena solución.
Gracias.
Lo que deseo es realizar una cajita musical como esas cajitas musicales de navidad que se colocan en los arbolitos de navidad y que tienen luces y que varían según las melodías que producen.
He visto en youtube que lo han realizado con un pic pero obviamente el codigo hex ni el diagrama te quieren dar.
Gracias
 
En mikrobasic tienes un ejemplo bastante explicito de como hacerlo, solo tienes que asignar un puerto de salida a cada tono, meter cada tono y cada puerto asignado a cada tono en un subproceso y activar el pueto antes de que suene el tono y que se desactive al finalizar el tono y finalizas el subproceso.
No te has de preocupar por los tiempos de encendido y apagado de los leds porque el tiempo de duracion del sound es el tiempo que estara activado cada puerto.
Asi que si un sonido dura 3 segundos y otro 500ms un led estara activado 3 segundos y el siguiente led 500ms.
Te dejo un ejemplo de como se hace.
Este es el programa original
Código:
' Cabecera******************************************************
program example_13 ' Nombre de programa

sub procedure Tone1()
  Sound_Play(659, 250) ' Frecuencia = 659Hz, duración = 250ms

end sub

sub procedure Tone2()
  Sound_Play(698, 250) ' Frecuencia = 698Hz, duración = 250ms
end sub

sub procedure Tone3()
  Sound_Play(784, 250) ' Frecuencia = 784Hz, duración = 250ms
end sub

sub procedure Melody() ' Tocar una melodía divertida 1
  Tone1() Tone2() Tone3() Tone3()
  Tone1() Tone2() Tone3() Tone3()
  Tone1() Tone2() Tone3()
  Tone1() Tone2() Tone3() Tone3()
  Tone1() Tone2() Tone3()
  Tone3() Tone3() Tone2() Tone2() Tone1()
end sub

sub procedure ToneA() ' Tonos utilizados en la función Melody2
  Sound_Play( 880, 50)
end sub

sub procedure ToneC()
  Sound_Play(1046, 50)
end sub

sub procedure ToneE()
  Sound_Play(1318, 50)
end sub

sub procedure Melody2() ' Tocar Melody2
  dim counter as byte
  for counter = 9 to 1 step -1
    ToneA()
    ToneC()
    ToneE()
  next counter
end sub

main: ' Inicio de programa

ANSEL = 0    ' Configurar pines analógicos como digitales de E/S
ANSELH = 0

C1ON_bit = 0 ' Deshabilitar los comparadores
C2ON_bit = 0

TRISB = 0xF0 ' Configurar los pines RB7..RB4 como entradas y RB3 como salida

Sound_Init(PORTD, 3)
Sound_Play(880, 5000)

while TRUE   ' Bucle infinito
  if (Button(PORTB,7,1,1)) then ' Si se presiona PORTB.7 tocar Tone1
      Tone1()
    while (RB7_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if

  if (Button(PORTB,6,1,1)) then ' Si se presiona PORTB.6 tocar Tone1
      Tone2()
    while (RB6_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if

  if (Button(PORTB,5,1,1)) then ' Si se presiona PORTB.5 tocar Tone1
    Melody2()
    while (RB5_bit <> 0)
      nop ' Esperar que se suelte el botón 
    wend
  end if

  if (Button(PORTB,4,1,1)) then ' Si se presiona PORTB.4 tocar Tone1

    Melody()
    while (RB4_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if
wend

end. ' Final de programa

Estos son los tonos
Código:
sub procedure Tone1()
  Sound_Play(659, 250) ' Frecuencia = 659Hz, duración = 250ms

end sub

sub procedure Tone2()
  Sound_Play(698, 250) ' Frecuencia = 698Hz, duración = 250ms
end sub

sub procedure Tone3()
  Sound_Play(784, 250) ' Frecuencia = 784Hz, duración = 250ms
end sub

Pues yo lo que he hecho para que lo comprendas, es esto:
Código:
' Cabecera******************************************************
program example_13 ' Nombre de programa

sub procedure Tone1() ' g
PORTA.0=1
  Sound_Play(196, 700) ' Frecuencia = 659Hz, duración = 250ms
PORTA.0=0
end sub

sub procedure Tone2() ' d
 PORTA.6=1
  Sound_Play(293, 1200) ' Frecuencia = 698Hz, duración = 250ms
 PORTA.6=0
end sub

sub procedure Tone3() ' c
PORTA.5=1
  Sound_Play(261, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.5=0
end sub

sub procedure Tone4() ' b
PORTA.4=1
  Sound_Play(246, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.4=0
end sub

sub procedure Tone5() ' a
PORTA.3=1
  Sound_Play(220, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.3=0
end sub

sub procedure Tone6()   'g
PORTA.7=1
  Sound_Play(392, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.7=0
end sub

sub procedure Tone7()   'd
PORTA.6=1
  Sound_Play(293, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.6=0
end sub

sub procedure Tone8()   'd
PORTA.3=1
  Sound_Play(220, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.3=0
end sub


sub procedure Melody() ' Tocar una melodía divertida 1
  Tone1() Tone2()  Tone3()  Tone4() Tone5() Tone6() Tone7() Tone3()
  Tone4() Tone5() Tone6() Tone7() Tone3() Tone4() Tone3() Tone8()
end sub

sub procedure ToneA() ' Tonos utilizados en la función Melody2
  Sound_Play( 880, 50)
end sub

sub procedure ToneC()
  Sound_Play(1046, 50)
end sub

sub procedure ToneE()
  Sound_Play(1318, 50)
end sub

sub procedure Melody2() ' Tocar Melody2
  dim counter as byte
  for counter = 9 to 1 step -1
    ToneA()
    ToneC()
    ToneE()
  next counter
end sub

main: ' Inicio de programa

ANSEL = 0    ' Configurar pines analógicos como digitales de E/S
ANSELH = 0
TRISB = 0xF0 ' Configurar los pines RB7..RB4 como entradas y RB3 como salida
TRISA =0x00
porta = 0x00
C1ON_bit = 0 ' Deshabilitar los comparadores
C2ON_bit = 0


Sound_Init(PORTD, 3)
'Sound_Play(880, 5000)

while TRUE   ' Bucle infinito
  if (Button(PORTB,7,1,1)) then ' Si se presiona PORTB.7 tocar Tone1
      Tone1()
    while (RB7_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if

  if (Button(PORTB,6,1,1)) then ' Si se presiona PORTB.6 tocar Tone1
      Tone2()
    while (RB6_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if

  if (Button(PORTB,5,1,1)) then ' Si se presiona PORTB.5 tocar Tone1
    Melody2()
    while (RB5_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if

  if (Button(PORTB,4,1,1)) then ' Si se presiona PORTB.4 tocar Tone1

    Melody()
    while (RB4_bit <> 0)
      nop ' Esperar que se suelte el botón
    wend
  end if
wend

end. ' Final de programa

Y antes de cada sound y despues, activas y desactivas el puerto que le hayas asignado a ese tono, asi:
Código:
sub procedure Tone1() ' g
PORTA.0=1
  Sound_Play(196, 700) ' Frecuencia = 659Hz, duración = 250ms
PORTA.0=0
end sub

sub procedure Tone2() ' d
 PORTA.6=1
  Sound_Play(293, 1200) ' Frecuencia = 698Hz, duración = 250ms
 PORTA.6=0
end sub

sub procedure Tone3() ' c
PORTA.5=1
  Sound_Play(261, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.5=0
end sub

sub procedure Tone4() ' b
PORTA.4=1
  Sound_Play(246, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.4=0
end sub

sub procedure Tone5() ' a
PORTA.3=1
  Sound_Play(220, 450) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.3=0
end sub

sub procedure Tone6()   'g
PORTA.7=1
  Sound_Play(392, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.7=0
end sub

sub procedure Tone7()   'd
PORTA.6=1
  Sound_Play(293, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.6=0
end sub

sub procedure Tone8()   'd
PORTA.3=1
  Sound_Play(220, 1200) ' Frecuencia = 784Hz, duración = 250ms
  PORTA.3=0
end sub

Te dejo la simulacion en proteus para que lo veas en funcionamiento.
Los comentarios de cada linea, solo son validos los del ejemjplo original.
No te guies por los demas comentarios ok?
Un saludo.
 

Adjuntos

  • sonidos y leds.rar
    19 KB · Visitas: 41
Última edición:
Gracias por responder,y si funciona lo que escribiste ,no se me había ocurrido usar "toggle".
No lo hace precisamente al ritmo de la música pero es una buena solución.
Gracias.
Lo que deseo es realizar una cajita musical como esas cajitas musicales de navidad que se colocan en los arbolitos de navidad y que tienen luces y que varían según las melodías que producen.
He visto en youtube que lo han realizado con un pic pero obviamente el codigo hex ni el diagrama te quieren dar.
Gracias

La duración del encendido apagado así como cual led prendes dura lo que dura la nota ya que cambias el estado una vez que entras o sales al generador de cada una de ellas por lo que de ti depende cuando y que prendes(seguir el ritmo). En ves de la instrucción Toggle puedes activar el bit del puerto individualmente que quieras así como pagarlo con
Código:
 PORTx.x = %01110001(led que quieras prender o apagar)
SOUND.....
......
 PORTx.x = %........
Si no quieres escribir tanto, le asignas una variable el numero correspondiente y luego solo la invocas.
Alternativas hay muchas.

Ric.
 
Última edición:
Se me ocurrió una manera más fácil usando interrupciones. (RB0)
Pero se necesita que las notas tengan espacios. (Notas sin sonido de la instrucción "Sound")

Adjunto el ejemplo probado físicamente con dos LED's.
Con dos 4017 y usando las salidas para los LED's, se puede incrementar el número de LED´s.

Saludos.
 

Adjuntos

  • 16F628A Sound & LED's.rar
    35.7 KB · Visitas: 49
Hola .Gracias por ayudarme en mi proyecto de cajita musical....Tengo una pregunta, al usar la instrucción "if..then" en mis proyectos para activar o desactivar algo con pulsadores ,yo uso por ejemplo "if porta.0 and porta.1 then (activo algo) ",es decir al apretar dos pulsadores al mismo tiempo me da un resultado ,pero en la simulacion y en la realidad es dificil que realice
ese resultado ,yo programe por ejemplo que al apretar porta.0 me active el led1 ,al apretar porta.1 me active el led 2 y al apretar al mismo tiempo porta.0 y porta.1 me active el led 3,
pero como dije es muy difícil que me realice esa acción,es decir hay que ser muy preciso al apretar los dos pulsadores para que funcione.Hay alguna solución .:confused:
Gracias.
 
Si tiene que funcionar la operación AND sobre los bits seleccionados.
A menos de que estén sucios los pulsadores, no funcionaría correctamente.
Colocar un capacitor de 100 nF. en cada pulsador, puede ayudar a evitar rebotes.

No olvides decirle al compilador los estados a comparar.
La estructura del código es la siguiente:
Código:
    [B][COLOR=Blue]If [/COLOR]PORTB.1 = 0 & PORTB.2 = 0 [COLOR=Blue]Then[/COLOR]
       [COLOR=Green]; Código a ejecutar[/COLOR]
      [COLOR=Blue] While[/COLOR] (PORTB.1 = 0 [COLOR=Blue]Or[/COLOR] PORTB.2 = 0): [COLOR=Blue]Wend[/COLOR]
    [COLOR=Blue]EndIf[/COLOR][/B]
Nota:
Para presionar dos pulsadores al mismo tiempo en Proteus, se usa la barra espaciadora del teclado.
 
Hola .Gracias por ayudarme en mi proyecto de cajita musical....Tengo una pregunta, al usar la instrucción "if..then" en mis proyectos para activar o desactivar algo con pulsadores ,yo uso por ejemplo "if porta.0 and porta.1 then (activo algo) ",es decir al apretar dos pulsadores al mismo tiempo me da un resultado ,pero en la simulacion y en la realidad es dificil que realice
ese resultado ,yo programe por ejemplo que al apretar porta.0 me active el led1 ,al apretar porta.1 me active el led 2 y al apretar al mismo tiempo porta.0 y porta.1 me active el led 3,
pero como dije es muy difícil que me realice esa acción,es decir hay que ser muy preciso al apretar los dos pulsadores para que funcione.Hay alguna solución .:confused:
Gracias.

Sospecho que lo tuyo es problema que, como estas tomado decisiones con el estado del pulsador individualmente, si no esperas un tiempo y realizas la verificación del estado de nuevo, y recién allí actuás en consecuencia, tendrás resultados aleatorios dependiendo de que pulsador presiones primero.

Ric.
 
Estimado TORRES: es posible usar algo de este código para hacer un contador o frecuencimetro o tacómetro, con caracteres grandes, que ocupen 2 lineas de un LCD ??? Algo dice al respecto el comentario Nro. 2963 sobre caracteres gigantes...CURSO DE PROGRAMACION EN PICBASIC.
Aclaro que empecé hace unos pocos días con este lenguaje, y casi no conozco su potencial...Por otro lado, hace años que estoy alejado de la vida estudiantil, más de 30 para ser preciso, ni se conocían las computadores personales por aquellos años, asi que estoy algo oxidado y desactualizado, pero conservo la capacidad de interpretación a pesar de mis años y tengo voluntad para aprender...Si conoce de información para mirar, se lo agradeceré enormemente.

Parece que el sitio no me deja pegar link, ni hacer citas, ni hacerle preguntas por privado, creo que hay que tener un mínimo de mensajes en el foro para ganarse ese derecho.

Saludos !!!
 
Última edición:
Saludos tengo el siguiente codigo con lo cual genero un pwm con una frecuancia fija de 1Khz
pero me gustaria variar el ciclo util de esta osea el duty, ya que haciendo un toggle en el pin
correspondiente consigo el 50% de este.
pero me gustaría realizar lo atraves de dos pus button.
agradeceria una ayuda oh comentario del mismo.

Código:
' Programa en Pic Basic Pro
'Int. Por TMR0 a 1 KHZ
@ DEVICE PIC12F683
@ DEVICE PIC12F683, FCMEN_OFF
@ DEVICE PIC12F683, IESO_OFF
@ DEVICE PIC12F683, WDT_ON
@ DEVICE PIC12F683, BOD_ON
@ DEVICE PIC12F683, PWRT_ON
@ DEVICE PIC12F683, PROTECT_OFF
@ DEVICE PIC12F683, MCLR_OFF
@ DEVICE PIC12F683, INTRC_OSC_NOCLKOUT
@ DEVICE PIC12F683, BOD_ON
Define Osc 4 ' Define el Oscilador para 4 Mhz.
I var Byte 
inc var byte
On Interrupt GoTo int_tmr0 '
Symbol TOIF = INTCON.2 ' 
Symbol INTF = INTCON.1 ' 
Symbol LED = GPIO.1 ' 
Pb_Inc	var	GPIO.0 ' 
Pb_Dec	var	GPIO.3 ' 
OSCCON=%01100001
ANSEL = 0
CMCON0 = 7
TRISIO = %11011101     
GPIO  = %00000000     
WPU = 0
OPTION_REG = %10000100 '
INTCON = %10100000 ' 

inc=0
Inicio:
if Pb_Inc = 0 then ' 
    inc=inc+1
ENDIF
IF Pb_Dec = 0 THEN
   inc=inc-1
ENDIF
GoTo Inicio ' 
End
'*********************************************************
Disable
int_tmr0:
If TOIF = 1 Then 
    TMR0 = 240
    toggle led
endif          
Reseteo:
TOIF = 0 
Resume
ENABLE
 
Estimado TORRES: es posible usar algo de este código para hacer un contador o frecuencimetro o tacómetro, con caracteres grandes, que ocupen 2 lineas de un LCD ??? Algo dice al respecto el comentario Nro. 2963 sobre caracteres gigantes...

Si se puede; Fijate que hay un articulo de como trabajar con estos display, y menciono como se grafican los caracteres :cool:

Parece que el sitio no me deja pegar link, ni hacer citas, ni hacerle preguntas por privado, creo que hay que tener un mínimo de mensajes en el foro para ganarse ese derecho.

Tal cual, y con un solo mensaje, yo te recomendaria darte una vuelta por presentaciones, un pase por el foro y ver en que se puede colaborar tampoco estaria mal, etc etc... Bienvenido al foro :cool:
 
Hola gente tanto tiempo :). les cuento que estoy intentando programar un Pic16f876A con un bootloader cargado y el software tiny bootloader. he estado investigando un poco y al parecer hay que escribir un par de líneas de código extra al programa que uno intenta cargar en el pic. el único problema que tengo, es que no tengo idea de lo que hay que escribir, ni en que parte del programa hay que escribirlo. será que podrán ayudarme a definir dónde y que escribir a un programa en pbp con algún ejemplillo??? Saludosss
 
Bueno, pude hacer andar el tiny bootloader y el codigo queda asi como lo ven... lo unico que me pregunto, o mejor dicho le pregunto a los que saben, que significa este mensaje??? (Reading HEX file...
WARNING: PCLATH not fully initialised before GOTO! , ... sucessfully repaired., Writing flash...
WRITE OK at 1:17, time:0.311 sec)

Código:
@ device xt_osc  ; oscilador externo XT
DEFINE LOADER_USED 1
define osc 4     ; especifica que se va a utilizar uno de 4 Mhz

LED var portb.4   ; asigna el nombre de led a RB4 del pic 16f877A


programa:          ; inicio de la linea de programa 
high led           ;enciende led
pause 2500         ; esperar 2.5 seg
low led            ;apaga led 
pause 500          ; espera 0.5 seg             
goto programa
end                ; fin del programa
 
Atrás
Arriba