Autor Tema: Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS  (Leído 4221 veces)

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

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
« Respuesta #15 en: 14 de Diciembre de 2020, 22:24:18 »
Ahora algo de código de la ISR de este proyecto:

1) Inicialización de la USART para recibir los mensajes del módulo GPS a 9600 baudios

Código: [Seleccionar]

; INICIALIZAR RX TX USART 

        bcf STATUS,RP1      ;apuntar       
bsf STATUS,RP0     ;banco1
    ; Ajustar divisor para 9600 baudios para xtal de 8MHZ
movlw 0x33         ; cargar el divisor baurate con 51 (33h), da 9615 = 8.000.000/(16*(51+1) ,  manual pag. 71
movwf SPBRG     ;para clock 8MHz da 9615  o sea +0,16 de error;
;
bsf TXSTA,BRGH ;poner el modo High Speed
bcf TXSTA,SYNC ;poner modo asincronico
        ;
bcf STATUS,RP0 ;apuntar banco 0
bsf RCSTA,SPEN ;conectar RB1 y RB2 como RX y TX, TRISB 1y2 deben ser 1 (buffer de salida desconectado)
bsf STATUS,RP0 ;apuntar banco  1

bsf TXSTA,TXEN ;Habilitar transmison , queda esperando el dato a transmitir
bsf PIE1,RCIE                  ;Habilitar interrupcion de recepcion

bcf STATUS,RP0 ;Apuntar banco 0
bsf RCSTA,CREN ;Habilitar recepcion de datos seriales en RB1 (RXD)
                                                ;Habilitar interrupciones
bsf INTCON,PEIE ; periheral interrup enable (incluye usart)
bsf INTCON,GIE ; all interrup enable


2) ISR,  Rutina de Servicio de Interrupción

Código: [Seleccionar]

ORG     0x0004                 ; interrupt vector location
movwf      WTEMP            ; salvar el W
movfw STATUS,W        ; salvar el
movwf STEMP              ; STATUS

bcf STATUS,RP1 ;  apuntar
bcf STATUS,RP0 ;  banco 0
call usa_rt                      ; llamando al procesar del dato que llegó
                                                        ;
movf   STEMP,W ; recuperar W y STATUS
movwf STATUS            ;
movf WTEMP,W
retfie                               ; return from interrupt 



3) La rutina de proceso del caracter (dato) recibido, usa_rt

Código: [Seleccionar]
;-------------------------------------------------------------------------------------------------------------------
usa_rt
;
        bsf PORTB,AZA4 ;apagar el Led indicador de errores
;
btfss PIR1,RCIF ; llego un caracter, ver como esta el flag de recepcion, debe estar encendido sino es ilogico
goto err_flag  ;hay algun error ilogico!!!

ckc_ferr                           ; llego un dato,  primero procesar errores
btfsc RCSTA,FERR    ;ver si hay error FRAME (o sea que NO se detecto el bit de STOP )
goto err_ferr           ; si hay error FRAME

ckc_over
        btfsc RCSTA,OERR   ;ver si hay error OVERRUN, si llego un dato y el anterior no se leyó!
        goto err_over         ; si hay error Over

sin_error                        ;ninguno de los dos errores fue detectado
movf RCREG,w       ; se resetea el flag de interrupcion RCIF, el FERR  y el dato recibido pasa al W
movwf RCDATO     ;se guarda el dato recibido
goto case_00       ; ir a procesar el Dato recibido!
;
        ;procesar errores, enciende LED indicador y  resetea Flags de errores,  el dato se procesa igual
err_flag
err_ferr
; encender el Led indicador de error, el proximo caracter correcto lo apaga
        bcf PORTA,AZA4   ;encender el indicador de error
goto sin_error     ; si el Led enciende permanente hay un problema

err_over
bcf RCSTA,CREN ;resetear error Overrun
nop
bsf RCSTA,CREN ;habilitar RX
goto err_flag           ; encender el Led indicador de errores y continuar
;                                                                 
;-------------------------------------------------------------------------------------
case_00
;


4) La detección del encabezamiento del mensaje $GNRMC

Código: [Seleccionar]
case_00  ;procesar estado 0 (reposo) de la máquina de estados
;
movfw ESTADO ; Comparar
xorlw 0x00       ; con estado 0
btfss STATUS,Z ;si son iguales saltar
goto case_01   ; no es 0, continuar
;el estado es 0, procesarlo
movfw RCDATO    ;el ESTADO es 0 (reposo), verifcar si llego $
xorlw 0x24      ; comparar con $, el primer caracter del encabezamiento $GNRMC
btfsc STATUS,Z ; ver si llego $, si no llego saltear cambio de ESTADO
goto si_PP       ;exito!, estado 0 y llego un $ ,
clrf ESTADO     ;no exito, esta en 0 pero no es $ lo que llegó
return        ;resetear ESTADO y volver (aca no haria falta resetear)
si_PP ;en ESTADO 0 llego un $, pasar al estado 1 y no echoar dato
movlw 0X01   ; cargar el estado 01
movwf ESTADO  ;pasar al estado 01 de la maquina de estados
return
;
case_01  ;procesar estado 1 y caracter "G"
;
movfw ESTADO  ; Comparar
xorlw 0x01        ; con estado 1
btfss STATUS,Z  ;si son iguales saltar
goto case_02    ; no es 1, continuar
movfw RCDATO    ;el ESTADO es 1, verifcar si llego el caracter G
xorlw 0x47        ; comparar con "G" (código ASCII en exadecimal)
btfsc STATUS,Z  ; ver si llego G, si no llego saltear cambio de ESTADO
goto si_GG        ;exito, estado en 1 y llego un G
clrf ESTADO       ;no exito, esta en 1 pero no es G
return         ;resetear ESTADO y volver, la secuencia exitosa se abortó
si_GG ;en ESTADO 1 llego un G, pasar al estado 2 y no echoar dato
movlw 0x02
movwf ESTADO ;pasar al estado 02
;call echo_ar  ;NO hacer eco del dato G a la PC
return
;
case_02  ;procesar estado 2 y "N"
movfw ESTADO ; Comparar
xorlw 0x02       ; con estado 2
btfss STATUS,Z ;si son iguales saltar
goto case_03   ; no es 2, continuar
movfw RCDATO    ;el ESTADO es 2, verifcar si llego "N"
xorlw 0x4E        ; comparar con N en ASCII exadecimal
btfsc STATUS,Z   ;ver si llego N, si no llego saltear cambio de ESTADO
goto si_NN  ;exito, esta en estado 1 y llego un G
clrf ESTADO ;no exito, esta en 1 pero no es G
return     ;resetear ESTADO y volver
si_NN  ;en ESTADO 2 y llego una N, pasar al estado 3 y no echoar dato
movlw 0x03
movwf ESTADO ;pasar al estado 03
;call echo_ar  ;hacer eco del dato N a la PC
return
;
case_03  ;procesar estado 3 y R
movfw ESTADO ; Comparar
xorlw 0x03   ; con estado 3
btfss STATUS,Z ;si son iguales saltar
goto case_04 ; no es 3, continuar
movfw RCDATO    ;el ESTADO es 3, verifcar si llego "R"
xorlw 0x52       ; comparar con R
btfsc STATUS,Z  ;ver si llego M, si no llego saltear cambio de ESTADO
goto si_RR     ;exito, estado en 3 y llego un R
clrf ESTADO    ;no exito, esta en 3 pero no es R
return     ;resetear ESTADO y volver
si_RR ;en ESTADO 3 llego un R, pasar al estado 4 y no echoar dato
movlw 0x04
movwf ESTADO ;pasar al estado 04
;call echo_ar  ;hacer eco del dato G a la PC
return
;
case_04  ;procesar estado 4 y M
movfw ESTADO ; Comparar
xorlw 0x04       ; con estado 4
btfss STATUS,Z ;si son iguales saltar
goto case_05 ; no es 0, continuar
movfw RCDATO    ;el ESTADO es 4, verifcar si llego "M"
xorlw 0x4D      ; comparar con "M"
btfsc STATUS,Z ;ver si llego M, si no llego saltear cambio de ESTADO
goto si_MM     ;exito, estado en 4 y llego un M
clrf ESTADO   ;no exito, estado en 4 pero no es M
return     ;resetear ESTADO y volver
si_MM  ;en ESTADO 4 llego un M, pasar al estado 5 y no echoar dato
movlw 0x05
movwf ESTADO ;pasar al estado 05
;call echo_ar    ;hacer eco del dato M a la PC
return
;
case_05  ;procesar estado 5 y "C"
movfw ESTADO  ; Comparar
xorlw 0x05        ; con estado 5
btfss STATUS,Z  ;si son iguales saltar
goto case_06   ; no es estado 5, continuar
movfw RCDATO    ;el ESTADO es 5, verifcar si llego "C"
xorlw 0x43          ; comparar con C
btfsc STATUS,Z ;ver si llego C, si no llego saltear cambio de ESTADO
goto si_CC       ;exito, estado en 5 y llego un C
clrf ESTADO      ;no exito, estado en 5 pero no es C
return         ;resetear ESTADO y volver
si_CC ;en ESTADO 5 llego un C, pasar al estado 6 y no echoar dato
movlw 0x06
movwf ESTADO ;pasar al estado 06
;call echo_ar  ;hacer eco del dato C a la PC
return
;
case_06  ;procesar estado 6 y , procesar la coma "," que sigue al encabezamiento
movfw ESTADO ; Comparar
xorlw 0x06        ; con estado 6
btfss STATUS,Z ;si son iguales saltar
goto case_10   ; no es 6, continuar
movfw RCDATO    ;el ESTADO es 6, verifcar si llego ","
xorlw 0x2C          ; comparar con , o 2E es . punto
btfsc STATUS,Z    ;ver si llego "," , si no llego saltear cambio de ESTADO
goto si_CO       ;exito, estado en 6 y llego un ,  pongo CO la , molesta
clrf ESTADO      ;no exito, esta en 6 pero no es ,
return     ;resetear ESTADO y volver
si_CO ;en ESTADO 6 llego una ,, pasar al estado 10 y no echoar dato
movlw 0x10  ;
movwf ESTADO ;pasar al estado 10
;call echo_ar  ;hacer eco del dato M a la PC
return
;
;La detección del encabezamiento fue exitosa, comienza recolección de datos de Hora
;
case_10  ;Recibiendo HORHIG (las decenas de Hora, viene en ASCII, o una segunda coma si no hay datos)


