Autor Tema: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a  (Leído 4088 veces)

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

Desconectado emelyjose

  • PIC10
  • *
  • Mensajes: 2
ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« en: 20 de Octubre de 2014, 20:57:30 »
hola me podrías ayudar o por lo menos guiarme como debo hacer para realizar dos o tres funciones simultáneamente pero con tiempos diferentes, sin que una interfiera en el trabajo de otra.

les explico....... soy nuevo en el foro y también tengo poco tiempo programando y utilizo el Portón IDE y lo poco que lo he expresado en este proyecto

hace tiempo compile un sensor controlador de temperatura que funciona muy bien, el programa que yo uso es el Proton IDE por su facilidad.

Este sensor y controlador lo realice para  una incubadora automática de huevos de gallinas que incluso ya he logrado sacar pollitos.pero dicha incubadora carece de volteo automático el cual es esencial en la incubacion.

lo que pretendo realizar es que con un mismo Pic (16f877a), poder controlar la temperatura y al mismo tiempo este mismo pic me realice el volteado automáticamente cada 8 horas y 25 minutos (8:25 horas).

me explico bien. el pic deberá realizar dos trabajos diferentes pero simultáneamente. 1) el primero que seria ser el censado y controlado de la temperatura (ya esto esta realizado hasta el momento)  y 2) el segundo que es lo que quiero lograr, es que a cada 8 horas con 25 min me permita realizar el volteado de los huevos....... la cuestión esta en que el uno no interfiera en trabajo de otro el otro

en algunos post he leido la utilizacion de los temporizadores pero no se como se usan

¿ como podría realizalo ?

aquí les dejo el código a ver si me puede ayudar,  mi correo es (smiller_josse@hotmail.com)

aqui esta solo es el codigo de programa:
el mismo cuenta con el ajuste de temperaturas altas y bajas en memoria no volatil, utiliza un lcd,pulsores y sensor de temperatura ds1822
'****************************************************************
'*  Name    : UNTITLED.BAS                                       *
'*  Author  : [EMELY SUMOZA]                                    *
'*  Notice  : Copyright (c) 2014 [SMILLER c.a]              *
'*          : All Rights Reserved                                     *
'*  Date    : 20/06/2014                                             *
'*  Version : 1.0                                                         *
'*  Notes   :                                                               *
'*          :                                                                  *
'****************************************************************

Device 16F877A ' Define LCD registers and bits
Declare Xtal=4
TRISA=0
CMCON = 7                    ; Set PORTA and PORTE to digital
;-------------------------------------------------------------------------------

Declare LCD_Type 0           ; definimos el tipo de lcd que se va a utilizar 
Declare LCD_DTPort PORTA     ; Definimos puertos a emplear
Declare LCD_DTPin PORTA.0    ; puertos que se usaran como línea de datos
Declare LCD_RSPin PORTB.2    ; puerto que va funcionar como RESET
Declare LCD_ENPin PORTB.1    ; Definimos el puerto que va a ENABLE en el LCD

;-------------------------------------------------------------------------------

DQ      VAR     PORTB.0      ; One-wire data pin
count_per_c VAR Byte         ; Count per degree C
;-------------------------------------------------------------------------------

temperature VAR Word           
x VAR Byte
x3 var Float
Tempbaj VAR Float
tempalt VAR Float
;------------------------------------------------------------
rF VAR PORTB.7
rC VAR PORTB.6
led VAR PORTA.4
enter VAR PORTB.5
bsubir VAR PORTB.4
bbajar VAR PORTB.3
;-------------------------------------------------------------------------------
DIn VAR Byte
DIn = 0
x1 var Float
x1 = 28.2
x2 var Float
x2 = 28

EWrite Din,[x1]
tempalt  = ERead 0
EWrite Din,[X2]        ;contenido inicial 0 de la EEPROM
                               ;lee la EEPROM 0 y lo guarda en tempalt
tempbaj  = ERead 1            ;lee la EEPROM 1 y lo guarda en tempbaj
;-------------------------------------------------------------------------------
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ."
DelayMS 1500
Print $fe, 1,"BIENVENIDO " ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO .."
DelayMS 1000
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ...."
DelayMS 1000
Print $fe, 1,"TEMPERATURA" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDA "
DelayMS 1000


