TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: Jorge Bern en 27 de Noviembre de 2020, 14:20:49

Título: Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 27 de Noviembre de 2020, 14:20:49
Buenas tardes colegas.
Este es mi primer posteo con este mi nuevo usuario, antes tuve otros en el foro pero cambié a este para unificar con otras cuentas que tengo por ahí.
El proyecto del asunto lo estoy desarrollando durante esta época tan especial de aislamiento y espero que les sea de interés, ya que integra el uso de PICs (uso el 16F628) enlazado con un módulo receptor GNSS(GPS) modelo Ublox GY-GPSV3-NEO-M8N que le provee la info de hora, fecha, posición, que el Reloj mostrará en su display.
Una particularidad de este Reloj es que utiliza un display de tubos de vacio TRC tipo IEE MIMO de unos 70 años de antiguedad.
Tambíen incorpora un control de temperatura para ventilar los TRCs utilizando un sensor digital tipo  DS18B20
En sucesivos posteos iré desarrollando el proyecto con el mayor detalle posible y será bienvenido todo comentario y/o sugerencia.
Saludos y gracias por la atención
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nocturno en 27 de Noviembre de 2020, 16:08:00
Interesante proyecto, permaneceré atento a tus progresos.

Una curiosidad, ¿por qué ese PIC?
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 27 de Noviembre de 2020, 16:26:15
Continuando con el tema del diseño de este Reloj presentaré el display que utiliza como dije, tubos de rayos catódicos (CRT) marca IEE modelo NIMO BA0006-P31 (ó IEE NIMO 6000-31-0006), que en adelante llamaré directamente Tubos.
Estas son joyas electrónicas  de los años 50 y 60, con su placa y circuiteria original recuperada desde el fondo de alguna tienda de antiguedades.
También es original la fuente de alimentación marca IEE modelo 14549, que ingresa con 110VAC por ser americana, y que provee 1,1 VAC para los filamentos (cátodos) y 3.500 VDC para los ánodos de  los Tubos.

Respecto de estos Tubos podemos detallar lo siguiente:
NIMO fue la marca comercial de una familia de Tubos de Rayos Catódicos (CRT) muy pequeños y no estandarizados, fabricados por IEE (Industrial Electronics Engineers de USA) a mediados de 1960.
En este caso el Tubo es el modelo BA0006-P31, que cuenta con 10 cañones de electrones con plantillas que dirigen y dan forma de dígito o caracter alfanumérico al haz de electrones que se proyecta e ilumina su pantalla superior.
Estos Tubos son de diseño interno artesanal y complejo pero de operación simple ya que proyectan un sólo dígito entre 10, normalmente de 0 a 9. Los hay más complejos de proyección multiple que cuentan con deflexión magnética especial pero este no es el caso.
Este modelo de Tubo posee 3 tipos de electrodos, un filamento catódico, un ánodo y 10 grillas o rejas de control que activan los 10 haces electrónicos con sus cuadrículas correspondientes.
Las ventajas de los Tubos NIMO respecto de sus contemporaneos NIXIE es su mejor ángulo de visualización, incluso el dígito proyectado se ve desde atrás del Tubo, y su color y brillo variable (dimmerizable). Sus desventajas es su mayor complejidad de alimentación y mayor consumo. El Tubo requiere mínimo 1750 Voltios de tensión DC de ánodo, 1.1 voltios de tensión AC para los filamentos, y cierta polarización catódica como se verá luego en el circuito de control.

Los datos del Tubo IEE BA0006-p31 pueden verse aqui:
https://drive.google.com/open?id=1DLRQtPeQQ1hgiz-LHyR7V1T94ZohrDft

 La placa de Tubos y su fuente de alimentación:

   - Tienes que ingresar para ver archivos adjuntos -  
  - Tienes que ingresar para ver archivos adjuntos -  

En la siguiente figura puede verse como varía el brillo o luminancia del Tubo en función de la tensión de Ánodo, lo que hace variable (dimmerizable) el brillo del tubo. Normalmente el control de brillo de un display numérico construido con estos Tubos se lograba con un reostato en el circuito primario del transformador de su fuente anódica, hoy con una alimentación switching variable supongo se lograría el mismo efecto.

   - Tienes que ingresar para ver archivos adjuntos -  

En la siguiente figura se muestra el circuito típico de testeo del Tubo NIMO.
Como en todo tubo de rayos catódicos, la corriente de haz se controla con la tensión del electrodo Grilla o reja. Como se ve en la figura, una tensión de Grilla de -6 Voltios respecto del Cátodo producirá la repulsión de los electrones del haz, llevando la corriente del Tubo al corte y apagando el brillo de la pantalla. En cambio una tensión de Grilla de +4 Voltios respecto del Cátodo permitirá el paso pleno de los electrones del haz y el brillo máximo de la pantalla del Tubo.
Cuando la Grilla de control sea negativa, su efecto de repulsión electrónica hará que la  corriente de haz de su cañon catódico sea nula. Cuando la Grilla sea positiva tomará unos pocos microamperes de corriente del haz, por lo cual debe usarse una resistencia de limitación de corriente de Grilla de un valor mínimo de 1 MegaOhms.

   - Tienes que ingresar para ver archivos adjuntos -  

