Curso de programación de PIC en PICBasic Pro

Por aca dejo un pequeño código muy interesante, puede controlar hasta 5 interruptores para el control de un led, funciona como los llamados 3 way, que usan dos interruptores para el apagado y encendido de un bombillo, ahora este tiene 5 y cualquiera de los 5 puede cambiar el estado del led, si esta prendido lo apaga y si esta apagado lo enciende, esta echo con un pic12F675 y el código realmente no es código, es mas configuración que código cuando lo vean se daran cuenta que únicamente tiene la instrucción GOTO inicio, y es solo ese loop lo que hace, lo interesante es que se trata de interrupciones por cambio de estado, al cambiar el estado de cualquiera de las entradas cambia el estado del led.

Código:
@ DEVICE PIC12F675
@ DEVICE INTRC_OSC_NOCLKOUT
@ DEVICE WDT_OFF       
@ DEVICE PWRT_OFF
@ DEVICE MCLR_OFF
@ DEVICE BOD_OFF
@ DEVICE PROTECT_OFF
@ DEVICE CPD_OFF 

DEFINE OSCCAL_1K 1
DEFINE OSC 4  

INTCON = %10001000 'INTERRUPCIONES ACTIVADAS
OPTION_REG = %00000000
WPU = %00110110 'TODOS LOS PINES CON PULL-UP MENOS GPIO.0 y GPIO.3
IOC = %00111110 'TODOS LOS PINES COMO INTERRUPCION MENOS GPIO.0 
ANSEL = %00000000 'ADC DESABILITADO 
CMCON = %00000111 'COMPARADOR DESABILITADO 
         
SYMBOL LED = GPIO.0

TRISIO =%00111110 'TODOS COMO ENTRADA MENOS GPIO.0    
GPIO  = %00000000 
    

ON INTERRUPT GOTO SWCHIT 
INTCON = %10001000 

INICIO:

GOTO INICIO

Disable
SWCHIT:
TOGGLE LED 
PAUSE 400
INTCON = %10001000 
Resume
Enabl

Cuando abran el archivo del código pbp, verán que esta full comentado para que vean cual es el truco del código, les dejo la simulación y el codigo...:cool:
 

Adjuntos

  • 12F675 INTERRUPCION EXTERNA IOC.rar
    15.7 KB · Visitas: 142
quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.
 
Hola amigos, quisiera por favor alguien me ayudara intruyendome un poco sobre el siguiente tema que pongo a su consideracion:
Sucede que estoy por presentar mi proyecto de grado el cual consiste en automatizar mi departamento usando PICs; bueno basicamente lo que hace el PIC es recibir un SMS enviado desde cualquier movil y accionar diferentes cosas en base a reles, en otras palabras el PIC recibe un mensaje y este le manda una señal a un o varios reles y estos proceden abrise o cerrarse; el problema que se me ha presentado esque no puedo independizar los reles, osea si quiero activar el rele dos, primero debo activar el rele uno, porque en el codigo fuente esta primero la linea que contiene al rele uno, entonces quiero saber si hay la posiblidad de saltarme esas lineas de codigo para que no siga el orden logico o bien sea poner condicionantes para que si a determinada accion se active cualquier rele ya sea el uno el dos, el tres, etc.

Adjunto mi codigo fuente que este hecho en Basic, en microcode studio.

Cualquier ayuda m sería de gran utilidad.

Gracias
 

Adjuntos

  • Programa.txt
    1.2 KB · Visitas: 58
quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.

Hola y que has hecho hasta el momento si tienes algo adelantado colócalo para poder ayudarte.



