Compare commits
	
		
			11 Commits
		
	
	
		
			b84ddd26be
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					893a5d2db4 | ||
| fc069bd63e | |||
| 
						 | 
					3f97f3f02a | ||
| 
						 | 
					7cccb3306c | ||
| 
						 | 
					1ae6e04559 | ||
| b56f705f05 | |||
| 
						 | 
					43a7b6307c | ||
| 
						 | 
					6add396b9f | ||
| 
						 | 
					109fb6adb3 | ||
| 
						 | 
					360e231008 | ||
| 
						 | 
					db4934d1bc | 
							
								
								
									
										168
									
								
								Font_Chrono1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								Font_Chrono1.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Font_Chrono1
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * created with FontCreator
 | 
				
			||||||
 | 
					 * written by F. Maximilian Thiele
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * http://www.apetech.de/fontCreator
 | 
				
			||||||
 | 
					 * me@apetech.de
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File Name           : Font_Chrono1.h
 | 
				
			||||||
 | 
					 * Date                : 10.01.2012
 | 
				
			||||||
 | 
					 * Font size in bytes  : 12422
 | 
				
			||||||
 | 
					 * Font width          : 10
 | 
				
			||||||
 | 
					 * Font height         : 16
 | 
				
			||||||
 | 
					 * Font first char     : 32
 | 
				
			||||||
 | 
					 * Font last char      : 128
 | 
				
			||||||
 | 
					 * Font used chars     : 96
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The font data are defined as
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * struct _FONT_ {
 | 
				
			||||||
 | 
					 *     uint16_t   font_Size_in_Bytes_over_all_included_Size_it_self;
 | 
				
			||||||
 | 
					 *     uint8_t    font_Width_in_Pixel_for_fixed_drawing;
 | 
				
			||||||
 | 
					 *     uint8_t    font_Height_in_Pixel_for_all_characters;
 | 
				
			||||||
 | 
					 *     unit8_t    font_First_Char;
 | 
				
			||||||
 | 
					 *     uint8_t    font_Char_Count;
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     uint8_t    font_Char_Widths[font_Last_Char - font_First_Char +1];
 | 
				
			||||||
 | 
					 *                  // for each character the separate width in pixels,
 | 
				
			||||||
 | 
					 *                  // characters < 128 have an implicit virtual right empty row
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     uint8_t    font_data[];
 | 
				
			||||||
 | 
					 *                  // bit field of all characters
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#include <inttypes.h>
 | 
				
			||||||
 | 
					#ifdef __AVR__
 | 
				
			||||||
 | 
					#include <avr/pgmspace.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define PROGMEM
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef Font_CHRONO1_H
 | 
				
			||||||
 | 
					#define Font_CHRONO1_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define Font_CHRONO1_WIDTH 10
 | 
				
			||||||
 | 
					#define Font_CHRONO1_HEIGHT 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t Font_Chrono1[] PROGMEM = {
 | 
				
			||||||
 | 
					    0x30, 0x86, // size
 | 
				
			||||||
 | 
					    0x0A, // width
 | 
				
			||||||
 | 
					    0x10, // height
 | 
				
			||||||
 | 
					    0x20, // first char
 | 
				
			||||||
 | 
					    0x60, // char count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // char widths
 | 
				
			||||||
 | 
					    0x00, 0x03, 0x07, 0x0B, 0x09, 0x0E, 0x0B, 0x03, 0x05, 0x05,
 | 
				
			||||||
 | 
					    0x06, 0x09, 0x03, 0x05, 0x03, 0x04, 0x08, 0x08, 0x08, 0x08,
 | 
				
			||||||
 | 
					    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x03, 0x09, 0x08,
 | 
				
			||||||
 | 
					    0x09, 0x08, 0x0C, 0x0C, 0x09, 0x09, 0x09, 0x09, 0x08, 0x0A,
 | 
				
			||||||
 | 
					    0x0A, 0x03, 0x09, 0x0C, 0x08, 0x0C, 0x0A, 0x0A, 0x09, 0x0A,
 | 
				
			||||||
 | 
					    0x0A, 0x09, 0x0B, 0x0A, 0x0C, 0x10, 0x0C, 0x0B, 0x09, 0x05,
 | 
				
			||||||
 | 
					    0x04, 0x05, 0x08, 0x08, 0x03, 0x09, 0x09, 0x09, 0x09, 0x09,
 | 
				
			||||||
 | 
					    0x06, 0x09, 0x09, 0x03, 0x04, 0x0A, 0x03, 0x0D, 0x09, 0x09,
 | 
				
			||||||
 | 
					    0x09, 0x09, 0x06, 0x08, 0x06, 0x09, 0x09, 0x0F, 0x0B, 0x09,
 | 
				
			||||||
 | 
					    0x07, 0x06, 0x02, 0x06, 0x09, 0x08,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // font data
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x1D, 0x1D, 0x1D, // 33
 | 
				
			||||||
 | 
					    0x1E, 0x1E, 0x1E, 0x00, 0x1E, 0x1E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 34
 | 
				
			||||||
 | 
					    0x30, 0x30, 0xF0, 0xFE, 0x3E, 0x30, 0x30, 0xF0, 0xFE, 0x3E, 0x30, 0x06, 0x1E, 0x1F, 0x07, 0x06, 0x06, 0x1E, 0x1F, 0x07, 0x06, 0x06, // 35
 | 
				
			||||||
 | 
					    0x38, 0x7C, 0xFE, 0xE6, 0xFF, 0xC6, 0xCE, 0x8C, 0x0C, 0x04, 0x0C, 0x1C, 0x18, 0x3F, 0x19, 0x1F, 0x0F, 0x07, // 36
 | 
				
			||||||
 | 
					    0x3C, 0x7E, 0x42, 0x42, 0x7E, 0x3C, 0x80, 0x60, 0x10, 0x8C, 0x82, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0C, 0x02, 0x01, 0x00, 0x0F, 0x1F, 0x10, 0x10, 0x1F, 0x0F, // 37
 | 
				
			||||||
 | 
					    0x00, 0x80, 0x9C, 0xFE, 0xFE, 0xE6, 0xBE, 0x3E, 0x9C, 0x80, 0x80, 0x07, 0x0F, 0x1F, 0x19, 0x18, 0x19, 0x1F, 0x0F, 0x0F, 0x1F, 0x1D, // 38
 | 
				
			||||||
 | 
					    0x1E, 0x1E, 0x1E, 0x00, 0x00, 0x00, // 39
 | 
				
			||||||
 | 
					    0xE0, 0xF8, 0xFC, 0x1E, 0x02, 0x0F, 0x3F, 0x7F, 0xF0, 0x80, // 40
 | 
				
			||||||
 | 
					    0x02, 0x1E, 0xFC, 0xF8, 0xE0, 0x80, 0xF0, 0x7F, 0x3F, 0x0F, // 41
 | 
				
			||||||
 | 
					    0x08, 0x68, 0x3E, 0x3E, 0x68, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 42
 | 
				
			||||||
 | 
					    0xC0, 0xC0, 0xC0, 0xF8, 0xF8, 0xF8, 0xC0, 0xC0, 0xC0, 0x01, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x01, // 43
 | 
				
			||||||
 | 
					    0x00, 0x00, 0x00, 0xDC, 0x7C, 0x3C, // 44
 | 
				
			||||||
 | 
					    0x80, 0x80, 0x80, 0x80, 0x80, 0x03, 0x03, 0x03, 0x03, 0x03, // 45
 | 
				
			||||||
 | 
					    0x00, 0x00, 0x00, 0x1C, 0x1C, 0x1C, // 46
 | 
				
			||||||
 | 
					    0x00, 0x80, 0x78, 0x06, 0x18, 0x07, 0x00, 0x00, // 47
 | 
				
			||||||
 | 
					    0xFC, 0xFE, 0x07, 0x03, 0x03, 0x07, 0xFE, 0xFC, 0x3F, 0x7F, 0xE0, 0xC0, 0xC0, 0xE0, 0x7F, 0x3F, // 48 (0)
 | 
				
			||||||
 | 
					    0x0C, 0x0E, 0x06, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, // 49 (1)
 | 
				
			||||||
 | 
					    0x0E, 0x0F, 0x03, 0x03, 0x83, 0xC3, 0xFF, 0x7E, 0xF8, 0xFC, 0xCE, 0xC7, 0xC3, 0xC1, 0xC0, 0xC0, // 50 (2)
 | 
				
			||||||
 | 
					    0x0C, 0x0E, 0x07, 0x83, 0x83, 0xC7, 0xFE, 0x7C, 0x38, 0x78, 0xE0, 0xC1, 0xC1, 0xE3, 0x7F, 0x3E, // 51 (3)
 | 
				
			||||||
 | 
					    0xE0, 0xF8, 0x1C, 0x0E, 0xFF, 0xFF, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, // 52 (4)
 | 
				
			||||||
 | 
					    0x7F, 0x7F, 0x63, 0x63, 0x63, 0xE3, 0xE3, 0xC3, 0x78, 0xF8, 0xE0, 0xC0, 0xC0, 0xE0, 0xFF, 0x7F, // 53 (5)
 | 
				
			||||||
 | 
					    0xFC, 0xFE, 0x87, 0x83, 0x83, 0x87, 0x1E, 0x1C, 0x3F, 0x7F, 0xE3, 0xC1, 0xC1, 0xE3, 0x7F, 0x3E, // 54 (6)
 | 
				
			||||||
 | 
					    0x1E, 0x1F, 0x03, 0x03, 0x83, 0xE3, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x07, 0x00, 0x00, // 55 (7)
 | 
				
			||||||
 | 
					    0x1C, 0xBE, 0xE7, 0xC3, 0xC3, 0xE7, 0xBE, 0x1C, 0x3F, 0x7F, 0xE1, 0xC0, 0xC0, 0xE1, 0x7F, 0x3F, // 56 (8)
 | 
				
			||||||
 | 
					    0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0x67, 0xFE, 0xFC, 0x30, 0x70, 0xE0, 0xC0, 0xC0, 0xE0, 0x7F, 0x3F, // 57 (9)
 | 
				
			||||||
 | 
					    0x00, 0x30, 0x30, 0x00, 0x00, 0x0C, 0x0C, 0x00, // 58 (:)
 | 
				
			||||||
 | 
					    0x70, 0x70, 0x70, 0xDC, 0x7C, 0x3C, // 59
 | 
				
			||||||
 | 
					    0xE0, 0xE0, 0xE0, 0xF0, 0x70, 0x70, 0x70, 0x38, 0x38, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x0E, 0x0E, // 60
 | 
				
			||||||
 | 
					    0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, // 61
 | 
				
			||||||
 | 
					    0x38, 0x38, 0x70, 0x70, 0x70, 0xF0, 0xE0, 0xE0, 0xE0, 0x0E, 0x0E, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, // 62
 | 
				
			||||||
 | 
					    0x18, 0x1C, 0x9E, 0xC6, 0xE6, 0xFE, 0x7C, 0x38, 0x00, 0x00, 0x1D, 0x1D, 0x1D, 0x00, 0x00, 0x00, // 63
 | 
				
			||||||
 | 
					    0xE0, 0x18, 0xC4, 0xF4, 0x3A, 0x0A, 0x0A, 0xF2, 0xFA, 0x7C, 0x08, 0xF0, 0x07, 0x18, 0x27, 0x2F, 0x48, 0x48, 0x4C, 0x4F, 0x4F, 0x28, 0x36, 0x11, // 64
 | 
				
			||||||
 | 
					    0x00, 0x80, 0xE0, 0xF8, 0xFE, 0x1E, 0xFE, 0xF8, 0xE0, 0x80, 0x00, 0x00, 0x1C, 0x1F, 0x0F, 0x07, 0x06, 0x06, 0x06, 0x07, 0x0F, 0x1F, 0x1C, 0x10, // 65
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xFE, 0xBC, 0x98, 0x00, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x18, 0x1F, 0x0F, 0x07, // 66
 | 
				
			||||||
 | 
					    0xF0, 0xFC, 0xFC, 0x0E, 0x06, 0x0E, 0x1E, 0x1C, 0x08, 0x03, 0x0F, 0x1F, 0x1C, 0x18, 0x1C, 0x1F, 0x0E, 0x06, // 67
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x06, 0x06, 0x0E, 0xFE, 0xFC, 0xF0, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x1C, 0x1F, 0x0F, 0x03, // 68
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x06, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // 69
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x06, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // 70
 | 
				
			||||||
 | 
					    0xF0, 0xFC, 0xFC, 0x0E, 0x06, 0xC6, 0xCE, 0xDE, 0xDC, 0xC8, 0x03, 0x0F, 0x0F, 0x1C, 0x18, 0x18, 0x1C, 0x1F, 0x0F, 0x0F, // 71
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0xFE, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, // 72
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x1F, 0x1F, 0x1F, // 73
 | 
				
			||||||
 | 
					    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x06, 0x0F, 0x1F, 0x1C, 0x18, 0x18, 0x1F, 0x0F, 0x07, // 74
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC0, 0xE0, 0xF0, 0xF8, 0xDC, 0x0E, 0x06, 0x02, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1F, 0x1E, 0x18, 0x10, // 75
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, // 76
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x3E, 0xF8, 0x80, 0x80, 0xF8, 0x3E, 0xFE, 0xFE, 0xFE, 0x1F, 0x1F, 0x1F, 0x00, 0x03, 0x1F, 0x1F, 0x03, 0x00, 0x1F, 0x1F, 0x1F, // 77
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x7C, 0xF0, 0xE0, 0x80, 0xFE, 0xFE, 0xFE, 0x1F, 0x1F, 0x1F, 0x00, 0x01, 0x03, 0x0F, 0x1F, 0x1F, 0x1F, // 78
 | 
				
			||||||
 | 
					    0xF0, 0xFC, 0xFC, 0x0E, 0x06, 0x06, 0x0E, 0xFC, 0xFC, 0xF0, 0x03, 0x0F, 0x0F, 0x1C, 0x18, 0x18, 0x1C, 0x0F, 0x0F, 0x03, // 79
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xFE, 0x7E, 0x3C, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80
 | 
				
			||||||
 | 
					    0xF0, 0xFC, 0xFC, 0x0E, 0x06, 0x06, 0x0E, 0xFC, 0xFC, 0xF0, 0x03, 0x0F, 0x0F, 0x1C, 0x18, 0x1E, 0x1C, 0x1F, 0x1F, 0x33, // 81
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC6, 0xC6, 0xC6, 0xFE, 0x7E, 0x3C, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x1C, 0x10, // 82
 | 
				
			||||||
 | 
					    0x38, 0x7C, 0xFE, 0xE6, 0xE6, 0xEE, 0xDE, 0xDC, 0x98, 0x06, 0x0E, 0x1E, 0x1C, 0x18, 0x19, 0x1F, 0x0F, 0x07, // 83
 | 
				
			||||||
 | 
					    0x06, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, // 84
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x07, 0x0F, 0x1F, 0x1C, 0x18, 0x18, 0x1C, 0x1F, 0x0F, 0x07, // 85
 | 
				
			||||||
 | 
					    0x1E, 0xFE, 0xFC, 0xF0, 0x80, 0x00, 0x80, 0xF0, 0xFC, 0xFE, 0x1E, 0x02, 0x00, 0x00, 0x03, 0x1F, 0x1F, 0x1C, 0x1F, 0x1F, 0x03, 0x00, 0x00, 0x00, // 86
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xF8, 0x00, 0x80, 0xF8, 0xFE, 0x3E, 0xFE, 0xF8, 0x80, 0x00, 0xF8, 0xFE, 0xFE, 0x06, 0x00, 0x0F, 0x1F, 0x1F, 0x1F, 0x07, 0x01, 0x00, 0x01, 0x07, 0x1F, 0x1F, 0x1F, 0x0F, 0x00, 0x00, // 87
 | 
				
			||||||
 | 
					    0x06, 0x1E, 0x3C, 0xF8, 0xF0, 0xE0, 0xF0, 0xF8, 0x3C, 0x1E, 0x06, 0x02, 0x18, 0x1E, 0x0F, 0x07, 0x03, 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x18, 0x10, // 88
 | 
				
			||||||
 | 
					    0x02, 0x0E, 0x1E, 0x7E, 0xF8, 0xE0, 0xF8, 0x7E, 0x1E, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, // 89
 | 
				
			||||||
 | 
					    0x00, 0x06, 0x06, 0xC6, 0xE6, 0xF6, 0x3E, 0x1E, 0x0E, 0x1C, 0x1E, 0x1F, 0x1B, 0x19, 0x18, 0x18, 0x18, 0x18, // 90
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x06, 0x06, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, // 91
 | 
				
			||||||
 | 
					    0x06, 0x78, 0x80, 0x00, 0x00, 0x00, 0x07, 0x18, // 92
 | 
				
			||||||
 | 
					    0x06, 0x06, 0xFE, 0xFE, 0xFE, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, // 93
 | 
				
			||||||
 | 
					    0x40, 0x70, 0x7C, 0x1E, 0x1E, 0x7C, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 94
 | 
				
			||||||
 | 
					    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 95
 | 
				
			||||||
 | 
					    0x02, 0x06, 0x04, 0x00, 0x00, 0x00, // 96
 | 
				
			||||||
 | 
					    0x40, 0x60, 0x70, 0x30, 0xB0, 0xB0, 0xF0, 0xF0, 0xE0, 0x0E, 0x1F, 0x1F, 0x1B, 0x19, 0x09, 0x1F, 0x1F, 0x1F, // 97
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x60, 0x30, 0x30, 0xF0, 0xE0, 0xC0, 0x1F, 0x1F, 0x1F, 0x0C, 0x18, 0x18, 0x1F, 0x0F, 0x07, // 98
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0x70, 0x30, 0x30, 0x70, 0x60, 0x40, 0x07, 0x0F, 0x1F, 0x1C, 0x18, 0x18, 0x1C, 0x0C, 0x04, // 99
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0x30, 0x30, 0x60, 0xFE, 0xFE, 0xFE, 0x07, 0x0F, 0x1F, 0x18, 0x18, 0x0C, 0x1F, 0x1F, 0x1F, // 100
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0xB0, 0xB0, 0xB0, 0xF0, 0xE0, 0xC0, 0x07, 0x0F, 0x1F, 0x1D, 0x19, 0x19, 0x1D, 0x0D, 0x05, // 101
 | 
				
			||||||
 | 
					    0x30, 0xFC, 0xFE, 0xFE, 0x36, 0x36, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, // 102
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0x30, 0x30, 0x60, 0xF0, 0xF0, 0xF0, 0x47, 0xCF, 0xDF, 0xD8, 0xD8, 0xCC, 0xFF, 0x7F, 0x3F, // 103
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x20, 0x30, 0x30, 0xF0, 0xF0, 0xE0, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, // 104
 | 
				
			||||||
 | 
					    0xF6, 0xF6, 0xF6, 0x1F, 0x1F, 0x1F, // 105
 | 
				
			||||||
 | 
					    0x00, 0xF6, 0xF6, 0xF6, 0xC0, 0xFF, 0xFF, 0x7F, // 106
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0xC0, 0xE0, 0xF0, 0xF0, 0x30, 0x10, 0x00, 0x1F, 0x1F, 0x1F, 0x03, 0x01, 0x07, 0x1F, 0x1E, 0x1C, 0x10, // 107
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFE, 0x1F, 0x1F, 0x1F, // 108
 | 
				
			||||||
 | 
					    0xF0, 0xF0, 0xF0, 0x20, 0x30, 0xF0, 0xF0, 0xE0, 0x20, 0x30, 0xF0, 0xF0, 0xE0, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x1F, // 109
 | 
				
			||||||
 | 
					    0xF0, 0xF0, 0xF0, 0x20, 0x30, 0x30, 0xF0, 0xF0, 0xE0, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, // 110
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0x70, 0x30, 0x70, 0xF0, 0xE0, 0xC0, 0x07, 0x0F, 0x1F, 0x1C, 0x18, 0x1C, 0x1F, 0x0F, 0x07, // 111
 | 
				
			||||||
 | 
					    0xF0, 0xF0, 0xF0, 0x60, 0x30, 0x70, 0xF0, 0xE0, 0xC0, 0xFF, 0xFF, 0xFF, 0x0C, 0x18, 0x18, 0x1F, 0x0F, 0x07, // 112
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xF0, 0x30, 0x30, 0x60, 0xF0, 0xF0, 0xF0, 0x07, 0x0F, 0x1F, 0x18, 0x18, 0x0C, 0xFF, 0xFF, 0xFF, // 113
 | 
				
			||||||
 | 
					    0xF0, 0xF0, 0xF0, 0x20, 0x30, 0x10, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, // 114
 | 
				
			||||||
 | 
					    0xE0, 0xF0, 0xF0, 0x90, 0x90, 0xB0, 0x30, 0x20, 0x08, 0x19, 0x1B, 0x13, 0x13, 0x1F, 0x1F, 0x0E, // 115
 | 
				
			||||||
 | 
					    0x30, 0xFC, 0xFC, 0xFE, 0x30, 0x30, 0x00, 0x0F, 0x1F, 0x1F, 0x18, 0x18, // 116
 | 
				
			||||||
 | 
					    0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x0F, 0x1F, 0x1F, 0x18, 0x18, 0x08, 0x1F, 0x1F, 0x1F, // 117
 | 
				
			||||||
 | 
					    0x10, 0xF0, 0xF0, 0xC0, 0x00, 0xE0, 0xF0, 0xF0, 0x10, 0x00, 0x00, 0x07, 0x1F, 0x1C, 0x1F, 0x07, 0x00, 0x00, // 118
 | 
				
			||||||
 | 
					    0x10, 0xF0, 0xF0, 0xE0, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0xE0, 0xF0, 0xF0, 0x10, 0x00, 0x00, 0x07, 0x1F, 0x1E, 0x0F, 0x03, 0x00, 0x03, 0x0F, 0x1E, 0x1F, 0x07, 0x00, 0x00, // 119
 | 
				
			||||||
 | 
					    0x10, 0x30, 0x70, 0xE0, 0xC0, 0x80, 0xC0, 0xE0, 0x70, 0x30, 0x10, 0x10, 0x18, 0x1E, 0x0F, 0x07, 0x03, 0x07, 0x0F, 0x1E, 0x18, 0x10, // 120
 | 
				
			||||||
 | 
					    0x10, 0xF0, 0xF0, 0xC0, 0x00, 0xC0, 0xF0, 0xF0, 0x30, 0xC0, 0xC0, 0xC7, 0xFF, 0xFC, 0x3F, 0x0F, 0x01, 0x00, // 121
 | 
				
			||||||
 | 
					    0x30, 0x30, 0x30, 0xF0, 0xF0, 0xF0, 0x30, 0x1C, 0x1E, 0x1F, 0x1B, 0x19, 0x18, 0x18, // 122
 | 
				
			||||||
 | 
					    0x00, 0x00, 0xFC, 0xFE, 0xFE, 0x06, 0x03, 0x03, 0x7F, 0xFF, 0xFC, 0xC0, // 123
 | 
				
			||||||
 | 
					    0xFE, 0xFE, 0xFF, 0xFF, // 124
 | 
				
			||||||
 | 
					    0x06, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0xC0, 0xFC, 0xFF, 0x7F, 0x03, 0x03, // 125
 | 
				
			||||||
 | 
					    0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, // 126
 | 
				
			||||||
 | 
					    0xF8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xF8, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F // 127
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										152
									
								
								Font_data.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								Font_data.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  Font_data.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  This is the data file for custom fonts, as alternative for the sysfont defined in MD_MAX72xx_font.cpp
 | 
				
			||||||
 | 
					  'fontClock' only has chars 32..126, saving a few bytes of memory
 | 
				
			||||||
 | 
					  The first number of every line is the width of the char, the number of columns
 | 
				
			||||||
 | 
					  The following numbers are the columns, each byte for 8 LED on/off
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef Font_data_H
 | 
				
			||||||
 | 
					#define Font_data_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//fontClock is adapted sysfont for better time/date display in Dutch language
 | 
				
			||||||
 | 
					MD_MAX72XX::fontType_t fontClock[] PROGMEM = 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  'F', 2, 0, 0, 0, 126, 8,
 | 
				
			||||||
 | 
					  0,		// 0
 | 
				
			||||||
 | 
						0,		// 1
 | 
				
			||||||
 | 
						0,		// 2
 | 
				
			||||||
 | 
						0,		// 3
 | 
				
			||||||
 | 
						0,		// 4
 | 
				
			||||||
 | 
						0,		// 5
 | 
				
			||||||
 | 
						0,		// 6
 | 
				
			||||||
 | 
						0,		// 7
 | 
				
			||||||
 | 
						0,		// 8
 | 
				
			||||||
 | 
						0,		// 9
 | 
				
			||||||
 | 
						0,		// 10
 | 
				
			||||||
 | 
						0,		// 11
 | 
				
			||||||
 | 
						0,		// 12
 | 
				
			||||||
 | 
						0,		// 13
 | 
				
			||||||
 | 
						0,		// 14
 | 
				
			||||||
 | 
						0,		// 15
 | 
				
			||||||
 | 
						0,		// 16
 | 
				
			||||||
 | 
						0,		// 17
 | 
				
			||||||
 | 
						0,		// 18
 | 
				
			||||||
 | 
						0,		// 19
 | 
				
			||||||
 | 
						0,		// 20
 | 
				
			||||||
 | 
						0,		// 21
 | 
				
			||||||
 | 
						0,		// 22
 | 
				
			||||||
 | 
						0,		// 23
 | 
				
			||||||
 | 
						0,		// 24
 | 
				
			||||||
 | 
						0,		// 25
 | 
				
			||||||
 | 
						0,		// 26
 | 
				
			||||||
 | 
						0,		// 27
 | 
				
			||||||
 | 
						0,		// 28
 | 
				
			||||||
 | 
						0,		// 29
 | 
				
			||||||
 | 
						0,		// 30
 | 
				
			||||||
 | 
						0,		// 31
 | 
				
			||||||
 | 
					  2, 0, 0, 		// 32 - 'Space'
 | 
				
			||||||
 | 
					  2, 0, 95,		// 33 - '!'
 | 
				
			||||||
 | 
					  3, 7, 0, 7,		// 34 - '"'
 | 
				
			||||||
 | 
					  5, 20, 127, 20, 127, 20,		// 35 - '#'
 | 
				
			||||||
 | 
					  5, 68, 74, 255, 74, 50,		// 36 - '$'
 | 
				
			||||||
 | 
					  5, 99, 19, 8, 100, 99,		// 37 - '%'
 | 
				
			||||||
 | 
					  5, 54, 73, 73, 54, 72,		// 38 - '&'
 | 
				
			||||||
 | 
					  1, 7,		// 39 - '''
 | 
				
			||||||
 | 
					  3, 62, 65, 65,		// 40 - '('
 | 
				
			||||||
 | 
					  3, 65, 65, 62,		// 41 - ')'
 | 
				
			||||||
 | 
					  //5, 8, 42, 28, 42, 8,		// 42 - '*'
 | 
				
			||||||
 | 
					  3, 2, 5, 2,		// 42 - '°' Degree symbol, replacing * char for easy of use'
 | 
				
			||||||
 | 
					  5, 8, 8, 62, 8, 8,		// 43 - '+'
 | 
				
			||||||
 | 
					  2, 96, 224,		// 44 - ','
 | 
				
			||||||
 | 
					  2, 8, 8, 	// 45 - '-'
 | 
				
			||||||
 | 
					  1, 64, 		// 46 - '.' width 1 
 | 
				
			||||||
 | 
					  5, 96, 16, 8, 4, 3,		// 47 - '/'
 | 
				
			||||||
 | 
					  5, 62, 81, 73, 69, 62,		// 48 - '0'
 | 
				
			||||||
 | 
					  5, 0, 4, 2, 127, 0,		// 49 - '1' - width 5  
 | 
				
			||||||
 | 
					  5, 113, 73, 73, 73, 70,		// 50 - '2'
 | 
				
			||||||
 | 
					  5, 65, 73, 73, 73, 54,		// 51 - '3'
 | 
				
			||||||
 | 
					  5, 15, 8, 8, 8, 127,		// 52 - '4'
 | 
				
			||||||
 | 
					  5, 79, 73, 73, 73, 49,		// 53 - '5'
 | 
				
			||||||
 | 
					  5, 62, 73, 73, 73, 48,		// 54 - '6'
 | 
				
			||||||
 | 
					  5, 1, 1, 121, 5, 3,		// 55 - european style '7'
 | 
				
			||||||
 | 
					  5, 54, 73, 73, 73, 54,		// 56 - '8'
 | 
				
			||||||
 | 
					  5, 6, 73, 73, 73, 62,		// 57 - '9'
 | 
				
			||||||
 | 
					  1, 36,		// 58 - colon ':' - width 1
 | 
				
			||||||
 | 
					  2, 108, 236,		// 59 - ';'
 | 
				
			||||||
 | 
					  3, 8, 20, 34,		// 60 - '<'
 | 
				
			||||||
 | 
					  4, 20, 20, 20, 20,		// 61 - '='
 | 
				
			||||||
 | 
					  3, 34, 20, 8,		// 62 - '>'
 | 
				
			||||||
 | 
					  5, 1, 89, 9, 9, 6,		// 63 - '?'
 | 
				
			||||||
 | 
					  5, 62, 65, 93, 89, 78,		// 64 - '@'
 | 
				
			||||||
 | 
					  5, 126, 9, 9, 9, 126,		// 65 - 'A'
 | 
				
			||||||
 | 
					  5, 127, 73, 73, 73, 54,		// 66 - 'B'
 | 
				
			||||||
 | 
					  5, 62, 65, 65, 65, 65,		// 67 - 'C'
 | 
				
			||||||
 | 
					  5, 127, 65, 65, 65, 62,		// 68 - 'D'
 | 
				
			||||||
 | 
					  5, 127, 73, 73, 73, 65,		// 69 - 'E'
 | 
				
			||||||
 | 
					  5, 127, 9, 9, 9, 1,		// 70 - 'F'
 | 
				
			||||||
 | 
					  5, 62, 65, 65, 73, 121,		// 71 - 'G'
 | 
				
			||||||
 | 
					  5, 127, 8, 8, 8, 127,		// 72 - 'H'
 | 
				
			||||||
 | 
					  3, 65, 127, 65,		// 73 - 'I'
 | 
				
			||||||
 | 
					  5, 48, 65, 65, 65, 63,		// 74 - 'J'
 | 
				
			||||||
 | 
					  5, 127, 8, 20, 34, 65,		// 75 - 'K'
 | 
				
			||||||
 | 
					  5, 127, 64, 64, 64, 64,		// 76 - 'L'
 | 
				
			||||||
 | 
					  5, 127, 2, 12, 2, 127,		// 77 - 'M'
 | 
				
			||||||
 | 
					  5, 127, 4, 8, 16, 127,		// 78 - 'N'
 | 
				
			||||||
 | 
					  5, 62, 65, 65, 65, 62,		// 79 - 'O'
 | 
				
			||||||
 | 
					  5, 127, 9, 9, 9, 6,		// 80 - 'P'
 | 
				
			||||||
 | 
					  5, 62, 65, 65, 97, 126,		// 81 - 'Q'
 | 
				
			||||||
 | 
					  5, 127, 9, 25, 41, 70,		// 82 - 'R'
 | 
				
			||||||
 | 
					  5, 70, 73, 73, 73, 49,		// 83 - 'S'
 | 
				
			||||||
 | 
					  5, 1, 1, 127, 1, 1,		// 84 - 'T'
 | 
				
			||||||
 | 
					  5, 63, 64, 64, 64, 63,		// 85 - 'U'
 | 
				
			||||||
 | 
					  5, 31, 32, 64, 32, 31,		// 86 - 'V'
 | 
				
			||||||
 | 
					  5, 63, 64, 56, 64, 63,		// 87 - 'W'
 | 
				
			||||||
 | 
					  5, 99, 20, 8, 20, 99,		// 88 - 'X'
 | 
				
			||||||
 | 
					  5, 3, 4, 120, 4, 3,		// 89 - 'Y'
 | 
				
			||||||
 | 
					  5, 97, 81, 73, 69, 67,		// 90 - 'Z'
 | 
				
			||||||
 | 
					  3, 127, 65, 65,		// 91 - '['
 | 
				
			||||||
 | 
					  5, 3, 4, 8, 16, 96,		// 92 - '\'
 | 
				
			||||||
 | 
					  3, 65, 65, 127,		// 93 - ']'
 | 
				
			||||||
 | 
					  5, 4, 2, 1, 2, 4,		// 94 - '^'
 | 
				
			||||||
 | 
					  4, 128, 128, 128, 128,		// 95 - '_'
 | 
				
			||||||
 | 
					  3, 1, 2, 4,		// 96 - '`'
 | 
				
			||||||
 | 
					  4, 56, 68, 68, 124,		// 97 - 'a'
 | 
				
			||||||
 | 
					  4, 127, 68, 68, 56,		// 98 - 'b'
 | 
				
			||||||
 | 
					  4, 56, 68, 68, 68,		// 99 - 'c'
 | 
				
			||||||
 | 
					  4, 56, 68, 68, 127,		// 100 - 'd'
 | 
				
			||||||
 | 
					  4, 56, 84, 84, 88,		// 101 - 'e'
 | 
				
			||||||
 | 
					  4, 4, 126, 5, 1,		// 102 - 'f'
 | 
				
			||||||
 | 
					  4, 24, 164, 164, 124,		// 103 - 'g'
 | 
				
			||||||
 | 
					  4, 127, 4, 4, 120,		// 104 - 'h'
 | 
				
			||||||
 | 
					  3, 0, 125, 0,		// 105 - 'i' width 3
 | 
				
			||||||
 | 
					  3, 132, 133, 124,		// 106 - 'j'
 | 
				
			||||||
 | 
					  4, 127, 16, 40, 68,		// 107 - 'k'
 | 
				
			||||||
 | 
					  3, 127, 0, 0,		// 108 - 'l' width 3
 | 
				
			||||||
 | 
					  5, 124, 4, 120, 4, 120,		// 109 - 'm'
 | 
				
			||||||
 | 
					  4, 124, 4, 4, 120,		// 110 - 'n'
 | 
				
			||||||
 | 
					  4, 56, 68, 68, 56,		// 111 - 'o'
 | 
				
			||||||
 | 
					  4, 252, 36, 36, 24,		// 112 - 'p'
 | 
				
			||||||
 | 
					  4, 24, 36, 36, 252,		// 113 - 'q'
 | 
				
			||||||
 | 
					  4, 124, 4, 4, 8,		// 114 - 'r'
 | 
				
			||||||
 | 
					  4, 88, 84, 84, 52,		// 115 - 's'
 | 
				
			||||||
 | 
					  4, 4, 127, 68, 0,		// 116 - 't' width 4
 | 
				
			||||||
 | 
					  4, 60, 64, 64, 124,		// 117 - 'u'
 | 
				
			||||||
 | 
					  4, 28, 32, 64, 124,		// 118 - 'v'
 | 
				
			||||||
 | 
					  5, 60, 64, 48, 64, 60,		// 119 - 'w'
 | 
				
			||||||
 | 
					  4, 108, 16, 16, 108,		// 120 - 'x'
 | 
				
			||||||
 | 
					  5, 125, 0, 132, 133, 124,		// 121 - 'ij' dutch 'y'
 | 
				
			||||||
 | 
					  4, 100, 84, 84, 76,		// 122 - 'z'
 | 
				
			||||||
 | 
					  4, 8, 54, 65, 65,		// 123 - '{'
 | 
				
			||||||
 | 
					  1, 127,		// 124 - '|' 
 | 
				
			||||||
 | 
					  4, 65, 65, 54, 8,		// 125 - '}'
 | 
				
			||||||
 | 
					  4, 2, 1, 2, 1,		// 126 - '~'
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// option: add multiple fonts definitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // Font_data_H
 | 
				
			||||||
							
								
								
									
										72
									
								
								GPS_RTC_Clock.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								GPS_RTC_Clock.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  GPS_RTC_Clock.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include "GPS_RTC_Clock.h"
 | 
				
			||||||
 | 
					#include "RTC_com.h"
 | 
				
			||||||
 | 
					#include "GPS_com.h"
 | 
				
			||||||
 | 
					#include "LocalDateTime.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool NewSec = false;
 | 
				
			||||||
 | 
					bool NewMin = false;
 | 
				
			||||||
 | 
					bool NewHour = false;
 | 
				
			||||||
 | 
					time_t Loc_t = 0;
 | 
				
			||||||
 | 
					time_t RTC_t = 0;
 | 
				
			||||||
 | 
					byte last_min = -1;
 | 
				
			||||||
 | 
					byte last_5min = -1;
 | 
				
			||||||
 | 
					byte last_hour = -1;
 | 
				
			||||||
 | 
					bool ResetMCU = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_RTC_Clock_setup() {
 | 
				
			||||||
 | 
					  RTC_LED_setup();
 | 
				
			||||||
 | 
					  RTC_setup();
 | 
				
			||||||
 | 
					  GPS_setup();
 | 
				
			||||||
 | 
					  TZ_setup();
 | 
				
			||||||
 | 
					  //Serial.println("DEBUG[GPS_RTC_Clock_setup] done");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_RTC_Clock_loop() {
 | 
				
			||||||
 | 
					  GPS_loop();
 | 
				
			||||||
 | 
					  RTC_loop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Sec_Flip(time_t t) {  // called from RTC_com
 | 
				
			||||||
 | 
					  Loc_t = TZ_Sec(t);       // convert UTC to Local Time
 | 
				
			||||||
 | 
					  RTC_t = t;
 | 
				
			||||||
 | 
					  NewSec = true;           // set "Ready to print"
 | 
				
			||||||
 | 
					  if (ResetMCU) {          // set init time
 | 
				
			||||||
 | 
					    ResetMCU = false;
 | 
				
			||||||
 | 
					    last_5min = minute(Loc_t) / 5;
 | 
				
			||||||
 | 
					    last_hour = hour(Loc_t);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (last_min != minute(Loc_t)) {  // Check new minute
 | 
				
			||||||
 | 
					    MinFlip();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MinFlip() {
 | 
				
			||||||
 | 
					  last_min = minute(Loc_t);
 | 
				
			||||||
 | 
					  if (last_5min != last_min / 5) {  // Check new 5-min
 | 
				
			||||||
 | 
					    Min5Flip();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (last_hour != hour(Loc_t)) {  // Check new hour
 | 
				
			||||||
 | 
					    HourFlip();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  NewMin = true;  // set "Ready to print"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Min5Flip() {
 | 
				
			||||||
 | 
					  last_5min = last_min / 5;
 | 
				
			||||||
 | 
					  GPS_ON();  // try sync RTC-GPS
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HourFlip() {  // do something on the flip of the RTC hour [UTC time]
 | 
				
			||||||
 | 
					  last_hour = hour(Loc_t);
 | 
				
			||||||
 | 
					  NewHour = true;  // set "Ready to print"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										63
									
								
								GPS_RTC_Clock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								GPS_RTC_Clock.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  GPS_RTC_Clock.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  main local Lib with Clock control, creating 'long term ±0.1 sec accurate Arduino clock'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  tested hardware:
 | 
				
			||||||
 | 
					  -Arduino Nano 5V ATmega328P 
 | 
				
			||||||
 | 
					  -see local *.h files for other hardware
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  main functions:
 | 
				
			||||||
 | 
					  - Sync RTC with GPS in UTC using interrupt
 | 
				
			||||||
 | 
					  - LED blinking in sync with GPS PPS, to check accuracy
 | 
				
			||||||
 | 
					  - LED ON if RTC synced in last hours
 | 
				
			||||||
 | 
					  - Convert to Local Date/Time
 | 
				
			||||||
 | 
					  - Setting flag for printing new time to display, using interrupt
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Notice *******************************************
 | 
				
			||||||
 | 
					  !! GPS & USB use the same serial port !!              
 | 
				
			||||||
 | 
					  you will have to disconnect the Arduino RX pin 0 from  
 | 
				
			||||||
 | 
					  the GPS TX pin, to upload a new sketch over USB       
 | 
				
			||||||
 | 
					  ->remove GPS PCB or Nano PCB from main PCB/breadboard 
 | 
				
			||||||
 | 
					********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef GPS_RTC_Clock_H
 | 
				
			||||||
 | 
					#define GPS_RTC_Clock_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ISOWeekNumber.h"  // pass to main ino
 | 
				
			||||||
 | 
					#include "Local_names.h"    // pass to main ino
 | 
				
			||||||
 | 
					#include "RTC_com.h"
 | 
				
			||||||
 | 
					#include <LiquidCrystal_I2C.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern bool NewSec;   // pass to main ino = second ready to print
 | 
				
			||||||
 | 
					extern bool NewMin;   // pass to main ino = minute ready to print
 | 
				
			||||||
 | 
					extern bool NewHour;  // pass to main ino = Hour ready to print
 | 
				
			||||||
 | 
					extern time_t Loc_t, RTC_t;  // pass to main ino = Local timestamp
 | 
				
			||||||
 | 
					extern bool gps_on;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern volatile bool GPS_sec, RTC_sec, RTC_sync;
 | 
				
			||||||
 | 
					extern unsigned long RTCMicros, GPSMicros;// call from main ino, GPS_RTC_Clock.h
 | 
				
			||||||
 | 
					extern LiquidCrystal_I2C lcd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_RTC_Clock_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// call from main ino, GPS_RTC_Clock.h
 | 
				
			||||||
 | 
					void GPS_RTC_Clock_loop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// process sec from RTC
 | 
				
			||||||
 | 
					void Sec_Flip(time_t t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// do something on reboot & the flip of the RTC minute [timezone independent]
 | 
				
			||||||
 | 
					void MinFlip();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// do something every 5 minutes
 | 
				
			||||||
 | 
					void Min5Flip();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// do something every hour, on the hour
 | 
				
			||||||
 | 
					void HourFlip();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // GPS_RTC_Clock_H
 | 
				
			||||||
							
								
								
									
										125
									
								
								GPS_RTC_Clock.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								GPS_RTC_Clock.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					/* GPS_RTC_Clock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  https://www.instructables.com/01-Sec-Accurate-RTC-GPS-Wall-Clock-Arduino-96x8-LE/
 | 
				
			||||||
 | 
					  https://github.com/hdrlux/GPS_RTC_Clock
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // needed for Nano Every
 | 
				
			||||||
 | 
					#include "GPS_RTC_Clock.h"
 | 
				
			||||||
 | 
					//#include "LED_96x8_matrix.h"
 | 
				
			||||||
 | 
					#include <DMD2.h>
 | 
				
			||||||
 | 
					#include <LiquidCrystal_I2C.h>
 | 
				
			||||||
 | 
					#include "Font_Chrono1.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define pin_RTC_SQW 3
 | 
				
			||||||
 | 
					#define DEBUG_PORT Serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SoftDMD dmd(2, 1);
 | 
				
			||||||
 | 
					LiquidCrystal_I2C lcd(0x27, 16, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char TempBuf[5] = "99.9";  // demo value
 | 
				
			||||||
 | 
					char HumiBuf[3] = "99";    // demo value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long TMR_FPS;
 | 
				
			||||||
 | 
					long FPS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool LCD_Simple_clock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup() {                         // the setup function runs once when you press reset or power the board
 | 
				
			||||||
 | 
					  // LCD
 | 
				
			||||||
 | 
					  lcd.init();  // Инициализация дисплея
 | 
				
			||||||
 | 
					  lcd.clear();
 | 
				
			||||||
 | 
					  lcd.backlight();
 | 
				
			||||||
 | 
					  lcd.setCursor(0,0);
 | 
				
			||||||
 | 
					  lcd.print("RTC sync GPS");
 | 
				
			||||||
 | 
					  lcd.setCursor(0,1);
 | 
				
			||||||
 | 
					  lcd.print("v1.2");
 | 
				
			||||||
 | 
					  DEBUG_PORT.begin(38400);
 | 
				
			||||||
 | 
					  DEBUG_PORT.flush();
 | 
				
			||||||
 | 
					  delay(1000);
 | 
				
			||||||
 | 
					  DEBUG_PORT.println("DEBUG[setup()]");
 | 
				
			||||||
 | 
					  //Serial.begin(19200);                  // = 9600, must be same as GPS for debug
 | 
				
			||||||
 | 
					  //Serial.println();                    // flush serial
 | 
				
			||||||
 | 
					  //Serial.println("-Arduino Reboot-");  // debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GPS_RTC_Clock_setup();               // first in setup
 | 
				
			||||||
 | 
					  //Matrix_setup();                      // LED display
 | 
				
			||||||
 | 
					  //dmd.setBrightness(5);
 | 
				
			||||||
 | 
					  //dmd.selectFont(Font_Chrono1);
 | 
				
			||||||
 | 
					  //dmd.begin();
 | 
				
			||||||
 | 
					  //dmd.clearScreen();
 | 
				
			||||||
 | 
					  lcd.setCursor(0, 0);
 | 
				
			||||||
 | 
					  lcd.print("                ");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop() {            // the loop function runs over and over again forever
 | 
				
			||||||
 | 
					//  if (millis() - tmr_Blink > 500) {
 | 
				
			||||||
 | 
					//    Serial.println("DEBUG[BLINK] " + int(digitalRead(13)));
 | 
				
			||||||
 | 
					//    tmr_Blink = millis();
 | 
				
			||||||
 | 
					//    digitalWrite(13, !digitalRead(13));
 | 
				
			||||||
 | 
					//  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GPS_RTC_Clock_loop();  // first in loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  RTCtoLCD();
 | 
				
			||||||
 | 
					  //chkFPS();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/////////////////////
 | 
				
			||||||
 | 
					void RTCtoLCD() {
 | 
				
			||||||
 | 
					  /*if (GPS_sec) {
 | 
				
			||||||
 | 
					    DEBUG_PORT.println("DEBUG[RTCtoLCD] GPS_sec");
 | 
				
			||||||
 | 
					    GPS_PPS_LCD = !GPS_PPS_LCD;
 | 
				
			||||||
 | 
					    lcd.setCursor(2, 0);
 | 
				
			||||||
 | 
					    lcd.print((GPS_PPS_LCD) ? " " : ":");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (RTC_sec) {
 | 
				
			||||||
 | 
					    DEBUG_PORT.println("DEBUG[RTCtoLCD] RTC_sec");
 | 
				
			||||||
 | 
					    RTC_SQW_LCD = !RTC_SQW_LCD;
 | 
				
			||||||
 | 
					    lcd.setCursor(5, 0);
 | 
				
			||||||
 | 
					    lcd.print((RTC_SQW_LCD) ? " " : ":");
 | 
				
			||||||
 | 
					  }*/
 | 
				
			||||||
 | 
					    //if (!GPS_sec and !RTC_sec) return;
 | 
				
			||||||
 | 
					    if (!NewSec && !NewMin && !NewHour) return;
 | 
				
			||||||
 | 
					    char Clock[9];
 | 
				
			||||||
 | 
					    char segment[3];
 | 
				
			||||||
 | 
					    char message[50];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (NewSec) {
 | 
				
			||||||
 | 
					      //DEBUG_PORT.println("DEBUG[RTCtoLCD] newSec");
 | 
				
			||||||
 | 
					      //DEBUG_PORT.println("DEBUG[RTCtoLCD] RTCMicros: " + String(RTCMicros));
 | 
				
			||||||
 | 
					      //DEBUG_PORT.println("DEBUG[RTCtoLCD] RTC_sec: " + String(RTC_sec));
 | 
				
			||||||
 | 
					      //DEBUG_PORT.println("DEBUG[RTCtoLCD] millis: " + String(millis()));
 | 
				
			||||||
 | 
					      //snprintf(segment, sizeof(segment),"%.2u", second(Loc_t));
 | 
				
			||||||
 | 
					      snprintf(segment, sizeof(segment),"%.2u", second(RTC_t));
 | 
				
			||||||
 | 
					      lcd.setCursor(14, 0);
 | 
				
			||||||
 | 
					      lcd.print(segment);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (NewMin) {
 | 
				
			||||||
 | 
					      //snprintf(segment, sizeof(segment),"%.2u", minute(Loc_t));
 | 
				
			||||||
 | 
					      snprintf(segment, sizeof(segment),"%.2u", minute(RTC_t));
 | 
				
			||||||
 | 
					      lcd.setCursor(11, 0);
 | 
				
			||||||
 | 
					      lcd.print(segment);
 | 
				
			||||||
 | 
					      //snprintf(segment, sizeof(segment),"%.2u", hour(Loc_t));
 | 
				
			||||||
 | 
					      snprintf(segment, sizeof(segment),"%.2u", hour(RTC_t));
 | 
				
			||||||
 | 
					      lcd.setCursor(8, 0);
 | 
				
			||||||
 | 
					      lcd.print(segment);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void chkFPS() {
 | 
				
			||||||
 | 
					  if (micros() - TMR_FPS > 1000000) {
 | 
				
			||||||
 | 
					    DEBUG_PORT.println("DEBUG[chkFPS] FPS: " + String(FPS));
 | 
				
			||||||
 | 
					    //DEBUG_PORT.println("DEBUG[chkFPS] TMR_FPS: " + String(TMR_FPS));
 | 
				
			||||||
 | 
					    TMR_FPS = micros();
 | 
				
			||||||
 | 
					    FPS = 0;
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  FPS++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										215
									
								
								GPS_com.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								GPS_com.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,215 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  GPS_com.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include <NMEAGPS.h>  // https://github.com/SlashDevin/NeoGPS
 | 
				
			||||||
 | 
					#include <TimeLib.h>  // https://github.com/PaulStoffregen/Time
 | 
				
			||||||
 | 
					#include "GPS_com.h"
 | 
				
			||||||
 | 
					#include "RTC_com.h"  // to set the RTC
 | 
				
			||||||
 | 
					#include "Serial_AdjustBaud.h"  // for adjust serial port baudrate
 | 
				
			||||||
 | 
					#include "LocalDateTime.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define cfg_pin_GPS_PPS 2
 | 
				
			||||||
 | 
					#define cfg_pin_GPS_Rx 8
 | 
				
			||||||
 | 
					#define cfg_pin_GPS_Tx 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// add the static modifier to limit visibility of these variables to just this file
 | 
				
			||||||
 | 
					static byte GPS_PPS_PIN = cfg_pin_GPS_PPS;  // Pin 2 = NANO INT0, GPS PPS interrupt signal on this Pin
 | 
				
			||||||
 | 
					static bool gps_on;           // flag for GPS ON/OFF
 | 
				
			||||||
 | 
					static int pulse_count = 0;
 | 
				
			||||||
 | 
					static time_t gps_seconds_t = 0;  // GPS time
 | 
				
			||||||
 | 
					static byte gps_sats = 0;
 | 
				
			||||||
 | 
					static bool GPScolon = false;
 | 
				
			||||||
 | 
					volatile bool GPS_sec = false;  // flag for GPS-PPS
 | 
				
			||||||
 | 
					unsigned long GPSMicros; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// set interrupt flag
 | 
				
			||||||
 | 
					void gps_interrupt() {
 | 
				
			||||||
 | 
					  GPSMicros = micros();
 | 
				
			||||||
 | 
					  GPS_sec = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NMEAGPS gps;  // This parses the GPS characters
 | 
				
			||||||
 | 
					gps_fix fix;  // This holds on to the latest values
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#include <AltSoftSerial.h>
 | 
				
			||||||
 | 
					#include <GPSport.h> // use only for soft-serial
 | 
				
			||||||
 | 
					//#define gpsPort Serial
 | 
				
			||||||
 | 
					//#define GPS_PORT_NAME "Serial"
 | 
				
			||||||
 | 
					#define GPS_PORT_NAME "AltSoftSerial"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Notice ********************************************
 | 
				
			||||||
 | 
					  Edit file \Arduino\libraries\NeoGPS\src\NMEAGPS_cfg.h
 | 
				
			||||||
 | 
					  UnComment line //#define NMEAGPS_PARSE_ZDA
 | 
				
			||||||
 | 
					  only process the NMEA sentences GGA, RMC en ZDA
 | 
				
			||||||
 | 
					*********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****** Notice *******************************************
 | 
				
			||||||
 | 
					  Edit file \Arduino\libraries\NeoGPS\src\NeoTime.h
 | 
				
			||||||
 | 
					  change both instances of the const name 'DAYS_PER_WEEK'
 | 
				
			||||||
 | 
					  to something else, they conflict with TimeLib.h
 | 
				
			||||||
 | 
					*********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compile check processing for both RMC & ZDA message [both contain date & time]
 | 
				
			||||||
 | 
					// Less dependent on GPS chip config
 | 
				
			||||||
 | 
					#ifndef NMEAGPS_PARSE_RMC
 | 
				
			||||||
 | 
					#error You must define NMEAGPS_PARSE_RMC in NMEAGPS_cfg.h!
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef NMEAGPS_PARSE_ZDA
 | 
				
			||||||
 | 
					#error You must define NMEAGPS_PARSE_ZDA in NMEAGPS_cfg.h!
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef NMEAGPS_PARSE_GGA
 | 
				
			||||||
 | 
					#error You must define NMEAGPS_PARSE_GGA in NMEAGPS_cfg.h!
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					const long POSIX_Y2K_offset = 946684800;  // = 10957 days = 30 years, NeoTime (GPS) & TimeLib (RTC) library use different Epoch year, 2000 & 1970
 | 
				
			||||||
 | 
					const long offset_28y = 883612800;        // = 10227 days = 28 years, simple test for 2038 bug
 | 
				
			||||||
 | 
					const long offset_26w = 15724800;         // = 182 days = 26 weeks, simple test for timezone
 | 
				
			||||||
 | 
					const char baud19200 [] PROGMEM = "PUBX,41,1,3,3,19200,0";
 | 
				
			||||||
 | 
					const char baud38400 [] PROGMEM = "PUBX,41,1,3,3,38400,0";
 | 
				
			||||||
 | 
					const char GGA_off [] PROGMEM = "PUBX,40,GGA,0,0,0,0";
 | 
				
			||||||
 | 
					const char GLL_off [] PROGMEM = "PUBX,40,GLL,0,0,0,0";
 | 
				
			||||||
 | 
					const char GSA_off [] PROGMEM = "PUBX,40,GSA,0,0,0,0";
 | 
				
			||||||
 | 
					const char GSV_off [] PROGMEM = "PUBX,40,GSV,0,0,0,0";
 | 
				
			||||||
 | 
					const char VTG_off [] PROGMEM = "PUBX,40,VTG,0,0,0,0";
 | 
				
			||||||
 | 
					const char RMC_off [] PROGMEM = "PUBX,40,RMC,0,0,0,0";
 | 
				
			||||||
 | 
					const char ZDA_off [] PROGMEM = "PUBX,40,ZDA,0,0,0,0";
 | 
				
			||||||
 | 
					const char RMC_on [] PROGMEM = "PUBX,40,RMC,0,1,0,0";
 | 
				
			||||||
 | 
					const char ZDA_on [] PROGMEM = "PUBX,40,ZDA,0,1,0,0";
 | 
				
			||||||
 | 
					// bool GPS_PPS_LCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_setup() {
 | 
				
			||||||
 | 
					  DEBUG_PORT.println(F("DEBUG[GPS_setup()] start"));
 | 
				
			||||||
 | 
					  GPS_sec = false;
 | 
				
			||||||
 | 
					  if (detRate(cfg_pin_GPS_Rx) != 38400) {
 | 
				
			||||||
 | 
					    DEBUG_PORT.println(F("DEBUG[GPS_setup()] baudrate not 38400"));
 | 
				
			||||||
 | 
					    gpsPort.begin(detRate(cfg_pin_GPS_Rx));  // set PC to same baudrate for debug messages
 | 
				
			||||||
 | 
					    gps.send_P(&gpsPort, (const __FlashStringHelper *) baud38400);
 | 
				
			||||||
 | 
					    gpsPort.flush();
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					    gpsPort.end();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    DEBUG_PORT.println(F("DEBUG[GPS_setup()] baudrate already 38400"));
 | 
				
			||||||
 | 
					  gpsPort.begin(38400);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) GGA_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) GLL_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) GSA_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) GSV_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) VTG_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) RMC_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) ZDA_off);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) RMC_on);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					  gps.send_P(&gpsPort, (const __FlashStringHelper *) ZDA_on);
 | 
				
			||||||
 | 
					  delay(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pinMode(GPS_PPS_PIN, INPUT_PULLUP);                                          // enable pullup on interrupt pin
 | 
				
			||||||
 | 
					  attachInterrupt(digitalPinToInterrupt(GPS_PPS_PIN), gps_interrupt, RISING);  // 100ms HIGH at start of second
 | 
				
			||||||
 | 
					  GPS_ON();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_loop() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (GPS_sec) {      // do after GPS PPS interrupt
 | 
				
			||||||
 | 
					    GPS_sec = false;  // clear flag
 | 
				
			||||||
 | 
					    GPScolon = true;
 | 
				
			||||||
 | 
					    lcd.setCursor(10, 0);
 | 
				
			||||||
 | 
					    lcd.print(":");
 | 
				
			||||||
 | 
					    GPS_PPS();
 | 
				
			||||||
 | 
					    DEBUG_PORT.println("PPS: " + String(GPSMicros));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (micros() - GPSMicros >= 500000 && GPScolon) {
 | 
				
			||||||
 | 
					    lcd.setCursor(10, 0);
 | 
				
			||||||
 | 
					    lcd.print(" ");
 | 
				
			||||||
 | 
					    GPScolon = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  GPS_read_seconds();  // continue reading buffer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_PPS() {  // do something on the flip of the GPS second
 | 
				
			||||||
 | 
					  int32_t drift = (int32_t)(GPSMicros - RTCMicros); // % (4294967295UL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Корректировка переполнения (wrap-around)
 | 
				
			||||||
 | 
					  if (drift > 900000)       // Если разница > 0.9 сек
 | 
				
			||||||
 | 
					    drift -= 1000000;       // Корректируем на -1 сек
 | 
				
			||||||
 | 
					  else if (drift < -900000) // Если разница < -0.9 сек
 | 
				
			||||||
 | 
					    drift += 1000000;       // Корректируем на +1 сек
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //DEBUG_PORT.println("DEBUG[GPS_loop()] drift: " + String(drift));  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Отображение дрейфа в правом нижнем углу LCD (16x2)
 | 
				
			||||||
 | 
					  String driftStr = String(drift);
 | 
				
			||||||
 | 
					  if (String(drift).length() > 6) driftStr = " error";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Вычисляем позицию для выравнивания справа: 16 - длина строки
 | 
				
			||||||
 | 
					  lcd.setCursor(16 - driftStr.length(), 1);
 | 
				
			||||||
 | 
					  lcd.print(driftStr);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //if (abs(drift) > 20000 && !gps_on) GPS_ON();
 | 
				
			||||||
 | 
					  if (RTC_sync && !gps_on) {
 | 
				
			||||||
 | 
					    GPS_ON();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (gps_on) {   // do only when needed
 | 
				
			||||||
 | 
					    if (pulse_count == 0) {
 | 
				
			||||||
 | 
					      lcd.setCursor(2, 0);
 | 
				
			||||||
 | 
					      lcd.print("S");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pulse_count += 1;
 | 
				
			||||||
 | 
					    if (pulse_count > 4) {       // skip first PPS-Pulses, to make shure time is from satellite
 | 
				
			||||||
 | 
					      if (gps_seconds_t != 0) {  // do only if value is set
 | 
				
			||||||
 | 
					        // gps_seconds_t += offset_28y; // debug & testing only!
 | 
				
			||||||
 | 
					        // gps_seconds_t += offset_26w; // debug & testing only!
 | 
				
			||||||
 | 
					        SetRTC(TZ_Sec(gps_seconds_t));  // sync RTC with GPS
 | 
				
			||||||
 | 
					        GPS_OFF();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_read_seconds() {
 | 
				
			||||||
 | 
					  //Serial.println("DEBUG[GPS_read_second()] Start");
 | 
				
			||||||
 | 
					  while (gps.available(gpsPort)) {
 | 
				
			||||||
 | 
					    fix = gps.read();
 | 
				
			||||||
 | 
					    if (fix.valid.time && fix.valid.date) {
 | 
				
			||||||
 | 
					      gps_seconds_t = fix.dateTime + POSIX_Y2K_offset;  // convert for different epoch year
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (fix.valid.satellites) {
 | 
				
			||||||
 | 
					      gps_sats = fix.satellites;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_ON() {  
 | 
				
			||||||
 | 
					  DEBUG_PORT.println("DEBUG[GPS_ON()] Start");
 | 
				
			||||||
 | 
					  gps_on = true;
 | 
				
			||||||
 | 
					  gps_seconds_t = 0;  // make shure GPS serial is alive before setting
 | 
				
			||||||
 | 
					  pulse_count = 0;
 | 
				
			||||||
 | 
					  lcd.setCursor(2, 0);
 | 
				
			||||||
 | 
					  lcd.print("S");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPS_OFF() {
 | 
				
			||||||
 | 
					  if (gps_on) {  // only if NOT off
 | 
				
			||||||
 | 
					    gps_on = false;
 | 
				
			||||||
 | 
					    RTC_sync = false;
 | 
				
			||||||
 | 
					    //Serial.println("GPS: OFF");  // debug
 | 
				
			||||||
 | 
					    lcd.setCursor(2, 0);
 | 
				
			||||||
 | 
					    lcd.print(" ");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										49
									
								
								GPS_com.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								GPS_com.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  GPS_com.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  all GPS time functions, tested hardware:
 | 
				
			||||||
 | 
					  - Ublox Neo M8N
 | 
				
			||||||
 | 
					  - External L1-antenna
 | 
				
			||||||
 | 
					  - set Pin: PPS Interrupt in file GPS_com.cpp [default: 2 = NANO INT0]
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***** Notice ********************************************
 | 
				
			||||||
 | 
					  Edit file \Arduino\libraries\NeoGPS\src\NMEAGPS_cfg.h
 | 
				
			||||||
 | 
					  UnComment line //#define NMEAGPS_PARSE_ZDA
 | 
				
			||||||
 | 
					  only process the NMEA sentences GGA, RMC en ZDA
 | 
				
			||||||
 | 
					*********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****** Notice *******************************************
 | 
				
			||||||
 | 
					  Edit file \Arduino\libraries\NeoGPS\src\NeoTime.h
 | 
				
			||||||
 | 
					  change both instances of the const 'DAYS_PER_WEEK'
 | 
				
			||||||
 | 
					  to something else, they conflict with TimeLib.h
 | 
				
			||||||
 | 
					*********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef GPS_com_H
 | 
				
			||||||
 | 
					#define GPS_com_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// handle interrupt
 | 
				
			||||||
 | 
					void gps_interrupt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setup hardware & interrupt from PseudoPPS
 | 
				
			||||||
 | 
					void GPS_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// main GPS loop, GPS_com
 | 
				
			||||||
 | 
					void GPS_loop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// do something on the flip of the GPS second
 | 
				
			||||||
 | 
					void GPS_PPS();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// get time & amount of satts in FIX
 | 
				
			||||||
 | 
					void GPS_read_seconds();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// turn GPS on
 | 
				
			||||||
 | 
					void GPS_ON();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// no hardware OFF, just ignore
 | 
				
			||||||
 | 
					void GPS_OFF();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // GPS_com_H
 | 
				
			||||||
							
								
								
									
										35
									
								
								ISOWeekNumber.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ISOWeekNumber.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  ISOWeekNumber.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux  
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include "ISOWeekNumber.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte ISOdayOfWeek(long days) {  // TimeLib.h deviates from ISO8601 with Sunday = 1
 | 
				
			||||||
 | 
					  // ONLY valid for Epoch year 1970
 | 
				
			||||||
 | 
					  return (((days + 3) % DAYS_PER_WEEK) + 1);  // Mon=1..Sun=7
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					byte ISOWeekNumber(time_t t) {  // uses TimeLib.h - valid until 2099
 | 
				
			||||||
 | 
					  // weeknumber ONLY valid for Mon=1..Sun=7 datelibrary
 | 
				
			||||||
 | 
					  // calculations valid for ANY Epoch year, only relative dates
 | 
				
			||||||
 | 
					  long NowDay = elapsedDays(t);                       // days_since_epoch: now
 | 
				
			||||||
 | 
					  long CloseThu = NowDay - ISOdayOfWeek(NowDay) + 4;  // days_since_epoch: closest Thursday from now
 | 
				
			||||||
 | 
					  int ISOYear = year(CloseThu * SECS_PER_DAY);        // Year for closest Thursday, may be different in first or last week
 | 
				
			||||||
 | 
					  tmElements_t tm;
 | 
				
			||||||
 | 
					  tm.Hour = 0;
 | 
				
			||||||
 | 
					  tm.Minute = 0;
 | 
				
			||||||
 | 
					  tm.Second = 0;
 | 
				
			||||||
 | 
					  tm.Day = 4;    // 4th day according ISO8601
 | 
				
			||||||
 | 
					  tm.Month = 1;  // Jan
 | 
				
			||||||
 | 
					  tm.Year = CalendarYrToTm(ISOYear);
 | 
				
			||||||
 | 
					  time_t JanFour = makeTime(tm);                                    // date: Year-Jan-4
 | 
				
			||||||
 | 
					  long JanFourDay = elapsedDays(JanFour);                           // days_since_epoch: Year-Jan-4
 | 
				
			||||||
 | 
					  int ISOYearDay = NowDay - JanFourDay + ISOdayOfWeek(JanFourDay);  // Day number in the ISOYear, range [1..371]
 | 
				
			||||||
 | 
					  return (((ISOYearDay - 1) / 7) + 1);                              // Convert Day number in the ISOYear to ISOWeek number, range [1..53]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										22
									
								
								ISOWeekNumber.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ISOWeekNumber.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  ISOWeekNumber.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  function:
 | 
				
			||||||
 | 
					  - provides weeknumber from Unix time, according ISO8601
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ISOWeekNumber_H
 | 
				
			||||||
 | 
					#define ISOWeekNumber_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TimeLib.h>    // https://github.com/PaulStoffregen/Time valid until year 2099, no 2038 bug !
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ISO8601 compliant, 1 = Monday
 | 
				
			||||||
 | 
					byte ISOdayOfWeek(long days);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ISO8601 compliant, ISOWeek number, range [1..53]
 | 
				
			||||||
 | 
					byte ISOWeekNumber(time_t t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // ISOWeekNumber_H
 | 
				
			||||||
							
								
								
									
										146
									
								
								LED_96x8_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								LED_96x8_matrix.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  LED_96x8_matrix.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>     // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include <MD_MAX72xx.h>  // https://github.com/MajicDesigns/MD_MAX72XX
 | 
				
			||||||
 | 
					#include "LED_96x8_matrix.h"
 | 
				
			||||||
 | 
					#include "Font_data.h"
 | 
				
			||||||
 | 
					#include "RTC_com.h"  // for Sync_Err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Define the number of devices we have in the chain and the hardware interface
 | 
				
			||||||
 | 
					#define MAX_DEVICES 12                     // total amount of 8x8 LED segments
 | 
				
			||||||
 | 
					#define LEFT_DEVICES 5                     // amount of 8x8 LED segments in left zone
 | 
				
			||||||
 | 
					#define HARDWARE_TYPE MD_MAX72XX::FC16_HW  // check if you get strange pixel print
 | 
				
			||||||
 | 
					#define CLK_PIN 13                         // or SCK [is also onboard LED on Nano]
 | 
				
			||||||
 | 
					#define DATA_PIN 11                        // or MOSI
 | 
				
			||||||
 | 
					#define CS_PIN 10                          // or SS
 | 
				
			||||||
 | 
					#define INIT_BRIGHT 0                      // inital intensity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DIP1 6  // Scroll DIP switch
 | 
				
			||||||
 | 
					#define DIP2 7  // Bright DIP switch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SPI hardware interface
 | 
				
			||||||
 | 
					MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Text parameters
 | 
				
			||||||
 | 
					#define CHAR_SPACING 1  // pixels between characters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Matrix_setup() {
 | 
				
			||||||
 | 
					  mx.begin();
 | 
				
			||||||
 | 
					  mx.setFont(fontClock);  // custom font in Font_data.h
 | 
				
			||||||
 | 
					  delay(100);             // wait init
 | 
				
			||||||
 | 
					  Bright_time_zone(INIT_BRIGHT);
 | 
				
			||||||
 | 
					  Bright_date_zone(INIT_BRIGHT);
 | 
				
			||||||
 | 
					  pinMode(DIP1, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  pinMode(DIP2, INPUT_PULLUP);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Bright_date_zone(byte value) {  // set range 0..15
 | 
				
			||||||
 | 
					  mx.control(0, MAX_DEVICES - LEFT_DEVICES - 1, MD_MAX72XX::INTENSITY, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Bright_time_zone(byte value) {  // set range 0..15
 | 
				
			||||||
 | 
					  mx.control(MAX_DEVICES - LEFT_DEVICES, MAX_DEVICES - 1, MD_MAX72XX::INTENSITY, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DIP_Bright() {
 | 
				
			||||||
 | 
					  if (digitalRead(DIP2) == LOW) {
 | 
				
			||||||
 | 
					    Bright_time_zone(3);
 | 
				
			||||||
 | 
					    Bright_date_zone(3);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    Bright_time_zone(INIT_BRIGHT);
 | 
				
			||||||
 | 
					    Bright_date_zone(INIT_BRIGHT);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool DIP_Scroll() {
 | 
				
			||||||
 | 
					  if (digitalRead(DIP1) == LOW) {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Print_date_zone(char *my_text) {
 | 
				
			||||||
 | 
					  char TextBuf[13];  // string buffer, max n-1 char
 | 
				
			||||||
 | 
					  char err_char;
 | 
				
			||||||
 | 
					  if (SyncErr) {
 | 
				
			||||||
 | 
					    err_char = '!';  // sync warning on display
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    err_char = ' ';  // space
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  snprintf(TextBuf, sizeof(TextBuf), "%c%s", err_char, my_text);  // add char before text, 'between' zones
 | 
				
			||||||
 | 
					  printText(0, MAX_DEVICES - LEFT_DEVICES - 1, TextBuf);          // right zone, from input side
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Print_time_zone(char *my_text) {  // assuming max 8 chars
 | 
				
			||||||
 | 
					  DIP_Bright();
 | 
				
			||||||
 | 
					  printText(MAX_DEVICES - LEFT_DEVICES, MAX_DEVICES - 1, my_text);  // left zone
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printText(uint8_t modStart, uint8_t modEnd, char *pMsg)
 | 
				
			||||||
 | 
					/***** HowTo **********************************************
 | 
				
			||||||
 | 
					  Simple text printing, uses minimal memory
 | 
				
			||||||
 | 
					  Print the text chars to the LED matrix modules specified.
 | 
				
			||||||
 | 
					  Message area is padded with blank columns after printing.
 | 
				
			||||||
 | 
					**********************************************************/
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint8_t state = 0;
 | 
				
			||||||
 | 
					  uint8_t curLen;
 | 
				
			||||||
 | 
					  uint16_t showLen;
 | 
				
			||||||
 | 
					  uint8_t cBuf[8];
 | 
				
			||||||
 | 
					  int16_t col = ((modEnd + 1) * COL_SIZE) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::OFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  do  // finite state machine to print the characters in the space available
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    switch (state) {
 | 
				
			||||||
 | 
					      case 0:  // Load the next character from the font table
 | 
				
			||||||
 | 
					        // if we reached end of message, reset the message pointer
 | 
				
			||||||
 | 
					        if (*pMsg == '\0') {
 | 
				
			||||||
 | 
					          showLen = col - (modEnd * COL_SIZE);  // padding characters
 | 
				
			||||||
 | 
					          state = 2;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // retrieve the next character form the font file
 | 
				
			||||||
 | 
					        showLen = mx.getChar(*pMsg++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
 | 
				
			||||||
 | 
					        curLen = 0;
 | 
				
			||||||
 | 
					        state++;
 | 
				
			||||||
 | 
					        // !! deliberately fall through to next state to start displaying
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case 1:  // display the next part of the character
 | 
				
			||||||
 | 
					        mx.setColumn(col--, cBuf[curLen++]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // done with font character, now display the space between chars
 | 
				
			||||||
 | 
					        if (curLen == showLen) {
 | 
				
			||||||
 | 
					          showLen = CHAR_SPACING;
 | 
				
			||||||
 | 
					          state = 2;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case 2:  // initialize state for displaying empty columns
 | 
				
			||||||
 | 
					        curLen = 0;
 | 
				
			||||||
 | 
					        state++;
 | 
				
			||||||
 | 
					        // fall through
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case 3:  // display inter-character spacing or end of message padding (blank columns)
 | 
				
			||||||
 | 
					        mx.setColumn(col--, 0);
 | 
				
			||||||
 | 
					        curLen++;
 | 
				
			||||||
 | 
					        if (curLen == showLen)
 | 
				
			||||||
 | 
					          state = 0;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        col = -1;  // this definitely ends the do loop
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } while (col >= (modStart * COL_SIZE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mx.control(modStart, modEnd, MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										42
									
								
								LED_96x8_matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								LED_96x8_matrix.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  LED_96x8_matrix.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  all LED Display functions, specific hardware:
 | 
				
			||||||
 | 
					  - MAX7219 with 8x8 LED segment 32x32mm
 | 
				
			||||||
 | 
					  - unit FC16 = 4 segments on one PCB
 | 
				
			||||||
 | 
					  - 3 units in series = chain of 12 segments, making a 96x8 display 
 | 
				
			||||||
 | 
					  - if NOT wired correct, ALL LED's are ON in HIGH brightness, using 9W power -> use 10W 5V/2A power source for project safety
 | 
				
			||||||
 | 
					  - normal operation uses 0,5W for LED display + 0,5W for control board
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LED_96x8_matrix_H
 | 
				
			||||||
 | 
					#define LED_96x8_matrix_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// main display setup
 | 
				
			||||||
 | 
					void Matrix_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// intensity right
 | 
				
			||||||
 | 
					void Bright_date_zone(byte value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// intensity left
 | 
				
			||||||
 | 
					void Bright_time_zone(byte value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Check DIP switch for brightness control
 | 
				
			||||||
 | 
					void DIP_Bright();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Check DIP switch for text scrolling
 | 
				
			||||||
 | 
					bool DIP_Scroll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// print right
 | 
				
			||||||
 | 
					void Print_date_zone(char *my_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// print left
 | 
				
			||||||
 | 
					void Print_time_zone(char *my_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// print chars to specific segment range, NO animations
 | 
				
			||||||
 | 
					void printText(uint8_t modStart, uint8_t modEnd, char *pMsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // LED_96x8_matrix_H
 | 
				
			||||||
							
								
								
									
										74
									
								
								LocalDateTime.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								LocalDateTime.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  LocalDateTime.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include <Timezone_Generic.h>  // https://github.com/khoih-prog/Timezone_Generic [only this one, DO NOT install all dependencies !!]
 | 
				
			||||||
 | 
					#include "LocalDateTime.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*** HowTo ****************************************************************
 | 
				
			||||||
 | 
					  TimeChangeRule myRule = {abbrev, week, dow, month, hour, offset};
 | 
				
			||||||
 | 
					  abbrev: is a character string abbreviation for the time zone, 
 | 
				
			||||||
 | 
					   it must be no longer than five characters.
 | 
				
			||||||
 | 
					  week: is the week of the month that the rule starts.
 | 
				
			||||||
 | 
					  dow: is the day of the week that the rule starts.
 | 
				
			||||||
 | 
					  hour: is the hour in local time that the rule starts (0-23).
 | 
				
			||||||
 | 
					  offset: is the UTC offset in minutes for the time zone being defined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  For convenience, the following symbolic names can be used:
 | 
				
			||||||
 | 
					  week: First, Second, Third, Fourth, Last
 | 
				
			||||||
 | 
					  dow: Sun, Mon, Tue, Wed, Thu, Fri, Sat
 | 
				
			||||||
 | 
					  month: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
 | 
				
			||||||
 | 
					**************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*** Instruction ******************************************************************
 | 
				
			||||||
 | 
					  Select ONE set of TimeChangeRules below, also for non DST zones
 | 
				
			||||||
 | 
					  Selection NOT possible during runtime, only at compiletime
 | 
				
			||||||
 | 
					  The timezones are defined by the offset, in minutes, from UTC. 
 | 
				
			||||||
 | 
					  This means the start of a new minute, and the seconds, are timezone independent !
 | 
				
			||||||
 | 
					**********************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Eastern US time zone [Ottawa, New York, Miami, Nassau]
 | 
				
			||||||
 | 
					//TimeChangeRule mySTD = { "EST", First, Sun, Nov, 2, -300 };  // change to UTC - 5 hours
 | 
				
			||||||
 | 
					//TimeChangeRule myDST = { "EDT", Second, Sun, Mar, 2, -240 }; // change to UTC - 4 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Western European Time Zone [London = GMT/BST, Dublin = GMT/IST, Lisboa = WET/WEST, Canarias]
 | 
				
			||||||
 | 
					//TimeChangeRule mySTD = { "WET ", Last, Sun, Oct, 2, 0 };  // change to UTC
 | 
				
			||||||
 | 
					//TimeChangeRule myDST = { "WEST", Last, Sun, Mar, 1, 60 }; // change to UTC + 1 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Central European Time Zone, directive 2000/84/EC [Bruxelles, Paris, Madrid, Roma, Beograd, Warszawa, Stockholm, Berlin]
 | 
				
			||||||
 | 
					// All 3 European timezones change at the same time: 01:00 UTC
 | 
				
			||||||
 | 
					// TimeChangeRule mySTD = { "CET ", Last, Sun, Oct, 3, 60 };   // change to UTC + 1 hours
 | 
				
			||||||
 | 
					// TimeChangeRule myDST = { "CEST", Last, Sun, Mar, 2, 120 };  // change to UTC + 2 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Eastern European Time Zone [Helsinki, Rīga, Kyiv, Αθήνα]
 | 
				
			||||||
 | 
					//TimeChangeRule mySTD = { "EET ", Last, Sun, Oct, 4, 120 }; // change to UTC + 2 hours
 | 
				
			||||||
 | 
					//TimeChangeRule myDST = { "EEST", Last, Sun, Mar, 3, 180 }; // change to UTC + 3 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Australia Eastern Time Zone [Canberra, Brisbane, Sydney, Melbourne, Hobart]
 | 
				
			||||||
 | 
					//TimeChangeRule mySTD = { "AEST", First, Sun, Apr, 3, 600 }; // change to UTC + 10 hours
 | 
				
			||||||
 | 
					//TimeChangeRule myDST = { "AEDT", First, Sun, Oct, 2, 660 }; // change to UTC + 11 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Москва Standard Time (MSK, does not observe DST)
 | 
				
			||||||
 | 
					TimeChangeRule mySTD = {"MSK ", Last, Sun, Oct, 1, 180}; // allways UTC + 3 hours
 | 
				
			||||||
 | 
					TimeChangeRule myDST = {"MSK ", Last, Sun, Mar, 1, 180}; // allways UTC + 3 hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Universal Time Coordinated [UTC]
 | 
				
			||||||
 | 
					//TimeChangeRule mySTD = {"UTC ", Last, Sun, Oct, 1, 0};
 | 
				
			||||||
 | 
					//TimeChangeRule myDST = {"UTC ", Last, Sun, Mar, 1, 0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Timezone* myTZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TZ_setup() {
 | 
				
			||||||
 | 
					  myTZ = new Timezone(myDST, mySTD);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					time_t TZ_Sec(time_t t) {  // convert UTC to Local-Time
 | 
				
			||||||
 | 
					  TimeChangeRule* tcr;   // pointer to the time change rule, use to get TZ abbrev 
 | 
				
			||||||
 | 
					  return (myTZ->toLocal(t, &tcr));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										25
									
								
								LocalDateTime.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								LocalDateTime.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  LocalDateTime.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  function:
 | 
				
			||||||
 | 
					  - Convert UTC timestamp to Local timestamp, including DST detection [=winter/summer time]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  usage:
 | 
				
			||||||
 | 
					  - uncomment ONE timezone in file LocalDateTime.cpp
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LocalDateTime_H
 | 
				
			||||||
 | 
					#define LocalDateTime_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <TimeLib.h>    // https://github.com/PaulStoffregen/Time valid until year 2099, no 2038 bug !
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// main TZ setup, GPS_RTC_Clock
 | 
				
			||||||
 | 
					void TZ_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// convert UTC to Local-Time
 | 
				
			||||||
 | 
					time_t TZ_Sec(time_t t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // LocalDateTime_H
 | 
				
			||||||
							
								
								
									
										37
									
								
								Local_names.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Local_names.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  Local_names.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>  // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include "Local_names.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define dt_MAX_STRING_LEN 9
 | 
				
			||||||
 | 
					#define dt_SHORT_STR_LEN 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char buffer_m[dt_MAX_STRING_LEN + 1];
 | 
				
			||||||
 | 
					static char buffer_d[dt_MAX_STRING_LEN + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";  // Translate to local Language
 | 
				
			||||||
 | 
					//const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThuFriSat";                   // Translate to local Language
 | 
				
			||||||
 | 
					const char monthShortNames_Loc[] PROGMEM = "ErrJanFebMrtAprMeiJunJulAugSepOktNovDec";  // Dutch
 | 
				
			||||||
 | 
					const char dayShortNames_Loc[] PROGMEM = "ErrZonMaaDinWoeDonVryZat";                   // Dutch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* monthShortStrLoc(uint8_t month) {
 | 
				
			||||||
 | 
					  for (int i = 0; i < dt_SHORT_STR_LEN; i++)
 | 
				
			||||||
 | 
					    buffer_m[i] = pgm_read_byte(&(monthShortNames_Loc[i + (month * dt_SHORT_STR_LEN)]));
 | 
				
			||||||
 | 
					  buffer_m[dt_SHORT_STR_LEN] = 0;
 | 
				
			||||||
 | 
					  return buffer_m;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* dayShortStrLoc(uint8_t day) {
 | 
				
			||||||
 | 
					  uint8_t index = day * dt_SHORT_STR_LEN;
 | 
				
			||||||
 | 
					  for (int i = 0; i < dt_SHORT_STR_LEN; i++)
 | 
				
			||||||
 | 
					    buffer_d[i] = pgm_read_byte(&(dayShortNames_Loc[index + i]));
 | 
				
			||||||
 | 
					  buffer_d[dt_SHORT_STR_LEN] = 0;
 | 
				
			||||||
 | 
					  return buffer_d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										20
									
								
								Local_names.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Local_names.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  Local_names.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Convert to short local weekday & month names
 | 
				
			||||||
 | 
					  Workaround because DateStrings.cpp in TimeLib is english only
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef Local_names_H
 | 
				
			||||||
 | 
					#define Local_names_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Local short month
 | 
				
			||||||
 | 
					char* monthShortStrLoc(uint8_t month);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Local short weekday
 | 
				
			||||||
 | 
					char* dayShortStrLoc(uint8_t day);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // Local_names_H
 | 
				
			||||||
							
								
								
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# GPS_RTC_Clock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See https://www.instructables.com/01-Sec-Accurate-RTC-GPS-Wall-Clock-Arduino-96x8-LE/
 | 
				
			||||||
							
								
								
									
										123
									
								
								RTC_com.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								RTC_com.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  RTC_com.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>    // for all the 'standard' Arduino stuff
 | 
				
			||||||
 | 
					#include <DS3232RTC.h>  // https://github.com/JChristensen/DS3232RTC
 | 
				
			||||||
 | 
					#include <TimeLib.h>    // https://github.com/PaulStoffregen/Time [valid until year 2099, no 2038 bug]
 | 
				
			||||||
 | 
					#include "GPS_RTC_Clock.h"
 | 
				
			||||||
 | 
					#include "RTC_com.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define cfg_pin_RTC_SQW 3;
 | 
				
			||||||
 | 
					#ifndef DEBUG_PORT
 | 
				
			||||||
 | 
					#define DEBUG_PORT Serial
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// add the static modifier to limit visibility of these variables to just this file
 | 
				
			||||||
 | 
					//static int ledPin_PPS = A6;      // Pin for RTC PseudoPPS LED [analog PIN used as digital PIN]
 | 
				
			||||||
 | 
					//static int ledPin_Sync = A7;     // Pin for valid RTC Sync
 | 
				
			||||||
 | 
					static byte RTC_1HZ_PIN = cfg_pin_RTC_SQW;     // Pin 3 = NANO INT1, RTC provides a 1Hz interrupt signal on this Pin
 | 
				
			||||||
 | 
					static time_t last_sync_t = 0;   // last sync
 | 
				
			||||||
 | 
					static byte sync_err_hours = 4;  // set to 4 for DS3231M, may be set to 8 for DS3231SN. Warning if no GPS sync after n hours, possible 0.1 sec error.
 | 
				
			||||||
 | 
					static bool RTCcolon = false;
 | 
				
			||||||
 | 
					bool SyncErr = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <DS3232RTC.h>
 | 
				
			||||||
 | 
					DS3232RTC myRTC(0x68); // cfg_
 | 
				
			||||||
 | 
					volatile bool RTC_sec = false;   // flag for PseudoPPS
 | 
				
			||||||
 | 
					volatile bool RTC_sync = false;  // flag for RTC sync
 | 
				
			||||||
 | 
					unsigned long RTCMicros;  // blinking timer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void rtc_interrupt() {
 | 
				
			||||||
 | 
					  //Serial.print("DEBUG[INT] RTC interrupt "); Serial.println(micros());
 | 
				
			||||||
 | 
					  RTCMicros = micros();
 | 
				
			||||||
 | 
					  RTC_sec = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RTC_LED_setup() {
 | 
				
			||||||
 | 
					  //pinMode(ledPin_PPS, OUTPUT);
 | 
				
			||||||
 | 
					  //pinMode(ledPin_Sync, OUTPUT);
 | 
				
			||||||
 | 
					  //digitalWrite(ledPin_PPS, LOW);   // LED off
 | 
				
			||||||
 | 
					  //digitalWrite(ledPin_Sync, LOW);  // LED off
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RTC_setup() {
 | 
				
			||||||
 | 
					  pinMode(RTC_1HZ_PIN, INPUT_PULLUP);                                           // enable pullup on interrupt pin (RTC SQW pin is open drain)
 | 
				
			||||||
 | 
					  attachInterrupt(digitalPinToInterrupt(RTC_1HZ_PIN), rtc_interrupt, FALLING);  // HIGH 500ms after start of second
 | 
				
			||||||
 | 
					  myRTC.begin();
 | 
				
			||||||
 | 
					  myRTC.squareWave(DS3232RTC::SQWAVE_1_HZ);  // 1 Hz square wave
 | 
				
			||||||
 | 
					  RTC_sec = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RTC_loop() {
 | 
				
			||||||
 | 
					  if (RTC_sec) {                    // do after RTC PseudoPPS interrupt, without interrupt NO time/date to display
 | 
				
			||||||
 | 
					    //DEBUG_PORT.println("DEBUG[RTC_loop()] RTC_sec: " + String(RTC_sec));
 | 
				
			||||||
 | 
					    //DEBUG_PORT.println("DEBUG[RTC_loop()] RTCMicros: " + String(RTCMicros));
 | 
				
			||||||
 | 
					    //DEBUG_PORT.println("DEBUG[RTC_loop()] millis: " + String(millis()));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    lcd.setCursor(13, 0);
 | 
				
			||||||
 | 
					    lcd.print(":");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RTCcolon = true;
 | 
				
			||||||
 | 
					    RTC_sec = false;                // clear flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int32_t drift = (int32_t)(GPSMicros - RTCMicros); // % (4294967295UL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Корректировка переполнения (wrap-around)
 | 
				
			||||||
 | 
					    if (drift > 900000)       // Если разница > 0.9 сек
 | 
				
			||||||
 | 
					      drift -= 1000000;       // Корректируем на -1 сек
 | 
				
			||||||
 | 
					    else if (drift < -900000) // Если разница < -0.9 сек
 | 
				
			||||||
 | 
					      drift += 1000000;       // Корректируем на +1 сек
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Отображение дрейфа в правом нижнем углу LCD (16x2)
 | 
				
			||||||
 | 
					    String driftStr = String(drift);
 | 
				
			||||||
 | 
					    // Вычисляем позицию для выравнивания справа: 16 - длина строки
 | 
				
			||||||
 | 
					    lcd.setCursor(16 - driftStr.length(), 1);
 | 
				
			||||||
 | 
					    lcd.print(driftStr);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    DEBUG_PORT.println("SQW: " + String(RTCMicros) + "; drift: " + String(drift) + "; newSec: " + String(NewSec));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (abs(drift) > 20000 && !gps_on) RTC_sync = true;
 | 
				
			||||||
 | 
					    //digitalWrite(ledPin_PPS, LOW);  // LED off
 | 
				
			||||||
 | 
					    time_t now_t = myRTC.get();
 | 
				
			||||||
 | 
					    if ((last_sync_t + (sync_err_hours * 3600)) < now_t) {
 | 
				
			||||||
 | 
					      SyncErr = true;
 | 
				
			||||||
 | 
					      //digitalWrite(ledPin_Sync, LOW);  // LED off
 | 
				
			||||||
 | 
					      lcd.setCursor(0, 0);
 | 
				
			||||||
 | 
					      lcd.print("r");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Sec_Flip(now_t);  // pass current datetime from RTC in UTC
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else if (micros() - RTCMicros >= 500000 && RTCcolon) {
 | 
				
			||||||
 | 
					    lcd.setCursor(13, 0);
 | 
				
			||||||
 | 
					    lcd.print(" ");
 | 
				
			||||||
 | 
					    RTCcolon = false;
 | 
				
			||||||
 | 
					    NewSec = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    NewSec = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /*if (millis() > (RTCMicros + 100)) {  // do 100ms after PseudoPPS interrupt
 | 
				
			||||||
 | 
					    digitalWrite(ledPin_PPS, HIGH);    // LED on
 | 
				
			||||||
 | 
					  }*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SetRTC(time_t t) {
 | 
				
			||||||
 | 
					  myRTC.set(t + 1);  // the GPS NMEA output is 1 second behind at PPS !!
 | 
				
			||||||
 | 
					  last_sync_t = t;
 | 
				
			||||||
 | 
					  SyncErr = false;
 | 
				
			||||||
 | 
					  //digitalWrite(ledPin_Sync, HIGH);   // LED on
 | 
				
			||||||
 | 
					  DEBUG_PORT.println("RTC set by GPS");  // debug
 | 
				
			||||||
 | 
					  lcd.setCursor(0, 0);
 | 
				
			||||||
 | 
					  lcd.print("R");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  char segment[9];
 | 
				
			||||||
 | 
					  snprintf(segment, sizeof(segment),"%.2u:%.2u:%.2u", hour(t), minute(t), second(t));
 | 
				
			||||||
 | 
					  lcd.setCursor(0, 1);
 | 
				
			||||||
 | 
					  lcd.print(segment);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//End
 | 
				
			||||||
							
								
								
									
										34
									
								
								RTC_com.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								RTC_com.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  RTC_com.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MIT License
 | 
				
			||||||
 | 
					  Copyright (c) 2023 hdrlux
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  all RTC functions, tested hardware:
 | 
				
			||||||
 | 
					  - DS3231SN via I2C, has only 2-digit years, the Epoch is 2000-01-01. Valid until year 2099
 | 
				
			||||||
 | 
					  - set Pin: PseudoPPS Interrupt in file RTC_com.cpp [default: 3 = NANO INT1]
 | 
				
			||||||
 | 
					  - set Pin: PseudoPPS LED in file RTC_com.cpp [default: A3]
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef RTC_com_H
 | 
				
			||||||
 | 
					#define RTC_com_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern bool SyncErr;        // RTC not synced in last n hours
 | 
				
			||||||
 | 
					#include "GPS_RTC_Clock.h"  // for passing new second
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// handle interrupt
 | 
				
			||||||
 | 
					void rtc_interrupt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setup the pin as output
 | 
				
			||||||
 | 
					void RTC_LED_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// setup hardware & interrupt from PseudoPPS
 | 
				
			||||||
 | 
					void RTC_setup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// main RTC loop, RTC_com
 | 
				
			||||||
 | 
					void RTC_loop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sync RTC from GPS
 | 
				
			||||||
 | 
					void SetRTC(time_t t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // RTC_com_H
 | 
				
			||||||
							
								
								
									
										55
									
								
								Serial_AdjustBaud.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Serial_AdjustBaud.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Serial_AdjustBaud
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Функция для вычисления и возврата скорости передачи данных (baud rate) на основе полученного входного пина.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param recpin входной пин для определения скорости передачи данных
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return рассчитанная скорость передачи данных на основе измеренной ширины нулевого бита
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long detRate(int recpin) {
 | 
				
			||||||
 | 
					    long baud, x, rate = 10000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pinMode(recpin, INPUT);      // make sure serial in is a input pin
 | 
				
			||||||
 | 
					    digitalWrite (recpin, HIGH); // pull up enabled just for noise protection
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    // Цикл для измерения ширины нулевого бита
 | 
				
			||||||
 | 
					    for (int i = 0; i < 15; i++){
 | 
				
			||||||
 | 
					        // Ожидание начала низкого бита
 | 
				
			||||||
 | 
					        while(digitalRead(recpin) == 1) {}
 | 
				
			||||||
 | 
					        x = pulseIn(recpin, LOW);   // Измерение ширины следующего нулевого бита
 | 
				
			||||||
 | 
					        rate = x < rate ? x : rate; // Обновление минимальной ширины нулевого бита
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    // Определение скорости передачи данных на основе измеренной ширины нулевого бита
 | 
				
			||||||
 | 
					    if (rate < 12)
 | 
				
			||||||
 | 
					        baud = 115200;
 | 
				
			||||||
 | 
					    else if (rate < 20)
 | 
				
			||||||
 | 
					        baud = 57600;
 | 
				
			||||||
 | 
					    else if (rate < 29)
 | 
				
			||||||
 | 
					        baud = 38400;
 | 
				
			||||||
 | 
					    else if (rate < 40)
 | 
				
			||||||
 | 
					        baud = 28800;
 | 
				
			||||||
 | 
					    else if (rate < 60)
 | 
				
			||||||
 | 
					        baud = 19200;
 | 
				
			||||||
 | 
					    else if (rate < 80)
 | 
				
			||||||
 | 
					        baud = 14400;
 | 
				
			||||||
 | 
					    else if (rate < 150)
 | 
				
			||||||
 | 
					        baud = 9600;
 | 
				
			||||||
 | 
					    else if (rate < 300)
 | 
				
			||||||
 | 
					        baud = 4800;
 | 
				
			||||||
 | 
					    else if (rate < 600)
 | 
				
			||||||
 | 
					        baud = 2400;
 | 
				
			||||||
 | 
					    else if (rate < 1200)
 | 
				
			||||||
 | 
					        baud = 1200;
 | 
				
			||||||
 | 
					    else if (rate < 2400)
 | 
				
			||||||
 | 
					        baud = 600;
 | 
				
			||||||
 | 
					    else if (rate < 4800)
 | 
				
			||||||
 | 
					        baud = 300;
 | 
				
			||||||
 | 
					    else 
 | 
				
			||||||
 | 
					        baud = 0;  
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return baud; // Возврат рассчитанной скорости передачи данных
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								Timezone_Generic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Timezone_Generic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					/*********************************************************************************************************************************
 | 
				
			||||||
 | 
					  Timezone_Generic.h
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  For AVR, ESP8266/ESP32, SAMD21/SAMD51, nRF52, STM32, WT32_ETH01 boards
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Based on and modified from Arduino Timezone Library (https://github.com/JChristensen/Timezone)
 | 
				
			||||||
 | 
					  to support other boards such as ESP8266/ESP32, SAMD21, SAMD51, Adafruit's nRF52 boards, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Copyright (C) 2018 by Jack Christensen and licensed under GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Built by Khoi Hoang https://github.com/khoih-prog/Timezone_Generic
 | 
				
			||||||
 | 
					  Licensed under MIT license
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Version: 1.10.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Version Modified By  Date      Comments
 | 
				
			||||||
 | 
					  ------- -----------  ---------- -----------
 | 
				
			||||||
 | 
					  1.2.4   K Hoang      17/10/2020 Initial porting to support SAM DUE, SAMD21, SAMD51, nRF52, ESP32/ESP8266, STM32, etc. boards
 | 
				
			||||||
 | 
					                                  using SPIFFS, LittleFS, EEPROM, FlashStorage, DueFlashStorage.
 | 
				
			||||||
 | 
					  1.2.5   K Hoang      28/10/2020 Add examples to use STM32 Built-In RTC.
 | 
				
			||||||
 | 
					  1.2.6   K Hoang      01/11/2020 Allow un-initialized TZ then use begin() method to set the actual TZ (Credit of 6v6gt)
 | 
				
			||||||
 | 
					  1.3.0   K Hoang      09/01/2021 Add support to ESP32/ESP8266 using LittleFS/SPIFFS, and to AVR, UNO WiFi Rev2, etc.
 | 
				
			||||||
 | 
					                                  Fix compiler warnings.
 | 
				
			||||||
 | 
					  1.4.0   K Hoang      04/06/2021 Add support to RP2040-based boards using RP2040 Arduino-mbed or arduino-pico core
 | 
				
			||||||
 | 
					  1.5.0   K Hoang      13/06/2021 Add support to ESP32-S2 and ESP32-C3. Fix bug
 | 
				
			||||||
 | 
					  1.6.0   K Hoang      16/07/2021 Add support to WT32_ETH01
 | 
				
			||||||
 | 
					  1.7.0   K Hoang      10/08/2021 Add support to Ameba Realtek RTL8720DN, RTL8722DM and RTM8722CSM
 | 
				
			||||||
 | 
					  1.7.1   K Hoang      10/10/2021 Update `platform.ini` and `library.json`
 | 
				
			||||||
 | 
					  1.7.2   K Hoang      02/11/2021 Fix crashing issue for new cleared flash
 | 
				
			||||||
 | 
					  1.7.3   K Hoang      01/12/2021 Auto detect ESP32 core for LittleFS. Fix bug in examples for WT32_ETH01
 | 
				
			||||||
 | 
					  1.8.0   K Hoang      31/12/2021 Fix `multiple-definitions` linker error
 | 
				
			||||||
 | 
					  1.9.0   K Hoang      20/01/2022 Make compatible to old code
 | 
				
			||||||
 | 
					  1.9.1   K Hoang      26/01/2022 Update to be compatible with new FlashStorage libraries. Add support to more SAMD/STM32 boards
 | 
				
			||||||
 | 
					  1.10.0  K Hoang      06/04/2022 Use Ethernet_Generic library as default. Add support to Portenta_H7 Ethernet and WiFi
 | 
				
			||||||
 | 
					  1.10.1  K Hoang      25/09/2022 Add support to `RP2040W` using `CYW43439 WiFi` with `arduino-pico` core
 | 
				
			||||||
 | 
					 **********************************************************************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TIMEZONE_GENERIC_H
 | 
				
			||||||
 | 
					#define TIMEZONE_GENERIC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Timezone_Generic.hpp"
 | 
				
			||||||
 | 
					#include "Timezone_Generic_Impl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif    // TIMEZONE_GENERIC_H
 | 
				
			||||||
		Reference in New Issue
	
	Block a user