Con esto y para no aburrir, finalizo la introducción a los Tubos a utilizar.
Un saludo.

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 27 de Noviembre de 2020, 16:46:05
Interesante proyecto, permaneceré atento a tus progresos.

Una curiosidad, ¿por qué ese PIC?


Ese PIC, si entiendo que es viejo, pero la principal razón fue que lo tenía en mi cajón jeje
Y en capacidad, memoria, USART, etc. estimo alcanza para este proyecto, aunque siempre se está a tiempo de cambiar.
Y gracias por el interés. espero no defraudar.
Un saludo
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 29 de Noviembre de 2020, 22:14:51
Continuando con este desarrollo, les cuento que como interface entre el PIC y los Tubos del Display, utilicé la técnica de registros de desplazamiento y decodificadores BCD que me anduvo bien en otros proyectos.
El decodificador BCD a decimal que utilicé es el CD4028 y su funcionamiento es simple, tiene 10 salidas y cada una se activará de acuerdo al código BCD de sus entradas. La alimentación será de 12 Voltios, de modo que con una polarización catódica de los Tubos de 6  Voltios, las 10 salidas del deco atacarán las 10 Grillas con +6 Voltios (tensión grilla-cátodo) cuando la salida está activa y encendiendo el dígito del Tubo, y con -6 Voltios (tensión grilla-cátodo) cuando la salida se desactiva y el dígito del Tubo se apaga. Claramente habrá un deco por cada Tubo.
Los códigos BCD de entrada a los decos los proveerán registros de desplazamiento o conversores serie/paralelo de 8 bits  tipo CD4094, entonces habrá un CD4094 por cada dos CD4028. Como el Reloj será de seis dígitos (Hora: Minutos:Segundos ó Año:Mes:Dia) usará seis CD4028 y tres CD4094. Los tres registros estarán en cascada y los datos entrarán en serie desde el PIC.

De acuerdo a esto, el circuito para dos Tubos (dígitos) es el siguiente:

  - Tienes que ingresar para ver archivos adjuntos -  

Y el diagrama para seis Tubos (dígitos) será:

  - Tienes que ingresar para ver archivos adjuntos -  


Un saludo.

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 03 de Diciembre de 2020, 02:44:30
Continuando con este proyecto, adjunto una foto de las primeras pruebas de los Tubos aún con su circuiteria original, la cual cambié por la detallada arriba.

  - Tienes que ingresar para ver archivos adjuntos -  

Ahora algunas consideraciones sobre el display del Reloj.
Como puede verse en las fotos, la placa de Tubos posee cinco Tubos NIMO o sea que falta uno para completar los seis dígitos necesarios para mostrar con dos dígitos cada uno, los tres valores de Hora, Minutos y Segundos en el modo Reloj, ó Día, Mes, Año en el modo Calendario. Y además como dije arriba, también mostrará Longitud y Latitud en el modo de Posicionador Geográfico.
Como estos Tubos son reliquias escasas y caras, la solución del sexto dígito será utilizar un Tubo especial (no NIMO) llamado de "medio dígito" que solamente mostrará un "1" o estará apagado.

Entonces de acuerdo a este criterio, el Display de seis dígitos mostrará (la X corresponde a dígito apagado):

- En el modo Reloj, la hora en el formato de 12 horas AM/PM, desde  X1:00:00 hasta 12:59:59
- En el modo Calendario, la fecha en el formato Mes:Año:Día, desde X1:20:01 hasta 12:20:31 (desde el 1ro de enero hasta el 31 de diciembre de este año, por ejemplo)
- En el modo Posicionador Geográfico,   
  - Longitud en el formato Grados (tres dígitos) y Minutos (dos digitos mas un dígito decimal)  desde + 180:00.0  hasta - 180:00.0
  - Latitud en el formato Grados (tres dígitos) y Minutos (dos digitos mas un dígito decimal)  desde + X90:00.0 hasta - X90:00.0

Como sólo hay seis digitos para mostrar todo, el cambio entre vista de Hora / Fecha será automático.
El Reloj en cada cuenta de diez segundos mostrará durante ocho segundos la Hora y durante dos segundos la Fecha.
Según esto, se verá en los segundos de 0 a 5 la Hora, durante los segundos 6 y 7 la Fecha, y en los segundos 8 y 9 de nuevo la Hora.

Y el cambio para pasar a mostrar Longitud/Latitud será con un pulsador que mientras esté oprimido, las vistas de Longitud/Latitud se alternarán cada cinco segundos.

Por ejemplo en este momento en Argentina, el Reloj mostrará:
- Hora,   2:31:35 ; Fecha,  12:03:20 ; Longitud, - 58:08.0;  Latitud, - 37:86.6

Toda esta info mostrada es sumistrada como ya dije, por el módulo GPS y ya está funcionando en un prototipo.
Pronto subiré algún video que aclarará lo expuesto.