Hola amigos, quisiera por favor alguien me ayudara intruyendome un poco sobre el siguiente tema que pongo a su consideracion:
Sucede que estoy por presentar mi proyecto de grado el cual consiste en automatizar mi departamento usando PICs; bueno basicamente lo que hace el PIC es recibir un SMS enviado desde cualquier movil y accionar diferentes cosas en base a reles, en otras palabras el PIC recibe un mensaje y este le manda una señal a un o varios reles y estos proceden abrise o cerrarse; el problema que se me ha presentado esque no puedo independizar los reles, osea si quiero activar el rele dos, primero debo activar el rele uno, porque en el codigo fuente esta primero la linea que contiene al rele uno, entonces quiero saber si hay la posiblidad de saltarme esas lineas de codigo para que no siga el orden logico o bien sea poner condicionantes para que si a determinada accion se active cualquier rele ya sea el uno el dos, el tres, etc.

Adjunto mi codigo fuente que este hecho en Basic, en microcode studio.

Cualquier ayuda m sería de gran utilidad.

Gracias

Hola vi tu código y según entiendo, el espera a que llegue 1 de 3 mensajes y según el que llegue primero es la acción a tomar, así que si primero llega "Activar R2", debería activar R2, bueno esa es mi primera teoría, ahora el "WAIT", es para indicarle que debe esperar hasta que llegue una secuencia exacta de caracteres y de ser así entonces se quedaría en la primera linea de serin2, hasta que llegue "Activar R1", ahora como no utilizas un gosub si no goto, las demás nunca van a llegar a funcionar ya que retorna directo a inicio y quedaría siempre en la primera linea.
Ahora para lograr lo que tu quieres una opcion es darle un timeout a la sentencia serin2, de tal manera que si no llega esa en un tiempo determinado la primera cadena de caracteres, siga a la siguiente con una subrutina.

Quedaría algo asi:

Código:
include "modedefs.bas"
define OSC 4
CMCON=7
REL1 VAR PORTA.0
REL2 VAR PORTA.1                   
RX VAR PORTB.0
TX VAR PORTB.1

INICIO:
GOTO RECIBIENDO1

RECIBIENDO1:
SERIN2 TX,16468,100,RECIBIENDO2,[WAIT("Activar R1")]  'espera 100ms y si no llega nada se va a RECIBIENDO2
HIGH REL1
pause 5000
goto ENVIAR
RECIBIENDO2:
SERIN2 TX,16468,100,RECIBIENDO3,[WAIT("Activar R2")] 'espera 100ms y si no llega nada se va a RECIBIENDO3
high rel2
PAUSE 5000
GOto ENVIAR1
RECIBIENDO3:
SERIN2 TX,16468,100,INICIO,[WAIT("Desactivar R1")] 'espera 100ms y si no llega nada se va a INICIO
high rel2
PAUSE 5000
GOto ENVIAR1

GOTO INICIO
end 


ENVIAR:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 activado",26]
        pause 50
    goto inicio

ENVIAR1:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
       PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R2 activado",26]
        pause 50
    goto inicio

DESCATIVAR:
    PAUSE 10000
    SEROUT2 RX,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 desactivado",26]
        pause 50
    goto inicio

Nota: No lo he probado, por lo que no se si funciona, si tienes un esquema en proteus para probar seria mejor y puede haber muchas otras maneras es solo una idea que se me ocurre ahora.
 
Última edición:
Hola amigo, primero antes de todo quiero darte mil gracias por el tiempo que has empleado en mi problema, en segundo lugar te doy las gracias por la ayuda que me has brindado en la programacion, se me han aclarado bastantes cosas partiendo de tu gran ayuda, tiene mucha logica lo que tu haces y procedere a probarlo ya en la practica y te comentaré como me fue.
Reitero mis agradecimientos para contigo
 
Disculpa una pregunta tu cres que con la cmucam 3 pueda tomar una foto y guardarla en una EEprom para verla via ethernet por un Pic conectado a Ethernet

En teoria yo diria que si...

si tienes una memoria lo suficientemente grande para que quepa la foto o si la envias por partes... y claro, si tienes un modulo usart-ethernet...
 
