Curso de programación de PIC en PICBasic Pro

Hola, no hace mucho me encontre una alarma tirada en el cesto de la basura de un amigo, asi que no dude en tomarla y ahora estoy en fase de recicle.
Esta alarma es un sistema que permite tener sensores alambrico e inalambricos; Como no tiene la posibilidad de conectar teclado, la hace practicamente obsoleta para recuperar y o re-programar, por lo tanto, se me ocurrio adicionar unproyecto que tengo de backup celular y hacer nuevamente que esta alarma funcione nuevamente; O sea, voy a implementar el circuito, pero con otra logica, y adicionando otras funciones mas.

hacking_alarm_2.JPG

hacking_alarm_3.JPG

pasando en limpio el circuito, simplificamos lo que nos interesa y tenemos lo siguiente:

hacking_alarm_1.JPG

La idea de mi re-diseño, es sumar un backup celular con un motorolla C115; y la etapa de control de salidas y entradas, reciclar la vieja tarjeta... Acá un ejemplo de mi proyecto de backup celular con Motorolla c115:


Lista de comandos AT: https://en.wikipedia.org/wiki/Motorola_phone_AT_commands

No es nada del otro mundo, pero cito este tema acá para compartir algunas partes de mi programa que se, que de seguro a mas de uno le puede servir para sus proyectos....
En esta 1era beta, voy a implementar un 16F877A, pero futuro vere si implemento un 18F4550 asi programo por software externo la lista blanca de numeros de telefonos, mensajes pre-grabados, etc

Hacking_AlarmBupCEL.jpg

Aca un estracto de como mandar un mensaje SMS con el motorola c115

Código:
NUM0 var byte
NUM0 = "1"   
;***numero de usuario1***
NUMA1 var byte
NUMB1 var byte
NUMC1 var byte
NUMD1 var byte
NUME1 var byte
NUMF1 var byte
NUMG1 var byte
NUMH1 var byte

;***numero de usuario2***
NUMA2 var byte
NUMB2 var byte
NUMC2 var byte
NUMD2 var byte
NUME2 var byte
NUMF2 var byte
NUMG2 var byte
NUMH2 var byte

.......

SEROUT2 portc.6,84,["AT",13]
PAUSE 500
serout2 portc.6,84,["AT+CMPS=",34,"SM",34,44,34,"SM",34,44,34,"SM",34,13]
pause 2000
serout2 portc.6,84,["AT+CMPS=",34,"ME",34,44,34,"ME",34,44,34,"ME",34,13]
PAUSE 2000
serout2 portc.6,84,["AT+CMGF=1",13] ; pasar modem gsm a modo texto
pause 500
serout2 portc.6,84,["AT+CMGS=",34,DEC NUM0,DEC NUMA1,DEC NUMB1,DEC NUMC1,DEC NUMD1,DEC NUME1,DEC NUMF1,DEC NUMG1,DEC NUMH1,34,13]
PAUSE 300
SEROUT2 portc.6,84,["DISPARO ALARMA",26] ; enviar texto
pause 200
serout2 portc.6,84,["AT+CMGS=",34,dec NUM0,dec NUMA1,dec NUMB1,dec NUMC1,dec NUMD1,dec NUME1,dec NUMF1,dec NUMG1,dec NUMH1,34,13]
pause 300
SEROUT2 portc.6,84,["DISPARO ALARMA",26]; enviar
PAUSE 5000
SEROUT2 portc.6,84,["AT",13]
PAUSE 1000
serout2 portc.6,84,["AT+CMPS=",34,"SM",34,44,34,"SM",34,44,34,"SM",34,13]
pause 2000
serout2 portc.6,84,["AT+CMPS=",34,"ME",34,44,34,"ME",34,44,34,"ME",34,13]
PAUSE 2000
serout2 portc.6,84,["AT+CMGF=1",13] ; pasar modem gsm a modo texto
pause 500
serout2 portc.6,84,["AT+CMGS=",34,dec NUM0,dec NUMA2,dec NUMB2,dec NUMC2,dec NUMD2,dec NUME2,dec NUMF2,dec NUMG2,dec NUMH2,34,13]
PAUSE 300
SEROUT2 portc.6,84,["DISPARO ALARMA",26]; texto a enviar 
pause 200
serout2 portc.6,84,["AT+CMGS=",34,dec NUM0,dec NUMA2,dec NUMB2,dec NUMC2,dec NUMD2,dec NUME2,dec NUMF2,dec NUMG2,dec NUMH2,34,13] ; enviar SMS
pause 300
SEROUT2 portc.6,84,["DISPARO ALARMA",26]; enviar
PAUSE 300