Un saludo.

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Picuino en 03 de Diciembre de 2020, 11:05:17
Interesante. Me apunto al hilo.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 05 de Diciembre de 2020, 23:14:59
Continuando por aquí, aunque faltan algunos detalles sobre el Display, ya tenemos una idea general de como se verá.

Pasaré ahora al estudio del módulo GNSS (GPS) que le suministrará la info al PIC, que procesará y  mostrará en el Display.

El módulo como ya adelanté, será un receptor y procesador de señal GNSS (Global Navigation Satellite System) marca Ublox modelo GY-GPSV3-NEO-M8N de octava generación (8G), que fue liberado para uso civil en 2018 (hasta 2018 la Ublox 8G  era de uso militar (drones), hoy es de uso militar la Ublox 9G)

El módulo en su placa de evaluación con su antena integrada:

  - Tienes que ingresar para ver archivos adjuntos -  

Sus características principales son las siguientes:

UbloxCompact 8th generation GPS/GNSS receive/processor GPS module‎ GY-GPSV3-NEO-M8N breakout board general features:

 - 72-channel u-blox M8 engine GPS/QZSS L1 C/A, GLONASS L10F, BeiDou B1 SBAS L1 C/A: WAAS, EGNOS, MSAS Galileo-ready E1B/C (NEO-M8N)
- SuperSense Indoor GPS, -167dBm
- On-board Ultra low noise 3.3V voltage regulator and RF filter for noise blocking
- I2C (SDA,SCL) and Uart (Tx,Rx)
- Triple band GPS, Glonass and BeiDou antenna
- Triple band Band Pass filter
- Triple Band LNA
- U-center GPS Evaluation Software
- Extensive visualization and evaluation features
- Supports AssistNow Online and AssistNow Offline A-GPS services
- 1 TTL UART port, 1 I2C port
- Time pulse LED
- Battery for HOT module start and settings storage
- Build-in HMC5983 Compass
- Dimensions: 33*33mm hole distance 22x22mm
- Fully assembled and ready to use

Las hojas de datos del módulo NEO-M8N pueden verse aquí:
NEO-M8N Hoja de datos
https://drive.google.com/open?id=1Wg52KlsVJ4rXwirX9jqGIUmcF6VxzKho (https://drive.google.com/open?id=1Wg52KlsVJ4rXwirX9jqGIUmcF6VxzKho)
 