Amigo Reyvilla, acabo de probar el programa en el protoboard, ya esta solucionado en parte el problema, digo en parte porque ahora el problemita q se me esta presentando es que tengo q darle unos 3 a 6 enviar para que se active o desactive algun rele, puesto que como esta ese tiempo de 100 ms y salta a la siguinte subrutina se pone hacer eso en cada serin2 y ahi es donde hay ese retraso, le puse una velocidad de 50 ms y nada y ahora con 10 ms y nada, talves me puedes sugerir algo mas?
 
Ok fíjate hay dos maneras, una la que ya te indique, otra que te trato por aqui: https://www.forosdeelectronica.com/f24/envio-sms-pbp-65929/index3.html
que es guardar el mensaje y luego hacer una comparación o condición según el mensaje, el tema que te coloque tiene tiempo sin movimiento, en fin es lo mismo que tu quieres lograr hacer. Tu código tiene como condición de recepción 3 alternativas,se utiliza como flag o bandera, si no se recibe esa bandera no recibe el dato siguiente, el dato verdadero seria el que le sigue. Para Manejar el dato, debido a que los datos son de 8 bits cada uno necesitarías hacer una arreglo de variable para tu mensaje, si el mensaje es "Activar R1", serian 10 datos de 8bits incluyendo el espacio en blanco que también forma parte del mensaje, para un total de 80bits, la variable mas grande es de 16bits que es la word, así que la única manera es utilizando un arreglo de una variable tipo byte, como indica el amigo lubeck en el tema que te coloque, de todas formas voy a ir chequeando a ver si consigo algo aparte y te estoy avisando
 
Hola y que has hecho hasta el momento si tienes algo adelantado colócalo para poder ayudarte.





Hola vi tu código y según entiendo, el espera a que llegue 1 de 3 mensajes y según el que llegue primero es la acción a tomar, así que si primero llega "Activar R2", debería activar R2, bueno esa es mi primera teoría, ahora el "WAIT", es para indicarle que debe esperar hasta que llegue una secuencia exacta de caracteres y de ser así entonces se quedaría en la primera linea de serin2, hasta que llegue "Activar R1", ahora como no utilizas un gosub si no goto, las demás nunca van a llegar a funcionar ya que retorna directo a inicio y quedaría siempre en la primera linea.
Ahora para lograr lo que tu quieres una opcion es darle un timeout a la sentencia serin2, de tal manera que si no llega esa en un tiempo determinado la primera cadena de caracteres, siga a la siguiente con una subrutina.

Quedaría algo asi:

Código:
include "modedefs.bas"
define OSC 4
CMCON=7
REL1 VAR PORTA.0
REL2 VAR PORTA.1                   
RX VAR PORTB.0
TX VAR PORTB.1

INICIO:
GOTO RECIBIENDO1

RECIBIENDO1:
SERIN2 TX,16468,100,RECIBIENDO2,[WAIT("Activar R1")]  'espera 100ms y si no llega nada se va a RECIBIENDO2
HIGH REL1
pause 5000
goto ENVIAR
RECIBIENDO2:
SERIN2 TX,16468,100,RECIBIENDO3,[WAIT("Activar R2")] 'espera 100ms y si no llega nada se va a RECIBIENDO3
high rel2
PAUSE 5000
GOto ENVIAR1
RECIBIENDO3:
SERIN2 TX,16468,100,INICIO,[WAIT("Desactivar R1")] 'espera 100ms y si no llega nada se va a INICIO
high rel2
PAUSE 5000
GOto ENVIAR1

GOTO INICIO
end 


ENVIAR:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 activado",26]
        pause 50
    goto inicio

ENVIAR1:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
       PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R2 activado",26]
        pause 50
    goto inicio

DESCATIVAR:
    PAUSE 10000
    SEROUT2 RX,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 desactivado",26]
        pause 50
    goto inicio

Nota: No lo he probado, por lo que no se si funciona, si tienes un esquema en proteus para probar seria mejor y puede haber muchas otras maneras es solo una idea que se me ocurre ahora.

