From 3012bdd3be19e31f1d199da9dab432a500963c82 Mon Sep 17 00:00:00 2001 From: willem Date: Sun, 17 Sep 2023 12:12:48 +0200 Subject: [PATCH] ntp +2h issue --- FW/NCM107-ESP32C3/original_ino.txt | 1109 ++++++++++++++++++++++++++++ FW/NCM107-ESP32C3/platformio.ini | 5 +- FW/NCM107-ESP32C3/src/clock.cpp | 104 ++- FW/NCM107-ESP32C3/src/clock.h | 14 +- FW/NCM107-ESP32C3/src/main.cpp | 823 +++------------------ FW/NCM107-ESP32C3/src/ntp.cpp | 105 +++ FW/NCM107-ESP32C3/src/ntp.h | 14 + FW/NCM107-ESP32C3/src/util.cpp | 7 + FW/NCM107-ESP32C3/src/util.h | 5 + 9 files changed, 1381 insertions(+), 805 deletions(-) create mode 100644 FW/NCM107-ESP32C3/original_ino.txt create mode 100644 FW/NCM107-ESP32C3/src/ntp.cpp create mode 100644 FW/NCM107-ESP32C3/src/ntp.h create mode 100644 FW/NCM107-ESP32C3/src/util.cpp create mode 100644 FW/NCM107-ESP32C3/src/util.h diff --git a/FW/NCM107-ESP32C3/original_ino.txt b/FW/NCM107-ESP32C3/original_ino.txt new file mode 100644 index 0000000..5a4f9ef --- /dev/null +++ b/FW/NCM107-ESP32C3/original_ino.txt @@ -0,0 +1,1109 @@ + const String FirmwareVersion="010310"; +//Format _X.XX__ +//NIXIE CLOCK MCU107 by GRA & AFCH (fominalec@gmail.com) +//1.0.31 27.04.2017 +//Added Antipoisoning effect - slot machine +//1.0.3 17.02.2017 +// Added: time synchronizing each 10 seconds +//1.02 17.10.2016 +//Fixed: RGB color controls +//Update to Arduino IDE 1.6.12 (Time.h replaced to TimeLib.h) +//1.01 +//Added RGB LEDs lock(by UP and Down Buttons) +//Added Down and Up buttons pause and resume self testing +//25.09.2016 update to HW ver 1.1 +//25.05.2016 + + +#include +#include +#include +#include +#include +#include + +#define Anode0Pin 5 +#define Anode1Pin 7 +#define Anode2Pin 8 + +#define Anode0ON PORTD=PORTD|B00100000 +#define Anode0OFF PORTD=PORTD&B11011111 + +#define Anode1ON PORTD=PORTD|B10000000 +#define Anode1OFF PORTD=PORTD&B01111111 + +#define Anode2ON PORTB=PORTB|B00000001 +#define Anode2OFF PORTB=PORTB&B11111110 + +//char* parseSong(char *p); + +const byte LEpin=10; //pin Latch Enabled data accepted while HI level +//const byte DHVpin=5; // off/on MAX1771 Driver Hight Voltage(DHV) 110-220V +const byte RedLedPin=9; //MCU WDM output for red LEDs 9-g +const byte GreenLedPin=6; //MCU WDM output for green LEDs 6-b +const byte BlueLedPin=3; //MCU WDM output for blue LEDs 3-r +const byte pinSet=A0; +const byte pinUp=A2; +const byte pinDown=A1; +const byte pinBuzzer=2; +const byte pinUpperDots=12; //HIGH value light a dots +const byte pinLowerDots=4; //HIGH value light a dots +const word fpsLimit=16666; // 1/60*1.000.000 //limit maximum refresh rate on 60 fps +bool RTC_present; + + +String stringToDisplay="000000";// Conten of this string will be displayed on tubes (must be 6 chars length) +int menuPosition=0; // 0 - time + // 1 - date + // 2 - alarm + // 3 - 12/24 hours mode + +byte blinkMask=B00000000; //bit mask for blinkin digits (1 - blink, 0 - constant light) + +// 0 1 2 3 4 5 6 7 8 9 +//word SymbolArray[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023}; +word SymbolArray[10]={1022, 1021, 1019, 1015, 1007, 991, 959, 895, 767, 511}; + +byte dotPattern=B00000000; //bit mask for separeting dots + //B00000000 - turn off up and down dots + //B1100000 - turn off all dots + +#define DS1307_ADDRESS 0x68 +byte zero = 0x00; //workaround for issue #527 +int RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, RTC_day_of_week; + +//-- ------------0--------1--------2-------3--------4--------5--------6--------7--------8--------9--------10-------11-------12-------13-------14 +// names: Time, Date, Alarm, 12/24 hours, mintues, seconds, day, month, year, hour, minute, second alarm01 hour_format +// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +int parent[15]={ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4}; +int firstChild[15]={4, 7, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +int lastChild[15]={ 6, 9, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +int value[15]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24}; +int maxValue[15]={ 0, 0, 0, 0, 23, 59, 59, 31, 12, 99, 23, 59, 59, 1, 24}; +int minValue[15]={ 0, 0, 0, 12, 00, 00, 00, 1, 1, 00, 00, 00, 00, 0, 12}; +byte blinkPattern[15]={ + B00000000, + B00000000, + B00000000, + B00000000, + B00000011, + B00001100, + B00110000, + B00000011, + B00001100, + B00110000, + B00000011, + B00001100, + B00110000, + B11000000, + B00001100}; +#define TimeIndex 0 +#define DateIndex 1 +#define AlarmIndex 2 +#define hModeIndex 3 +#define TimeHoursIndex 4 +#define TimeMintuesIndex 5 +#define TimeSecondsIndex 6 +#define DateDayIndex 7 +#define DateMonthIndex 8 +#define DateYearIndex 9 +#define AlarmHourIndex 10 +#define AlarmMinuteIndex 11 +#define AlarmSecondIndex 12 +#define Alarm01 13 +#define hModeValueIndex 14 + +bool editMode=false; + +long downTime=0; +long upTime=0; +const long settingDelay=150; +bool BlinkUp=false; +bool BlinkDown=false; +unsigned long enteringEditModeTime=0; +bool RGBLedsOn=true; +byte RGBLEDsEEPROMAddress=0; +byte HourFormatEEPROMAddress=1; +byte AlarmTimeEEPROMAddress=2;//3,4,5 +byte AlarmArmedEEPROMAddress=6; +byte LEDsLockEEPROMAddress=7; +byte LEDsRedValueEEPROMAddress=8; +byte LEDsGreenValueEEPROMAddress=9; +byte LEDsBlueValueEEPROMAddress=10; + +//buttons pins declarations +ClickButton setButton(pinSet, LOW, CLICKBTN_PULLUP); +ClickButton upButton(pinUp, LOW, CLICKBTN_PULLUP); +ClickButton downButton(pinDown, LOW, CLICKBTN_PULLUP); +/////////////////// + +Tone tone1; +#define isdigit(n) (n >= '0' && n <= '9') +//char *song = "MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d"; +char *song = "PinkPanther:d=4,o=5,b=160:8d#,8e,2p,8f#,8g,2p,8d#,8e,16p,8f#,8g,16p,8c6,8b,16p,8d#,8e,16p,8b,2a#,2p,16a,16g,16e,16d,2e"; +//char *song="VanessaMae:d=4,o=6,b=70:32c7,32b,16c7,32g,32p,32g,32p,32d#,32p,32d#,32p,32c,32p,32c,32p,32c7,32b,16c7,32g#,32p,32g#,32p,32f,32p,16f,32c,32p,32c,32p,32c7,32b,16c7,32g,32p,32g,32p,32d#,32p,32d#,32p,32c,32p,32c,32p,32g,32f,32d#,32d,32c,32d,32d#,32c,32d#,32f,16g,8p,16d7,32c7,32d7,32a#,32d7,32a,32d7,32g,32d7,32d7,32p,32d7,32p,32d7,32p,16d7,32c7,32d7,32a#,32d7,32a,32d7,32g,32d7,32d7,32p,32d7,32p,32d7,32p,32g,32f,32d#,32d,32c,32d,32d#,32c,32d#,32f,16c"; +//char *song="DasBoot:d=4,o=5,b=100:d#.4,8d4,8c4,8d4,8d#4,8g4,a#.4,8a4,8g4,8a4,8a#4,8d,2f.,p,f.4,8e4,8d4,8e4,8f4,8a4,c.,8b4,8a4,8b4,8c,8e,2g.,2p"; +//char *song="Scatman:d=4,o=5,b=200:8b,16b,32p,8b,16b,32p,8b,2d6,16p,16c#.6,16p.,8d6,16p,16c#6,8b,16p,8f#,2p.,16c#6,8p,16d.6,16p.,16c#6,16b,8p,8f#,2p,32p,2d6,16p,16c#6,8p,16d.6,16p.,16c#6,16a.,16p.,8e,2p.,16c#6,8p,16d.6,16p.,16c#6,16b,8p,8b,16b,32p,8b,16b,32p,8b,2d6,16p,16c#.6,16p.,8d6,16p,16c#6,8b,16p,8f#,2p.,16c#6,8p,16d.6,16p.,16c#6,16b,8p,8f#,2p,32p,2d6,16p,16c#6,8p,16d.6,16p.,16c#6,16a.,16p.,8e,2p.,16c#6,8p,16d.6,16p.,16c#6,16a,8p,8e,2p,32p,16f#.6,16p.,16b.,16p."; +//char *song="Popcorn:d=4,o=5,b=160:8c6,8a#,8c6,8g,8d#,8g,c,8c6,8a#,8c6,8g,8d#,8g,c,8c6,8d6,8d#6,16c6,8d#6,16c6,8d#6,8d6,16a#,8d6,16a#,8d6,8c6,8a#,8g,8a#,c6"; +//char *song="WeWishYou:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,2g,d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,1g,d,g,g,g,2f#,f#,g,f#,e,2d,a,b,8a,8a,8g,8g,d6,d,d,e,a,f#,2g"; +#define OCTAVE_OFFSET 0 +char *p; + +int notes[] = { 0, +NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, +NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, +NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, +NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 +}; + +int fireforks[]={0,0,1,//1 + -1,0,0,//2 + 0,1,0,//3 + 0,0,-1,//4 + 1,0,0,//5 + 0,-1,0}; //array with RGB rules (0 - do nothing, -1 - decrese, +1 - increse + +void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w=1); + +int functionDownButton=0; +int functionUpButton=0; +bool LEDsLock=false; + +/******************************************************************************************************* +Init Programm +*******************************************************************************************************/ +void setup() +{ + // digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V + + Wire.begin(); + //setRTCDateTime(23,40,00,25,7,15,1); + + Serial.begin(115200); + + if (EEPROM.read(HourFormatEEPROMAddress)!=12) value[hModeValueIndex]=24; else value[hModeValueIndex]=12; + if (EEPROM.read(RGBLEDsEEPROMAddress)!=0) RGBLedsOn=true; else RGBLedsOn=false; + if (EEPROM.read(AlarmTimeEEPROMAddress)==255) value[AlarmHourIndex]=0; else value[AlarmHourIndex]=EEPROM.read(AlarmTimeEEPROMAddress); + if (EEPROM.read(AlarmTimeEEPROMAddress+1)==255) value[AlarmMinuteIndex]=0; else value[AlarmMinuteIndex]=EEPROM.read(AlarmTimeEEPROMAddress+1); + if (EEPROM.read(AlarmTimeEEPROMAddress+2)==255) value[AlarmSecondIndex]=0; else value[AlarmSecondIndex]=EEPROM.read(AlarmTimeEEPROMAddress+2); + if (EEPROM.read(AlarmArmedEEPROMAddress)==255) value[Alarm01]=0; else value[Alarm01]=EEPROM.read(AlarmArmedEEPROMAddress); + if (EEPROM.read(LEDsLockEEPROMAddress)==255) LEDsLock=false; else LEDsLock=EEPROM.read(LEDsLockEEPROMAddress); + Serial.print("led lock="); + Serial.println(LEDsLock); + + pinMode(RedLedPin, OUTPUT); + pinMode(GreenLedPin, OUTPUT); + pinMode(BlueLedPin, OUTPUT); + + pinMode(pinUpperDots, OUTPUT); + pinMode(pinLowerDots, OUTPUT); + + //digitalWrite(pinUpperDots, HIGH); + //while(1); + + tone1.begin(pinBuzzer); + song=parseSong(song); + + pinMode(LEpin, OUTPUT); + //pinMode(DHVpin, OUTPUT); + + // SPI setup + + SPI.begin(); // + SPI.setDataMode (SPI_MODE3); // Mode 3 SPI + SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK = 16MHz/128= 125kHz + + //buttons pins inits + pinMode(pinSet, INPUT_PULLUP); + pinMode(pinUp, INPUT_PULLUP); + pinMode(pinDown, INPUT_PULLUP); + //////////////////////////// + pinMode(pinBuzzer, OUTPUT); + + //buttons objects inits + setButton.debounceTime = 20; // Debounce timer in ms + setButton.multiclickTime = 30; // Time limit for multi clicks + setButton.longClickTime = 2000; // time until "held-down clicks" register + + upButton.debounceTime = 20; // Debounce timer in ms + upButton.multiclickTime = 30; // Time limit for multi clicks + upButton.longClickTime = 2000; // time until "held-down clicks" register + + downButton.debounceTime = 20; // Debounce timer in ms + downButton.multiclickTime = 30; // Time limit for multi clicks + downButton.longClickTime = 2000; // time until "held-down clicks" register + + // + //digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + doTest(); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if (LEDsLock==1) + { + setLEDsFromEEPROM(); + } + getRTCTime(); + byte prevSeconds=RTC_seconds; + unsigned long RTC_ReadingStartTime=millis(); + RTC_present=true; + while(prevSeconds==RTC_seconds) + { + getRTCTime(); + //Serial.println(RTC_seconds); + if ((millis()-RTC_ReadingStartTime)>3000) + { + Serial.println(F("Warning! RTC DON'T RESPOND!")); + RTC_present=false; + break; + } + } + setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); +// digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V + //setRTCDateTime(RTC_hours,RTC_minutes,RTC_seconds,RTC_day,RTC_month,RTC_year,1); //записываем только что считанное время в RTC чтобы запустить новую микросхему +// digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V + //p=song; +} + +int rotator=0; //index in array with RGB "rules" (increse by one on each 255 cycles) +int cycle=0; //cycles counter +int RedLight=255; +int GreenLight=0; +int BlueLight=0; +unsigned long prevTime=0; // time of lase tube was lit +unsigned long prevTime4FireWorks=0; //time of last RGB changed +//int minuteL=0; //младшая цифра минут + +//antipoisoning transaction +bool modeChangedByUser=false; +bool transactionInProgress=false; +#define timeModePeriod 60000 +#define dateModePeriod 5000 +long modesChangePeriod=timeModePeriod; +//antipoisoning end + +/*************************************************************************************************************** +MAIN Programm +***************************************************************************************************************/ +void loop() { + + if (((millis()%60000)==0)&&(RTC_present)) //synchronize with RTC every 10 seconds + { + getRTCTime(); + setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); + Serial.println("sync:"); + Serial.println(RTC_seconds); + } + + p=playmusic(p); + + if ((millis()-prevTime4FireWorks)>5) + { + rotateFireWorks(); //change color (by 1 step) + prevTime4FireWorks=millis(); + } + + if ((menuPosition==TimeIndex) || (modeChangedByUser==false) ) modesChanger(); + doIndication(); + + setButton.Update(); + upButton.Update(); + downButton.Update(); + if (editMode==false) + { + blinkMask=B00000000; + + } else if ((millis()-enteringEditModeTime)>60000) + { + editMode=false; + menuPosition=firstChild[menuPosition]; + blinkMask=blinkPattern[menuPosition]; + } + if (setButton.clicks>0) //short click + { + modeChangedByUser=true; + p=0; //shut off music ))) + tone1.play(1000,100); + enteringEditModeTime=millis(); + menuPosition=menuPosition+1; + if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; + Serial.print(F("menuPosition=")); + Serial.println(menuPosition); + Serial.print(F("value=")); + Serial.println(value[menuPosition]); + + blinkMask=blinkPattern[menuPosition]; + if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) + { + if ((parent[menuPosition-1]-1==1) && (!isValidDate())) + { + menuPosition=DateDayIndex; + return; + } + editMode=false; + menuPosition=parent[menuPosition-1]-1; + if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); + if (menuPosition==DateIndex) setTime(hour(), minute(), second(),value[DateDayIndex], value[DateMonthIndex], 2000+value[DateYearIndex]); + if (menuPosition==AlarmIndex) {EEPROM.write(AlarmTimeEEPROMAddress,value[AlarmHourIndex]); EEPROM.write(AlarmTimeEEPROMAddress+1,value[AlarmMinuteIndex]); EEPROM.write(AlarmTimeEEPROMAddress+2,value[AlarmSecondIndex]); EEPROM.write(AlarmArmedEEPROMAddress, value[Alarm01]);}; + if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, value[hModeValueIndex]); + // digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V + setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1); + // digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V + } + value[menuPosition]=extractDigits(blinkMask); + } + if (setButton.clicks<0) //long click + { + tone1.play(1000,100); + if (!editMode) + { + enteringEditModeTime=millis(); + if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(minute())+PreZero(second()); //temporary enabled 24 hour format while settings + } + menuPosition=firstChild[menuPosition]; + if (menuPosition==AlarmHourIndex) {value[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} + editMode=!editMode; + blinkMask=blinkPattern[menuPosition]; + value[menuPosition]=extractDigits(blinkMask); + } + + if (upButton.clicks != 0) functionUpButton = upButton.clicks; + + if (upButton.clicks>0) + { + modeChangedByUser=true; + p=0; //shut off music ))) + tone1.play(1000,100); + incrementValue(); + if (!editMode) + { + LEDsLock=false; + EEPROM.write(LEDsLockEEPROMAddress, 0); + } + } + + if (functionUpButton == -1 && upButton.depressed == true) + { + BlinkUp=false; + if (editMode==true) + { + if ( (millis() - upTime) > settingDelay) + { + upTime = millis();// + settingDelay; + incrementValue(); + } + } + } else BlinkUp=true; + + if (downButton.clicks != 0) functionDownButton = downButton.clicks; + + if (downButton.clicks>0) + { + modeChangedByUser=true; + p=0; //shut off music ))) + tone1.play(1000,100); + dicrementValue(); + if (!editMode) + { + LEDsLock=true; + EEPROM.write(LEDsLockEEPROMAddress, 1); + EEPROM.write(LEDsRedValueEEPROMAddress, RedLight); + EEPROM.write(LEDsGreenValueEEPROMAddress, GreenLight); + EEPROM.write(LEDsBlueValueEEPROMAddress, BlueLight); + } + } + + if (functionDownButton == -1 && downButton.depressed == true) + { + BlinkDown=false; + if (editMode==true) + { + if ( (millis() - downTime) > settingDelay) + { + downTime = millis();// + settingDelay; + dicrementValue(); + } + } + } else BlinkDown=true; + + if (!editMode) + { + if (upButton.clicks<0) + { + tone1.play(1000,100); + RGBLedsOn=true; + EEPROM.write(RGBLEDsEEPROMAddress,1); + Serial.println("RGB=on"); + setLEDsFromEEPROM(); + } + if (downButton.clicks<0) + { + tone1.play(1000,100); + RGBLedsOn=false; + EEPROM.write(RGBLEDsEEPROMAddress,0); + Serial.println("RGB=off"); + } + } + + static bool updateDateTime=false; + switch (menuPosition) + { + case TimeIndex: //time mode + if (!transactionInProgress) stringToDisplay=updateDisplayString(); + doDotBlink(); + checkAlarmTime(); + break; + case DateIndex: //date mode + if (!transactionInProgress) stringToDisplay=updateDateString(); + dotPattern=B01000000;//turn on lower dots + /*digitalWrite(pinUpperDots, LOW); + digitalWrite(pinLowerDots, HIGH);*/ + checkAlarmTime(); + break; + case AlarmIndex: //alarm mode + stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); + if (value[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //turn on upper dots + else + { + /*digitalWrite(pinUpperDots, LOW); + digitalWrite(pinLowerDots, LOW);*/ + dotPattern=B00000000; //turn off upper dots + } + checkAlarmTime(); + break; + case hModeIndex: //12/24 hours mode + stringToDisplay="00"+String(value[hModeValueIndex])+"00"; + dotPattern=B00000000;//turn off all dots + /*digitalWrite(pinUpperDots, LOW); + digitalWrite(pinLowerDots, LOW);*/ + checkAlarmTime(); + break; + } +} + +String PreZero(int digit) +{ + if (digit<10) return String("0")+String(digit); + else return String(digit); +} + +void rotateFireWorks() +{ + if (!RGBLedsOn) + { + analogWrite(RedLedPin,0 ); + analogWrite(GreenLedPin,0); + analogWrite(BlueLedPin,0); + return; + } + if (LEDsLock) return; + RedLight=RedLight+fireforks[rotator*3]; + GreenLight=GreenLight+fireforks[rotator*3+1]; + BlueLight=BlueLight+fireforks[rotator*3+2]; + analogWrite(RedLedPin,RedLight ); + analogWrite(GreenLedPin,GreenLight); + analogWrite(BlueLedPin,BlueLight); + cycle=cycle+1; + if (cycle==255) + { + rotator=rotator+1; + cycle=0; + } + if (rotator>5) rotator=0; +} + + +void doIndication() +{ + static byte b=1; + + static unsigned long lastTimeInterval1Started; + if ((micros()-lastTimeInterval1Started)>5000) + { + lastTimeInterval1Started=micros(); + Anode0OFF; Anode1OFF; Anode2OFF; + unsigned long var32; + unsigned long tmpVar; + + int curTube=b*2-2; + //stringToDisplay="000000"; + var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()]; + tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()]; + + var32|=doEditBlink(curTube); + tmpVar|=doEditBlink(curTube+1); + //Serial.println(var32); + + var32 |= tmpVar<<10; + + digitalWrite(LEpin, LOW); // allow data input (Transparent mode) + + SPI.transfer(var32>>16); //[A3][A2][A1][A0][RC9][RC8][RC7][RC6] - A5-A0 - anodes + SPI.transfer(var32>>8); //[RC5][RC4][RC3][RC2][RC1][RC0][LC9][RC8] - RC9-RC0 - Right tubes cathodes + SPI.transfer(var32); + + digitalWrite(LEpin, HIGH); // latching data + + switch (b) + { + case 1:{Anode0ON; Anode1OFF; Anode2OFF; break;}; + case 2:{Anode0OFF; Anode1ON; Anode2OFF; break;}; + case 3:{Anode0OFF; Anode1OFF; Anode2ON; break;}; + } + b=b+1; + if (b==4) {b=1;} + } +} + +byte CheckButtonsState() +{ + static boolean buttonsWasChecked; + static unsigned long startBuzzTime; + static unsigned long lastTimeButtonsPressed; + if ((digitalRead(pinSet)==0)||(digitalRead(pinUp)==0)||(digitalRead(pinDown)==0)) + { + if (buttonsWasChecked==false) startBuzzTime=millis(); + buttonsWasChecked=true; + } else buttonsWasChecked=false; + if (millis()-startBuzzTime<30) + { + digitalWrite(pinBuzzer, HIGH); + } else + { + digitalWrite(pinBuzzer, LOW); + } +} + +void doTest() +{ + String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""}; + testStringArray[10]=FirmwareVersion; + Serial.println(testStringArray[10]); + + Serial.print(F("Firmware version: ")); + Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); + Serial.println(F("Start Test")); + + p=song; + parseSong(p); + + analogWrite(RedLedPin,255); + delay(1000); + analogWrite(RedLedPin,0); + analogWrite(GreenLedPin,255); + delay(1000); + analogWrite(GreenLedPin,0); + analogWrite(BlueLedPin,255); + delay(1000); + + //if (Uinput<10) testStringArray[10]="000"+String(int(Uinput*100)); else testStringArray[10]="00"+String(int(Uinput*100)); + + int dlay=500; + bool test=1; + byte strIndex=-1; + unsigned long startOfTest=millis(); + bool digitsLock=false; + byte b=1; + while (test) + { + if (digitalRead(pinDown)==0) digitsLock=true; + if (digitalRead(pinUp)==0) digitsLock=false; + + for (int i=0; i<10; i++) + { + if ((millis()-startOfTest)>dlay) + { + startOfTest=millis(); + if (!digitsLock) strIndex=strIndex+1; + if (strIndex==10) dlay=3000; + if (strIndex==11) test=0; + + stringToDisplay=testStringArray[strIndex]; + Serial.print("stringToDisplay="); + Serial.println(stringToDisplay); + Serial.print("strIndex="); + Serial.println(strIndex); + Serial.print("i="); + Serial.println(i); + } + + unsigned long var32=0; + unsigned long tmpVar=0; + int curTube=b*2-2; + var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()]; + tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()]; + + var32 |= tmpVar<<10; + + digitalWrite(LEpin, LOW); // allow data input (Transparent mode) + + SPI.transfer(var32>>16); //[A3][A2][A1][A0][RC9][RC8][RC7][RC6] - A5-A0 - anodes + SPI.transfer(var32>>8); //[RC5][RC4][RC3][RC2][RC1][RC0][LC9][RC8] - RC9-RC0 - Right tubes cathodes + SPI.transfer(var32); + + digitalWrite(LEpin, HIGH); // latching data + + switch (b) + { + case 1:{Anode0ON; Anode1OFF; Anode2OFF; break;}; + case 2:{Anode0OFF; Anode1ON; Anode2OFF; break;}; + case 3:{Anode0OFF; Anode1OFF; Anode2ON; break;}; + } + b=b+1; + if (b==4) {b=1;} + delayMicroseconds(2000); + }; + } + Serial.println(F("Stop Test")); +} +void doDotBlink() +{ + static unsigned long lastTimeBlink=millis(); + static bool dotState=0; + if ((millis()-lastTimeBlink)>1000) + { + lastTimeBlink=millis(); + dotState=!dotState; + if (dotState) + { + dotPattern=B11000000; + /*digitalWrite(pinUpperDots, HIGH); + digitalWrite(pinLowerDots, HIGH);*/ + } + else + { + dotPattern=B00000000; + /*digitalWrite(pinUpperDots, LOW); + digitalWrite(pinLowerDots, LOW);*/ + } + } +} + +void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w) +{ + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(zero); //stop Oscillator + + Wire.write(decToBcd(s)); + Wire.write(decToBcd(m)); + Wire.write(decToBcd(h)); + Wire.write(decToBcd(w)); + Wire.write(decToBcd(d)); + Wire.write(decToBcd(mon)); + Wire.write(decToBcd(y)); + + Wire.write(zero); //start + + Wire.endTransmission(); + +} + +byte decToBcd(byte val){ +// Convert normal decimal numbers to binary coded decimal + return ( (val/10*16) + (val%10) ); +} + +byte bcdToDec(byte val) { +// Convert binary coded decimal to normal decimal numbers + return ( (val/16*10) + (val%16) ); +} + +void getRTCTime() +{ + Wire.beginTransmission(DS1307_ADDRESS); + Wire.write(zero); + Wire.endTransmission(); + + Wire.requestFrom(DS1307_ADDRESS, 7); + + RTC_seconds = bcdToDec(Wire.read()); + RTC_minutes = bcdToDec(Wire.read()); + RTC_hours = bcdToDec(Wire.read() & 0b111111); //24 hour time + RTC_day_of_week = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday + RTC_day = bcdToDec(Wire.read()); + RTC_month = bcdToDec(Wire.read()); + RTC_year = bcdToDec(Wire.read()); +} + +word doEditBlink(int pos) +{ + if (!BlinkUp) return 0; + if (!BlinkDown) return 0; + //if (pos==5) return 0xFFFF; //need to be deleted for testing purpose only! + int lowBit=blinkMask>>pos; + lowBit=lowBit&B00000001; + + static unsigned long lastTimeEditBlink=millis(); + static bool blinkState=false; + word mask=0; + static int tmp=0;//blinkMask; + if ((millis()-lastTimeEditBlink)>300) + { + lastTimeEditBlink=millis(); + blinkState=!blinkState; + + if (blinkState) tmp= 0; + else tmp=blinkMask; + } + if (((dotPattern&~tmp)>>6)&1==1) digitalWrite(pinLowerDots, HIGH); + else digitalWrite(pinLowerDots, LOW); + if (((dotPattern&~tmp)>>7)&1==1) digitalWrite(pinUpperDots, HIGH); + else digitalWrite(pinUpperDots, LOW); + + if ((blinkState==true) && (lowBit==1)) mask=0xFFFF;//mask=B11111111; + //Serial.println(mask); + return mask; +} + +int extractDigits(byte b) +{ + String tmp="1"; + /*Serial.print("blink pattern= "); + Serial.println(b); + Serial.print("stringToDisplay= "); + Serial.println(stringToDisplay);*/ + if (b==B00000011) + { + tmp=stringToDisplay.substring(0,2); + /*Serial.print("stringToDisplay1= "); + Serial.println(stringToDisplay);*/ + } + if (b==B00001100) + { + tmp=stringToDisplay.substring(2,4); + /*Serial.print("stringToDisplay2= "); + Serial.println(stringToDisplay);*/ + } + if (b==B00110000) + { + tmp=stringToDisplay.substring(4); + /*Serial.print("stringToDisplay3= "); + Serial.println(stringToDisplay);*/ + } + /*Serial.print("stringToDisplay4= "); + Serial.println(stringToDisplay);*/ + return tmp.toInt(); +} + +void injectDigits(byte b, int value) +{ + if (b==B00000011) stringToDisplay=PreZero(value)+stringToDisplay.substring(2); + if (b==B00001100) stringToDisplay=stringToDisplay.substring(0,2)+PreZero(value)+stringToDisplay.substring(4); + if (b==B00110000) stringToDisplay=stringToDisplay.substring(0,4)+PreZero(value); +} + +bool isValidDate() +{ + int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; + if (value[DateYearIndex]%4==0) days[1]=29; + if (value[DateDayIndex]>days[value[DateMonthIndex]-1]) return false; + else return true; + +} + +byte default_dur = 4; +byte default_oct = 6; +int bpm = 63; +int num; +long wholenote; +long duration; +byte note; +byte scale; +char* parseSong(char *p) +{ + // Absolutely no error checking in here + // format: d=N,o=N,b=NNN: + // find the start (skip name, etc) + + while(*p != ':') p++; // ignore name + p++; // skip ':' + + // get default duration + if(*p == 'd') + { + p++; p++; // skip "d=" + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + if(num > 0) default_dur = num; + p++; // skip comma + } + + // get default octave + if(*p == 'o') + { + p++; p++; // skip "o=" + num = *p++ - '0'; + if(num >= 3 && num <=7) default_oct = num; + p++; // skip comma + } + + // get BPM + if(*p == 'b') + { + p++; p++; // skip "b=" + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + bpm = num; + p++; // skip colon + } + + // BPM usually expresses the number of quarter notes per minute + wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) + return p; +} + + // now begin note loop + static unsigned long lastTimeNotePlaying=0; + char* playmusic(char *p) + { + if(*p==0) + { + return p; + } + if (millis()-lastTimeNotePlaying>duration) + lastTimeNotePlaying=millis(); + else return p; + // first, get note duration, if available + num = 0; + while(isdigit(*p)) + { + num = (num * 10) + (*p++ - '0'); + } + + if(num) duration = wholenote / num; + else duration = wholenote / default_dur; // we will need to check if we are a dotted note after + + // now get the note + note = 0; + + switch(*p) + { + case 'c': + note = 1; + break; + case 'd': + note = 3; + break; + case 'e': + note = 5; + break; + case 'f': + note = 6; + break; + case 'g': + note = 8; + break; + case 'a': + note = 10; + break; + case 'b': + note = 12; + break; + case 'p': + default: + note = 0; + } + p++; + + // now, get optional '#' sharp + if(*p == '#') + { + note++; + p++; + } + + // now, get optional '.' dotted note + if(*p == '.') + { + duration += duration/2; + p++; + } + + // now, get scale + if(isdigit(*p)) + { + scale = *p - '0'; + p++; + } + else + { + scale = default_oct; + } + + scale += OCTAVE_OFFSET; + + if(*p == ',') + p++; // skip comma for next note (or we may be at the end) + + // now play the note + + if(note) + { + tone1.play(notes[(scale - 4) * 12 + note], duration); + if (millis()-lastTimeNotePlaying>duration) + lastTimeNotePlaying=millis(); + else return p; + tone1.stop(); + } + else + { + return p; + } + Serial.println(F("Incorrect Song Format!")); + return 0; //error + } + + +void incrementValue() + { + enteringEditModeTime=millis(); + if (editMode==true) + { + if(menuPosition!=hModeValueIndex) // 12/24 hour mode menu position + value[menuPosition]=value[menuPosition]+1; else value[menuPosition]=value[menuPosition]+12; + if (value[menuPosition]>maxValue[menuPosition]) value[menuPosition]=minValue[menuPosition]; + if (menuPosition==Alarm01) + { + if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;//turn on all dots + /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //turn off all dots + } + injectDigits(blinkMask, value[menuPosition]); + } + } + +void dicrementValue() +{ + enteringEditModeTime=millis(); + if (editMode==true) + { + if (menuPosition!=hModeValueIndex) value[menuPosition]=value[menuPosition]-1; else value[menuPosition]=value[menuPosition]-12; + if (value[menuPosition]1000)) Alarm1SecondBlock=false; + if (Alarm1SecondBlock==true) return; + if ((hour()==value[AlarmHourIndex]) && (minute()==value[AlarmMinuteIndex]) && (second()==value[AlarmSecondIndex])) + { + lastTimeAlarmTriggired=millis(); + Alarm1SecondBlock=true; + Serial.println(F("Wake up, Neo!")); + p=song; + } +} + +void setLEDsFromEEPROM() +{ + digitalWrite(RedLedPin, EEPROM.read(LEDsRedValueEEPROMAddress)); + digitalWrite(GreenLedPin, EEPROM.read(LEDsGreenValueEEPROMAddress)); + digitalWrite(BlueLedPin, EEPROM.read(LEDsBlueValueEEPROMAddress)); +} + + +void modesChanger() +{ + if (editMode==true) return; + static unsigned long lastTimeModeChanged=millis(); + static unsigned long lastTimeAntiPoisoningIterate=millis(); + if ((millis()-lastTimeModeChanged)>modesChangePeriod) + { + lastTimeModeChanged=millis(); + if (menuPosition==TimeIndex) {menuPosition=DateIndex; modesChangePeriod=dateModePeriod;} + else {menuPosition=TimeIndex; modesChangePeriod=timeModePeriod;} + if (modeChangedByUser==true) + { + menuPosition=TimeIndex; + } + modeChangedByUser=false; + } + if ((millis()-lastTimeModeChanged)<2000) + { + if ((millis()-lastTimeAntiPoisoningIterate)>100) + { + lastTimeAntiPoisoningIterate=millis(); + if (menuPosition==TimeIndex) + stringToDisplay=antiPoisoning2(PreZero(day())+PreZero(month())+PreZero(year()%1000), getTimeNow()); + else stringToDisplay=antiPoisoning2(getTimeNow(), PreZero(day())+PreZero(month())+PreZero(year()%1000)); + // Serial.println("StrTDInToModeChng="+stringToDisplay); + } + } else transactionInProgress=false; +} + +String antiPoisoning2(String fromStr, String toStr) +{ + //static bool transactionInProgress=false; + //byte fromDigits[6]; + static byte toDigits[6]; + static byte currentDigits[6]; + static byte iterationCounter=0; + if (!transactionInProgress) + { + transactionInProgress=true; + for (int i=0; i<6; i++) + { + currentDigits[i]=fromStr.substring(i, i+1).toInt(); + toDigits[i]=toStr.substring(i, i+1).toInt(); + } + } + for (int i=0; i<6; i++) + { + if (iterationCounter<10) currentDigits[i]++; + else if (currentDigits[i]!=toDigits[i]) currentDigits[i]++; + if (currentDigits[i]==10) currentDigits[i]=0; + } + iterationCounter++; + if (iterationCounter==20) + { + iterationCounter=0; + transactionInProgress=false; + } + String tmpStr; + for (int i=0; i<6; i++) + tmpStr+=currentDigits[i]; + return tmpStr; +} + +String updateDisplayString() +{ + static unsigned long lastTimeStringWasUpdated; + if ((millis()-lastTimeStringWasUpdated)>1000) + { + lastTimeStringWasUpdated=millis(); + return getTimeNow(); + } + return stringToDisplay; +} + +String getTimeNow() +{ + if (value[hModeValueIndex]==24) return PreZero(hour())+PreZero(minute())+PreZero(second()); + else return PreZero(hourFormat12())+PreZero(minute())+PreZero(second()); +} + +String updateDateString() +{ + static unsigned long lastTimeDateUpdate=millis(); + static String DateString=PreZero(day())+PreZero(month())+PreZero(year()%1000); + if ((millis()-lastTimeDateUpdate)>1000) + { + lastTimeDateUpdate=millis(); + DateString=PreZero(day())+PreZero(month())+PreZero(year()%1000); + } + return DateString; +} \ No newline at end of file diff --git a/FW/NCM107-ESP32C3/platformio.ini b/FW/NCM107-ESP32C3/platformio.ini index 0548c09..9d854a4 100644 --- a/FW/NCM107-ESP32C3/platformio.ini +++ b/FW/NCM107-ESP32C3/platformio.ini @@ -13,7 +13,6 @@ platform = espressif32 board = seeed_xiao_esp32c3 framework = arduino lib_deps = - fbiego/ESP32Time@^2.0.4 - neironx/RTCLib@^1.6.0 - arduino-libraries/NTPClient@^3.2.1 paulstoffregen/Time@^1.6.1 + jchristensen/Timezone@^1.2.4 + arduino-libraries/NTPClient@^3.2.1 diff --git a/FW/NCM107-ESP32C3/src/clock.cpp b/FW/NCM107-ESP32C3/src/clock.cpp index 7c6e4fa..6f08efd 100644 --- a/FW/NCM107-ESP32C3/src/clock.cpp +++ b/FW/NCM107-ESP32C3/src/clock.cpp @@ -1,80 +1,68 @@ #include "clock.h" -int RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, RTC_day_of_week; bool RTC_present; +bool NTPinit = false; +// Central European Time (Frankfurt, Paris) +TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time +TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time +Timezone myTZ(CEST, CET); -const char *ssid = "iot"; -const char *password = "Rijnstraat214"; +TimeChangeRule *tcr; - - -void getRTCTime() +bool timeIsSet() { - // RTC_seconds = timeClient.getSeconds(); - // RTC_minutes = timeClient.getMinutes(); - // RTC_hours = timeClient.getHours(); - // RTC_day_of_week = 1 - // RTC_day = timeClient.getDay(); - // RTC_month = timeClient. - // RTC_year = + return RTC_present; } - +void printDateTime(time_t t, const char *tz) { - WiFi.begin(ssid, password); - while ( WiFi.status() != WL_CONNECTED ) { - delay ( 500 ); - Serial.print ( "." ); - } - //setup NTP - timeClient.begin(); + char buf[32]; + char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) + strcpy(m, monthShortStr(month(t))); + sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s", + hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tz); + Serial.println(buf); +} +time_t getLocalTime() +{ + time_t utc = getNtpTime(); + time_t local = myTZ.toLocal(utc, &tcr); + printDateTime(local,tcr -> abbrev); + printDateTime(utc,"UTC"); - getRTCTime(); - byte prevSeconds=RTC_seconds; - unsigned long RTC_ReadingStartTime=millis(); - RTC_present=true; - while(prevSeconds==RTC_seconds) - { - getRTCTime(); - //Serial.println(RTC_seconds); - if ((millis()-RTC_ReadingStartTime)>3000) - { - Serial.println(F("Warning! RTC DON'T RESPOND!")); - RTC_present=false; - break; - } - } - setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); + return local; +} + +void initClock() +{ + initNTP(); } void loopClock() { - timeClient.update(); - - // if (((millis()%60000)==0)&&(RTC_present)) //synchronize with RTC every 10 seconds -// { -// getRTCTime(); -// setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); -// Serial.println("sync:"); -// Serial.println(RTC_seconds); -// } + if(getWifiStatus()) + { + if(!NTPinit && getWifiStatus()) + { + setSyncProvider(getLocalTime); + setSyncInterval(300); + NTPinit = true; + } + RTC_present = timeStatus ? timeSet: true, false; + } + else + { + RTC_present = false; + } } String getTimeNow() -{ - if (value[hModeValueIndex]==24) return PreZero(tijd.getHour())+PreZero(tijd.getMinute())+PreZero(tijd.getSecond()); - else return PreZero(tijd.getHour())+PreZero(tijd.getMinute())+PreZero(tijd.getSecond()); +{ + return PreZero(hour())+PreZero(minute())+PreZero(second()); } String updateDateString() { - static unsigned long lastTimeDateUpdate=millis(); - static String DateString=PreZero(tijd.getDay())+PreZero(tijd.getMonth())+PreZero(tijd.getYear()%1000); - if ((millis()-lastTimeDateUpdate)>1000) - { - lastTimeDateUpdate=millis(); - DateString=PreZero(tijd.getDay())+PreZero(tijd.getMonth())+PreZero(tijd.getYear()%1000); - } - return DateString; -} \ No newline at end of file + return PreZero(day())+PreZero(month())+PreZero(year()%1000); +} diff --git a/FW/NCM107-ESP32C3/src/clock.h b/FW/NCM107-ESP32C3/src/clock.h index 62756cb..945e978 100644 --- a/FW/NCM107-ESP32C3/src/clock.h +++ b/FW/NCM107-ESP32C3/src/clock.h @@ -1,12 +1,16 @@ #pragma once #include -#include -#include -#include -#include +#include "ntp.h" +#include "TimeLib.h" +#include "util.h" +#include // https://github.com/JChristensen/Timezone + + void initClock(); void loopClock(); String getTimeNow(); -String updateDateString(); \ No newline at end of file +String updateDateString(); +// bool isValidDate(); +bool timeIsSet(); \ No newline at end of file diff --git a/FW/NCM107-ESP32C3/src/main.cpp b/FW/NCM107-ESP32C3/src/main.cpp index 3460b76..507d554 100644 --- a/FW/NCM107-ESP32C3/src/main.cpp +++ b/FW/NCM107-ESP32C3/src/main.cpp @@ -24,8 +24,8 @@ //#include // #include -#include -#include "JC_Button.h" +// #include +// #include "JC_Button.h" #define Anode0Pin 10 #define Anode1Pin 3 @@ -42,45 +42,48 @@ #define mosiPin 5 #define misoPin 9 -#define sckPin 6 +#define sckPin 6 +#define LEpin 7 + + #define TimeIndex 0 + #define DateIndex 1 +// #define AlarmIndex 2 +// #define hModeIndex 3 +// #define TimeHoursIndex 4 +// #define TimeMintuesIndex 5 +// #define TimeSecondsIndex 6 +// #define DateDayIndex 7 +// #define DateMonthIndex 8 +// #define DateYearIndex 9 +// #define AlarmHourIndex 10 +// #define AlarmMinuteIndex 11 +// #define AlarmSecondIndex 12 +// #define Alarm01 13 +// #define hModeValueIndex 14 String updateDateString(); String updateDisplayString(); -void doDotBlink(); -void checkAlarmTime(); -String PreZero(int digit); +// void doDotBlink(); +// void checkAlarmTime(); +// String PreZero(int digit); word doEditBlink(int pos); -byte decToBcd(byte val); +// byte decToBcd(byte val); String antiPoisoning2(String fromStr, String toStr); -String getTimeNow(); +// String getTimeNow(); String antiPoisoning2(String fromStr, String toStr); -void doTest(); +bool doTest(); // void getRTCTime(); void modesChanger(); void doIndication(); - -const byte LEpin= 7; //pin Latch Enabled data accepted while HI level -//const byte DHVpin=5; // off/on MAX1771 Driver Hight Voltage(DHV) 110-220V -//const byte RedLedPin=9; //MCU WDM output for red LEDs 9-g -//const byte GreenLedPin=6; //MCU WDM output for green LEDs 6-b -//const byte BlueLedPin=3; //MCU WDM output for blue LEDs 3-r -const byte pinSet=-1; -const byte pinUp=4; -const byte pinDown=2; -//const byte pinBuzzer=2; -//const byte pinUpperDots=12; //HIGH value light a dots -//const byte pinLowerDots=4; //HIGH value light a dots const word fpsLimit=16666; // 1/60*1.000.000 //limit maximum refresh rate on 60 fps - String stringToDisplay="000000";// Conten of this string will be displayed on tubes (must be 6 chars length) int menuPosition=0; // 0 - time // 1 - date // 2 - alarm // 3 - 12/24 hours mode -byte blinkMask=B00000000; //bit mask for blinkin digits (1 - blink, 0 - constant light) // 0 1 2 3 4 5 6 7 8 9 //word SymbolArray[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023}; @@ -90,87 +93,20 @@ byte dotPattern=B00000000; //bit mask for separeting dots //B00000000 - turn off up and down dots //B1100000 - turn off all dots -byte zero = 0x00; //workaround for issue #527 - -//-- ------------0--------1--------2-------3--------4--------5--------6--------7--------8--------9--------10-------11-------12-------13-------14 -// names: Time, Date, Alarm, 12/24 hours, mintues, seconds, day, month, year, hour, minute, second alarm01 hour_format -// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -int parent[15]={ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4}; -int firstChild[15]={4, 7, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -int lastChild[15]={ 6, 9, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -int value[15]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24}; -int maxValue[15]={ 0, 0, 0, 0, 23, 59, 59, 31, 12, 99, 23, 59, 59, 1, 24}; -int minValue[15]={ 0, 0, 0, 12, 00, 00, 00, 1, 1, 00, 00, 00, 00, 0, 12}; -byte blinkPattern[15]={ - B00000000, - B00000000, - B00000000, - B00000000, - B00000011, - B00001100, - B00110000, - B00000011, - B00001100, - B00110000, - B00000011, - B00001100, - B00110000, - B11000000, - B00001100}; -#define TimeIndex 0 -#define DateIndex 1 -#define AlarmIndex 2 -#define hModeIndex 3 -#define TimeHoursIndex 4 -#define TimeMintuesIndex 5 -#define TimeSecondsIndex 6 -#define DateDayIndex 7 -#define DateMonthIndex 8 -#define DateYearIndex 9 -#define AlarmHourIndex 10 -#define AlarmMinuteIndex 11 -#define AlarmSecondIndex 12 -#define Alarm01 13 -#define hModeValueIndex 14 - -bool editMode=false; - -long downTime=0; -long upTime=0; -const long settingDelay=150; -bool BlinkUp=false; -bool BlinkDown=false; -unsigned long enteringEditModeTime=0; -bool RGBLedsOn=false; -byte RGBLEDsEEPROMAddress=0; -byte HourFormatEEPROMAddress=1; -byte AlarmTimeEEPROMAddress=2;//3,4,5 -byte AlarmArmedEEPROMAddress=6; -byte LEDsLockEEPROMAddress=7; -byte LEDsRedValueEEPROMAddress=8; -byte LEDsGreenValueEEPROMAddress=9; -byte LEDsBlueValueEEPROMAddress=10; - -//buttons pins declarations -Button setButton(pinSet, 20,true, true); -Button upButton(pinUp, 20,true, true); -Button downButton(pinDown, 20,true, true); -const unsigned long longClickTime(2000); -int functionDownButton=0; -int functionUpButton=0; -bool LEDsLock=false; +int teststate = -1; +String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""}; +unsigned long startOfTest; + + /******************************************************************************************************* Init Programm *******************************************************************************************************/ void setup() { - - // Wire.begin(); - // Wire.setPins(0,1); - + Serial.begin(115200); pinMode(LEpin, OUTPUT); @@ -184,31 +120,20 @@ void setup() pinMode(Anode1Pin, OUTPUT); pinMode(Anode2Pin, OUTPUT); - //////////////////////////// - //pinMode(pinBuzzer, OUTPUT); - - //buttons objects inits - setButton.begin(); - upButton.begin(); - downButton.begin(); + initClock(); - // //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - doTest(); + while(!timeIsSet()) + { + doTest(); + loopClock(); + } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - initClock(); } -int rotator=0; //index in array with RGB "rules" (increse by one on each 255 cycles) -int cycle=0; //cycles counter -int RedLight=255; -int GreenLight=0; -int BlueLight=0; -unsigned long prevTime=0; // time of lase tube was lit -unsigned long prevTime4FireWorks=0; //time of last RGB changed -//int minuteL=0; //младшая цифра минут + //antipoisoning transaction bool modeChangedByUser=false; @@ -223,226 +148,66 @@ MAIN Programm ***************************************************************************************************************/ void loop() { -loopClock(); + loopClock(); - - //p=playmusic(p); - - // if ((millis()-prevTime4FireWorks)>5) - // { - // rotateFireWorks(); //change color (by 1 step) - // prevTime4FireWorks=millis(); - // } - - // if ((menuPosition==TimeIndex) || (modeChangedByUser==false) ) modesChanger(); + if ((menuPosition==TimeIndex) || (modeChangedByUser==false) ) modesChanger(); doIndication(); - - // setButton.Update(); - // upButton.Update(); - // downButton.Update(); - // if (editMode==false) - // { - // blinkMask=B00000000; - - // } else if ((millis()-enteringEditModeTime)>60000) - // { - // editMode=false; - // menuPosition=firstChild[menuPosition]; - // blinkMask=blinkPattern[menuPosition]; - // } - // if (setButton.clicks>0) //short click - // { - // modeChangedByUser=true; - // p=0; //shut off music ))) - // //tone1.play(1000,100); - // enteringEditModeTime=millis(); - // menuPosition=menuPosition+1; - // if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; - // Serial.print(F("menuPosition=")); - // Serial.println(menuPosition); - // Serial.print(F("value=")); - // Serial.println(value[menuPosition]); - - // blinkMask=blinkPattern[menuPosition]; - // if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) - // { - // if ((parent[menuPosition-1]-1==1) && (!isValidDate())) - // { - // menuPosition=DateDayIndex; - // return; - // } - // editMode=false; - // menuPosition=parent[menuPosition-1]-1; - // if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); - // if (menuPosition==DateIndex) setTime(hour(), minute(), second(),value[DateDayIndex], value[DateMonthIndex], 2000+value[DateYearIndex]); - // if (menuPosition==AlarmIndex) {EEPROM.write(AlarmTimeEEPROMAddress,value[AlarmHourIndex]); EEPROM.write(AlarmTimeEEPROMAddress+1,value[AlarmMinuteIndex]); EEPROM.write(AlarmTimeEEPROMAddress+2,value[AlarmSecondIndex]); EEPROM.write(AlarmArmedEEPROMAddress, value[Alarm01]);}; - // if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, value[hModeValueIndex]); - // // digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V - // setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1); - // // digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V - // } - // value[menuPosition]=extractDigits(blinkMask); - // } - // if (setButton.clicks<0) //long click - // { - // tone1.play(1000,100); - // if (!editMode) - // { - // enteringEditModeTime=millis(); - // if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(minute())+PreZero(second()); //temporary enabled 24 hour format while settings - // } - // menuPosition=firstChild[menuPosition]; - // if (menuPosition==AlarmHourIndex) {value[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} - // editMode=!editMode; - // blinkMask=blinkPattern[menuPosition]; - // value[menuPosition]=extractDigits(blinkMask); - // } - - // if (upButton.clicks != 0) functionUpButton = upButton.clicks; - - // if (upButton.clicks>0) - // { - // modeChangedByUser=true; - // p=0; //shut off music ))) - // tone1.play(1000,100); - // incrementValue(); - // if (!editMode) - // { - // LEDsLock=false; - // EEPROM.write(LEDsLockEEPROMAddress, 0); - // } - // } - - // if (functionUpButton == -1 && upButton.depressed == true) - // { - // BlinkUp=false; - // if (editMode==true) - // { - // if ( (millis() - upTime) > settingDelay) - // { - // upTime = millis();// + settingDelay; - // incrementValue(); - // } - // } - // } else BlinkUp=true; - - // if (downButton.clicks != 0) functionDownButton = downButton.clicks; - - // if (downButton.clicks>0) - // { - // modeChangedByUser=true; - // p=0; //shut off music ))) - // tone1.play(1000,100); - // dicrementValue(); - // if (!editMode) - // { - // LEDsLock=true; - // EEPROM.write(LEDsLockEEPROMAddress, 1); - // EEPROM.write(LEDsRedValueEEPROMAddress, RedLight); - // EEPROM.write(LEDsGreenValueEEPROMAddress, GreenLight); - // EEPROM.write(LEDsBlueValueEEPROMAddress, BlueLight); - // } - // } - - // if (functionDownButton == -1 && downButton.depressed == true) - // { - // BlinkDown=false; - // if (editMode==true) - // { - // if ( (millis() - downTime) > settingDelay) - // { - // downTime = millis();// + settingDelay; - // dicrementValue(); - // } - // } - // } else BlinkDown=true; - - // if (!editMode) - // { - // if (upButton.clicks<0) - // { - // tone1.play(1000,100); - // RGBLedsOn=true; - // EEPROM.write(RGBLEDsEEPROMAddress,1); - // Serial.println("RGB=on"); - // setLEDsFromEEPROM(); - // } - // if (downButton.clicks<0) - // { - // tone1.play(1000,100); - // RGBLedsOn=false; - // EEPROM.write(RGBLEDsEEPROMAddress,0); - // Serial.println("RGB=off"); - // } - // } - + static bool updateDateTime=false; switch (menuPosition) { - case TimeIndex: //time mode + case TimeIndex: //time mode if (!transactionInProgress) stringToDisplay=updateDisplayString(); - doDotBlink(); - //checkAlarmTime(); break; case DateIndex: //date mode if (!transactionInProgress) stringToDisplay=updateDateString(); dotPattern=B01000000;//turn on lower dots - /*digitalWrite(pinUpperDots, LOW); - digitalWrite(pinLowerDots, HIGH);*/ - //checkAlarmTime(); break; - // case AlarmIndex: //alarm mode - // stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); - // if (value[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //turn on upper dots - // else - // { - // /*digitalWrite(pinUpperDots, LOW); - // digitalWrite(pinLowerDots, LOW);*/ - // dotPattern=B00000000; //turn off upper dots - // } - // //checkAlarmTime(); - // break; - // case hModeIndex: //12/24 hours mode - // stringToDisplay="00"+String(value[hModeValueIndex])+"00"; - // dotPattern=B00000000;//turn off all dots - // /*digitalWrite(pinUpperDots, LOW); - // digitalWrite(pinLowerDots, LOW);*/ - // //checkAlarmTime(); - // break; + } } -String PreZero(int digit) -{ - if (digit<10) return String("0")+String(digit); - else return String(digit); -} +int dlay=500; +// bool test=1; +byte strIndex=-1; +// bool digitsLock=false; -void rotateFireWorks() +bool doTest() { - // if (!RGBLedsOn) - // { - // analogWrite(RedLedPin,0 ); - // analogWrite(GreenLedPin,0); - // analogWrite(BlueLedPin,0); - // return; - // } - // if (LEDsLock) return; - // RedLight=RedLight+fireforks[rotator*3]; - // GreenLight=GreenLight+fireforks[rotator*3+1]; - // BlueLight=BlueLight+fireforks[rotator*3+2]; - // analogWrite(RedLedPin,RedLight ); - // analogWrite(GreenLedPin,GreenLight); - // analogWrite(BlueLedPin,BlueLight); - // cycle=cycle+1; - // if (cycle==255) - // { - // rotator=rotator+1; - // cycle=0; - // } - // if (rotator>5) rotator=0; -} + if(!timeIsSet()) return true; + if(teststate == -1) + { + Serial.println(F("Start Test")); + startOfTest=millis(); + teststate = 0; + Serial.println(testStringArray[10]); + } + + // byte b=1; + + if ((millis()-startOfTest)>dlay) + { + startOfTest=millis(); + strIndex=strIndex+1; + if (strIndex==10) dlay=3000; + + stringToDisplay=testStringArray[strIndex]; + Serial.print("stringToDisplay="); + Serial.println(stringToDisplay); + Serial.print("strIndex="); + Serial.println(strIndex); + Serial.print("i="); + Serial.println(teststate); + + if (strIndex==11) strIndex = -1; + + } + + doIndication(); + + return false; +} void doIndication() { @@ -457,14 +222,9 @@ void doIndication() unsigned long tmpVar; int curTube=b*2-2; - //stringToDisplay="000000"; var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()]; tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()]; - var32|=doEditBlink(curTube); - tmpVar|=doEditBlink(curTube+1); - //Serial.println(var32); - var32 |= tmpVar<<10; digitalWrite(LEpin, LOW); // allow data input (Transparent mode) @@ -486,108 +246,7 @@ void doIndication() } } -byte CheckButtonsState() -{ - static boolean buttonsWasChecked; - static unsigned long startBuzzTime; - static unsigned long lastTimeButtonsPressed; - if ((digitalRead(pinSet)==0)||(digitalRead(pinUp)==0)||(digitalRead(pinDown)==0)) - { - if (buttonsWasChecked==false) startBuzzTime=millis(); - buttonsWasChecked=true; - } else buttonsWasChecked=false; - // if (millis()-startBuzzTime<30) - // { - // digitalWrite(pinBuzzer, HIGH); - // } else - // { - // digitalWrite(pinBuzzer, LOW); - // } - return 0; -} -void doTest() -{ - String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""}; - testStringArray[10]=FirmwareVersion; - Serial.println(testStringArray[10]); - - Serial.print(F("Firmware version: ")); - Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); - Serial.println(F("Start Test")); - - // p=song; - // parseSong(p); - - // analogWrite(RedLedPin,255); - // delay(1000); - // analogWrite(RedLedPin,0); - // analogWrite(GreenLedPin,255); - // delay(1000); - // analogWrite(GreenLedPin,0); - // analogWrite(BlueLedPin,255); - // delay(1000); - - //if (Uinput<10) testStringArray[10]="000"+String(int(Uinput*100)); else testStringArray[10]="00"+String(int(Uinput*100)); - - int dlay=500; - bool test=1; - byte strIndex=-1; - unsigned long startOfTest=millis(); - bool digitsLock=false; - byte b=1; - while (test) - { - // if (digitalRead(pinDown)==0) digitsLock=true; - // if (digitalRead(pinUp)==0) digitsLock=false; - - for (int i=0; i<10; i++) - { - if ((millis()-startOfTest)>dlay) - { - startOfTest=millis(); - if (!digitsLock) strIndex=strIndex+1; - if (strIndex==10) dlay=3000; - if (strIndex==11) test=0; - - stringToDisplay=testStringArray[strIndex]; - Serial.print("stringToDisplay="); - Serial.println(stringToDisplay); - Serial.print("strIndex="); - Serial.println(strIndex); - Serial.print("i="); - Serial.println(i); - } - - unsigned long var32=0; - unsigned long tmpVar=0; - int curTube=b*2-2; - var32=SymbolArray[stringToDisplay.substring(curTube, curTube+1).toInt()]; - tmpVar=SymbolArray[stringToDisplay.substring(curTube+1, curTube+2).toInt()]; - - var32 |= tmpVar<<10; - - digitalWrite(LEpin, LOW); // allow data input (Transparent mode) - - SPI.transfer(var32>>16); //[A3][A2][A1][A0][RC9][RC8][RC7][RC6] - A5-A0 - anodes - SPI.transfer(var32>>8); //[RC5][RC4][RC3][RC2][RC1][RC0][LC9][RC8] - RC9-RC0 - Right tubes cathodes - SPI.transfer(var32); - - digitalWrite(LEpin, HIGH); // latching data - - switch (b) - { - case 1:{Anode0ON; Anode1OFF; Anode2OFF; break;}; - case 2:{Anode0OFF; Anode1ON; Anode2OFF; break;}; - case 3:{Anode0OFF; Anode1OFF; Anode2ON; break;}; - } - b=b+1; - if (b==4) {b=1;} - delayMicroseconds(2000); - }; - } - Serial.println(F("Stop Test")); -} void doDotBlink() { static unsigned long lastTimeBlink=millis(); @@ -611,24 +270,6 @@ void doDotBlink() } } -void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w) -{ - Wire.beginTransmission(DS1307_ADDRESS); - Wire.write(zero); //stop Oscillator - - Wire.write(decToBcd(s)); - Wire.write(decToBcd(m)); - Wire.write(decToBcd(h)); - Wire.write(decToBcd(w)); - Wire.write(decToBcd(d)); - Wire.write(decToBcd(mon)); - Wire.write(decToBcd(y)); - - Wire.write(zero); //start - - Wire.endTransmission(); - -} byte decToBcd(byte val){ // Convert normal decimal numbers to binary coded decimal @@ -640,303 +281,8 @@ byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); } - - -word doEditBlink(int pos) -{ - if (!BlinkUp) return 0; - if (!BlinkDown) return 0; - //if (pos==5) return 0xFFFF; //need to be deleted for testing purpose only! - int lowBit=blinkMask>>pos; - lowBit=lowBit&B00000001; - - static unsigned long lastTimeEditBlink=millis(); - static bool blinkState=false; - word mask=0; - static int tmp=0;//blinkMask; - if ((millis()-lastTimeEditBlink)>300) - { - lastTimeEditBlink=millis(); - blinkState=!blinkState; - - if (blinkState) tmp= 0; - else tmp=blinkMask; - } - // if (((dotPattern&~tmp)>>6)&1==1) digitalWrite(pinLowerDots, HIGH); - // else digitalWrite(pinLowerDots, LOW); - // if (((dotPattern&~tmp)>>7)&1==1) digitalWrite(pinUpperDots, HIGH); - // else digitalWrite(pinUpperDots, LOW); - - if ((blinkState==true) && (lowBit==1)) mask=0xFFFF;//mask=B11111111; - //Serial.println(mask); - return mask; -} - -int extractDigits(byte b) -{ - String tmp="1"; - /*Serial.print("blink pattern= "); - Serial.println(b); - Serial.print("stringToDisplay= "); - Serial.println(stringToDisplay);*/ - if (b==B00000011) - { - tmp=stringToDisplay.substring(0,2); - /*Serial.print("stringToDisplay1= "); - Serial.println(stringToDisplay);*/ - } - if (b==B00001100) - { - tmp=stringToDisplay.substring(2,4); - /*Serial.print("stringToDisplay2= "); - Serial.println(stringToDisplay);*/ - } - if (b==B00110000) - { - tmp=stringToDisplay.substring(4); - /*Serial.print("stringToDisplay3= "); - Serial.println(stringToDisplay);*/ - } - /*Serial.print("stringToDisplay4= "); - Serial.println(stringToDisplay);*/ - return tmp.toInt(); -} - -void injectDigits(byte b, int value) -{ - if (b==B00000011) stringToDisplay=PreZero(value)+stringToDisplay.substring(2); - if (b==B00001100) stringToDisplay=stringToDisplay.substring(0,2)+PreZero(value)+stringToDisplay.substring(4); - if (b==B00110000) stringToDisplay=stringToDisplay.substring(0,4)+PreZero(value); -} - -bool isValidDate() -{ - int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; - if (value[DateYearIndex]%4==0) days[1]=29; - if (value[DateDayIndex]>days[value[DateMonthIndex]-1]) return false; - else return true; - -} - -// byte default_dur = 4; -// byte default_oct = 6; -// int bpm = 63; -// int num; -// long wholenote; -// long duration; -// byte note; -// byte scale; -// char* parseSong(char *p) -// { -// // Absolutely no error checking in here -// // format: d=N,o=N,b=NNN: -// // find the start (skip name, etc) - -// while(*p != ':') p++; // ignore name -// p++; // skip ':' - -// // get default duration -// if(*p == 'd') -// { -// p++; p++; // skip "d=" -// num = 0; -// while(isdigit(*p)) -// { -// num = (num * 10) + (*p++ - '0'); -// } -// if(num > 0) default_dur = num; -// p++; // skip comma -// } - -// // get default octave -// if(*p == 'o') -// { -// p++; p++; // skip "o=" -// num = *p++ - '0'; -// if(num >= 3 && num <=7) default_oct = num; -// p++; // skip comma -// } - -// // get BPM -// if(*p == 'b') -// { -// p++; p++; // skip "b=" -// num = 0; -// while(isdigit(*p)) -// { -// num = (num * 10) + (*p++ - '0'); -// } -// bpm = num; -// p++; // skip colon -// } - -// // BPM usually expresses the number of quarter notes per minute -// wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) -// return p; -// } - - // now begin note loop -// static unsigned long lastTimeNotePlaying=0; -// char* playmusic(char *p) -// { -// if(*p==0) -// { -// return p; -// } -// if (millis()-lastTimeNotePlaying>duration) -// lastTimeNotePlaying=millis(); -// else return p; -// // first, get note duration, if available -// num = 0; -// while(isdigit(*p)) -// { -// num = (num * 10) + (*p++ - '0'); -// } - -// if(num) duration = wholenote / num; -// else duration = wholenote / default_dur; // we will need to check if we are a dotted note after - -// // now get the note -// note = 0; - -// switch(*p) -// { -// case 'c': -// note = 1; -// break; -// case 'd': -// note = 3; -// break; -// case 'e': -// note = 5; -// break; -// case 'f': -// note = 6; -// break; -// case 'g': -// note = 8; -// break; -// case 'a': -// note = 10; -// break; -// case 'b': -// note = 12; -// break; -// case 'p': -// default: -// note = 0; -// } -// p++; - -// // now, get optional '#' sharp -// if(*p == '#') -// { -// note++; -// p++; -// } - -// // now, get optional '.' dotted note -// if(*p == '.') -// { -// duration += duration/2; -// p++; -// } - -// // now, get scale -// if(isdigit(*p)) -// { -// scale = *p - '0'; -// p++; -// } -// else -// { -// scale = default_oct; -// } - -// scale += OCTAVE_OFFSET; - -// if(*p == ',') -// p++; // skip comma for next note (or we may be at the end) - -// // now play the note - -// if(note) -// { -// tone1.play(notes[(scale - 4) * 12 + note], duration); -// if (millis()-lastTimeNotePlaying>duration) -// lastTimeNotePlaying=millis(); -// else return p; -// tone1.stop(); -// } -// else -// { -// return p; -// } -// Serial.println(F("Incorrect Song Format!")); -// return 0; //error -// } - - -void incrementValue() - { - enteringEditModeTime=millis(); - if (editMode==true) - { - if(menuPosition!=hModeValueIndex) // 12/24 hour mode menu position - value[menuPosition]=value[menuPosition]+1; else value[menuPosition]=value[menuPosition]+12; - if (value[menuPosition]>maxValue[menuPosition]) value[menuPosition]=minValue[menuPosition]; - if (menuPosition==Alarm01) - { - if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;//turn on all dots - /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //turn off all dots - } - injectDigits(blinkMask, value[menuPosition]); - } - } - -void dicrementValue() -{ - enteringEditModeTime=millis(); - if (editMode==true) - { - if (menuPosition!=hModeValueIndex) value[menuPosition]=value[menuPosition]-1; else value[menuPosition]=value[menuPosition]-12; - if (value[menuPosition]1000)) Alarm1SecondBlock=false; -// if (Alarm1SecondBlock==true) return; -// if ((hour()==value[AlarmHourIndex]) && (minute()==value[AlarmMinuteIndex]) && (second()==value[AlarmSecondIndex])) -// { -// lastTimeAlarmTriggired=millis(); -// Alarm1SecondBlock=true; -// Serial.println(F("Wake up, Neo!")); -// p=song; -// } -} - -void setLEDsFromEEPROM() -{ - // digitalWrite(RedLedPin, EEPROM.read(LEDsRedValueEEPROMAddress)); - // digitalWrite(GreenLedPin, EEPROM.read(LEDsGreenValueEEPROMAddress)); - // digitalWrite(BlueLedPin, EEPROM.read(LEDsBlueValueEEPROMAddress)); -} - - void modesChanger() { - if (editMode==true) return; static unsigned long lastTimeModeChanged=millis(); static unsigned long lastTimeAntiPoisoningIterate=millis(); if ((millis()-lastTimeModeChanged)>modesChangePeriod) @@ -955,10 +301,9 @@ void modesChanger() if ((millis()-lastTimeAntiPoisoningIterate)>100) { lastTimeAntiPoisoningIterate=millis(); - DateTime time = time; if (menuPosition==TimeIndex) - stringToDisplay=antiPoisoning2(PreZero(tijd.getDay())+PreZero(tijd.getMonth())+PreZero(tijd.getYear()%1000), getTimeNow()); - else stringToDisplay=antiPoisoning2(getTimeNow(), PreZero(tijd.getDay())+PreZero(tijd.getMonth())+PreZero(tijd.getYear()%1000)); + stringToDisplay=antiPoisoning2(updateDateString(), getTimeNow()); + else stringToDisplay=antiPoisoning2(getTimeNow(), updateDateString()); // Serial.println("StrTDInToModeChng="+stringToDisplay); } } else transactionInProgress=false; diff --git a/FW/NCM107-ESP32C3/src/ntp.cpp b/FW/NCM107-ESP32C3/src/ntp.cpp new file mode 100644 index 0000000..46f5f60 --- /dev/null +++ b/FW/NCM107-ESP32C3/src/ntp.cpp @@ -0,0 +1,105 @@ +#include "ntp.h" + +static const char ntpServerName[] = "us.pool.ntp.org"; +const int timeZone = 2; +unsigned int localPort = 8888; // local port to listen for UDP packets +const char *ssid = "iot"; +const char *password = "Rijnstraat214"; +const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets +const unsigned int remotePort = 123; + +bool printed = false; +bool wifiConnected = false; + + + +WiFiUDP Udp; +// NTPClient timeClient(Udp); + +bool _timeupdated = false; + +bool timeUpdated() +{ + return _timeupdated; +} + +void initNTP() +{ + WiFi.begin(ssid, password); + +} + +bool getWifiStatus() +{ + wifiConnected = WiFi.status() == WL_CONNECTED; + + if(!printed && wifiConnected) + { + Serial.print("IP number assigned by DHCP is "); + Serial.println(WiFi.localIP()); + Serial.println("Starting UDP"); + Udp.begin(localPort); + Serial.println("waiting for sync"); + printed = true; + } + return wifiConnected; +} + + +// send an NTP request to the time server at the given address +void sendNTPpacket(IPAddress &address) +{ + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); // NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} + +time_t getNtpTime() +{ + IPAddress ntpServerIP; // NTP server's ip address + + while (Udp.parsePacket() > 0) + ; // discard any previously received packets + Serial.println("Transmit NTP Request"); + // get a random server from the pool + WiFi.hostByName(ntpServerName, ntpServerIP); + Serial.print(ntpServerName); + Serial.print(": "); + Serial.println(ntpServerIP); + sendNTPpacket(ntpServerIP); + uint32_t beginWait = millis(); + while (millis() - beginWait < 1500) + { + int size = Udp.parsePacket(); + if (size >= NTP_PACKET_SIZE) + { + Serial.println("Receive NTP Response"); + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer + unsigned long secsSince1900; + // convert four bytes starting at location 40 to a long integer + secsSince1900 = (unsigned long)packetBuffer[40] << 24; + secsSince1900 |= (unsigned long)packetBuffer[41] << 16; + secsSince1900 |= (unsigned long)packetBuffer[42] << 8; + secsSince1900 |= (unsigned long)packetBuffer[43]; + return secsSince1900 - 2208988800UL * SECS_PER_HOUR; + } + } + Serial.println("No NTP Response :-("); + return 0; // return 0 if unable to get the time +} diff --git a/FW/NCM107-ESP32C3/src/ntp.h b/FW/NCM107-ESP32C3/src/ntp.h new file mode 100644 index 0000000..0d4ba93 --- /dev/null +++ b/FW/NCM107-ESP32C3/src/ntp.h @@ -0,0 +1,14 @@ +#pragma once +#include "Arduino.h" +#include +#include +#include + + + +void initNTP(); +void loopNTP(); + +time_t getNtpTime(); +bool getWifiStatus(); +bool timeUpdated(); diff --git a/FW/NCM107-ESP32C3/src/util.cpp b/FW/NCM107-ESP32C3/src/util.cpp new file mode 100644 index 0000000..b35de4d --- /dev/null +++ b/FW/NCM107-ESP32C3/src/util.cpp @@ -0,0 +1,7 @@ +#include "util.h" + +String PreZero(int digit) +{ + if (digit<10) return String("0")+String(digit); + else return String(digit); +} \ No newline at end of file diff --git a/FW/NCM107-ESP32C3/src/util.h b/FW/NCM107-ESP32C3/src/util.h new file mode 100644 index 0000000..1e17728 --- /dev/null +++ b/FW/NCM107-ESP32C3/src/util.h @@ -0,0 +1,5 @@ +#pragma once + +#include "Arduino.h" + +String PreZero(int digit); \ No newline at end of file