Respecto del tiempo de ejecución,
la ISR será llamada a ejecutarse cada vez que la USART tenga un caracter/dato listo para procesar.
Como la velocidad de datos es 9600 baudios, la duración de bit será de 1/9600 = 104  uS y la duración de caracter será de 1 mS aprox.
(tomando 1 bit START, 8 bit DATO, 1 bit STOP , total 10 bits)
O sea que la ISR será llamada a ejecutarse como máximo una vez en cada milisegundo, por lo cual el proceso de la ISR no puede tardar mas que un miliSeg para que no se pierdan datos. Con un cristal de 8 MHz en el PIC estimo que ese tiempo sobrará.

Otra consideración es que la ISR procesa el mensaje $GNRMC hasta que obtiene los datos de Fecha que están al final del mensaje, todo lo que sigue incluido el Checksum, lo descarta ya que no se justifica para esta aplicación

Luego agregaré algo de la recolección de los datos de Hora y Fecha

Un  saludo.
« Última modificación: 14 de Diciembre de 2020, 23:11:11 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
« Respuesta #16 en: 16 de Diciembre de 2020, 22:53:13 »
Un poco más de código de la ISR, aqui la parte de recibir los seis digitos de la Hora

Código: [Seleccionar]
case_10 ;Recibiendo HORHIG , el dígito Decenas de Horas, viene en ASCII
              ;o la segunda coma si todavía no hay datos (módulo inicializandose)
              ; , o el botón para mostrar Posición Geográfica
movfw ESTADO ; Comparar
xorlw 0x10       ; con estado 10
btfss STATUS,Z ;si son iguales saltar
goto case_11   ; no es estado 10, continuar
movfw RCDATO    ;el ESTADO es 10, llega HORHIG en ASCII, le sobran 30 para obtener el número a mostrar
xorlw 0x2C   ; comparar con la segunda coma para detectar el mensaje de NO DATA   $GNRMC,,V,,,,,,,,,,N*4D
btfsc STATUS,Z ; si no es coma, continuar, pues no es el mensaje de NO DATA (el módulo aún no no adquiere info de los GNSS)
goto es_coma ;se detecta la segunda coma, todavia no llegan los datos válidos
movfw RCDATO   ;si no es coma, recuperar dato recibido y procesarlo
andlw 0x0F     ; mascara para borrar ASCII, sacarle el 30; el 30 queda en 00, 31 en 01 etc.
movwf HORHIX   ; cargar el digito de hora en registro auxiliar HORHIX (es hora  UTC, no local)
;chequear boton de solicitud de mostrar Posición geográfica
        btfss PORTB,BTB3 ;si el boton no fue apretado,esta en 1, seguir, saltar
goto bot_on  ;si hay boton oprimido, ir a procesar latitud/longitud ; si no continuar normal con hora y fecha
movlw 0x11
movwf ESTADO ;pasar al estado 11
call echo_ar  ;hacer eco del dígito de Hora HORHIG a la PC para chequear su validez
return
;
bot_on  ;el boton esta oprimido, ir a recoger latitud y longitud y mostrala. Ya se recibio HORHIG pero ese valor se  descarta
movlw 0x02 ;cargar el contador de comas a saltear dentro del mensaje, son 2
movwf ESTAUX ; en ESTAUX
        movlw 0x40   ; el proximo estado de la maquina de estados sera el 40, arranca la secuencia de recoger  latitud y longitud
movwf ESTADO ;pasar al estado 40
return
es_coma ;se detecto una segunda coma despues de la primera, el mensaje completo $GNRMC con todos los datos todavia no llega
movlw 0x36 ; estado final 36,  para no mandar nada pues esta llegando el mensaje sin data $GNRMC,,V,,,,,,,,,,N*4D
movwf ESTADO ;pasar al estado 36, solo para mandar $+CR+LF e ir al estado de reposo 38, el último estado de la maquina
movlw 0x24   ;echoar el signo $ a la PC, luego CR,LF; la HiperTerminal de monitoreo mostrará el signo $, una linea por segundo
call tx_dato  ; mientras no llega Data (el módulo GPS esta en inicialización o perdió toda señal)
return        ;
;No hubo segunda coma , no hubo Boton, la secuencia continua normalmente recogiendo los dígitos de Hora
case_11 ;Recibiendo el dígito de Unidades de Hora, se guarda en registro HORLOX , viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x11       ; con estado 11
btfss STATUS,Z ;si son iguales saltar
goto case_12  ; no es 11, continuar
movfw RCDATO    ;el ESTADO es 11, llega el dígito de unidades de Horas HORLOX en ASCII, le sobran 30
andlw 0x0F     ; mascara para borrar ASCII, 30 queda en 00, 31 en 01 etc.
movwf HORLOX   ; cargar el digito de hora en registro auxiliar HORLOX para corregir hora UTC a hora local
movlw 0x12
movwf ESTADO ;pasar al estado 12
call echo_ar      ;hacer eco del dígito a la PC
return
;
case_12 ;Recibiendo decenas de Minutos, se guarda en el registro MINHIG , viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x12       ; con estado 12
btfss STATUS,Z ;si son iguales saltar
goto case_13    ; no es 12, continuar
movfw RCDATO    ;el ESTADO es 12, llega MINHIG en ASCII, le sobran 30
andlw 0x0F     ; mascara para borrar ASCII, 30 queda en 00, 31 en 01 etc
movwf MINHIG   ; cargar el digito de MINHIG
movlw 0x13
movwf ESTADO ;pasar al estado 13
call echo_ar  ;MINHIG a la PC
return
;
case_13 ;Recibiendo unidades de minutos, se guarda en MINLOW , viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x13       ; con estado 13
btfss STATUS,Z ;si son iguales saltar
goto case_14 ; no es 13, continuar
movfw RCDATO    ;el ESTADO es 13, llega MINLOW en ASCII, le sobran 30
andlw 0x0F     ; mascara para borrar ASCII, 30 queda en 00, 31 en 01 etc
movwf MINLOW   ; cargar el digito MINLOW
movlw 0x14
movwf ESTADO ;pasar al estado 14
call echo_ar  ;hacer eco de MINLOW a la PC
return
;
case_14 ;Recibiendo digito de decenas de Segundos, guardar en SEGHIG , viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x14       ; con estado 14
btfss STATUS,Z ;si son iguales saltar
goto case_15 ; no es 14, continuar
movfw RCDATO    ;el ESTADO es 14, llega SEGHIG en ASCII, le sobran 30
andlw 0x0F     ; mascara para borrar ASCII, 30 queda en 00, 31 en 01 etc
movwf SEGHIG   ; cargar el digito SEGHIG
movlw 0x15
movwf ESTADO ;pasar al estado 15
call echo_ar  ;hacer eco de SEGHIG a la PC
return
;
case_15 ;Recibiendo unidades de Segundos, guardar en SEGLOW ,
movfw ESTADO ; Comparar
xorlw 0x15       ; con estado 15
btfss STATUS,Z ;si son iguales saltar
goto case_16   ; no es 15, continuar a 16
movfw RCDATO    ;el ESTADO es 15, llega SEGLOW en ASCII, le sobran 30
andlw 0x0F     ; mascara para borrar ASCII, 30 queda en 00, 31 en 01 etc
movwf SEGLOW  ; cargar el digito SEGLOW
movlw 0x16   
movwf ESTADO ;pasar al estado 16
call echo_ar  ;hacer eco de SEGLOW a la PC
return
;