mira, creo que la idea es que el mensaje que llegue se direccione a pin estableciendo un valor y tenes que utilizar los condicionales " if - then para que el pic te hubique el pin al cual queres darle salida. asumiendo que ya conoces los comandos AT y la comunicacion serial con pic. cuando el comando llegue al pic debe haber un valor entonces lo que tenes que hacer es si ese valor existe entonces 1 en pin. podes guardar ese valor en una variable y cuando le oredenes al pic que si esa variable es igual al valor contenido en el comando entonces el te direcciona de una.

quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.



solucionado el problema, era el calculo que le habia planteado al pic muchas gracias por la respuesta.
 
Hola amigo, gracias por tu respuesta, sabes justamente eso pensé en un princio porner un IF THEN, es mas ya lo he puesto, pero sin resultados, lo mas seguro esque lo estoy ubicando mal por eso no consigo nada, talves me podrias ayudar partiendo de ese codigo que el amigo reyvilla lo puso a ubicar los IF y la variable?.
Si conozco los comandos AT y la comunicacion serial.

muchas gracias de antemano
 
parece que si es para algun debugger...
como estos...
pics_debugger_keyword.gif


por que mira lo que dice...
DEBUG is one of several built-in asynchronous serial functions. It is the smallest of the software generated serial routines. It can be used to send debugging information (variables, program position markers, etc.) to a terminal program like Hyperterm. It can also be used anytime serial output is desired on a fixed pin at a fixed baud rate.
 
Si eso vi también que puede ser usado como depurador de código, en el manual que yo tengo en español solo tiene el DEBUG y dice lo siguiente:

DEBUG es una de varias funciones seriales asincronicas pre-construidas .Es la más pequeña de las rutinas
seriales generadas por software .Puede ser usada para enviar información de depuración (variables
,posición de marcadores , etc).a un programa terminal como HyperTerm .También se puede usar cuando
se desee salida serial sobre un pin determinado y con un baud rate determinado .
 
:unsure: pues le doy un 90% que solo sirve para eso y la verdad a mi no me agradan mucho los debuggers... soy mas de probar y programar, probar y programar... y pues con eso de las simulaciones en proteus que son bastante buenas no me llama la atención buscarle por ese lado de los debuggers...

si me topo con algun dato adicional te echo un grito...:D
 
Fijate este codigo:

Código:
@ device PIC16F72 , xt_osc, wdt_off, pwrt_on, protect_oN
Include "MODEDEFS.BAS"          ' Include Shiftin/out modes
DEFINE DEBUG_REG PORTC
DEFINE DEBUGIN_REG PORTC
DEFINE DEBUGIN_BIT 7
DEFINE DEBUG_BIT 6 
DEFINE DEBUG_MODE 0 		' 1 = Inverted (w/o max) , 0 = true (with max)
DEFINE DEBUGIN_MODE 0
DEFINE DEBUG_BAUD 9600
'-----------------------------------------------------------------
' HARDWARE DEFINES
'-----------------------------------------------------------------
' Define LCD pins
Define Lcd_dreg Porta
Define Lcd_dbit 0
Define Lcd_rsreg Porta
Define Lcd_rsbit 4
Define Lcd_ereg Porta
Define Lcd_ebit 5
'-----------------------------------------------------------------
Define Osc 4                   ' We're using a 4 MHz oscillator
'-----------------------------------------------------------------
    Adcon1 = 7                     ' Set PORTA DIGITAL
    OPTION_REG.7 = 0               ' DISABLE INTERNAL PULLUPS
    Trisa = %00000000              ' SETS ALL PORTA PINS TO OUTPUT
    Trisb = %00000000              ' ALL OUTPUT
    Trisc = %00001011              ' 6 Pins - LCD and 2 Pins RF Module