Ahora voy a pulir lo que tengo hasta ahora y sacarle un poco mas de brillo; Ni bien ueda terminar aunque sea la 1er parte, voy a subir para compartir el resto... estoy trabado en como sumar controles RF y o sensores RF en la memoria para adicionar o borrar dispositivos inalambricos... En fin, esto es solo el inicio
 

Adjuntos

  • HackAlarmBupCEL.pdf
    2.4 MB · Visitas: 53
para los que me preguntaron como es la parte receptora, 1ero que nada les pido que no me pregunten porprivado asi toda la info queda aca y sirve para todos... 2do, enmodo respuesta, la etapa receptora es 98% siilar a la que esta aca con el lm358
https://www.forosdeelectronica.com/f22/esquema-pcb-modulo-433-mhz-comercial-99526/
Bueno... ya tengo algo funcionando; en un rato si me hago de tiempo libre con el trabajo, me voy a poner a soldar cables y armar la placa del pic con la alarma vieja...
la idea seria que quede algo asi:


aca unas fotos de los avances :cool:

placa ya sin el micro original...
hacking_alarm_4.JPG

soldando los 1eros conductores...
hacking_alarm_5.JPG

Al terminar, le di un refuerzon con la pistola de plastico para evitar movimientos que me desuelden los conductores...
hacking_alarm_6.JPG

Tenia una placa generica mia de 40 pines que se adapta perfecto para el proyecto, sai que me puse a perforarla...
hacking_alarm_7.JPG

vista del gabinete con el trafo, la bateria y el hardware antiguo
hacking_alarm_8.JPG

hacking_alarm_9.JPG

idea de donde va a quedar la otra placa... y tengo que perforar la chapa del frnte para poner el display
hacking_alarm_999.JPG

esto solo es el 10% del trabajo... despues tengo que hacer el teclado RF :rolleyes:
Es indispensable antes de armar el sistema, o sea, activar la alarma, saber si todos los sensores estan funcionando o por lo menos, si estos no estan activados (ventanas o puertas abiertas, etc); Es por eso que le sume un par de lineas mas para chequear todas las zonas cuando recibe la orden de activar...les muestro unas lineas de como lo hice

Código:
BACKUP:
SENAL=0
LCDOUT $FE,1
PAUSE 200
LCDOUT $FE,$80,"  MODO ALARMA   "
LCDOUT $FE,$C0,"  DESACTIVADA   "
BACKUP2:
SERIN PORTB.1,T2400,50,BACKUP2,SENAL
if SENAL="A" then 
    HIGH BIP
    PAUSE 900
    LOW BIP
    GOTO CHECK
   ENDIF
GOTO BACKUP2

;***************************
;===========================
;***************************
CHECK:
if zona1 = 0 then Z1=1
if zona2 = 0 then Z2=2
if zona3 = 0 then Z3=3
if zona4 = 0 then Z4=4
if zona5 = 0 then Z5=5
if zona6 = 0 then Z6=6
IF PORTB.0=0 THEN Z7=7

if Z1 > 0 THEN ERROR
if Z2 > 0 THEN ERROR
if Z3 > 0 THEN ERROR
if Z4 > 0 THEN ERROR
if Z5 > 0 THEN ERROR
if Z6 > 0 THEN ERROR
IF Z7 > 0 THEN ERROR
GOTO INICIO   ; sub programa donde monitoreamos las zonas

ERROR:
LCDOUT $FE,1
PAUSE 200
LCDOUT $FE,$80,"ERROR EN ZONAS: "
LCDOUT $FE,$C0,DEC Z1," ",DEC Z2," ",DEC Z3," ",DEC Z4," ",DEC Z5," ",DEC Z6," ",DEC Z7
PAUSE 2000
Z1=0
Z2=0
Z3=0
Z4=0
Z5=0
Z6=0
Z7=0
GOTO BACKUP
mañana despues de trabajar, seguire otro buen rato...

Saludos


pd: Ricardo, no me dejo editar e mensaje anterior para poner todo junto... disculpas
 
Última edición:
ya casi casi lo tengo... ya hice unas pruebas y corregi algunas cositas... Como sabia que despues tenia que modificar casi todo para poder configurarlo por software, migre todo al 18F4550 y despues de hacer todo eso, no me arrancaba... le di tantas vueltas que casi casi lo tiro por la ventana (No me reconocia la PC el hardware)...
Se me ocurrio medir el capacitor de VUSB y estaba dañado :rolleyes: sin este capacitor, o con un capacitor de un valor fuera de los 220nF/470nF, no funciona :oops:

hacking_alarm_10.JPG

hacking_alarm_11.JPG

hacking_alarm_12.JPG