Y sus características mas detalladas de funciones y protocolos pueden verse aquí:
NEO-M8N características, funciones y protocolos
https://drive.google.com/open?id=1hKEx1slVAucMVO-bgP09KaiCiaI47X_1
 (https://drive.google.com/open?id=1hKEx1slVAucMVO-bgP09KaiCiaI47X_1)

Este módulo receptor/procesador NEO-M8N cumple con las especificaciones y normas actuales de los sistemas GNSS globales que están en operación, que actualmente son cuatro, el GPS(USA), el GLONASS(URSS), el BeiDou(China) y el Galileo(UE, aún en desarrollo),
y realmente de su gran potencia y versatilidad se usará muy poco en esta aplicación.

Aquí el uC se comunicará con el módulo por medio de su interface serial USART, utilizando el protocolo universal NMEA por medio del cual recibirá los parámetros de tiempo necesarios para actualizar su indicación de Hora, Minutos y Segundos,  de Dia, Mes y Año, y de Posición.
El protocolo NMEA es un estandar de comunicaciones jerárquico bidireccional (master-slave) para equipos electrónicos marítimos introducido en USA en el año 1983 y actualizado en los 2000s. Su manual de referencia puede verse aquí:
https://drive.google.com/file/d/1RhDY-q_ySYCkBr4vmcCsvrs7YXQbilkR/view?usp=sharing

El módulo NEO-M8N dispone entre otros de ese protocolo, que utiliza comunicación serial asincrónica (normas RS422/RS232) entre un dispositivo "hablador" (master ó talker) y uno o varios "escuchas" (slave ó listener).
Los parámetros de comunicación serial normalizados son los siguientes:

Baud rate: 9600
Number of data bits: 8 (bit 7 is 0)
Stop bits: 1 (or more)
Parity: none
Handshake: none

El formato general de los mensajes del protocolo NMEA  utiliza exclusivamente caracteres imprimibles en formato ASCII de 8 bits, comenzando el mensaje con el signo $ (pesos) y terminando con CR (carriage return) y LF (line feed)
El formato general del mensaje que recibirá el PIC será el siguiente:

 $TTSSS,D1,D2,...<CR>,<LF>

Donde TT es el identificador del dispositivo Master que envía el mensaje (dos letras), SSS es identificador de mensaje (tres letras) , y D1, D2, etc. son los datos que eventualmente acompañaran la respuesta.

Para testear el módulo  NEO-M8N, conocer sus características principales y elegir el mensaje adecuado para obtener los datos de Hora,  Fecha y Posición en tiempo real,  utilizaré la aplicación provista por el fabricante, la U-Center v20.01 GNSS Evaluation Software for Windows cuya guía de usuario puede verse aqui:

U-Center v20.01 User Guide
https://drive.google.com/file/d/1r5-AHrd7OM2dSNtgfnSi6tgzCkTW0eCF/view?usp=sharing (https://drive.google.com/file/d/1r5-AHrd7OM2dSNtgfnSi6tgzCkTW0eCF/view?usp=sharing)

Un saludo.

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 06 de Diciembre de 2020, 00:58:00
Test y pruebas del módulo GNSS NEO-M8N

Entonces continuando, para testear el módulo  NEO-M8N, conocer sus características principales y elegir el mensaje a utilizar para obtener los datos, utilizaré la aplicación provista por el fabricante, la U-Center v20.01 GNSS Evaluation Software for Windows
cuya vista principal se ve asi:

  - Tienes que ingresar para ver archivos adjuntos -  

Como se vé,  la aplicación brinda toda la información en tiempo real que provee el módulo NEO-M8N. Le daremos un rápido vistazo a sus ventanas.
En la linea de abajo se lee que el módulo está conectado al Computador por la interface serial COM6 a 9600 baudios y que utiliza el protocolo NMEA.
De izquierda a derecha en la pantalla de la aplicación aparecen distintas ventanas con información variada.
La primera ventana muestra los satélites GNSS recibidos, su rótulo y nivel de señal, los 6 de letra G son GPS (USA) y los 4 de letra R son GLONASS (Rusia), los Verdes están OK recibidos normalmente, los Azules están en proceso de adquisición, y en los Rojos se ha perdido la señal.
Luego está la ventana de Satellite Position que muestra la constelación visible y su posición relativa, luego la ventana de Signal History que indica el historial de señal, sus rotulos y las banderas de nacionalidad de los distintos satélites visibles.

Luego aparecen las ventanas de Data View, Altitude, Compass y Watch (Reloj) que se muestran con mas detalle aquí:

  - Tienes que ingresar para ver archivos adjuntos -  

Por último aparece la ventana de Consola que muestra los mensajes en formato NMEA que se reciben del módulo y que proveen toda la información para actualizar todas las ventanas.
Luego de este vistazo a las pantallas de la aplicación U-center de test y control, veremos cual mensaje de la gran variedad que envía el módulo será el requerido para que el uC rescate la info de Hora,  Fecha y Posición necesaria para mostrar en el Reloj.

El mensaje seleccionado será el $GNRMC, cuyo formato será:

   - Tienes que ingresar para ver archivos adjuntos -  

El mensaje a procesar entonces será el que tenga el encabezado $GNRMC, (24-47-4E-52-4D-43-2C en Hexa)  cuyos datos se marcan en la siguiente captura de consola y será la info que el PIC deberá extraer.

  - Tienes que ingresar para ver archivos adjuntos -  

Un saludo.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nocturno en 06 de Diciembre de 2020, 03:27:04
Tiene buena pinta ese modulito. Yo tengo experiencia con la serie SIM900 pero este parece mucho más pequeño.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 06 de Diciembre de 2020, 22:54:36
Tiene buena pinta ese modulito. Yo tengo experiencia con la serie SIM900 pero este parece mucho más pequeño.
No conocía ese módulo, parece interesante para aplicaciones GSM/GPRS
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 11 de Diciembre de 2020, 00:38:32
Continuando con este proyecto, ya hemos definido que mensaje transmitido por el módulo NEO-M8N proveerá toda la info a mostrar en el display del Reloj
Este será el mensaje $GNRMC, donde el identificador de dispositivo es GN (GNSS módule) y el tipo de memsaje es RMC (Recommended Minimum Specific GNSS Data)
Como se ve, la indicación de tiempo es suministrada con una resolución de milesimas de segundo y la presición será la correspondiente a los relojes atómicos del sistema GPS. Logicamente esta gran presición excede los requerimientos de este diseño.
Toda la info adicional suministrada como vimos será:

  - Tienes que ingresar para ver archivos adjuntos -  

Entonces la USART del módulo se comunicará con el PIC a 9600 baudios (parámetros vistos arriba) pasándole los mensajes.
La USART del PIC actuará por interrupciones y su rutina (rutina de servicio de interrupción o ISR) identificará el mensaje requerido y recogerá los datos que serán almacenados en registros de memoria.
Luego el PPal (programa principal) procesará estos datos y los mostrará en el Display.

El siguiente diagrama muestra la interacción entre la ISR y el PPal

  - Tienes que ingresar para ver archivos adjuntos -  

La USART recibe los mensajes NMEA del módulo y dispara la ISR con cada caracter (dato) recibido, identifica el encabezado del mensaje y almacena los datos en registros de memoria. el PPal lee esos registros, procesa los datos como veremos luego y los muestra en el Display.
El Display como ya vimos es de seis digitos y mostrará alternativamente Hora, Minutos y Segundos, y Mes, Año, Dia.
En la figura, HD y HU corresponden a Hora Decenas y Hora Unidades, MD y MU a Minuto Decenas y Minuto Unidades, y SD y SU a Segundos Decenas y Segundos Unidades. Lo mismo ocurre con la Fecha y DD,DU, ED,EU y AD,AU (la E la uso para Mes pues la M ya esta usada). La info de Posición no esta en el diagrama pero se obtiene en forma similar.

La ISR de la USART sigue el modelo de "maquina de estados", o sea tiene una variable de estado que le indica en que punto del mensaje está y que debe hacer con  el dato recibido.
Un diagrama simpificado de esta ISR es el siguiente:

  - Tienes que ingresar para ver archivos adjuntos -  

El proceso ingresa por el punto Verde y en la primera columna sigue el encabezamiento de mensaje $GNRMC y avanza la variable de Estado (É) comparando el dato recibido (Á) con los caracteres del encabezamiento. Cualquier comparación que no se cumpla en el seguimiento del encabezado de mensaje $GNRMC abortará la secuencia volviendo al Estado de Reposo (É=0)
Si se alcanza el estado É=7 significa que el mensaje fué identificado con exito y comienza en la segunda columna la adquisición de los datos en los registros de memoria.
Al final de esta columna se habilita un "contador de comas" para que la ISR saltee los parámetros que trae el mensaje y que no interesan, las comas son los separadores de parámetros y son constantes.
Por último en la tercera columna se recojen los datos de fecha y finaliza la secuencia exitosa de la ISR, volviendo al Estado de reposo y comenzando de nuevo con la detección del encabezamiento.
Luego con el código del programa aclararé más detalles.

Un saludo.



 
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nocturno en 11 de Diciembre de 2020, 02:42:54
Jorge, ¿el lenguaje que vas a usar no tiene rutinas de tratamiento de strings?
Lo digo porque la máquina de estados que vas a implementar, carácter a carácter, tiene pinta de pesadilla y a poco que cometas el más mínimo error te va a dar muchos dolores de cabeza para depurar.
Recuerdo que en mi aplicación (en lenguaje C) recibía líneas enteras hasta detectar el retorno de carro, y luego hacía una búsqueda de un string dentro de otro (strstr) y en caso de encontrar GPRMC, iba extrayendo los trozos de cadena que me interesaban.

Así se simplifica mucho el código y es mucho más fácil de depurar
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: KILLERJC en 11 de Diciembre de 2020, 12:20:55
Citar
Recuerdo que en mi aplicación (en lenguaje C) recibía líneas enteras hasta detectar el retorno de carro, y luego hacía una búsqueda de un string dentro de otro (strstr) y en caso de encontrar GPRMC, iba extrayendo los trozos de cadena que me interesaban.

Pero no es tan dificil tampoco implementar una maquina de estados que lo haga sobre la marcha... solo necesitas un indice, y luego ir comparandolo con otro string, que tenga el mismo comienzo (que te interese), menos memoria necesaria para procesar todo un string mas si lo hace con un PIC16F. Lo que si no se como lo implementó, imagino que ya lo tiene realizado.

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 14 de Diciembre de 2020, 12:48:58
Jorge, ¿el lenguaje que vas a usar no tiene rutinas de tratamiento de strings?
Hola, te comento que en todo este proyecto, el código lo hice en ASM (assembler) o como le llames.
Tengo alguna experiencia en C o VisualBasic con las instrucciones InString, mid$, etc. de tratamiento de strings.
Pero acá la detección es caracter por caracter con comparaciones en ASM y avanzando en la secuencia con la variable de estado.
Esta ISR ya la tengo funcionando y para chequearla hago eco de los datos recogidos a una HiperTerminal en PC.
En el diagrama de la ISR no aclaré pero se indica que el retorno de la rutina cuando recoje los datos es con "eco de datos" (salida con círculo rojo), y mientras sincroniza el mensaje no hay eco de datos (salidas con circulo naranja).
Luego pondré algo del código de la ISR, que es bastante largo.

Un saludo.


Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern 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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern 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
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 22 de Diciembre de 2020, 17:32:52
Continuando con este desarrollo, ahora veamos algo de hardware y como se conectará el PIC.

  - Tienes que ingresar para ver archivos adjuntos -  

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:

  - Tienes que ingresar para ver archivos adjuntos -  

- 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.


Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern 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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 04 de Enero de 2021, 23:41:12
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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 12 de Enero de 2021, 01:23:17
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í:

  - Tienes que ingresar para ver archivos adjuntos -  

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

  - Tienes que ingresar para ver archivos adjuntos -  

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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nocturno en 12 de Enero de 2021, 03:35:49
¡Qué chulo te ha quedado, enhorabuena!  :-/
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 13 de Enero de 2021, 12:49:44
¡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:

  - Tienes que ingresar para ver archivos adjuntos -  

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.


Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Picuino en 13 de Enero de 2021, 16:11:55
 ((:-)) ((:-)) ((:-)) ((:-)) ((:-))
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 20 de Enero de 2021, 12:30:26
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:

  - Tienes que ingresar para ver archivos adjuntos -  

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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nichita en 21 de Febrero de 2021, 00:11:52
Excelente !!  felicidades ((:-))
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 06 de Marzo de 2021, 00:14:27
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.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 20 de Marzo de 2021, 01:37:33
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:

  - Tienes que ingresar para ver archivos adjuntos -  

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:

  - Tienes que ingresar para ver archivos adjuntos -  

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 (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



 

Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: KILLERJC en 20 de Marzo de 2021, 07:26:09
Ese tipo de displays no los había visto nunca  :D
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 20 de Marzo de 2021, 12:28:15
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:
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 26 de Marzo de 2021, 00:03:45
Continuando, veamos con más detalle el diseño.

Como se ve en el video de arriba, luego del testeo del display el programa efectúa la lectura de los ID de 64 bytes que identifican los sensores DS0 y DS1 (64-BIT LASERED ROM).
Como dijimos el primer byte del ID es un identificador de tipo de sensor ( 28h) ,  el programa sólo lee los dos primeros bytes del ID de los dos sensores sólo 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 este caso el DS0 responde con los códigos exadecimales 28 91, y el DS1 responde 28 XX (el XX no se ve porque es un valor exadecimal no displayable). Los restantes 62 bytes de los ID no son leidos pues no hacen falta ya que como vimos, el DS0 se maneja exclusivamente con la linea RA0 y el DS1 con la linea RA1.

Entonces, la secuencia del programa para leer los dos primeros bytes del ID del sensor DS0 de acuerdo al procedimiento aconsejado en su hoja de datos, actuando el PIC como Master y el DS0 como Slave, será la siguiente:

1) Coloca RA0 como salida (TRISA0 = 0) y coloca un estado Bajo ("0") durante 480 uS (Master Reset Pulse)
2) Coloca RA0 como entrada (TRISA0=1), espera  de 15 uS a 60 uS y sensa el estado Bajo ("0") de respuesta del DS0 (Slave Presence Pulse) de 60 a 240 uS.
Si el pulso de presencia es detectado significa que el sensor está conectado y listo, en cambio si no se detecta durante un timeout de 480 uS, significa que el sensor no está o no funciona. En ese caso el programa mostrará guiones en el display indicando que el Master Reset falló.
3) Una vez que se detecta la presencia del sensor DS0 y este libera la linea de datos,  pasa RA0 nuevamente como salida
4) El Master (PIC) envía sobre la linea, el Read ID Command byte (33h) y a continuación invierte RA0 como entrada
5) Lee el primer byte del ID, lo guarda en memoria. Lee el segundo byte del ID y lo guarda en memoria. Los restantes 62 bytes del ID no son leidos
6) Muestra ambos valores leidos en el display.