'-----------------------------------------------------------------    
RELAY1      VAR PORTB.0     ' RELAY 1
RELAY2      VAR PORTB.1     ' RELAY 2
RELAY3      VAR PORTB.2     ' RELAY 3
RELAY4      VAR PORTB.3     ' RELAY 4
RELAY5      VAR PORTB.4     ' RELAY 5
RELAY6      VAR PORTB.5     ' RELAY 6
RELAY7      VAR PORTB.6     ' RELAY 7
RELAY8      VAR PORTB.7     ' RELAY 8
LED         VAR PORTC.4     ' LED (SINK)
RELAY       VAR BYTE        ' RELAY NUMBER
MYDATA      VAR BYTE        ' GENERAL PURPOSE DATA VARIABLE
INDEX       VAR BYTE        ' SMS INDEX NUMBER
I           VAR BYTE        ' GENERAL VARIABLE
Pause 500                   ' Wait .5 second
'-----------------------------------------------------------------    
B2400   Con 16780           ' Inverted 2400 baud for SERIN2

    HIGH LED 
    PORTB = 0		    ' TURN OFF ALL RELAYS

    Lcdout $fe, 1,   "SMS CONTROL"  ' Send to LCD
    Lcdout $fe, $C0, "SMS TEST C5"  ' Second Line
    PAUSE 2000

    ' GOSUB OLD
LOOP:

    Lcdout $fe, 1,   "WAITING 4 SMS"  ' Send to LCD
    DEBUGIN [WAIT("+CMTI:"), SKIP 7 , DEC INDEX]
    Lcdout $fe, $C0, "SMS RX: " , DEC INDEX ' Second Line
    PAUSE 5000
    Lcdout $fe, 1,   "READ MSG "  ' Send to LCD
    DEBUG "AT+CMGR=", DEC INDEX, 13
    'DEBUGIN [WAIT("+CMGR:"), SKIP 51 , DEC MYDATA]
    DEBUGIN [WAIT("+CMGR:"), SKIP 53 , DEC MYDATA]
    Lcdout $fe, 1,   "MYDATA: " , DEC MYDATA   ' Send to LCD
    PAUSE 3000
    
    SELECT CASE MYDATA
    
    CASE 20
        Lcdout $fe, 1,   "RELAY 2"
        Lcdout $fe, $C0, "ON" 
        
    CASE 21
        Lcdout $fe, 1,   "RELAY 2"
        Lcdout $fe, $C0, "OFF" 
    
    CASE 10
        Lcdout $fe, 1,   "RELAY 1"
        Lcdout $fe, $C0, "ON" 
        
    CASE 11
        Lcdout $fe, 1,   "RELAY 1"
        Lcdout $fe, $C0, "OFF" 
        

    CASE 30
        Lcdout $fe, 1,   "RELAY 3"
        Lcdout $fe, $C0, "ON" 
        
    CASE 31
        Lcdout $fe, 1,   "RELAY 3"
        Lcdout $fe, $C0, "OFF" 

    CASE 40
        Lcdout $fe, 1,   "RELAY 4"
        Lcdout $fe, $C0, "ON" 
        
    CASE 41
        Lcdout $fe, 1,   "RELAY 4"
        Lcdout $fe, $C0, "OFF" 


    END SELECT
    
    PAUSE 3000
    Lcdout $fe, 1,   "DELETE SMS MSG"
    Lcdout $fe, $C0, "#:" , DEC INDEX
    DEBUG "AT+CMGD=", DEC INDEX, 13
    PAUSE 3000

GOTO LOOP

END

Lo saque de este Link: http://www.picbasic.co.uk/forum/showthread.php?t=3765
Según tengo entendido es para el control de relays a traves de un SMS, por eso mi duda al respecto con esos comandos DEBUG y DEBUGIN :confused:
Quería ver si los ponía a prueba pero aun no se como ya que no tengo un sistema para la recepción de SMS, que modulo uso o que materiales aparte del pic necesito?
 
Última edición:
Atrás
Arriba