Ni bien termine de emprolijar todo y armar el conector RS232 para la comunicacion con el celular C115, armo video y subo las lineas de programacion mas relevantes para que puedan armar sus ideas.
Saludos


PD: El software en Vb me esta volviendo loco, pero vamos a ver si lo puedo sacar a flote bien, sin ningun error :cry:



Bien.... 1er problema surgente.. cuando estaba reformando todo, se me ocurrio ver la manera de reciclar unos controles remotos que tenia tirado... como no sabia si eran de 2400-4800 o 9600 baudios, para ver, se me ocurrio hacer esto:

Código:
INISISTEMA:
GOSUB PRUEBASENAL
IF SENAL = 0 THEN 
  LCDOUT $FE,1
   LCDOUT $FE,$80,"     NO HAY     "
   LCDOUT $FE,$C0," SENAL ENTRANTE "
   
GOTO INISISTEMA
ENDIF
IF SENAL > 0 THEN BACKUP
IF PORTA.1 = 0 THEN BACKUP
GOTO INISISTEMA


PRUEBASENAL:
LCDOUT $FE,1
LCDOUT $FE,$80," PROBANDO SENAL "
FOR X = 1 TO 5
high bip
pause 1100
low bip
GOSUB TEST1
high bip
pause 1100
low bip
GOSUB TEST2
NEXT
goto inisistema

TEST1:
LCDOUT $FE,$C0,"     EN 2400    "
SERIN PORTB.1,T2400,2000,TEST1A,rfprog1
RETURN

TEST2:
LCDOUT $FE,$C0,"     EN 9600    "
SERIN PORTB.1,T9600,2000,TEST2A,rfprog2
RETURN

TEST1A:
RFprog1= SENAL
GOTO INISISTEMA

TEST2A:
RFprog2= SENAL
GOTO INISISTEMA

Pero de la imaginacion al hecho, me parece que algo confundi o mal interprete... No logre que capture ni ruido :cry:
mi idea era que capture algo...aunque sea unos bits... sera que tendre que trabajarlo con una variable word? voy a probar otras cosas pero con otro micro para ver si puedo leer los bits (si no mal recuerdo, la gran mayoria trabaja con 10 bits) aunque sea de los controles remotos y guardarlos... Si alguien tiene una idea de como puedo encarar esta parte...orientacion... cualquier cosa es bienvenida; Slaudos
 
Última edición:
Les tengo una pregunta...

estoy trabajando con la libreria del punto flotante y me surgio una duda...

si yo quiero hacer una multiplicacion en enteros digamos 100*14, pues no es problema pongo:

Código:
aint = 100
Gosub itofa			' Convert aint to float

bint = 14
Gosub itofb			' Convert bint to float

Gosub fpmul			
Gosub ftoia	
Lcdout  $fe,1, "100*14="
If  (aint.15) Then Lcdout "-"	
lcdout dec abs aint

¿pero como en nombre de zeus se le hace para multiplicar un entero con un flotante como por ejemplo 100*2.5 ?
 
Ya le diste una leida a las libretias de darrel tailor ? ( :unsure: mepa que se escribia asi)
Creo que guarde en algun momento algo similar a lo que planteas...dejame ver si encuentro en ie disco esta..no importa si esta en asm?
 
Ya le diste una leida a las libretias de darrel tailor ?

Nop, no las he leido...

Creo que guarde en algun momento algo similar a lo que planteas...dejame ver si encuentro en ie disco esta..no importa si esta en asm?
quisiera hacerlo en basic utilizando la libreria del PBP, y lo que quiero evitar es inmiscuirme en ver como esta echa la libreria que hasta donde se utiliza la libreria propia del MPASM (math16).

tambien quiero evitar el hacer operaciones antes, como por ejemplo dividir o sea 5/100 y despues sumar al entero 2 y bla, bla.. quisiera poner directamente el flotante en alguna variable de las que utiliza la propia libreria y despues efectuar la multiplicacion que supongo se podria.
 
Última edición:
Lindo laburito... si no queres usar asm y o cuentas,
Sip, está laborioso en cuanto a investigar por donde meterla, pero si se puede porque en los ejemplos de la librería utilizan un resultado que arroja flotante y lo multiplican por una cantidad y si da.
Lo que no logro decifrar, es por dónde regresa y cómo ese valor.

Hago la pregunta por si alguien ya lo resolvió, y mientras tanto le sigo indagando.
Si encuentro la forma la comparto pues no hay mucha información al respecto o no la he encontrado. XD

---------- Actualizado después de 2 horas ----------


Me encontré esto:
It should be ...
((high_%_span - low_%_span ) / (high_count_span - low_count_span)) * (Measured - low_count_span)

((100000 - 0) / (46461 - 22600)) * (Measured - 22600)