A continuación, la secuencia del programa para leer los dos primeros bytes del ID del sensor DS1 será la misma sobre su linea RA1.
Y ambos valores leidos se mostrarán a continuación en el display como puede verse en el video.

Luego de leer y mostrar ambos ID de ambos sensores, el programa entrará en el lazo de  medición, muestra y comparación de la temperatura en ambos sensores.
Estos estarán por defecto en su máxima resolución de 12 bits y tendrán un tiempo de conversión de 750 mS.

La medición de temperatura en el DS0 se inicia con la siguiente secuencia:
1) Coloca RA0 como salida y envía el pulso de Reset (Master Reset Pulse)
2) Coloca RA0 como entrada y se verifica el pulso de respuesta del DS0 (Slave Presence Pulse)
3) Coloca RA0 como salida
4) El Master (PIC) envía sobre la linea, el Skip ROM Command byte (CCh)
5) El Master (PIC) envía sobre la linea, el Start Conversion Command byte (44h)
6) Coloca RA0 como entrada, el DS0 (Slave) colocará un Bajo "0" en la linea mientras dura la conversión de temperatura (750 mS)

7) A continuación, La medición de temperatura en el DS1 se inicia con misma secuencia sobre la linea RA1
8 ) Entra en el lazo de espera de fin de conversión sensando el estado Bajo "0" en RA0 forzado por el DSO mientras convierte
9) Una vez que el tiempo de conversión del DS0  finaliza indicado por la liberación de la linea RA0, se verifica también la finalización de conversión en el DS1 indicado por la liberación de la linea RA1.
Ambos sensores disparan su conversión en forma casi simultánea por lo cual  ambos tendrán la medición lista en el mismo período de 750 mS