;-------------------------------------------------------------------------------
inicio: ;3 parpadeos del led que indica funciona
For x =1 To 3
High led
DelayMS 500
Low led
DelayMS 300
Next
;-------------------------------------------------------------------------------
mainloop:
        OWrite DQ, 1, [$CC, $44] ' Start temperature conversion
        High led
        DelayMS 100
        Low led   
        DelayMS 100
       
        OWrite DQ, 1, [$CC, $BE]         ' Read the temperature
        ORead DQ, 0, [temperature.LowByte, temperature.HighByte]
        temperature = temperature */ 1600
        x3=temperature/100
        Print $fe, 1,"TEMPERATURA"
        Print $fe, $c1, Dec1 x3,06, 223,"C"
        ;-----------------------------------------------------------------------
        For x = 1 To 100 ;repetir 100 veces
        If enter =0 Then grabar1a
       
        DelayMS 10
        If X3 <= tempbaj  Then calentar ;si X3 es <tempbaj ir a calentar
        If X3 >= tempalt Then enfriar  ;si X3 es >tempALT ir a ENFRIAR
               
        Low rC : Low rF ;apagar los 2 relés
        Next
       
        GoTo mainloop ;continuar sensando

calentar:
High rC : Low rF
GoTo mainloop

enfriar:
High rF : Low rC
GoTo mainloop

grabar1a:
GoSub soltar

grabar1:
Print  $fe, 1, "Programar temp."
Print $fe,$c0,"baja= ",Dec1 tempbaj ,223,"C"
DelayMS 50
If bbajar=0 Then restar1
If bsubir=0 Then sumar1
If enter=0 Then grabarA
GoTo grabar1

restar1:
GoSub soltar ;programa antirrebote de tecla
If tempbaj < 1 Then grabar1
tempbaj= tempbaj -0.1
GoTo grabar1

sumar1:
GoSub soltar
If tempbaj > 100 Then grabar1
tempbaj= tempbaj + 0.1
GoTo grabar1

;..................................................................
grabarA:
GoSub soltar
EWrite 1,[x1] ;escribir en la dirección 0 de la EEPROM
;...................................................................

grabar2:
Print $fe, 1, "Programar temp."
Print $fe,$c0,"alta= ",Dec1 tempalt ,223,"C"
DelayMS 100
If bbajar=0 Then restar2
If bsubir=0 Then sumar2
If enter=0 Then grabarB
GoTo grabar2

restar2:
GoSub soltar
If tempalt < 5 Then grabar2
tempalt= tempalt -0.1
GoTo grabar2

sumar2:
GoSub soltar
If tempalt > 50 Then grabar2
tempalt= tempalt + 0.1
GoTo grabar2

;................................................................
grabarB:
GoSub soltar
EWrite 0,[x2];escribir en la dirección 1 de la EEPROM
GoTo inicio
;................................................................

soltar: ;programa antirrebote de tecla
 
High led:
High PORTB.7
DelayMS 150
Low led

soltar2:
If bbajar=0 Then soltar2
If bsubir=0 Then soltar2
If enter=0 Then soltar2
DelayMS 100
Return
End

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3495
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #1 en: 22 de Octubre de 2014, 07:06:50 »
La estructura de tu programa no  esta pensada para controlar varios eventos a la vez, esto no quiere decir que no se pueda, solo que es más difícil de hacer. También mezclas los saltos goto y gosub/return, que es algo que no se debería de realizar, el goto hace más de 30 años que no se utiliza en los lenguajes de alto nivel, el gosub/return sustituyo al goto y las funciones sustituyeron al gosub/return, pero no todos los lenguajes basic permiten funciones por lo que el gosub/return se utiliza mucho todavía hoy en día.

Estoy revisando tu código a ver si logro entenderme con el y te cuento. De todas maneras a ver si otro amigo que utilice tu lenguaje basic te puede echar una mano mientras.
Saludos desde Granada, España.