Since ((100000 - 0) / (46461 - 22600)) are all constants that are known ahead of time ...
They can be reduced to a single constant ... 4.190939189

4.190939189 * (Measured - 22600)

In floating point format, 4.190939189 = 0x81061C2D.
Which makes the code much easier...


Measured VAR WORD
Measured = 30000 ; 22600 - 46461
...
bexp = $81 ; 4.190939189
bargb0 = $06
bargb1 = $1C
bargb2 = $2D


AINT = Measured - 22600
GOSUB ItoFA
GOSUB FPMUL


BINT = 1000 ; /1000 for % with 3 decimal places
GOSUB ItoFB
GOSUB FPDIV

fpplaces = 3 : gosub fpdisplayr ; put the percentage result on LCD
Creo que por ahí va.

¿Pero de dónde sale que?:
In floating point format, 4.190939189 = 0x81061C2D

Bueno, me respondo. XD
Sale del protocolo IEEE 754

http://www.h-schmidt.net/FloatConverter/IEEE754.html

Ahora a estudiar cómo se hace eso. XD

Edito:

Si funciona el código, pero no descifro como integra el número.

IMG_20150918_193444.jpg

Lo logreeeeee!!!!!!!!!! :LOL:

para sacar ese numero esta en la nota de microchip AN575, esta re-facil pero si no nos dicen pues ¿como? XD...

Aunque vi un rumor de que esa libreria tiene un BUG pero no estoy seguro, porque el que lo menciono parecia que no tenia mucha idea, pero bueno... empezare a jugar con esa libreria para ver hasta donde llega.
 

Adjuntos

  • AN575.pdf
    786 KB · Visitas: 38
Última edición:
Les dejo un simple ejemplo de un Rele Temporizado (hasta 24Hs)- Rele Biestable (hasta 60 minutos) con un PIC 16F628... Esta configurado para trabajar en RC y es todo por software (sin TMR), por lo tanto los retardos no son perfectos....

Código:
'****************************************************************
;************* CONFIGURACION DE VARIABLES GENERALES *************
;****************************************************************

Define osc 4    ; definimos el oscilador en 4 mhz

CMCON = 7               ; PUERTO A TODO DIGITAL
TRISA = %11111111       ; PUERTO A TODO COMO ENTRADA
TRISB = %00000000       ; PUERTO B TODO COMO SALIDA

Define    LCD_DREG    PORTB    ;PUERTO B.O.1.2.3 DEL PIC PARA CONTROL DEL LCD
Define    LCD_DBIT    0
Define    LCD_RSREG    PORTB    ; PIN RS CONECTADO EN PORTB5
Define    LCD_RSBIT    5
Define    LCD_EREG    PORTB    ; PIN E CONECTADO EN PORTB4
Define    LCD_EBIT    4
DEFINE LCD_BITS      4             ;LCD CONFIGURADO EN 4 BITS
DEFINE LCD_LINES  2          ;LCD DE 2 LINEAS

START_button var PORTA.0   ; boton inicio
STOP_button var PORTA.1    ; boton parada
CLEAR_button var PORTA.2   ; boton borrar
MAS_button var PORTA.3     ; boton mas
MENOS_button var PORTA.4   ; boton menos
DISP_button var PORTA.5    ; entrada disparo auxiliar
RELAY var PORTB.6          ; salida para control del relay
BEEP VAR PORTB.7           ; salida para el control del buzzer

bandera var byte           ;variable auxiliar 
Ticks VAR byte             ;variable auxiliar para los for-next
setHOUR VAR BYTE           ; variable set HORAS programadas
setMINUTE VAR BYTE         ; variable set minutos programadas
Hour VAR byte              ; variable HORAS cronometro
Minute VAR byte            ; variable Minutos cronometro
Second VAR byte            ; variable Segundos cronometro
DelayHon VAR byte            ; uso futuro
DelayMon var byte            ; uso futuro
DelaySon var byte
DelayHoff VAR byte            ; uso futuro
DelayMoff var byte            ; uso futuro
DelaySoff var byte            ; uso futuro
SETHOUR=0                  ; valor inicial de la variable 
SETMINUTE=0                ; valor inicial de la variable

;*****************************************************************
;******************** INICIO DEL PROGRAMA ************************
;*****************************************************************
Inicio:
HOUR = 0                ; valor inicial de la variable
MINUTE=0                ; valor inicial de la variable
SECOND=0                ; valor inicial de la variable
LCDOUT $FE, 1           ; limpiamos el lcd
HIGH BEEP               ; encender buzzer
PAUSE 1000              ; pausa 1 segundo
LOW BEEP                ; apagar buzzer
pause 50