Una vez que se verifica que ambos sensores terminaron su conversión de temperatura, se leen los valores con la siguiente secuencia:

1) Coloca RA0 como salida y envía el pulso de Reset (Master Reset Pulse)
2) Coloca RA0 como entrada y se verifica el pulso de respuesta del DS0 (Slave Presence Pulse)
3) Coloca RA0 como salida
4) El Master (PIC) envía sobre la linea, el Skip ROM Command byte (CCh)
5) El Master (PIC) envía sobre la linea, el Read Scratchpad Command byte (44h), los dos primeros bytes recibidos serán el valor de temperatura en 12 bits
6) Coloca RA0 como entrada
7) Lee el primer byte del Scratchpad, son los 8 bits de menor peso (LS byte) donde están las unidades y los decimales
8 ) Lee el segundo byte del Scratchpad, son los 8 bits de mayor peso (MS byte) donde están los signos y las decenas

El formato de ambos bytes y los pesos de los bits será el siguiente:

 LS byte    2^3  2^2  2^1  2^0  2^-1  2^-2  2^-3  2^-4  (unidades y decimales)
 MS byte    S    S    S    S    S     2^6   2^5   2^4   (bits de signo y decenas)

Los S son los bits de Signo que serán 0s con temperaturas positivas, el rango a mostrar será de 00.0 ºC  a  99.9 ºC