Desconectado siniestro

  • PIC10
  • *
  • Mensajes: 44
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #2 en: 22 de Octubre de 2014, 13:18:55 »
Mira, yo estoy trabajando en un proyecto para control de invernadero donde se leen 2 sensores de humedad y temperatura (dht11), 4 sensores de humedad de la tierra y cada 5 minutos se envia la informacion hacia una computadora, el control de tiempos muy precisos cuando hablamos de n horas o n minutos en PIC yo lo hice conectando un modulo RTC y en cada regreso a la rutina principal yo leo los minutos y las horas y en un if pregunto si es un minuto donde deba mandar la informacion.

Yo programo en PicBasicPro (soy muy novato aun),yo uso subrutinas a grandes rasgos mi codigo es asi:

Código: [Seleccionar]
LOOP:
GOSUB Leo_Tiempo 'se guarda en variables hora y minuto
GOSUB Leo_Sensores 'Guarda los valores en las variables con ese fin
GOSUB EscriboEnLCD 'Muestro datos en la pantall
GOSUB ComprueboEnvio 'Veo si es momento de enviar lo hago, si no, continuo
GOTO LOOP

Leo_Tiempo:
'Aqui mi codigo que lee la hora, minutos y fecha
RETURN

Leo_Sensores:
'Aqui leo los valores de mis sensores
RETURN

EscriboEnLCD:
'Aqui el codigo que escribe los datos en el LCD
RETURN

ComprueboEnvio:
'con una variable bit verifico si mande o no la informacion
'podria poner una hora y minuto específico para enviar
RETURN

De esta forma las pequeñas subrutinas se ejecutan en cada ejecucion del ciclo principal y en base a condiciones se ejutan diversas acciones, se hace tan rapido que parece que todo funciona al mismo tiempo.
Saber de todo un poco, sin ser experto en nada (una filosofia extraña)

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1295
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #3 en: 22 de Octubre de 2014, 16:58:40 »
Definitivamente creo que el uso del Timer1 y de interrupciones puede resolver tu problema.
El timer 1 es un timer de 16 bits eso quiere decir qeu este timer realiza una cuenta desde 0 hasta 65536 (genrando un desborde). Si estas usando un cristal de 4MHz eso quiere decir que el timer es capaz de contar hasta 65536 microsegundos. Ahora bien, el timer tiene prescalares que pueden ser 2, 4 u 8. Puede usar el prescalar en 8, entonces el timer se incrementa en uno cada 8 microsegundos.
Me viene a la mente entonces generar un delay de 0.5 segundos con este timer. 0.5 segundos son 500,000 microsegundos eso quiere decir que si divido 500000/8, obtengo 65200. Eso quiere decir que el timer debe contar 62500 y en ese valor generar un desborde. Como el timer 1 es de 16 bits este puede contar hasta 65536; por lo tanto 65,536-65200 = 3036. Bingo!!!! Tengo que inicializar el valor del timer1 en 3036 o lo que es lo mismo 0X0BDC.
Lo anterior quiere decir que el timer1 generará un desborde cas 0.5segundos. Pero lo que necesitamos es untimer de 8horas y 25 minutos. Bueno pues convirtamos este tiempo en segundos.
Sabemos que 1 hora tiene 60 minutos, por lo tanto 8X60=480 minutos. Ahora bien 480m + 25m = 505 minutos. 1 cada minuto tiene 60 segundos, entonces 505 X 60 = 30300 segundos. Nuestro timer se desborda cada 0.5 segundos, entonces tenemos que multimplicar 30300 X 2 = 60600. Esto quiere decir que el timer se tiene que desbordar 60600 veces. Esto se puede hacer usando una variable de tipo word para contar las veces que el timer1 se dsborda. Y cuando llegas a la cuenta de 60600 desbordes (es decir 60600 veces que el timer se desborda cada 0.5 segundos). La interrupcion te servira para saber cuando se desbordo el timer1 y entonces incrementas la variable de cuenta de desborde en 1, vuelves a reinicializar el timer 1 para que se desborde otra vez en 0.5 segundos. Preguntas si la variable de cuenta de desborde ya es 60600, sino entonces sales de la interrupcion y tu programa continua de forma normal. Pero si ya se alcanzo la cuenta, entonces envias la señal para voltear los huevos.