MENU:
LCDOUT $fe,2,"RTempo   (START)"  
LCDOUT $fe,$c0,"RBiestable(STOP)"  
 if start_button = 0 then 
 LCDOUT $FE, 1
 goto menu2
 endif
 IF stop_button = 0 then CONFIG2
goto MENU

menu2:
LCDOUT $fe,2,"Ini Tempo(-)"  
LCDOUT $fe,$c0,"Prog Tempo(+)"  
 if mas_button = 0 then TEMPO        ;si presionamos boton "MAS",ir a TEMPO 
 IF MENOS_BUTTON = 0 THEN INI_TEMPO  ;si presionamos boton "MENOS",ir a INI_TEMPO
 IF stop_button = 0 then 
 LCDOUT $FE, 1
 goto menu 
 endif
goto menu2
;**************************************************************************
;************* INICIO SUBPROGRAMA PARA CONFIGURAR TIEMPO ******************
;**************************************************************************

TEMPO:
HIGH BEEP
PAUSE 1000
LOW BEEP
PAUSE 800
HIGH BEEP
PAUSE 1000
LCDOUT $FE, 1
LOW BEEP 
pause 50
;**************************************************************************
;**************** sub programa para configurar el tiempo ******************
;**************************************************************************
CONFIG:
  LCDOUT $fe,2,"INICIO   (START)"
  LCDOUT $fe,$C0,DEC2 SETHour,":",DEC2 SETMinute,":00"

IF MAS_button = 0 THEN
  PAUSE 500 
  SETMinute = SETMinute + 1
IF SETMinute = 60 THEN
  SETMinute = 0
  SETHour = SETHour + 1
IF Hour => 24 THEN
 Hour = 24
  ENDIF
   ENDIF
    ENDIF
     

IF CLEAR_button = 0 THEN
  SETHour = 0
  SETMinute = 0
 ENDIF

IF START_button = 0 THEN 
  LCDOUT $FE, 1
  GOTO INI_TEMPO
   ENDIF

GOTO CONFIG

;*****************************************************
;************* PROGRAMA DEL TEMPORIZADOR**************
;*****************************************************

INI_TEMPO:

IF SETHOUR = HOUR AND SETMINUTE = MINUTE THEN

IF STOP_button = 0 THEN GOSUB PARADA
 LCDOUT $FE, 1
  LCDOUT $fe,2,"TIEMPO PROGRAMA"
  LCDOUT $fe,$C0,"    TERMINADO  "
  high beep
  LOW RELAY
  PAUSE 2000
  low beep
  GOTO INICIO
 ENDIF

HIGH RELAY
 
LCDOUT $fe,2,"Set:",DEC2 SETHour,":",DEC2 SETMinute,":00"
LCDOUT $fe,$C0,"Tiempo:",DEC2 Hour,":",DEC2 Minute,":",DEC2 Second

PAUSE 450

GOSUB CONTADOR

IF STOP_button = 0 THEN GOSUB PARADA

GOTO INI_TEMPO

;**************************************************************************
;********************** sub programa para la pausa ************************
;**************************************************************************

PARADA:
LOW RELAY
TICKS=0
LCDOUT $FE, 1
FOR TICKS = 1 TO 4 
LCDOUT $fe,2,"Set:",DEC2 SETHour,":",DEC2 SETMinute,":00"
LCDOUT $fe,$C0,"Tiempo:",DEC2 Hour,":",DEC2 Minute,":",DEC2 Second
PAUSE 250
IF START_button = 0 THEN 
LCDOUT $FE, 1
HIGH RELAY
RETURN
ENDIF
IF CLEAR_button = 0 THEN inicio
NEXT TICKS
TICKS=0
LCDOUT $FE, 1
FOR TICKS = 1 TO 4 
 LCDOUT $FE, 1
 LCDOUT $fe,2,"TIEMPO DETENIDO"
LCDOUT $fe,$C0,"SEGUIR (START)"
PAUSE 250
IF START_button = 0 THEN 
LCDOUT $FE, 1
HIGH RELAY
RETURN
ENDIF
IF CLEAR_button = 0 THEN inicio
NEXT TICKS
GOTO PARADA

;**************************************************************************
;****************** sub programa para el cronometro ***********************
;**************************************************************************

CONTADOR:
  Second = Second + 1  ; incrementar 1 en variable segundo
 IF Second = 60 THEN   ; consigna: si variable segundos es = a 60, entonces
  Second = 0           ; ponemos variable segundos en 0 
  Minute = Minute + 1  ; incrementamos 1 en variable minuto
 IF Minute = 60 THEN   ; consigna dentro de consigna, si minuto es = 60 entonces
  Minute = 0           ; ponemos variable minutos en 0
  Hour = Hour + 1      ; incrementamos 1 en variable hora
 IF Hour = 24 THEN     ; consigna dentro de consigna, si hora = 24 entonces
  Hour = 24            ; ponemos como limite maximo, hora = 24... modificar este
                       ; valor si se quiere mas horas
   ENDIF               ; cerramos 1era consigna
    ENDIF              ; cerramos 2da consigna
     ENDIF             ; cerramos 3er consigna
 PAUSE 500             ; pausa 1/2 segundo