case_16 ;Recibiendo el punto decimal de las centecimas de Segundos en el mensaje, viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x16       ; con estado 16
btfss STATUS,Z ;si son iguales saltar
goto case_17  ; no es 16, ir a 17
        movfw RCDATO    ;el ESTADO es 16, verifcar si llego el "."
xorlw 0x2E      ; comparar con  . punto
btfsc STATUS,Z ; si no llego, hay error, en ese lugar debe haber un punto, si no está hay error, ergo resetear estado
goto si_PU  ; si se detecta  el "." ir a seguir la secuencia exitosa
clrf ESTADO ;no se detecto el "."
return     ;resetear ESTADO y volver
si_PU ;
movlw 0x17
movwf ESTADO ;pasar al estado 17
call echo_ar ;hacer eco del punto decimal a la PC
return

case_17 ;Recibiendo el cero 0X de las centecimas de Segundo en el mensaje, viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x17       ; con estado 17
btfss STATUS,Z ;si son iguales saltar
goto case_18   ; el estado no es 17,
        movfw RCDATO    ;el ESTADO es 17, verifcar si llego 0 (el modo del módulo no reporta decimales, estos siempre serán ceros)
xorlw 0x30           ; comparar con  0
btfsc STATUS,Z ; si no llego 0, hay error, resetear estado
goto si_0X  ; si llego el 0, seguir secuencia
clrf ESTADO ;no era 0
return     ;resetear ESTADO y volver
si_0X ;
movlw 0x18
movwf ESTADO ;pasar al estado 18
movlw 0x0D     ; en lugar de mandar las centesimas que siempre son 00, mandar CR(0Dh), luego LF (0Ah)
call tx_dato      ; para que la linea del HiperTerminal de monitoreo muestre la Hora y avance una linea
return

case_18 ;Recibiendo el cero x0 o segundo cero  de las centecimas, viene en ASCII
movfw ESTADO ; Comparar
xorlw 0x18       ; con estado 18
btfss STATUS,Z  ;si son iguales saltar
goto case_20    ; no es 18, sera 20?
        movfw RCDATO    ;el ESTADO es 18, verifcar si llego 0
xorlw 0x30      ; comparar con 0 en ASCII
btfsc STATUS,Z ; si no llego 0, hay error, resetear estado
goto si_X0       ; si llego el 0 , seguir secuencia
clrf ESTADO     ;no era "0"
return        ;resetear ESTADO y volver
si_X0 ;
movlw 0x08    ; ACA cargar el contador de comas a saltear, parámetros que no son requeridos son salteados, SON 8!
movwf ESTAUX ; en el registro ESTAUX
movlw 0x20
movwf ESTADO ;pasar al estado 20 de la máquina de estados
movlw 0x0A ; mandar LF (0Ah) para completar la linea en la HiperTerminal
call tx_dato ;
return

case_20 ;aqui se cuentan las 8 comas que separan la Hora de la Fecha en el mensaje, luego se recoje la Fecha con secuencia
              ;de estados similar a la Hora y se cargan sus registros.


No más código por ahora sino se pone pesado el tema.

Un saludo
« Última modificación: 16 de Diciembre de 2020, 23:01:54 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
« Respuesta #17 en: 22 de Diciembre de 2020, 17:32:52 »
Continuando con este desarrollo, ahora veamos algo de hardware y como se conectará el PIC.

 

* nimo_cc1.jpg
(75.43 kB, 640x360 - visto 367 veces)


Como se ve, la interface entre el módulo GPS NEO-M8N y el PIC es un CD40106 (Hex Inverter Schmitt Trigger) que adapta los 3,3 Voltios de salida Txd del módulo a los 5 Voltios de RXD (RB1) del PIC, por medio de R1 y R2.
El módulo se alimenta con 5V y tiene un regulador integrado de 3,3V y las señales Rxd y Txd son de 3,3V.
La salida TXD (RB2) del PIC pasa también por inversores proveyendo la salida para monitoreo para HiperTerminal.
Al final hay dos Leds que indican la actividad de datos de RXD(Verde) y TXD(Amarillo).

Los transistores T1 y T2 actúan de interface con los registros de desplazamiento del Display, pasando las señales de 5V RB6 (CK) y RB7 (DT) a señales de 12V, siendo DT los datos seriales de los registros y CK el clock de los registros.
Luego está el Xtal de 8 MHz en RA6/RA7
El pulsador BT ingresa en RB3, y actúa como ya dije, para cambiar la visualización de Hora/Fecha a Longitud/Latitud

Todos los resistores del pulsador BT y de los Leds van a la fuente de +5 Voltios

Las demás lineas (pines) se usan para manejar Leds Separadores (RGB tres colores) e Indicadores (Amarillos) en el Display. Los Leds se muestran en el color que encienden o sin color (apagados), según la siguiente figura:

 

* display_cc1.jpg
(107.17 kB, 640x360 - visto 361 veces)


- SVHM (RB5) maneja 4 Leds Separadores Verdes Hora:Minuto:Segundo. Estos Leds parpadean 1/4 Seg en cada Segundo.
- SRAM (RB4) maneja 4 Leds Separadores Rojos Mes:Dia:Año. Estos Leds parpadean 1/4 Seg. en cada Segundo.

Recuérdese que en el modo normal Hora/Fecha, el Display durante los segundos 0,1,2,3,4 y 9 mostrará la Hora y durante los segundos 5,6 y 7 mostrará la Fecha, con el correspondiente cambio de color en los Leds Separadores parpadeantes.

- SVLO (RA3) maneja 2 Leds Separadores Verdes y un Led de Punto Decimal de Longitud;  Grados:Minutos.Decimas de Min.
- SRLA (RA2) maneja 2 Leds Separadores Rojos y un Led de Punto Decimal de Latitud;  Grados:Minutos.Decimas de Min.

Recuérdese que con el pulsador BT se cambiará la visualización del modo normal Hora/Fecha al modo Posición Geográfica Longitud/Latitud.
La indicación de Longitud/Latitud se alternará cada 5 Seg., con el correspondiente cambio de color en los Leds Separadores y Punto Decimal parpadeantes.