Te recomiendo que primero hagas lo del timer con la interrupcion y luego lo adpates a tu codigo.
Una vez que tengas esto avisame y lo revisamos.

Saludos.

Elreypic.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3495
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #4 en: 23 de Octubre de 2014, 05:20:08 »
Mira, yo estoy trabajando en un proyecto para control de invernadero donde se leen 2 sensores de humedad y temperatura (dht11), 4 sensores de humedad de la tierra y cada 5 minutos se envia la informacion hacia una computadora, el control de tiempos muy precisos cuando hablamos de n horas o n minutos en PIC yo lo hice conectando un modulo RTC y en cada regreso a la rutina principal yo leo los minutos y las horas y en un if pregunto si es un minuto donde deba mandar la informacion.

Yo programo en PicBasicPro (soy muy novato aun),yo uso subrutinas a grandes rasgos mi codigo es asi:

Código: [Seleccionar]
LOOP:
GOSUB Leo_Tiempo 'se guarda en variables hora y minuto
GOSUB Leo_Sensores 'Guarda los valores en las variables con ese fin
GOSUB EscriboEnLCD 'Muestro datos en la pantall
GOSUB ComprueboEnvio 'Veo si es momento de enviar lo hago, si no, continuo
GOTO LOOP

Leo_Tiempo:
'Aqui mi codigo que lee la hora, minutos y fecha
RETURN

Leo_Sensores:
'Aqui leo los valores de mis sensores
RETURN

EscriboEnLCD:
'Aqui el codigo que escribe los datos en el LCD
RETURN

ComprueboEnvio:
'con una variable bit verifico si mande o no la informacion
'podria poner una hora y minuto específico para enviar
RETURN

De esta forma las pequeñas subrutinas se ejecutan en cada ejecucion del ciclo principal y en base a condiciones se ejutan diversas acciones, se hace tan rapido que parece que todo funciona al mismo tiempo.


El ejemplo que expones esta realmente bien estructurado, pero emelyjose utiliza las pausas (wait) para sincronizar su programa, y esto es un gran obstáculo para trabajar con una rutina principal con eventos. Para que no tenga que cambiar la estructura de su programa lo mejor es como indica elreypic2, con un timer e interrupciones, y si quiere precisión tendra que incorporar un reloj en tiempo real (RTC).
Saludos desde Granada, España.

Desconectado siniestro

  • PIC10
  • *
  • Mensajes: 44
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #5 en: 23 de Octubre de 2014, 23:30:47 »
el reypic2 menciono las interrupciones, yo pense en ellas pero aun no las entiendo bien y de hecho no he trabajado con ellas, por ello yo incorporé el Reloj de tiempo real en mi proyecto para tener una mayor precision (y de paso muestro la fecha y hora en un display de 4 segmentos, ademas de los valores del ambiente).

Citar
El ejemplo que expones esta realmente bien estructurado
Gracias por tus palabras dogflu66  :oops: yo decidí programar asi los PIC tal y como se hace en C++, JAVA y en los demas lenguajes estructurados. .
Saber de todo un poco, sin ser experto en nada (una filosofia extraña)

Desconectado Daikataro

  • PIC10
  • *
  • Mensajes: 22
Re: ayuda como ejecutar dos rutinas simultaneamente en pic 16f877a
« Respuesta #6 en: 26 de Noviembre de 2014, 01:11:15 »
Considerando que es un lapso de tiempo considerable, yo incorporaría un DS1307 al desarrollo y programaría el pic para que volteara los huevos a horas determinadas. Con el 1307 llevando el registro del tiempo te ahorras mucho problema y dejas al pic que sólo le pregunte al relojito "ya es hora? ya? ya?" cual niño pequeño hasta que efectivamente, sea hora.

Puedes incorporar el 1307 tú mismo al desarrollo o si lo prefieres (lo recomiendo personalmente) venden ya plaquitas completamente armadas y listas para adjuntar por poco dinero (por acá cuestan 3-5 USD).


 

anything