RETURN                 ; volver

;*****************************************************
;************* PROGRAMA RELAY BIESTABLE **************
;*****************************************************
 CONFIG2:
LCDOUT $FE, 1 

 CONFIG2a:
  LCDOUT $fe,2,"RELAY tiempo ON"
  LCDOUT $fe,$C0,"Min:",DEC2 delaymon," Seg:",dec2 delayson

IF MAS_button = 0 THEN
  PAUSE 500 
 delayson = delayson + 1  ; incrementar 1 en variable segundo
 IF delayson = 60 THEN   ; consigna: si variable segundos es = a 60, entonces
  delayson = 0  
  delaymon = delaymon + 1
IF delaymon = 60 THEN
  delaymon = 0
  delayhon = delayhon + 1
IF delayhon => 24 THEN
 delayhon = 24
  ENDIF
   ENDIF
    ENDIF
     endif
     
IF CLEAR_button = 0 THEN
  delayhon = 0
  delaymon = 0
  delayson = 0
 ENDIF

IF START_button = 0 THEN 
  high beep
  pause 1000
  low beep
  pause 50
  LCDOUT $FE, 1
  GOTO CONFIG3
   ENDIF

GOTO CONFIG2a

CONFIG3:
  LCDOUT $fe,2,"RELAY tiempo OFF"
  LCDOUT $fe,$C0,"Min:",DEC2 delaymoff," Seg:",dec2 delaysoff

IF MAS_button = 0 THEN
  PAUSE 500
delaysoff = delaysoff + 1  ; incrementar 1 en variable segundo
 IF delaysoff = 60 THEN   ; consigna: si variable segundos es = a 60, entonces
  delaysoff = 0     
  delaymoff = delaymoff + 1
IF delaymoff = 60 THEN
  delaymoff = 0
  delayhoff = delayhoff + 1
IF delayhoff => 24 THEN
 delayhoff = 24
  ENDIF
   ENDIF
    ENDIF
     endif

IF CLEAR_button = 0 THEN
  delayhoff = 0
  delaymoff = 0
  delaysoff = 0
 ENDIF

IF START_button = 0 THEN 
  high beep
  pause 1000
  low beep
  pause 50
  LCDOUT $FE, 1
  GOTO INI_RELAY
   ENDIF

GOTO CONFIG3

INI_RELAY:
  LCDOUT $fe,2,"ESPERANDO"
  LCDOUT $fe,$C0,"INICIO"
IF START_button = 0 THEN INI_RELAY2
IF STOP_button = 0 THEN INICIO
GOTO INI_RELAY
 
  
INI_RELAY2
hour=0
minute=0
second=0
LCDOUT $FE, 1
gosub activar_relay
hour=0
minute=0
second=0
LCDOUT $FE, 1
gosub desactivar_relay

IF STOP_button = 0 THEN GOSUB INICIO
 
GOTO INI_RELAY2

activar_relay:
IF STOP_button = 0 THEN GOSUB INICIO
bandera=1
LCDOUT $fe,2,"SI:",DEC2 delaymon,":",dec2 delayson,"NO:",DEC2 delaymoff,":",DEC2 delaysoff
LCDOUT $fe,$C0,"T:",DEC2 Minute,":",DEC2 Second," R:",dec bandera
HIGH RELAY
pause 500
gosub contador
IF delaymon = MINUTE and delayson = second THEN return
goto activar_relay

desactivar_relay:
IF STOP_button = 0 THEN GOSUB INICIO
bandera=0 
LCDOUT $fe,2,"SI:",DEC2 delaymon,":",dec2 delayson,"NO:",DEC2 delaymoff,":",DEC2 delaysoff
LCDOUT $fe,$C0,"T:",DEC2 Minute,":",DEC2 Second," R:",dec bandera
low relay
pause 500
GOSUB CONTADOR
IF delaymoff = MINUTE and delaysoff = second THEN return
goto desactivar_relay
PAUSE 450
IF STOP_button = 0 THEN GOSUB PARADA
goto INI_relay

;*************************************************************************
END                    ; Fin del programa
;*************************************************************************
Saludos
 

Adjuntos

  • tempoLCD.rar
    19.5 KB · Visitas: 90