- IHMS (RA1) maneja 3 Leds Indicadores Amarillos de HOR:MIN:SEG que se encienden debajo del Display
- IDMA (RA0) maneja 3 Leds Indicadores Amarillos de MES:AÑO:DIA que se encienden debajo del Display

Los otros 4 Leds Indicadores Amarillos de LONG, GRADOS, MINUTOS y LATITUD encienden por otros medios que veremos luego.

Por último la linea IAER (RA4) encenderá los 7 Leds RGB en color AZUL del Display, indicando algún error (ya vimos los errores de USART que encenderán estos Leds)

Un saludo.


« Última modificación: 22 de Diciembre de 2020, 17:50:14 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
« Respuesta #18 en: 31 de Diciembre de 2020, 02:28:45 »
Continuando, veremos el tema de conversión del Tiempo UTC al Tiempo Local

Digamos que al utilizar un módulo GNSS (GPS) como el  NEO-M8N para obtener la información de Hora y Fecha desde los sistemas satelitales, aparece el problema de la corrección a la Hora y Fecha Locales que deberá ser mostrada en el Reloj.
Los sistemas de satélites GNSS que recibe el módulo (GPS, GLONASS, Beidou, Galileo) son globales y transmiten sus señales a todo el mundo, por lo cual envían con alta presición exclusivamente el tiempo UTC (Coordinated Universal Time) ó GMT (Greenwich Mean Time) y no incluyen en su programación ninguna corrección por posición geográfica. 
Por lo tanto el país o región que reciba y procese dicha señal, deberá realizar las correcciones necesarias a su Hora y Fecha Local, que dependerá de su posición geográfica y factores estacionales (países que adelantan su hora en invierno, etc.)

En este tema de corrección de tiempo deben tenerse en cuenta algunos detalles.
Por ejemplo los países americanos que se encuentran al Oeste de Greenwich o Meridiano Cero tienen correcciones de tiempo negativas, p.e. para Argentina la corrección o Offset horario es (-3), esto significa que cuando la Hora UTC es p.e. 09:17 en Argentina es Hora Local 06:17. La solución de este corrimiento o Offset horario sería sencillo, sólo basta restar 3 a la Hora UTC y queda la Hora Local corregida.

Otro ejemplo sería que la Hora UTC es p.e. 02:36 entonces la Hora Local será 23:36 y la resta debe hacerse en el sistema binario en el PIC para obtener la Hora a mostrar, y además la Fecha UTC ya estará un día adelantada a la Fecha Local y también deberá corregirse mostrando el dia anterior.

Esta corrección al día anterior que debe mantenerse en las tres últimas horas del día corriente en un país con Offset ( -3) como Argentina se complica un poco más el primer día del mes, ya que el día anterior al 1ro de mes depende de cual fue el mes anterior que puede contar con 28, 30 o 31 días, y se deberá mostrar además el mes anterior en ese caso. También además en un Reloj que muestra Mes y Año como en este caso, deberá corregirse el Mes mostrado y el año mostrado en las tres últimas horas del 31/12, ya que el tiempo UTC ya estará en año y mes nuevo, mientrás que el país todavía en año y mes viejo.
Otra tema adicional son los años bisiestos que en principio no los tendremos en cuenta

Entonces resumiendo, deberán efectuarse cuatro correcciones a los datos recibidos del módulo para luego mostrar el Tiempo correcto en el Display, que son los siguientes:

 1) Restar el Offset (-3) a la Hora UTC recibida para obtener la Hora local a mostrar
 2) Si con la corrección de Hora se pasa al dia anterior, mostrar el Dia anterior
 3) Si con la corrección de Dia se pasa al mes anterior, corregir el Mes y el Dia anterior
 4) La hora corregida en el punto 1 está en el formato 24 hs, pasar al formato 12 hs AM/PM

El punto 1 se procesa con la siguiente rutina, que usa una tabla en EPROM que tiene ya grabados los resultados para varios Offsets

Código: [Seleccionar]
;
off_hor ;Calcular la hora local aplicando el Offset a la hora UTC leida (Argentina es Offset -3)         
    ; la hora UTC leida del módulo GPS se guarda en los auxiliares HORHIX y HORLOX)
    ;   
       swapf HORHIX,0  ;invertir los nibles, queda en W, el HORHIX no cambia
       andlw 0xF0   ;limpiar los bits de < peso
       iorwf HORLOX,0 ; sumo ambos , la hora de dos digitos esta ahi
       addwf OFFSEX,0 ;sumarle el OFFSEX de 5 (8-3=5)   
       ;conversion por tabla eprom, el numero de entrada viene en w
       ; sumar el offset dentro de la eeprom   EL OFFSET para esta tabla ES 00
       bsf STATUS, RP0  ;apuntar banco 1
       movwf EEADR ;cargar en el puntero address eeprom
       bsf EECON1,RD         ;iniciar el READ
       movfw EEDATA ;pasar el dato eeprom al w
       bcf STATUS, RP0       ;banco 0
       movwf HORLOW ; pasar el valor completo, solo los 4 bits < peso se usan para mostrar. HORLOW es unidades de Hora corregida
       movwf HORHIG   ; pasar el valor completo,  solo los 4 bits < peso se usan para mostrar. HORHIG es decenas de Hora corregida
       swapf HORHIG,1 ;invertir otra vez los nibles ;y mostrar
       return
;----------------------------------------------------------------------------------------
ORG 0X2100   ;LUGAR de la EEPROM
       ;TABLA DE OFFSETS ---- de UTC a LOCAL, verla completa mas abajo
       ;offset tabulados  -5, -6, -4, -3
;(00)  Comienzo de la tabla de offsets
de 0xFF ; 00
de 0xFF ; 01
de 0x18 ; 02
de 0x19 ; 03
de 0x20 ; 04
de 0x21 ; 05
de 0x22 ; 06
de 0x23 ; 07
de 0x00 ; 08
de 0x01 ; 09
de 0x02 ; 0A
de 0x03 ; 0B
de 0x04 ; 0C
de 0x05 ; 0D
de 0x06 ; OE
de 0xFF ; OF
;(10)
de 0xFF ; 10 16
de 0xFF ; 11 17
de 0x04 ; 12 18
de 0x05 ; 13 19
de 0x06 ; 14 20
de 0x07 ; 15 21
de 0x08 ; 16 22
de 0x09 ; 17 23
de 0x10 ; 18 24
de 0x11 ; 19 25
de 0x12 ; 1A 26
de 0x13 ; 1B 27
de 0x14 ; 1C 28
de 0x15 ; 1D 29
de 0x16 ; 1E 30
de 0xFF ; 1F 31
;(20)
de 0xFF ;20 32
de 0xFF ;21 33
de 0x14 ;22 34
de 0x15 ;23 35
de 0x16 ;24 36
de 0x17 ;25 37
de 0x18 ;26 38
de 0x19 ;27 39
de 0x20 ;28 40  fin de la tabla de offset
de 0xFF ;29 41 
de 0xFF ;2A 42 
de 0xFF ;2B 43 
de 0xFF ;2C 44 
de 0xFF ;2D 45 
de 0xFF ;2E 46 
de 0xFF ;2F 47 



El Offset de tabla sale de restar el Offset horario de una constante ( 8 ):
Entonces el Offset de tabla es 8-3=5 para Argentina
Algunos ejemplos para Offset -3 (Argentina):

1) Hora UTC = 00:00,  Puntero de tabla 00+5 = 05 , retorno de la posición 05 = 21  ->  Hora UTC=00:00, Hora Local=21:00
2) Hora UTC = 07:00,  Puntero de tabla 07+5 = 0C , retorno de la posición 0C = 04  ->  Hora UTC=07:00, Hora Local=04:00
3) Hora UTC = 15:00,  Puntero de tabla 15+5 = 1A , retorno de la posición 1A = 12  ->  Hora UTC=15:00, Hora Local=12:00
4) Hora UTC = 22:00,  Puntero de tabla 22+5 = 27 , retorno de la posición 27 = 19  ->  Hora UTC=22:00, Hora Local=19:00