Ejemplos de lectura de temperatura (ver manual del DS18B20)
 - Temp= +125 °C , se lee 07D0h, o sea 7x16+13 = 125 . El ultimo digito son los decimales, que son cero
 - Temp= +25.0625°C, se lee 0191h, o sea 2x16+5+ 0,0625 x 1  (la resolucion en 12 bits es 0,0625 ºC)
 - Temp= +0.5°C, se lee 0008h, o sea 0,0625 x 8 = 0,5

La conversión de los valores binarios leidos en los bytes MS y LS a los valores BCD a mostrar en los displays será por tablas en EPROM
El contenido de la tabla de conversión para decenas y unidades será simple, se direcciona con decenas y unidades en binario (exadecimal) y se obtiene el valor a mostrar en BCD:
Tabla: (arranca en la posición 00h de la EPROM)
   de 0x00 ; 00
   de 0x01 ; 01
   de 0x02 ; 02
    de 0x03 ; 03
   de 0x04 ; 04
   de 0x05 ; 05
   de 0x06 ; 06
    de 0x07 ; 07
   de 0x08 ; 08  - Ejemplo: si los MS y LS bytes son 0080 , el valor BCD a mostrar en decenas y unidades será 08
   de 0x09 ; 09
   de 0x10 ; 0A
    de 0x11 ; 0B
   de 0x12 ; 0C
   de 0x13 ; 0D   - Ejemplo: si los MS y LS bytes son 00D0 , el valor BCD a mostrar en decenas y unidades será 13       
   de 0x14 ; 0E
    de 0x15 ; 0F
...la tabla continua hasta los valores finales...
   de 0x90 ; 5A
        de 0x91 ; 5B
    de 0x92 ; 5C
   de 0x93 ; 5D
   de 0x94 ; 5E
   de 0x95 ; 5F  - Ejemplo: si los MS y LS bytes son 05F0 (16x5+15), el valor BCD a mostrar en decenas y unidades será 95       
    de 0x96 ; 60
        de 0x97 ; 61
    de 0x98 ; 62
   de 0x99 ; 63  - Ejemplo: si los MS y LS bytes son 0630 (16x6+3) , el valor BCD a mostrar en decenas y unidades será 99       
   
El contenido de la tabla de conversión para los decimales será el siguiente, se direcciona con el nibble de decimales ( 2^-1  2^-2  2^-3  2^-4) del LS byte en binario (exadecimal), y se obtiene el valor redondeado a mostrar en BCD (la resolucion en 12 bits es 1/16 o sea 0,0625 ºC)

Tabla (empieza en la posición 70h de la EPROM):
   de 0x00 ;70 0  0,0000 
   de 0x01 ;71 1  0,0625   
   de 0x01 ;72 2  0,1250   
    de 0x02 ;73 3  0,1875   - Ejemplo: el nibble de decimales es 3 (03h), la dirección de memoria será 73h, el valor de temp será
   de 0x02 ;74 4  0,2500                    0,0625x3=0,1875 ºC, el valor redondeado retornado para mostrar será 2
   de 0x03 ;75 5  0,3125
   de 0x04 ;76 6  0,3750
    de 0x04 ;77 7  0,4375
   de 0x05 ;78 8  0,5000
   de 0x06 ;79 9  0,5625
   de 0x06 ;7A A  0,6250
    de 0x07 ;7B B  0,6875 - Ejemplo: el nibble de decimales es B (0Bh), la dirección de memoria será 7Bh, el valor de temp. será
   de 0x07 ;7C C  0,7500                  0,0625x11=0,6875 ºC, el valor redondeado retornado para mostrar será 7
   de 0x08 ;7D D  0,8125           
   de 0x09 ;7E E  0,8750
    de 0x09 ;7F F   0,9375

Luego agregaré algo de código que hace todo esto.

Saludos
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 20 de Junio de 2021, 02:49:12
Buenas noches colegas,
primero pido disculpas por haber colgado este proyecto durante estos meses pero tuve inconvenientes con el gabinete de acrílico que con esta pandemia me tardaron en entregar.
Finalmente logré instalar el prototipo en el gabinete (bastante desprolijo por cierto) con todo lo aquí descrito y ya está funcionando como muestro en el siguiente video.