Hola tengo un problema con un lcd 4x16 .Mi objetivo es hacer 4 cronómetros independientes en las 4 lineas y dependiendo de la entrada (RA0, RA1,RA2,RA3) con un interruptor o pulsador , que se activen o se pause el tiempo.
Primero he hecho un solo cronometro y me funciona (adjunto el programa y el esquema para la simulación) , el problema es al intentar que sean 4 cronómetros el tiempo va super despacio o no cuentan .
Si alguien me pudiera ayudar , os dejo tambien el codigo y el circuito para simular.
 

Adjuntos

  • CRONO41.rar
    62.8 KB · Visitas: 37
  • CRONO1.rar
    67.1 KB · Visitas: 41
Primero he hecho un solo cronómetro y me funciona.
El problema es al intentar que sean 4 cronómetros, el tiempo va súper despacio o no cuentan.
El programa está muy mal. Para eso necesitas usar un timer. (P.E. El Timer 1 y algunas banderas "Flags")
Las configuraciones también están mal:
El PIC18F2550 en el puerto E, tan sólo cuenta con el bit 3, (MCLR) y no es necesario que se configure como entrada porque por defecto ese pin es únicamente de entrada.
Y si escribes 8 bits en el registro TRISE, estarás escribiendo en locaciones inexistentes.

También es importante que uses la palabra de configuración correcta, porque en este tipo de PIC que puede ser llevado hasta 48 MHz, si no se usa la configuración adecuada, no funcionará o lo hará mal.
Sobre éste tema puedes usar el buscador porque ya se ha tratado.

La configuración del registro ADCON1 para hacer los puertos digitales también se ha tratado en el Foro, pero puedes recurrir a la hoja de datos y ver cuál es la configuración correcta.

En fin, ese programa es para volverlo a escribir desde 0.
 
Última edición:
Buenos días. D@rkbytes, he leído la respuesta que has dejado sobre mi caso.
Intento hacer 4 cronómetros en una pantalla y voy a rehacer el código desde cero.
Estoy iniciándome en este mundo, así que hay partes que me cuesta mas entenderlas.

He montado uno físico con una lcd y me funciona, el problema es que no sé usar los timers, como me recomiendas.
Lo he hecho con el código que te pasé y el tiempo no va sincronizado, tarda 10 segundos más cada minuto.

He leído por el foro algún ejemplo, éste es el enlace donde lo vi:
https://www.forosdeelectronica.com/f26/cronometro-picbasic-18f2550-128749/#post1005262

¿Podrías compartir el ejemplo, para ver si consigo hacer el de 4 tiempos?
 
Última edición por un moderador:
He leído por el foro algún ejemplo, éste es el enlace donde lo vi:
https://www.forosdeelectronica.com/f26/cronometro-picbasic-18f2550-128749/#post1005262

¿Podrías compartir el ejemplo, para ver si consigo hacer el de 4 tiempos?
Claro que si.
Aquí está el ejemplo de cronómetro usando el Timer 1 (PIC18F2550)

El programa está escrito en MicroCode Studio v5.0.0.5 y PBPX v3.0.8.1
También se puede compilar con versiones anteriores pero se debe omitir la palabra de configuración y usar el procedimiento que se mencionó en éste enlace: https://www.forosdeelectronica.com/f26/cronometro-picbasic-18f2550-128749/#post1005262

PD:
También puedes ver otro ejemplo: Cronómetro con Timer 1 y displays de 7 segmentos

Suerte.
 

Adjuntos

  • 18F2550 Cronómetro con Timer1.rar
    59.4 KB · Visitas: 59
Muchas gracias, D@rkbytes.
El programa me ha sido de gran ayuda, aunque era más complicado de lo que esperaba.
También lo he montado en un protoboard y va perfecto, sin ningún tipo de retardo.

¿Para hacer que el cronometro sólo cuente cuando esté el pulsador presionado, debería quitar las lineas del contador,o escribirlas de manera que siempre se esté incrementando y cuando deje de presionar pare?
Programa:
PHP:
Button pulsador,0,255,10,B0,0,Display  ; Si se presiona el pulsador...
        While pulsador = 0          ; Mientras esté pulsado...
            contador = contador + 1 ; Incrementar "contador"
            Pause 1                 ; Retardo de 1ms.
            
            If contador = 3000 Then ; Si "contador" llegó a 3000 (3 segundos)...         
                T1CON = 0           ; Deshabilitar Timer1
                horas = 0           ; Limpiar "horas"
                minutos = 0         ; Limpiar "minutos"
                segundos = 0        ; Limpiar "segundos"
                milisegundos = 0    ; Limpiar "milisegundos"
                flag = 1            ; Mantener "flag" en 1 (Para que el soltar el pulsador no avance el conteo)
                LCDOut $FE,$C3,"00:00:00.00"    ; Poner en ceros la pantalla.
            EndIf
        Wend