Un saludo.
« Última modificación: 04 de Enero de 2021, 22:35:36 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Continuando un poco más con el proceso de Fecha, 
se deberá mostrar el día anterior al día UTC si con el Offset de Hora aplicado, se está todavía en el día anterior (las tres últimas horas del día con Offset -3 (Argentina)
Además el día anterior dependerá del mes anterior si se está en el primer día del mes
Cuando se deba atrazar uno el día mostrado, se procesará en esta rutina:

Código: [Seleccionar]
       ;En DIAHIX la ISR guardó las decenas del Día UTC recibido del módulo GPS
       ;En DIALOX la ISR guardó las unidades del Día UTC recibido del módulo GPS
       ;
        swapf DIAHIX,0 ;invertir los nibles, el resultado queda en W
        andlw 0xF0   ;limpiar los bits de < peso por las dudas
        iorwf DIALOX,1 ; sumo ambos, el resultado queda en DIALOX , el dia de dos digitos esta ahi
        movfw DIALOX   ;salvar el dia en w
        decfsz DIALOX,1 ; chequear si el día es 01
        goto mes_nor ; el dia NO es 01, procesar mes normal
goto mes_ant ; el día ES 01 , hay que buscar el dia anterior en el mes anterior
        ;
mes_nor ;
        movwf DIALOX ;el día UTC se recupera en DIALOX
movlw 0x10 ; comparar el dia con 10, 20 y 30
subwf DIALOX,0 ;comparar el dia primero con 10
btfss STATUS,Z ; el decremento directo dara 0F, valor que no va
goto noes_10 ;continuar porque no es 10
movlw 0x09     ;el día es 10, cargar entonces directamente el día anterior 09
goto mes_out
noes_10
movlw 0x20 ;
subwf DIALOX,0 ;comparar el dia con 20
btfss STATUS,Z ;
goto noes_20 ; continuar porque no es 20
movlw 0x19     ;el día es 20, cargar directamente el día anterior 19
goto mes_out
noes_20
        movlw 0x30 ;
subwf DIALOX,0 ;comparar el dia con 30
btfss STATUS,Z ;
goto noes_30 ; no es 30, continuar
movlw 0x29   ;el día es 30, cargar directamente con 29
goto mes_out
noes_30 ;el dia no es ni 01, ni 10, ni 20 ni 30
decf DIALOX,1 ; entonces decrementarlo directamente
movfw DIALOX ; el día anterior está en DIALOX
mes_out       
movwf DIALOW ; pasar el valor completo, pues solo los 4 bits < peso se usarán para mostrar en el display
        movwf DIAHIG ;
        swapf DIAHIG,1 ;invertir otra vez los nibles ;sólo los 4 bits de < p se usan para mostrar en el display
        return ; y salir...............
;
mes_ant ; es primero de mes o sea dia 01, hay que pasar al ultimo dia del mes anterior, con el indice del mes UTC
        swapf MESHIG,0 ;invertir los nibles, el resultado, queda en W, el MESHIG no cambia
        andlw 0xF0   ;limpiar los bits de < peso por las dudas
        iorwf MESLOW,0 ; sumo ambos ,  el dia de dos digitos esta en W
;conversion por tabla eprom OFFSET 60,
        addlw 0x60 ; sumar el offset de eeprom EL OFFSET para esta tabla ES 60
        bsf STATUS, RP0  ;apuntar banco 1
        movwf EEADR ;cargar en el puntero address eeprom
        bsf EECON1,RD    ;iniciar el READ
        movfw EEDATA ;pasar el dato eeprom al w, alli está el dia anterior o último día del mes anterior
        bcf STATUS, RP0  ;banco 0
        goto mes_out ;
        ;
;
       ORG 0X2100   ;LUGAR de la EEPROM


;Offset de EEPROM (60) ;TABLA DE MES -Debe atrazarse el dia por la correccion UTC, y el dia es 01,
;
de 0xFF ; 60 96 00 mes UTC 00 no existe   
de 0x31 ; 61 97 01 mes 01 enero, mes anterior diciembre, el dia anterios al 01/01 es 31 
de 0x31 ; 62 98 02 mes 02 feb, mes anterior enero tiene 31         
de 0x28 ; 63 99 03                          febrero 28                       
de 0x31 ; 64 100 04                         marzo 31
de 0x30 ; 65 101 05            abril 30
de 0x31 ; 66 102 06            mayo 31
de 0x30 ; 67 103 07            junio 30
de 0x31 ; 68 104 08      julio 31
de 0x31 ; 69 105 09      agosto 31
de 0xFF ; 6A 106 0A NOVA
de 0xFF ; 6B 107 0B
de 0xFF ; 6C 108 0C
de 0xFF ; 6D 109 0D
de 0xFF ; 6E 110 0E
de 0xFF ; 6F 111 0F NOVA
;(70)
        de 0x30 ; 70 112 10 setiembre 30
de 0x31 ; 71 113 11 octubre 31
de 0x30 ; 72 114 12 novimbre 30  FIN TABLA MES ANTERIOR

;---------
;


Un saludo.

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Ya promediando este proyecto, veremos unos detalles más sobre el Display y luego un video del primer prototipo funcionando.
Como dijimos antes , el Display será de 6 dígitos de los cuales 5 dígitos serán Tubos Nimo normales con números de 0 a 9, y el sexto tubo será de medio dígito y sólo mostrará el número 1 o estará apagado.
También como se vio, el Display será manejado por 3 registros de desplazamiento CD4094 y 5 decodificadores CD4028 para cada uno de los dígitos completos, ya que no hace falta un deco para el sexto medio dígito, que sólo se maneja con un bit.
Por lo tanto los 3 bits sobrantes en el (medio) registro del sexto dígito,  serán usados para un efecto de Back Light o luz de fondo de los Tubos, usando 6 Leds RGB.

De acuerdo a esto, el diagrama del Display será así:

 

* nimo_f.jpg
(60.75 kB, 640x353 - visto 325 veces)


y el circuito de mando de los Leds RGB será así:

 

* rgb_nimo.jpg
(37.96 kB, 402x386 - visto 278 veces)


y la rutina de mando de los dígitos al Display será la siguiente

Código: [Seleccionar]
;------------------------------------------------------------------------------
;---  MOSTRAR HORA, MIN, SEG EN EL DISPLAY, SHIFTEANDO LOS BITS EN LOS REGISTROS
;------------------------------------------------------------------------------
;
; El orden de envio serial de los números será HU, MD, MU, SD, SU, y  HD que será 0 o 1
; luego se envían los bits de Back Light
;
mos_hor ; mostrar hora,min,seg, "SHIFtiando" el dato de memoria en los registros de desplazamiento
    ;CKB7 (RB7) es el Clock (CK) de los registros.        Recordar que los transistores de cambio de tensión
    ;DTB6  (RB6) es el Dato (DT) de los registros         invierten las señales CK y DT
    ;
    ;mandar hora low HU, las unidades de Hora están en los 4 bits < peso de HORLOW
    bsf PORTB,DTB6    ; Poner Datos a 1, o sea 0 en los registros (el Transistor  invierte)
    btfsc HORLOW,0 ; si el bit esta en 0 no hacer nada, el T ya esta en 0
    bcf PORTB,DTB6  ; si el bit esta en 1, poner DT a 0 pues el T invierte y estara en 1
    call Pulso ; Pulsar CK para cargar/shiftear el bit en los registros
    btfsc HORLOW,1 ; continuar con los restantes 3 bits del registro
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc HORLOW,2 ;
    bcf PORTB,DTB6  ;
    call Pulso 
    btfsc HORLOW,3 ;
    bcf PORTB,DTB6  ;
    call Pulso
    ;
   ;mandar minutos high MD, las decenas de Minutos están en los 4 bits < peso de MINHIG
    btfsc MINHIG,0 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINHIG,1 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINHIG,2 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINHIG,3 ;
    bcf PORTB,DTB6  ;
    call Pulso
    ;
    ;mandar minutos low MU
    btfsc MINLOW,0 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINLOW,1 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINLOW,2 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc MINLOW,3 ;
    bcf PORTB,DTB6  ;
    call Pulso
    ;
    ;mandar segundos high SD
    btfsc SEGHIG,0 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc SEGHIG,1 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc SEGHIG,2 ;
    bcf PORTB,DTB6  ;
    call Pulso
    btfsc SEGHIG,3 ;
    bcf PORTB,DTB6  ;
    call Pulso
    ;
   ;mandar segundos low SU
    btfsc SEGLOW,0 ; Si el bit es UNO
    bcf PORTB,DTB6  ; apagar o sea encender el T
    call Pulso  ; pulsa el Clock y deja en cero la salida
    btfsc SEGLOW,1 ;
    bcf PORTB,DTB6  ; apagar o sea encender
    call Pulso
    btfsc SEGLOW,2 ;
    bcf PORTB,DTB6  ; apagar/encender
    call Pulso
    btfsc SEGLOW,3 ;
    bcf PORTB,DTB6  ;
    call Pulso
    ;
    ;mandar hora high HD, Decenas de Horas  el HD es "apagado o 1"
    btfsc HORHIG,0 ;      HORHIG sera 0000 entonces apagar
    bcf PORTB,DTB6  ;  HORHIG = 0001 entonces encender el 1 del medio digito
    call Pulso   
   ;Aqui se mandan  los 3 bits del RGB del back light
    btfsc BACLIG,0 ; mandar el bit R             serán Q1, Q2 y Q3 del ultimo registro
    bcf PORTB,DTB6  ;     
    call Pulso
    btfsc BACLIG,1 ;mandar el bit G         Mandar el estado del contador de BACLIG
    bcf PORTB,DTB6  ;
    call Pulso 
    btfsc BACLIG,2 ; mandar el bit B
    bcf PORTB,DTB6  ;
    call Pulso
    ;
    return
;---------------- FIN DE MOSTRAR HORA 

Pulso ; el Clock de los registros de desplazamiento
    nop  ;Los NOPs regulan el ancho de pulso y los tiempos de bajada y subida
    nop   ; los colectores de los transistores con resistencia manejando entradas CMOS dan un tiempo de subida de 2 uS
    nop   ;
    nop  ;estabilizar la salida con NOPs
    nop
    nop
    bcf PORTB,CKB7 ;flanco descendente, flanco ascendente en los registros, se produce el SHIFT
    nop  ; el tiempo que el PULSO esta en 0 (1)
    nop
    nop
    nop  ;estabilizar la salida
    nop
    nop
    bsf PORTB,CKB7 ;pasa a  1 (cero) el pulso
    nop  ;estabilizar la salida
    nop
    nop
    nop
    nop
    nop
    bsf PORTB,DTB6    ;  y dejar la salida en 1 (0) Los transistores invierten
    return
;-------------------------------------------------------------------------------------------
;
; La rutina de proceso del Back Light, es llamada cada de 7 a 10 minutos para el cambio de código de color
baklig
    ;AQUI PROCESAR EL BACKLIGHT
    incf CONLIG,1 ;incrementar el contador de espera de cambio de color
    btfss CONLIG,0X07 ;1000.0000 contador de espera para cambiar el color
    return ; si no llegó todavia, entonces volver
    clrf CONLIG ; si llegó, resetear contador de espera y procesar backlight
    btfss SEGLOW,0 ;  Agrego este toque pseudoramdom, depende como se encuentren los bits del SEGLOW, salto el color
    incf BACLIG,1 ; este incremento es random                 <Para que la secuencia de color de fondo no sea siempre la misma>
    btfss SEGLOW,1 ; Otro toque pseudoranmdom           <se agrega un toque pseudorandom de acuerdo al estado de los bits de los>
    incf BACLIG,1 ; este incremento es random                   <segundos en el momento de cambiar de codigo de color>
    incf BACLIG,1   ;incrementar el registro de Back Light, ESTE se hace siempre
    btfsc BACLIG,0X03 ; detectar 0000.1000 ó 0000.1XXX para que solo se manejen 3 bits
    clrf BACLIG ;poner a cero si llego a 8 o se pasó a 9 0 A por el random
    return
;-------------FIN DE BACK LIGHT ----------   
;


Les dejo un video del prototipo con todo lo dicho hasta ahora metido adentro.
Puede verse la Hora y la Fecha en el Display, y el cambio a indicación de Longitud/Latitud.
También puede verse el cambio de color de la luz de Back Light de los Tubos


Un saludo.
« Última modificación: 12 de Enero de 2021, 02:47:11 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"


Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
¡Qué chulo te ha quedado, enhorabuena!  :-/

Gracias por el buen comentario Compañero!

Sólo faltan dos puntos para finalizar este proyecto, al menos de mi punto de vista

1) Le agregaré una especie de display calendario con LEDs que indique además de Hora,  Fecha y Posición geográfica;
Nombre del Día de la semana y nombre del Mes
Será parecido a este intento, pero más prolijo:

 

