WolfLarsen33

VFD Clock V3

Jul 6th, 2021 (edited)
802
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   VFD_Clock V3
  3.   auteur: Laurent VOLFOVSKY
  4.   date: Confinement 2021
  5.  
  6.   le VFD est spécifique, 4 caractères numeriques (2 par grille) et 8 caractères 15/15 segments avec un point central... on fait avec.
  7. */
  8.  
  9. #define SERpin 4    //pin 14 du premier 75HC595
  10. #define RCLKpin 17  //pin 12 des 75HC595
  11. #define SRCLKpin 16 //pin 11 des 75HC595
  12.  
  13. #define nbGrid 10   //nombre de grilles de contrôle
  14. #define nbCar 8     //nombre de caracteres alphanum
  15.  
  16. const int Gpin[] = { 13, 12, 14, 27, 26, 25, 33, 32, 15, 2};
  17.  
  18. const uint16_t Gseg[] = {
  19. 0b0000000000000000, //      32    20
  20. 0b1000001000000100, // !    33    21
  21. 0b0010001000000000, // "    34    22
  22. 0b1010001101100100, // #    35    23
  23. 0b1101001101100101, // $    36    24
  24. 0b1001010000101000, // %    37    25
  25. 0b1000000000000000, // &    38    26
  26. 0b0000010000000000, // '    39    27
  27. 0b1000010000000010, // (    40    28
  28. 0b1000100000001000, // )    41    29
  29. 0b1000111101001110, // *    42    2A
  30. 0b1000001101000100, // +    43    2B
  31. 0b0000000000001000, // ,    44    2C
  32. 0b1000000101000000, // -    45    2D
  33. 0b1000000000000000, // .    46    2E
  34. 0b1000010000001000, // /    47    2F
  35. 0b1111010000111001, // 0    48    30
  36. 0b0010010000100000, // 1    49    31
  37. 0b1110000101010001, // 2    50    32
  38. 0b1110000001100001, // 3    51    33
  39. 0b1001001101000100, // 4    52    34
  40. 0b1100100001100001, // 5    53    35
  41. 0b1101000100010011, // 6    54    36
  42. 0b1100010101001000, // 7    55    37
  43. 0b1111000101110001, // 8    56    38
  44. 0b1110100001100001, // 9    57    39
  45. 0b0000001000000100, // :    58    3A
  46. 0b0000001000001000, // ;    59    3B
  47. 0b1000010000001001, // <    60    3C
  48. 0b1000000101000001, // =    61    3D
  49. 0b1000100000000011, // >    62    3E
  50. 0b1110000011000100, // ?    63    3F
  51. 0b1111001001010001, // @    64    40
  52. 0b1111000101110000, // A    65    41
  53. 0b1110001001100101, // B    66    42
  54. 0b0101000000010001, // C    67    43
  55. 0b1110001000100101, // D    68    44
  56. 0b1101000100010001, // E    69    45
  57. 0b1101000100010000, // F    70    46
  58. 0b0101000001110001, // G    71    47
  59. 0b1011000101110000, // H    72    48
  60. 0b1100001000000101, // I    73    49
  61. 0b0010000000110001, // J    74    4A
  62. 0b1001010100010010, // K    75    4B
  63. 0b0001000000010001, // L    76    4C
  64. 0b1011110000110000, // M    77    4D
  65. 0b1011100000110010, // N    78    4E
  66. 0b0111000000110001, // O    79    4F
  67. 0b1111000101010000, // P    80    50
  68. 0b0111000000110011, // Q    81    51
  69. 0b1111000101010010, // R    82    52
  70. 0b1101000101100001, // S    83    53
  71. 0b1100001000000100, // T    84    54
  72. 0b0011000000110001, // U    85    55
  73. 0b1001010000011000, // V    86    56
  74. 0b1011000000111010, // W    87    57
  75. 0b1000110000001010, // X    88    58
  76. 0b1000110000000100, // Y    89    59
  77. 0b1100010000001001, // Z    90    5A
  78. 0b0101000000010001, // [    91    5B
  79. 0b1000100000000010, // \    92    5C
  80. 0b0110000000100001, // ]    93    5D
  81. 0b1000000000001010, // ^    94    5E
  82. 0b0000000000000001, // _    95    5F
  83. 0b1010010001000000, // `    96    60 utilisé pour le signe °
  84. 0b1000000100010101, // a    97    61
  85. 0b1001000100010011, // b    98    62
  86. 0b1000000101010001, // c    99    63
  87. 0b1010000001101001, // d    100   64
  88. 0b1000000100011001, // e    101   65
  89. 0b1000010101000100, // f    102   66
  90. 0b1010010001100001, // g    103   67
  91. 0b1001000100010100, // h    104   68
  92. 0b1000000000000100, // i    105   69
  93. 0b1000001000011000, // j    106   6A
  94. 0b1000011000000110, // k    107   6B
  95. 0b0001000000010000, // l    108   6C
  96. 0b1000000101110100, // m    109   6D
  97. 0b1000000100010100, // n    110   6E
  98. 0b1000000101110001, // o    111   6F
  99. 0b1001100100010000, // p    112   70
  100. 0b1010010001100000, // q    113   71
  101. 0b1000000100010000, // r    114   72
  102. 0b1000000001000011, // s    115   73
  103. 0b1001000100010001, // t    116   74
  104. 0b0000000000110001, // u    117   75
  105. 0b1000000000011000, // v    118   76
  106. 0b1000000000111010, // w    119   77
  107. 0b1000110000001010, // x    120   78
  108. 0b1010001001100001, // y    121   79
  109. 0b1000000100001001, // z    122   7A
  110. 0b0100100100001001, // {    123   7B
  111. 0b1000001000000100, // |    124   7C
  112. 0b0100010001000011, // }    125   7D
  113. 0b1000010101001000, // ~    126   7E
  114. 0b1000000000000000, // DEL  127   7F
  115. };
  116.  
  117. const uint8_t G0seg[] = {
  118. 0b01110111, // 0
  119. 0b00100100, // 1
  120. 0b01101011, // 2
  121. 0b01101101, // 3
  122. 0b00111100, // 4
  123. 0b01011101, // 5
  124. 0b01011111, // 6
  125. 0b01100100, // 7
  126. 0b01111111, // 8
  127. 0b01111101, // 9
  128. };
  129.  
  130. const uint8_t G1seg[] = {
  131. 0b01110111, // 0
  132. 0b00100010, // 1
  133. 0b01101101, // 2
  134. 0b01101011, // 3
  135. 0b00111010, // 4
  136. 0b01011011, // 5
  137. 0b01011111, // 6
  138. 0b01100010, // 7
  139. 0b01111111, // 8
  140. 0b01111011, // 9
  141. };
  142.  
  143. #define MAXTEXTBUFFER 64    //nombre max de caracteres alphanum du buffer
  144. char textBuffer[MAXTEXTBUFFER];
  145. int posBuffer;
  146. volatile char hourBuffer[5];
  147.  
  148. uint32_t delayStart = 0, delayInterm = 0;
  149. uint32_t r_delayStart = 0, r_delayInterm = 0;
  150.  
  151. //#include <Wire.h>
  152. //#include <RtcDS1307.h>
  153. //RtcDS1307<TwoWire> Rtc(Wire);
  154. //#include <time.h>
  155.  
  156. //#include <dhtnew.h>
  157. //#define DHTpin 2
  158. //DHTNEW DHTSensor(DHTpin);
  159.  
  160. #define TIMER_USED 1  // quel timer est utilisé: 1 ou 2
  161.  
  162. volatile int ligneINT=0; // La ligne de grille courante (pour l'interruption)
  163.  
  164. // ---- Variables utilisées dans le loop()
  165. #define nbSequences 29 // nombre de séquences de découpage de l'affichage. Pour afficher heure, date, jour, temp, etc.
  166.  
  167. //unsigned long int cptDate=22;
  168. //RtcDateTime now;;
  169. //int chkDHT;
  170.  
  171. hw_timer_t * timer = NULL;
  172.  
  173. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
  174.  
  175. #include <WiFi.h>
  176. #include "time.h"
  177.  
  178. const char* ntpServer = "pool.ntp.org";
  179. const char* ssid       = "mabox";
  180. const char* password   = "a12e46e132456a46fze1231";
  181.  
  182. const long  gmtOffset_sec = 3600;
  183. const int   daylightOffset_sec = 3600;
  184.  
  185.  
  186.  
  187. //------------------------------------------------------------------------------
  188. // Interruption : sélection de la grille et indication de refresh
  189. //------------------------------------------------------------------------------
  190. void IRAM_ATTR onTimer() {
  191.   ligneINT++;
  192.   digitalWrite(Gpin[ligneINT-1], HIGH);
  193.   if (ligneINT >= nbGrid) {
  194.     ligneINT=0;
  195.   }
  196.   portENTER_CRITICAL_ISR(&timerMux);
  197.  
  198.   switch (ligneINT) {
  199.     case 0:
  200.       digitalWrite(RCLKpin, LOW);
  201.       shiftOut(SERpin, SRCLKpin, LSBFIRST, G0seg[hourBuffer[0]-48] ^ 0xFF);
  202.       shiftOut(SERpin, SRCLKpin, LSBFIRST, G1seg[hourBuffer[1]-48] ^ 0xFF);
  203.       digitalWrite(RCLKpin, HIGH);
  204.       break;
  205.      
  206.     case 1:
  207.       digitalWrite(RCLKpin, LOW);
  208.       shiftOut(SERpin, SRCLKpin, LSBFIRST, G0seg[hourBuffer[2]-48] ^ 0xFF);
  209.       shiftOut(SERpin, SRCLKpin, LSBFIRST, G1seg[hourBuffer[3]-48] ^ 0xFF);
  210.       digitalWrite(RCLKpin, HIGH);
  211.       break;
  212.      
  213.     default:
  214.       //---- Les 8 caractères alphanum
  215.       char car = textBuffer[posBuffer+ligneINT-2];
  216.       digitalWrite(RCLKpin, LOW);
  217.       if (car > '\0') {
  218.         uint16_t caractere = Gseg[car-32];
  219.         shiftOut(SERpin, SRCLKpin, LSBFIRST, caractere ^ 0xFFFF);
  220.         shiftOut(SERpin, SRCLKpin, LSBFIRST, (caractere ^ 0xFFFF) >>8);
  221.       }
  222.       else {
  223.         shiftOut(SERpin, SRCLKpin, LSBFIRST, 0xFF);
  224.         shiftOut(SERpin, SRCLKpin, LSBFIRST, 0xFF);
  225.       }
  226.       digitalWrite(RCLKpin, HIGH);
  227.       break;
  228.   }
  229.  
  230.   portEXIT_CRITICAL_ISR(&timerMux);
  231.   digitalWrite(Gpin[ligneINT], LOW);
  232.  
  233.   if (r_delayStart > 0) {
  234.     //---- phase attente avant défilement
  235.     r_delayStart--;
  236.     r_delayInterm = delayInterm;
  237.   }
  238.   else {
  239.     if (strlen((char *)textBuffer) > nbCar && posBuffer < strlen((char *)textBuffer) - nbCar) {
  240.       //---- phase défilement
  241.       if (--r_delayInterm <= 0) {
  242.         r_delayInterm = delayInterm;
  243.         posBuffer++;
  244.       }
  245.     }
  246.   }
  247. }
  248.  
  249. //---------------------------------------------
  250. void setup(){
  251.   Serial.begin(115200);
  252.   Serial.println("VFD Clock Start");
  253.  
  254.   pinMode(SERpin, OUTPUT);
  255.   digitalWrite(SERpin, LOW);
  256.   pinMode(RCLKpin, OUTPUT);
  257.   digitalWrite(RCLKpin, LOW);
  258.   pinMode(SRCLKpin, OUTPUT);
  259.   digitalWrite(SRCLKpin, LOW);
  260.  
  261.   for(int g=0; g<10; g++){
  262.     pinMode(Gpin[g], OUTPUT);
  263.     digitalWrite(Gpin[g], HIGH);
  264.   }
  265.   digitalWrite(RCLKpin, LOW);
  266.   for(int c=0; c<16; c++){
  267.     digitalWrite(SRCLKpin, LOW);
  268.     digitalWrite(SERpin, HIGH);
  269.     digitalWrite(SRCLKpin, HIGH);
  270.   }
  271.   digitalWrite(RCLKpin, HIGH);
  272.  
  273.   Serial.printf("Connecting to %s ", ssid);
  274.   WiFi.begin(ssid, password);
  275.   Serial.println("  Attente");
  276.   while (WiFi.status() != WL_CONNECTED) {
  277.       delay(500);
  278.       Serial.print(".");
  279.   }
  280.   Serial.println(" CONNECTED");
  281.  
  282.   timer = timerBegin(0, 80, true);
  283.   timerAttachInterrupt(timer, &onTimer, true);
  284.   timerAlarmWrite(timer, 2000, true);
  285.   timerAlarmEnable(timer);
  286.  
  287.   scrollToLeft("VFD_Clock Version 3_0 by Laurent Volfovsky", 500,60);
  288.   delay(600);
  289. }              
  290.  
  291. //-----------------------------------------------------------
  292. void loop(){
  293.  
  294.   static uint32_t delayMsg=0;
  295.   static uint16_t sequence=0;
  296.   static char jour[10];
  297.   static char aujourdhui[20];
  298.   static struct tm timeinfo;
  299.  
  300.   //--- toutes les secondes, on regarde ce qu'il y a à afficher
  301.   if (millis()-delayMsg > 1000) {
  302.     delayMsg = millis();
  303. //    Serial.println(sequence);
  304.    
  305.     if (++sequence > nbSequences) {
  306.       sequence = 0;
  307.     }
  308.     switch (sequence) {
  309.      
  310.       case 0:   // obtention de l'heure / date
  311.       case 10:
  312.       case 20:
  313.         configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  314.         if(!getLocalTime(&timeinfo)){
  315.           scrollToLeft("Err.NTP", 100,50);
  316.         }
  317.         else {
  318.           switch (timeinfo.tm_wday) {
  319.             case 0: strcpy(jour, "DiManche"); break;
  320.             case 1: strcpy(jour, "Lundi"); break;
  321.             case 2: strcpy(jour, "Mardi"); break;
  322.             case 3: strcpy(jour, "Mercredi"); break;
  323.             case 4: strcpy(jour, "Jeudi"); break;
  324.             case 5: strcpy(jour, "Vendredi"); break;
  325.             case 6: strcpy(jour, "SaMedi"); break;
  326.           }
  327.           sprintf(aujourdhui, "%s %02i/%02i/%02i", jour, timeinfo.tm_mday, timeinfo.tm_mon+1,timeinfo.tm_year%100);
  328.           sprintf((char *)hourBuffer, "%02i%02i", timeinfo.tm_hour, timeinfo.tm_min);
  329.         }
  330.         scrollToLeft(aujourdhui, 250,50);
  331.         break;
  332.  
  333.       case 6:   // affichage des jours spéciaux
  334.         if (timeinfo.tm_mday==1 && (timeinfo.tm_mon+1)==1) {
  335.           scrollToLeft("Jour de l'an",250,50);
  336.         }
  337.         else if (timeinfo.tm_mday==1 && (timeinfo.tm_mon+1)==5) {
  338.           scrollToLeft("Fete du Travail",250,50);
  339.         }
  340.         else if (timeinfo.tm_mday==8 && (timeinfo.tm_mon+1)==5) {
  341.           scrollToLeft("Victoire 1945",250,50);
  342.         }
  343.         else if (timeinfo.tm_mday==25 && (timeinfo.tm_mon+1)==12) {
  344.           scrollToLeft("Noel",250,50);
  345.         }
  346.         //--- aujourd'hui :)
  347.         else if (timeinfo.tm_mday==6 && (timeinfo.tm_mon+1)==7) {
  348.           scrollToLeft("Un jour comme un autre...",250,50);
  349.         }
  350.         break;
  351.  
  352.       case 25:
  353.         scrollToLeft("Humidite=56%", 100,20);
  354.         break;
  355.      
  356.         /*
  357.       case 11:  // affichage la temperature
  358.         TIMSK2 = 0x00;
  359.         chkDHT = DHTSensor.read();
  360.         TIMSK2 = 0x02;
  361.         switch (chkDHT)
  362.         {
  363.           case DHTLIB_OK:
  364.             sprintf(lti, "Temperature= %2d*", (int)DHTSensor.temperature );
  365.             scrollToLeft(lti,500,100);
  366.             break;
  367.           case DHTLIB_ERROR_CHECKSUM:
  368.             scrollToLeft("CH-SUM error",250,100);
  369.             break;
  370.           case DHTLIB_ERROR_TIMEOUT:
  371.             scrollToLeft("Timeout error",250,100);
  372.             break;
  373.           default:
  374.             scrollToLeft("Other error",250,100);
  375.         }
  376.         break;
  377.    
  378.       case 12:  // affichage l'humidité
  379.         TIMSK2 = 0x00;
  380.         chkDHT = DHTSensor.read();
  381.         TIMSK2 = 0x02;
  382.         switch (chkDHT)
  383.         {
  384.           case DHTLIB_OK:
  385.             sprintf(lti, "Humidite= %2d%%", (int)DHTSensor.humidity );
  386.             scrollToLeft(lti,500,100);
  387.             break;
  388.           case DHTLIB_ERROR_CHECKSUM:
  389.             scrollToLeft("CH-SUM error",250,100);
  390.             break;
  391.           case DHTLIB_ERROR_TIMEOUT:
  392.             scrollToLeft("Timeout error",250,100);
  393.             break;
  394.           default:
  395.             scrollToLeft("Other error",250,100);
  396.         }
  397.         break;
  398.    
  399. */
  400.     }
  401.   }
  402.  
  403. //  testChangeDateTime();  
  404. }
  405.  
  406.  
  407. //-----------------------------------------------------------
  408. // Change la date ou l'heure si demandé ou autre action
  409. //-----------------------------------------------------------
  410. void testChangeDateTime() {
  411. /*
  412.   // ---- Prend les commandes de changement d'heure/date
  413.   char str[50];
  414.   int index=0;
  415.   while (Serial.available()) {
  416.     char c = Serial.read();
  417.     if(index < 49 && c!=10 && c!=13) {
  418.       str[index++] = c;
  419.       delay(10);
  420.     }
  421.   }
  422.   str[index] = '\0';
  423.   if (index) {  // une commande a été tapée
  424.     int nbarg_ok;
  425.     int s_day=0,s_month=0,s_year=0;
  426.     int s_heure=0,s_min=0,s_sec=0;
  427.     nbarg_ok = sscanf(str, "set date %02d/%02d/%02d", &s_day, &s_month, &s_year );
  428.     if (nbarg_ok == 3) { // met a jour la date
  429.       Serial.println("Changement de date");
  430.       RtcDateTime now = Rtc.GetDateTime();
  431.       s_heure = now.Hour();
  432.       s_min = now.Minute();
  433.       s_sec = now.Second();
  434.       RtcDateTime dt = RtcDateTime(s_year,s_month,s_day, s_heure,s_min,s_sec);
  435.       Rtc.SetDateTime(dt);
  436.     }
  437.     else {
  438.       nbarg_ok = sscanf(str, "set time %02d:%02d:%02d", &s_heure, &s_min, &s_sec );
  439.       if (nbarg_ok >= 2) { // met a jour l'heure
  440.         Serial.println("Changement d'heure");
  441.         RtcDateTime now = Rtc.GetDateTime();
  442.         s_year = now.Year();
  443.         s_month = now.Month();
  444.         s_day = now.Day();
  445.         RtcDateTime dt = RtcDateTime(s_year,s_month,s_day, s_heure,s_min,s_sec);
  446.         Rtc.SetDateTime(dt);
  447.       }
  448.       else if (strcmp(str,"saisie")==0) {
  449.         charTest();
  450.       }
  451.       else if (strcmp(str,"scroll")==0) {
  452.         charScroll();
  453.       }
  454.     }
  455.   }
  456. */
  457. }
  458.  
  459. //-----------------------------------------------------------
  460. // Fait un effet de scoll de droite à gauche
  461. //-----------------------------------------------------------
  462. void scrollToLeft(const char * p_disp, unsigned int p_delayStart, unsigned int p_delayInterm) {
  463.  
  464.   memset(textBuffer, 0, sizeof(textBuffer));
  465.   strncpy(textBuffer, p_disp, sizeof(textBuffer));
  466.   posBuffer = 0;
  467.   delayStart = p_delayStart;
  468.   r_delayStart = p_delayStart;
  469.   delayInterm = p_delayInterm;
  470.   r_delayInterm = delayInterm;
  471. }
  472.  
  473. //
RAW Paste Data