Un saludo.
 
Última edición por un moderador:
Esa rutina que muestras sobre el pulsador, tiene tres funciones.
Cada vez que se presiona cambia el estado de una bandera (Flag), y eso determina si el Timer 1 se enciende o se apaga.
Pero cuando el pulsador permanece presionado por más de 3 segundos, entonces se resetea el conteo y se apaga el Timer 1.

Si lo único que quieres es que el tiempo se muestre mientras se presiona el pulsador, entonces es más sencillo.
Por ejemplo:
Código:
While Pulsador = 0
    T1CON.0 = 1
Wend
T1CON.0 = 0
Y para reiniciar a 0, lo harás usando el reset (MCLR) del PIC.

También se puede cambiar el estado de una bandera que podrás usar dentro del servicio de interrupción.
El objetivo lo puedes realizar de otras formas porque es condicional.
 
He sustituido las lineas que me has puesto por las otras ,y parece que funciona bien (el tiempo esta detenido y si presiono el pulsador empieza a contar si dejo de presionar el tiempo se para , todo el tiempo viendose en la lcd) , por lo menos en la simulación del isis.

Te adjunto el código para que lo veas ,he modificado el que me pasaste. Al cambiarlo quite las banderas ,esto puede influir en que ahora no me haga un segundo justo ?

Si esta bien voy a pasar hacer que se vean dos cronometros , pero no se que estructura seguir ,se puede hacer con el Timer 1 o necesitaria mas Timer ya que este lo estoy usando en el primer cronometro.
 

Adjuntos

  • CRONO_1.rar
    72.5 KB · Visitas: 37
Al cambiarlo quite las banderas.
¿Ésto puede influir en que ahora no me haga un segundo justo?
No, eso es algo que no logré solucionar con el PIC18F2550.
He revisado todos los registros sin encontrar nada extraño, pero posiblemente algo se me está pasando.
No pude encontrar la causa por la que va un poco más rápido el conteo. :unsure:
Con otros PIC's va muy exacto, pero con éste 18F2550 no sé qué esté pasando.

Si está bien, voy a pasar a hacer que se vean dos cronómetros, pero no sé qué estructura seguir.
¿Se puede hacer con el Timer 1 o necesitaría más Timers?
Ya que éste lo estoy usando en el primer cronómetro.
Para otros conteos puedes aumentar las variables y usar banderas, para que sólo se realice el conteo en cada una cuando el estado de su respectiva bandera sea verdadero.

Por ejemplo:
Código:
If crono_1 = 1 Then
    milisegundos_1 = milisegundos_1 + 1
    ; Incremento de las siguientes variables del cronómetro 1
EndIf

If crono_2 = 1 Then
    milisegundos_2 = milisegundos_2 + 1
    ; Incremento de las siguientes variables del cronómetro 2
EndIf

; Etc.
De esa forma usas un solo timer, pero ya no lo debes detener para que el desborde del Timer 1 sirva para incrementar todas las variables.
 
He declarado las variables y cambiado esa parte que me escribiste , pero no se como juntar la parte del programa que usa el timer 1 y que desde ahi me vaya a la parte

If crono_1 = 1 Then
milisegundos_1 = milisegundos_1 + 1
; Incremento de las siguientes variables del cronómetro 1
EndIf

Te adjunto el codigo para que me digas que hago mal.
 

Adjuntos

  • CRONO2.rar
    78.5 KB · Visitas: 33
Para lograr el funcionamiento de esa forma con más de 1 cronómetro, se tienen que modificar algunas cosas.
Ya no se debe actuar como cuando es sólo un cronómetro, porque el Timer 1 siempre debe estar activo.

Adjunto una forma de hacerlo con dos cronómetros.
Dejé el uso de las instrucciones "Button" pero también se puede hacer uso de sentencias "IF"
El problema va a ser que resuelvas que el tiempo de cada cronómetro sólo funcione cuando esté en 1 o en 0 el pulsador correspondiente.
Te menciono éste detalle porque el uso de "While" detendrá el proceso de verificación de otros pulsadores.
 

Adjuntos

  • CRONO2.rar
    41.7 KB · Visitas: 50
Creo que ya esta el programa acabado ,por ahora solo lo he simulado en el ordenador y funciona bien .
Cuando lo monte veré si tiene algún tipo de desfase con el tiempo real .
Lo dejo aquí por si le ves algún tipo de mejoría que le pudiera hacer al código.
 

Adjuntos

  • CRONOMETRO2.rar
    114.4 KB · Visitas: 50
Atrás
Arriba