* calendario1.jpg
(48.44 kB, 912x152 - visto 322 veces)


2) El termómetro de dos canales con  DS18B20 que ya estoy probando todavía en protoboard, que sensará la temperatura externa e interna del gabinete, y controlará el encendido del ventilador de los Tubos.
Aquí un primer video:


Aquí puede verse luego de una inicialización y test del display de 4 dígitos, la medicíón de temperatura en ambos canales en simultaneo (alrededor del  Seg. 18 del video)
Dos dígitos para el canal A que muestra 19.9 grados (19 y 9.9 se alternan en los dos primeros dígitos)
Y dos dígitos para el canal B que muestra 20.4 grados (20 y 0.4 se alternan en los dos últimos dígitos)
También puede verse en el osciloscopio, las secuencias de pulsos seriales de acceso a los sensores.

En unos días, más detalles.
Un saludo.


« Última modificación: 13 de Enero de 2021, 12:58:34 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
 ((:-)) ((:-)) ((:-)) ((:-)) ((:-))

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Gracias por los conceptos  :mrgreen:

Continuando con los dos puntos faltantes, el display calendario mostrado arriba estará debajo de los Tubos y indicará Nombre del Dia de la Semana y Nombre del Mes iluminando la indicación con Leds, además de Hora, Dia y Posición.
Entonces contará con 6+4+7+12 = 29 Leds en 4 lineas

Primera linea (6 Leds):         HOR MES    MIN AÑO   SEG DIA                                    (estos son manejados directamente por el PIC)
Segunda linea (4 Leds):       LON.  GRADOS  MINUTOS LAT                                     (estos son manejados por registros de desplazamiento)
Tercera linea (7 Leds):         LUN MAR MIE JUE VIE SAB DOM                                   (estos son manejados por registros de desplazamiento)
Cuarta linea (12 Leds):     ENE FEB MAR ABR MAY JUN JUL AGO SEP OCT NOV DIC      (estos son manejados por registros de desp.)

La electrónica para manejarlos será otra vez con registros de desplazamiento CD4094 como se ve aquí,  los tres grupos de Leds de cada linea:

 

* nimo_cal.jpg
(25.89 kB, 466x194 - visto 286 veces)


Estos tres registros seguirán en cascada a los tres registros anteriores que manejan el Display de Tubos (totalizando seis registros), y se deberán mandar los bits seriales con los códigos de Leds a encender antes que los códigos de los dígitos del Display.

El criterio para mandar el código correcto del Nombre de Mes a encender será sencillo. Con el número de Mes mostrado en el Display se entra a una tabla y se obtiene el código del Led correspondiente a enviar y encender.
El criterio de Nombre del Día de la semana es más complicado. De acuerdo a con que día arranca el Mes, se cuenta en módulo 7 hasta el día presente, y con ese contador en módulo 7 se obtiene desde tabla, el código del Led correspondiente a enviar y encender.
En un rato subiré las rutinas que procesan esto y se aclarará lo expuesto (eso espero)