El video muestra al principio la hora local  10:29:32  (con leds separadores verdes e indicación de HOR MIN SEG ) y luego la fecha 19:06:21 (con leds separadores rojos e indicación de MES AÑO DIA) También el calendario se enciende en día SAB y mes JUN
Luego oprimiendo el pulsador el display muestra LONG 57 Grados 33.5 Minutos y LAT 37 Grados 58.2 Minutos que es la posición geográfica donde se encuentra el Reloj.
Sobre la derecha como ya vimos se ven los displays del termómetro de dos canales, mostrando temperatura exterior 17.3 ºC  e interior 39.9 ºC
En el Seg.28 del video la temperatura interna pasa a 40ºC y el ventilador se enciende, puede verse funcionando en el Seg.33, entonces la temperatura baja a 39ºC y el ventilador se detiene.
En el Seg.39 se ven los leds de interface con el módulo GPS, el verde indica actividad de datos entrantes (mensaje de sincronismo GPS) y el amarillo indica el eco de los datos de salida (HyperTerminal)
En el Seg.59 puede verse el sensor de temperatura interna sobre el transformador de alta tensión (3.500V) de los TRCs NIMO, que es el punto mas caliente del equipo.
Por último en el Seg.112 se ve nuevamente que la temperatura del trafo alcanza los 40ºC , se enciende el ventilador y esta baja a 39ºC.

Con este posteo y con el prototipo terminado y funcionando, de mi parte doy por terminado este tema, espero les haya resultado interesante.
Cualquier comentario y/o aclaración de los colegas, quedo a disposición
Gracias por vuestros comentarios y atención

Un saludo.


Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: KILLERJC en 21 de Junio de 2021, 06:08:41
Te quedo excelente Jorge. Muchas Felicitaciones
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Nocturno en 21 de Junio de 2021, 11:19:57
Grandísimo hilo y grandísimo proyecto. Felicidades Jorge
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Picuino en 22 de Junio de 2021, 15:36:45
 (((:-))) (((:-))) (((:-)))
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 24 de Junio de 2021, 02:41:02
Muchas gracias colegas por los comentarios y felicitaciones.
Son de muy buen nivel los temas que se presentan aquí y espero haber estado a la altura.
Algún otro proyecto presentare por aquí en breve.
Un saludo  :-/
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: KILLERJC en 18 de Julio de 2021, 12:36:30
Hay una cosa que vi hace bastante y por falta de tiempo no pude decirtelo, en la parte donde buscas el "$GNRMC," podrias haberlo realizado asi:

Código: ASM
  1. enc_gps:
  2.         ADDWF   PCL,f
  3.         DT "$GNRMC,",0x00
  4.  
  5. recepcion:     
  6.         MOVF    INDEX, W
  7.         CALL    enc_gps
  8.         IORLW   0x00                    ; Reviso que no sea un 0x00, para determinar si llegue a la ultima letra
  9.         BTFSC   STATUS, Z
  10.         GOTO    encabezado_correcto
  11.         XORWF   RCDATO
  12.         BTFSS   STATUS, Z
  13.         GOTO    siguiente_letra
  14.         CLRF    INDEX                   ; Es otro encabezado
  15.         RETURN
  16. siguiente_letra:
  17.         INCF    INDEX, F
  18.         RETURN
  19.  
  20. encabezado_correcto:
  21.          ;Aca podes usar los estados, para determinar todo lo que viene y quitar las comas. Especialmente si usar acceso indirecto para almacenarlo en espacios contiguos de la RAM, ya que solo seria incrementar.

Aplicando lo mismo podes hacer la separacion de los datos del receptor

Código: ASM
  1. Limpieza_recepcion_inicial
  2.         ;Aca limpiar todo los datos anteriores.
  3.         CLRF    INDEX_DATA
  4.         GOTO    cargar_direccion
  5. Recepcion_datos:
  6.         MOVF    RCDATO, W
  7.         XORLW   ','
  8.         BTFSC   STATUS,Z
  9.         GOTO    siguiente_dato
  10.         MOVF    RCDATO
  11.         MOVWF   INDF
  12.         RETURN
  13.  
  14. siguiente_dato:
  15.         INCF    INDEX_DATA, F
  16. cargar_direccion:
  17.         MOVF    INDEX_DATA, W
  18.         CALL    tabla_direccion
  19.         IORLW   0x00  ; Proteccion
  20.         BTFSC   STATUS, Z
  21.         GOTO    error_recepcion
  22.         MOVWF   FSR
  23.         RETURN
  24.  
  25. error_recepcion:
  26.         ;Se recibieron mas comas que lo pensado.
  27.  
  28. tabla_direccion:
  29.         ADDWF PCL, F
  30.         DT      0x20,0x25,0x30,0x35,0x40, 0x00  ;Inicio de direcciones de RAM donde se van a depositar cada valor, mas un 0x00 por las dudas, definir los espacios necesarios para una recepcion completa

Lo mejor para esto hubiera sido un PIC18F. Tiene muchas mas ventajas respecto al manejo de la memoria.

PD: Lo escribí sin probarlo, lo hice en el bloc de notas, así que seguramente tenga algunos/millones de errores. Es solo de referencia.
Título: Re:Reloj/Calendario/Posicionador Geográfico/Termómetro sincronizado por módulo GPS
Publicado por: Jorge Bern en 19 de Julio de 2021, 01:47:56
Hola Killer,
En un momento pensé hacer así como decís , comparar la parte fija de los mensajes con una tabla en memoria en lugar de la casi interminable maquina de estados, probablemente hubiera quedado mas sencillo el código.
Gracias por el aporte!