Un saludo.
« Última modificación: 20 de Enero de 2021, 12:39:26 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Nichita

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 86
Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
« Respuesta #25 en: 21 de Febrero de 2021, 00:11:52 »
Excelente !!  felicidades ((:-))

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Mis disculpas, me quedó un poco colgado este tema pero trataré ya de finalizarlo.

Continuando con lo visto, en el siguiente video les muestro el display calendario presentado debajo de los Tubos, con el Reloj en modo Test.
En el modo Test entra el Reloj cuando no detecta señal de sincronismo GPS,  efectuando el Test de los dígitos y todos los Leds del display, mientras los Leds Azules parpadean indicando el error de falta de sincronismo (el video salió con mucho brillo y se ven los colores saturados).


Luego en el siguiente video se muestra el Reloj en funcionamiento normal, recibiendo la señal de sincronismo GPS y realizando las correcciones ya vistas entre tiempo UTC y tiempo Local en Hora y Fecha (para Argentina)
Asi el Reloj muestra la Hora 1:17:XX del día Viernes 5 de Marzo de 2021.
La Hora 1:17:XX es mostrada durante 7 segundos en los dígitos con los Leds separadores parpadeando en Verde y los indicadores HOR, MIN, SEG encendidos debajo.
La Fecha 3:21:05 es mostrada durante 3 segundos en los dígitos con los Leds separadores parpadeando en Rojo y los indicadores MES, AÑO, DIA encendidos debajo.
La indicación de Día de la semana VIErnes y la indicación de Mes MARzo se muestran en las siguientes lineas del display calendario.

Aprox. en el segundo 20 se oprime el Botón para visualizar la posición geográfica, 
entonces los dígitos pasan a mostrar la longitud 57:33.5 con la indicación LONG, GRADOS, MINUTOS y los Leds separadores y punto decimal parpadeando en Verde durante 5 segundos.
Durante los 5 segundos siguientes los dígitos pasan a mostrar la latitud 37:58.2 con la indicación  GRADOS, MINUTOS, LAT y los Leds separadores y punto decimal parpadeando en Rojo durante 5 segundos.
Al liberar el Botón, el display vuelve a la visualización normal de Hora y Fecha.


A continuación, algo del código que maneja esta parte del proceso


Código: [Seleccionar]
act_alm
;actualizar variables de almanaque antes de enviar las variable a los registros externos y encender los Leds
;Las variables que se usan y su asignación:
;                            Posiciones de bits;   7   6   5   4     3   2   1   0       
;P0SDI3  Variable de LEDs de posición y tres dias: LON,GRA,MIN,LAT,LIBRE,LUN,MAR,MIE
;DI4ME4  Variable de LEDs de 4 dias y 4 meses:     JUE,VIE,SAB,DOM,  ENE,FEB,MAR,ABR
;MESES8  Variable de LEDs de 8 meses:              MAY,JUN,JUL,AGO,  SEP,OCT,NOV,DIC
;Uso las auxiliares COUNT0, COUNT1, COUNT3
;
;--------primero procesar mes -----------------------------------
;       
    clrf MESES8 ; acerar variables del almanaque
    clrf DI4ME4 ;
    clrf POSDI3 ;
    ;Recuperar el mes mostrado en el display, armar las variables de almanaque y mandarlas a los registros externos
    swapf MESHIG,0 ;invertir los nibles, queda en W, el MESHIG no cambia (MESHIG son las decenas de Mes)
    andlw 0xF0   ;limpiar los bits de < peso por las dudas
    iorwf MESLOW,0 ; sumo ambos, el dato queda en W, el MESLOW no cambia
    movwf COUNT0 ; salvar el mes en la auxiliar COUNT0, el mes expresado en BCD está ahi
    ;
    ;-------------------------------------------------------
    movfw COUNT0 ; recuperar el mes en BCD
    xorlw 0x12 ; ver si es 12 (diciembre)
    btfss STATUS,Z
    goto no_12
    bsf MESES8,0 ; es 12 diciembre, encender el bit del led
    movlw 0x03 ;el 01/12/21 es miercoles   OJO , Código ACTUALIZADO AL 2021
    movwf COUNT1 ; uso la auxiliar COUNT1 para guardar el indice del primer dia del mes
    goto dia_alm ;                     
no_12 ;             Indice que se guarda en COUNT1 es : 1-lun,2-mar,3-mie,4-jue,5-vie,6-sab,7-dom
    movfw COUNT0 ;
    xorlw 0x11
    btfss STATUS,Z
    goto no_11
    bsf MESES8,1 ; es 11 (nov), encender el led
    movlw 0x01 ;el 01/11/21 es lunes
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_11
    movfw COUNT0 ;
    xorlw 0x10 
    btfss STATUS,Z
    goto no_10
    bsf MESES8,2 ; es 10 octubre, encender el led
    movlw 0x05 ;el 01/10/21 es viernes
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_10
    movfw COUNT0 ;
    xorlw 0x09
    btfss STATUS,Z
    goto no_09
    bsf MESES8,3 ; es 09 septiembre, encender el led
    movlw 0x03 ;el 01/09/21 es miercoles
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_09
    movfw COUNT0 ;
    xorlw 0x08
    btfss STATUS,Z
    goto no_08
    bsf MESES8,4 ; es 08 agosto, encender el led
    movlw 0x07 ;el 01/08/21 es domingo
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_08
    movfw COUNT0 ;
    xorlw 0x07
    btfss STATUS,Z
    goto no_07
    bsf MESES8,5 ; es 07 julio, encender el led
    movlw 0x04 ;el 01/07/21 es jueves
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_07
    movfw COUNT0 ;
    xorlw 0x06
    btfss STATUS,Z
    goto no_06
    bsf MESES8,6 ; es 06 junio, encender el led
    movlw 0x02 ;el 01/06/21 es martes
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_06
    movfw COUNT0 ;
    xorlw 0x05
    btfss STATUS,Z
    goto no_05
    bsf MESES8,7 ; es 05 mayo , encender el led
    movlw 0x06 ;el 01/12/21 es sabado
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_05
    movfw COUNT0 ;
    xorlw 0x04
    btfss STATUS,Z
    goto no_04
    bsf DI4ME4,0 ; es 04 abril, encender el led
    movlw 0x04 ;el 01/04/21 es jueves
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_04
    movfw COUNT0 ;
    xorlw 0x03
    btfss STATUS,Z
    goto no_03
    bsf DI4ME4,1 ; es 03 marzo, encender el led
    movlw 0x01 ;el 01/03/21 es lunes
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_03
    movfw COUNT0 ;
    xorlw 0x02
    btfss STATUS,Z
    goto no_02
    bsf DI4ME4,2 ; es 02 febrero, encender el led
    movlw 0x01 ;el 01/02/21 es lunes
    movwf COUNT1 ;inicializar COUNT1
    goto dia_alm
no_02 ; entonces es 01
    bsf DI4ME4,3 ; es 01 enero, encender el led
    movlw 0x05 ;el 01/01/21 es viernes
    movwf COUNT1 ;inicializar COUNT1

dia_alm
;
;--------aqui procesar dia de la semana -----------------------------------
;       

;


Código: [Seleccionar]
    ;
dia_alm
;procesando el día de la semana encender en el almanaque
 ;   
    swapf DIAHIG,0 ;invertir los nibles, queda en W, el DIAHIG no cambia (son las decenas de Dia)
    andlw 0xF0   ;limpiar los bits de < peso por las dudas
    iorwf DIALOW,0 ; sumo ambos, el dato queda en W, el DIALOW no cambia (son las unidades de Dia)
    movwf COUNT3 ; salvar el dia en la auxiliar COUNT3, el dia esta en BCD
    clrf COUNT0  ;inicializar contador
    ;
    ; arranca el lazo de cuenta, hasta igualar COUNT0 con COUNT3,
    ; mientras se cuenta en COUNT1 con modulo 7
    ;cuando COUNT0 iguala a COUNT3, en COUNT1 estará el puntero de dia de la semana
    ;previamente COUNT1 lo precargo con el OFFSET del día de principio de mes que le cargué arriba
       
laz_alm  ;lazo de cuenta
    incf COUNT0,1 ; incrementar COUNT0
    movfw COUNT0 ; salvar en w
    andlw 0x0F  ;
    xorlw 0x0A ;  ver si el COUNT0 llego a 0A (10) o 1A o 2A
    btfss STATUS,Z ; saltar si no es XA
    goto no_xxx ; si aun no es A, no corregir
    movfw COUNT0 ; si ya es A
    addlw 0x06 ; sumar 6 y saltear los valores exadecimales. Si era 0A ahora es 10
    movwf COUNT0; actualizar COUNT0, si era 1A ahora es 20, si era 2A ahora es 30
no_xxx
    movfw COUNT0 ;recuperar COUNT0
    xorwf COUNT3,0 ;comparar con el día mostrado en el display guardado en COUNT3, esta en BCD
    btfsc STATUS,Z ;si son iguales, se llego al  fin de la cuenta
    goto fin_cue  ;si no se llego al fin de cuenta, seguir incrementando el puntero de dia de la semana
    ;aca está la cuenta en modulo 7
    incf COUNT1,1 ; ir contando el día de la semana en modulo7, que ya viene con el OFFSET cargado arriba
    bcf COUNT1,3 ; si llego a 0000.1000 dejarlo en 0000.0000 (modulo 8)
    movf COUNT1,1  ;solo para mover el Z y saber s iquedo en 0
    btfsc STATUS,Z ;si es 0000.0000 pasarlo a 0000.0001, o sea saltear el 0
    incf COUNT1,1 ; o sea que la cuenta sea 1,2,3,4,6,7, 1,2,3,4,5,6,7 .... cuenta en módulo 7 de los 7 días de la semana
    goto laz_alm  ;retornar al lazo de cuenta
; la cuenta termino,
fin_cue ;en COUNT1 esta el puntero de día de la semana ya corregido y con el offset de arranque de mes
    ;------------------------------------------------------------
    movfw COUNT1 ;
    xorlw 0x01 ; ver si es 01, lunes
    btfss STATUS,Z
    goto no_lu ; no es lunes
    bsf POSDI3,2 ;encender el bit del Led del lunes   
    return
no_lu
    movfw COUNT1 ;
    xorlw 0x02 ; ver si es 02, martes
    btfss STATUS,Z
    goto no_ma ; no es martes
    bsf POSDI3,1 ;encender el martes
    return
no_ma
    movfw COUNT1 ;
    xorlw 0x03 ; ver si es 03, miercoles
    btfss STATUS,Z
    goto no_mi ; no es miercoles
    bsf POSDI3,0 ;encender el miercoles
    return
no_mi
    movfw COUNT1 ;
    xorlw 0x04 ; ver si es 04, jueves
    btfss STATUS,Z
    goto no_ju ; no es jueves
    bsf DI4ME4,7 ;encender el jueves
    return
no_ju
    movfw COUNT1 ;
    xorlw 0x05 ; ver si es 05, viernes
    btfss STATUS,Z
    goto no_vi ; no es viernes
    bsf DI4ME4,6 ;encender el viernes 
    return
no_vi
    movfw COUNT1 ;
    xorlw 0x06 ; ver si es 06, sabado
    btfss STATUS,Z
    goto no_sa ; no es sabado
    bsf DI4ME4,5 ;encender el sabado
    return
no_sa ;entonces es domingo
    movfw COUNT1 ;
    xorlw 0x07 ; ver si es 06, sabado
    btfss STATUS,Z
    goto no_di ; no es ningun dia
    bsf DI4ME4,4 ;encender el domingo
    return
no_di ;entonces no es nin gun  dia
    movlw 0xFF  ;encender todos los Leds
    movwf DI4ME4 ;para indicar el error
    return

;P0SDI3, DI4ME4, MESES8 quedan actualizadas listas para enviar a los registros
;-----------------------------------------------------
;----------- FIN DE ACTUALIZAR ALMANAQUE -------------

Un saludo.
« Última modificación: 06 de Marzo de 2021, 01:30:30 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Ya entrando en la parte final de este proyecto que se ha hecho largo,
veremos el tema del Termómetro de dos canales con  sensores tipo DS18B20, que medirá la temperatura externa e interna del gabinete, y controlará el encendido del ventilador de los Tubos.
El diagrama de bloques del diseño será el siguiente:

 

* reloj.jpg
(95.6 kB, 795x561 - visto 226 veces)


El Termómetro ya funcionando en la plaqueta prototipo se ve en el siguiente video:


Primero haré una introducción del video y luego vendrán los detalles.
Como se ve, el programa arranca testeando los displays de matriz de puntos que son del tipo HP5082-7300 cuya hoja de datos es:

 

* displayhp.jpg
(47.29 kB, 365x500 - visto 229 veces)


Estos displays son del tipo de matriz de puntos con driver y decodificador BCD incluido. Tienen cuatro entradas A,B,C,D de código BCD, una entrada DP para el punto decimal, y una entrada de control ST (Strobe) que habilita y carga el código.
Entonces como se ve en el video en los primeros 10 segundos, el programa testea las 16 combinaciones de las entradas ABCD y el display muestra los 10 números y luego otros símbolos de las combinaciones no BCD.

A continuación el programa accede a los sensores tipo DS18B20 cuya hoja de datos puede verse aqui:
https://drive.google.com/file/d/1XvrKbaIGorJYNGA3N2tBmrW5Oz-dV278/view?usp=sharing

Cada sensor de temperatura DS18B20 tiene un único ID de 64 bytes que lo identifica (64-BIT LASERED ROM).
El primer byte de todo ID es un identificador de tipo de sensor ( 28h) . Como se ve, en este diseño cada sensor se maneja con una linea de datos separada (RA0 y RA1) entonces no hace falta identificar varios sensores conectados en una misma linea, el programa sólo lee los dos primeros bytes del ID de los dos sensores para verificar su presencia. En caso que un sensor no esté conectado o no responda, el display mostrará un guión (-) en lugar de su ID.
En el video en los segundos 12 y 14 se ven los ID de ambos sensores que indican que efectivamente están en linea, en uno 28 91, en el otro 28 XX.
Luego de este testeo arranca la medición de temperatura y se muestra en los displays, los dos dígitos de arriba corresponden al Sensor DS0 que será el de temperatura interna del Reloj, y los dos dígitos de abajo corresponden al Sensor DS1 que será el de temperatura externa o ambiente.
Ambos sensores DS18B20 trabajan en alta presición de 12 bits (como veremos luego en detalle) por lo cual los displays que tienen sólo dos dígitos, muestran alternadamente decenas - unidades y unidades - decimales de los valores de temperatura.
Esto puede verse a partir del segundo 15 del video, los display alternan entre 21 y 1.5 ó 1.4  indicando una temperatura de 21.5 ó 21.4 ºC.  Los dos sensores pueden verse ahi cercanos a la plaqueta con sus cables, por lo cual medirán valores similares.
A partir del segundo 31 del video puede verse el seteo de temperatura de encendido del ventilador del Reloj con los switches de Down (RA3) en 40, 39, 38...  y de Up (RA2)  en 30, 31, 32...45

Esta sería la introducción, luego pondré mas detalles del código de este diseño.

Saludos



 

« Última modificación: 20 de Marzo de 2021, 01:53:07 por Jorge Bern »

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Ese tipo de displays no los había visto nunca  :D

Desconectado Jorge Bern

  • PIC10
  • *
  • Mensajes: 46
    • Mis Proyectos de Electrónica Aplicada
Ese tipo de displays no los había visto nunca  :D
Estos son muy viejos, unos 50 años. Desconozco si se siguen fabricando  :shock:

"Voyager 1, llevando el microcontrolador activo que más se alejó de sus programadores"


 

anything