logo elektroda
logo elektroda
X
logo elektroda

Clock on ESP12 and MAX7219 display - tutorial - part 1, ArduinoOTA, basics

p.kaczmarek2 3603 59
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • ESP8266 Clock Project with MAX7219 Display
    I will show here the design of a clock built on ESP8266 and MAX7219 based display, additionally enhanced with a relay module on MCP23017. The PCB under the ESP will come from the web, the relay module on the other hand I designed myself. I will assemble the firmware myself in PlatformIO from ready-made libraries. The time will be downloaded from the internet via NTP.
    The main PCB for ESP12 used here is by "kbprogram" and was shared on his blog, and one of his pieces was sent to me by one of my readers (along with a bunch of other parts).
    As a rule, ready-made kits (so-called kits) I never assemble and have never put together - even my first circuits made 6 or more years ago were DIY - including, for example, As a rule, I never put together a kit. with the TQFP tracing , or there with my PIC32 board , or with my Ethernet attempts on a PIC with everything I need built in .
    In this case, however, since I had already received a PCB from a reader, I just decided to use it. Here are the contents of the whole package I received (I will try to describe something else from it in the future):
    Set of electronic components and a blue PCB on a table. Cardboard box containing various electronic components, including a PCB board, relays, and a power plug.
    Thank you for the package!
    As for the relay module mentioned in turn, it was originally intended as an overlay for this project:
    Home Assistant/Tasmota HTTP compatible relay controller + housing
    But when ordering the boards I got 10 pieces, so there are some left over for other projects.
    So much for the introduction, here we go.

    Soldering the board
    This board is a strange mix of THT and SMD. I don't know why exactly the author conceived it this way, maybe it was supposed to be a golden mean between size and soldering difficulty? You have the documentation of the project on the author's page given on the board. Basically, there is nothing to discuss here. Power block with a 3.3V LDO (I used a TC1264), ESP12, clock block with battery cage, I2C lines with pull up resistors, EEPROM also on I2C and basically that's it.
    Blue PCB with electronic component markings for an LED clock. Blue PCB with etched traces and mounting holes.
    Those SMD transistors on the bottom of the board are only needed if you want to reset the chip with lines from the UART. I myself reset and entered the programming state with buttons.
    I soldered the WiFi module by making a drop of solder on one pad, grabbing that pad and then soldering the others.
    PCB board with ESP8266 module and labeled connectors. PCB with mounted Wi-Fi module ESP12. WiFi module ESP mounted on a printed circuit board. PCB for LED matrix clock with labeled components on a blue background. PCB for LED matrix clock with labeled components on a blue background.
    I had the 100nF decoupling capacitors in slightly smaller enclosures:
    PCB with a soldered capacitor and placeholder for components. Electronic components for a clock project arranged on a table.
    Almost ready, can be programmed:
    Electronic kit consisting of a PCB with an ESP8266 module and a connected relay component. PCB for a clock project with ESP8266 and a TC1264 component
    I still soldered the components, unfortunately the holes for the cage legs for the watch battery to hold the time were too small, I had to drill :
    Close-up of a PCB with an ESP8266 module, resistors, and capacitors, and a slot for a clock battery.


    ArduinoOTA, or convenient batch uploading via WiFi
    For programming, I chose the PlatformIO platform. I have not been exposed to it before:
    https://platformio.org/
    Installation description for VSCode:
    https://platformio.org/install/ide?install=vscode
    The installation is done in two steps. First the VSCode and then the PlatformIO addon. It went without any problems.
    For uploading the batch, I chose ArduinoOTA - that is, uploading the batch over WiFi.
    Here is the platform.ini file used:
    
    ; PlatformIO Project Configuration File
    ;
    ;   Build options: build flags, source filter
    ;   Upload options: custom upload port, speed and extra flags
    ;   Library options: dependencies, extra library storages
    ;   Advanced options: extra scripting
    ;
    ; Please visit documentation for the other options and examples
    ; https://docs.platformio.org/page/projectconf.html
    
    [env:d1_mini]
    platform = espressif8266
    board = d1_mini
    framework = arduino
    monitor_speed = 115200
    lib_deps = 
    	me-no-dev/ESP Async WebServer@^1.2.3
    
    [env:d1_mini_ota]
    extends = env:d1_mini
    upload_protocol = espota
    upload_port = 192.168.0.124
    lib_deps = 
    	me-no-dev/ESP Async WebServer@^1.2.3
    

    The skeleton of the OTA application with a wildly added LED blink on GPIO2, that is the LED on board the very WiFi module I had:
    Code: C / C++
    Log in, to see the code

    This batch has to be uploaded once 'via cable', then it can be uploaded via WiFi.
    The batch must be completed with the SSID and password of your WiFi network.
    It is also important to set the IP as in the OTA configuration - in my case this is simply done by reserving an IP for the MAC of my ESP.

    All without any problems. You can already program the ESP8266 over WiFi.

    For a better configuration of our WIFi network the WiFiManager library could be plugged in:
    https://www.arduino.cc/reference/en/libraries/wifimanager/
    It would allow you to reset the WiFi configuration and roll back the device to AP configuration mode with a simple button, and then in AP mode enter our SSID and password, which is then remembered when switched off. A bit like the Tasmota.
    But that's something I haven't implemented yet in this project.

    Library MD_Parol
    For the control of the MAX7219, I have chosen the MD_Parola library. It can be installed very easily via PlatformIO. Basically you just have to search for it and click through the installation process. Everything is automatic.
    PlatformIO screenshot displaying the MD_Parola library.
    Once you have searched for the library, you can select the version and click "Add to Project".
    Screenshot of MD_Parola library registry on PlatformIO
    PlatformIO libraries installation message
    Using MD_Parol is really quite simple. The documentation is here:
    https://github.com/MajicDesigns/MD_Parola
    We define the type of display and its SPI pins (although this is truncated in his case, the communication is one way):
    Code: C / C++
    Log in, to see the code

    We then initialise it via Begin:
    Code: C / C++
    Log in, to see the code

    And then, already in the loop we can control and animate it.
    Code: C / C++
    Log in, to see the code


    Below is my code with the library attached:
    Code: C / C++
    Log in, to see the code

    Effect:
    Clock based on ESP8266 with LED display MAX7219



    NTP or internet time
    I've written about my own NTP client here, among other things, but with PlatformIO and the ready-made Arduino libraries, you don't even need to know what UDP is - there's a ready-made one here too.
    Adding NTPClient project dependency in PlatformIO.
    We include the client header:
    Code: C / C++
    Log in, to see the code

    We create the NTP client, it consists of two parts:
    Code: C / C++
    Log in, to see the code

    The address of the time server can be changed. We set the time zone and start NTP:
    Code: C / C++
    Log in, to see the code

    In a loop we update its operation:
    Code: C / C++
    Log in, to see the code

    We still need to transfer the time to the display, but the Printf function already built into the Parola class will help us with this:
    Code: C / C++
    Log in, to see the code

    All I had to do was add a few lines of code and there you go - we have a time display:
    Code: C / C++
    Log in, to see the code

    NOTE: this hour one five will display what 1:5, there is no adding extra zeros here.
    You can get the current date from NTP in a similar way, so it is very easy to expand on the previous example and get this effect:



    Below is the full code for my date display, additionally relying on a helper function which formats the number by adding a preceding zero (so that, for example, 5 minutes past 10 is displayed as 10:05 rather than 10:5):
    Code: C / C++
    Log in, to see the code

    Code: C / C++
    Log in, to see the code

    I haven't played around with checking the buffer size here, although it should be mentioned anyway. If the buffer given to sprintf is not of sufficient size then the sprintf operation has undefined effects, it will overwrite further memory contents. Consider using its safe counterpart, checking the size of the target buffer, for example sprintf_s.
    It is worth noting that the text itself to the display is sent by this line:
    Code: C / C++
    Log in, to see the code

    it also turns on the animation. Of course, there are other solutions, you can use a ready-made function to convert time to text:
    Code: C / C++
    Log in, to see the code

    The advantage of this function is that it will not exceed the buffer size, so it is safer.

    Relay board - MCP23017
    As mentioned, this board is of my own making and on board it contains a port expander (16-bit) MCP23017 with I2C interface. For its control we need two lines - SDA and SCL. In addition, we need VDD - here 3.3V and relay supply - 5V. Some of the MCP23017 leads are brought out on goldpins, as I did not fit as many as 16 relays on the PCB. In addition, on the board there are pads allowing you to select the address of the expander (three address pins - A0, A1, A2), we can choose as many as 2^3 address combinations, so some of these expanders can be connected to the I2C bus.
    Pinout diagram of the MCP23017 integrated circuit.
    Time for soldering - I soldered the SMD in such a way that I first put the solder on one pad (with flux), then positioned the component with a pesette and melted this solder with a soldering tip, and then soldered its other leg.
    Printed circuit board with markings and soldering points. Printed circuit board on wooden surface.
    Binder jumpers for address selection:
    Bottom of a green PCB with several SMD components.
    Relay module PCB board
    I used surface-mounted S9014 transistors:
    Boxes labeled with electronic components.
    Almost done:
    Printed circuit board with relay components on a workbench
    Circuit board with relay module and electronic components
    Relay board based on MCP23017 on a wooden surface
    Printed circuit board with four relays mounted on a workbench.


    Observation of MCP23017
    As before - we have the library ready.
    https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
    We install it:
    Search results for MCP23017 libraries in PlatformIO.
    We include the header:
    Code: C / C++
    Log in, to see the code

    We create the object:
    Code: C / C++
    Log in, to see the code

    The library assumes by default that we have connected all address pins to ground, as I also did, so you don't even need to specify the address.
    It really surprised me too, here everything is simplified to the absolute minimum, it's so very friendly novice that a beginner doesn't even need to know about I2C addresses to use MCP....
    It remains to modify my flashing condition in the main loop:
    Code: C / C++
    Log in, to see the code

    Yes - that's really all it takes, just mcp.digitalWrite!
    Result (need to include audio):



    You can hear the relay working - blink works.


    Web server
    I then prepared a simple web server to configure the timer and relays based on AsyncWebServer, but.... i will put the details in the next section. The final plan is to develop a simple calendar on the web panel, where we can set when which relay switches on, preferably including the days of the week as well. Of course, there will also be an alarm clock based on a buzzer. But that is still some time away.

    Summary
    I basically started the project just out of curiosity, for a reader, because he just sent me parts for it. Even the board for this clock was not mine, but a ready-made one from the web. The whole thing went (or is going, as it is not ready yet) very smoothly and pleasantly. The ready-made libraries under ESP and the mass of examples make it all come together from ready-made components, without the need for any deep understanding of what works and how it works. This is very different from what I usually do, like the clock project on the PIC18F2550 . In that project I had to run most of the things myself, knowing more or less how they worked, while here you don't even need to know what protocol the MAX7219 uses to display text on it! Just whether this is good for beginners? Opinions are probably divided...

    Cool? Ranking DIY
    Helpful post? Buy me a coffee.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    p.kaczmarek2 wrote 13978 posts with rating 11765, helped 631 times. Been with us since 2014 year.
  • ADVERTISEMENT
  • #2 20840065
    speedy9
    Helpful for users
    I'm probably going to look into this PlatformIO, because I find the Arduino a bit annoying, especially when it comes to libraries. And here and OTA easy. I look forward to the next part with the web server.
  • #4 20840124
    p.kaczmarek2
    Moderator Smart Home
    @speedy9 PlatformIO is really convenient and easy to use. Additionally, it resides in VSCode, which I also use for purposes other than microcontroller programming. For example, it is convenient to write and test simple websites (e.g. thanks to the option to run with live server)

    @Kuniarz This is a finished project from Thingiverse printed from PLA, here the subject SMD tumblers from Thingiverse - my review and print test
    Helpful post? Buy me a coffee.
  • #5 20840150
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #6 20840569
    krzbor
    Level 28  
    speedy9 wrote:
    I think I'll take a look at this PlatformIO, as I find the Arduino a bit annoying, especially when it comes to libraries.

    Can you elaborate on this thought?
  • #7 20841872
    pitsa
    Level 12  
    speedy9 wrote:
    and OTA easy.

    Try ElegantOTA.
  • #8 20842142
    Karol966
    Level 31  
    p.kaczmarek2 wrote:
    PlatformIO is really convenient and easy to use

    I have a different opinion, my beginnings with it were difficult and because the trauma remained, today I probably wouldn't be able to create a new project, add libraries, etc. in a short time but would have to recall everything from scratch. By the way, perhaps you would like to create a simple tutorial on the subject? Certainly VSC+PlatformIO is a much better choice than Arduino IDE :)
  • ADVERTISEMENT
  • #9 21759151
    p.kaczmarek2
    Moderator Smart Home
    Update after two years - I am working on this project again:
    ESP module with DHT11 sensor, LED matrix, and USB power supply on a wooden tableDHT11 sensor module connected to a development board with jumper wiresAM2301 sensor module connected to an ESP8266 board on a workbenchPCB with ESP8266 module, potentiometer, and connected jumper wires

    @max4elektroda what's the status of DS3231 in OBK now?
    Helpful post? Buy me a coffee.
  • #10 21759171
    max4elektroda
    Level 23  
    p.kaczmarek2 wrote:
    @max4elektroda what's the status of DS3231 in OBK now?

    Working - just synched today and fixed the berry part with NTP (since I changed to a general time source, using g_ntpTime directly is no longer possible (nor sensible), it's "Clock_GetCurrentTime()" now). And I switched to "obktime.h" to avoid time.h function like gmtime.

    So this is the code now (original code only commented out) - not tested, but selftest is o.k., so I expect it's working:
    
    int be_gmtime(bvm *vm) {
       struct tm *ltm;
       const char *fields;
       int i;
    
       int top = be_top(vm);
       if (top == 1 && be_isstring(vm, 1)) {
          fields = be_tostring(vm, 1);
       }
       else {
          fields = "YMDhmsw"; // default all fields
       }
    
    /*
       ltm = gmtime(&g_ntpTime);
    
       be_newobject(vm, "list"); // create a new list on top of the stack
    
       for (i = 0; fields[i]; i++) {
          int value = 0;
          switch (fields[i]) {
          case 'Y': value = ltm->tm_year + 1900; break;
          case 'M': value = ltm->tm_mon + 1;     break;
          case 'D': value = ltm->tm_mday;        break;
          case 'h': value = ltm->tm_hour;        break;
          case 'm': value = ltm->tm_min;         break;
          case 's': value = ltm->tm_sec;         break;
          case 'w': value = ltm->tm_wday;        break;
          }
    
          be_pushint(vm, value);    // push value onto stack
          be_data_push(vm, -2);     // append value to list at -2
          be_pop(vm, 1);            // pop the temporary value
       }
    */
    
       TimeComponents tc;
       tc=calculateComponents(Clock_GetCurrentTime());
    
       be_newobject(vm, "list"); // create a new list on top of the stack
    
       for (i = 0; fields[i]; i++) {
          int value = 0;
          switch (fields[i]) {
          case 'Y': value = tc.year;   break;
          case 'M': value = tc.month;  break;
          case 'D': value = tc.day;    break;
          case 'h': value = tc.hour;   break;
          case 'm': value = tc.minute; break;
          case 's': value = tc.second; break;
          case 'w': value = tc.wday;   break;
          }
    
          be_pushint(vm, value);    // push value onto stack
          be_data_push(vm, -2);     // append value to list at -2
          be_pop(vm, 1);            // pop the temporary value
       }
    
    
    
       be_pop(vm, 1);
       be_return(vm); // return the list on top of the stack
    }
  • #11 21759292
    p.kaczmarek2
    Moderator Smart Home
    No abnormal size increase on clock-disabled branches? What's current growth size for Beken and ... for BL602?

    And here is my preparation for running MAX7219 clock on Windows:
    LED display showing the digits 12345 in front of schematic and debug console
    Helpful post? Buy me a coffee.
  • #13 21759384
    p.kaczmarek2
    Moderator Smart Home
    Acceptable, ready to merge now?
    Helpful post? Buy me a coffee.
  • #14 21759479
    max4elektroda
    Level 23  
    Ready, though over the night I realized, DS3231 driver maybe should have a default behavior that setting device clock should also set RTC time automatically?
    Sure, this can be added later, will try in the afternoon...
    So wait for this small addition or merge now and let me improve driver later - it's up to you.

    And maybe give a hint, what you think about the proposed change in the ESP8266 thread for the IO pins (using "NC" for unusable pins, which are hidden in GUI) and the changes for ADC pin.
    Thanks

    Added after 1 [hours] 48 [minutes]:

    Changed PR accordingly: Setting device clock (e.g. with an NTP update) will set RTC, too (if driver is running).

    So a possible startup command for this case would be
    startdriver DS3231 <CLK-Pin> <DATA-Pin> 1


    which will set local time to RTC-time once on startup, and later, if NTP is running, it will be adjusted every time NTP update is received.

    Just for reference again the optional last argument "sync clock":
    0: do nothing (same, if not present)
    1: on driver start set device clock to RTC
    2: set device clock regularly to RTC - so RTC is "clock master" (if you have no other clock source, RTC will usually be more stable than device)
  • #15 21759558
    p.kaczmarek2
    Moderator Smart Home
    So you really want to match internal pin indexes with ESP indexes? Ok, I guess it's acceptable... we can bit the bullet and break configs on ESP8266 once.

    I didn't have time to to check whole code of your PR yet, but you basically want to automatically update RTC to time from NTP?

    max4elektroda wrote:

    which will set local time to RTC-time once on startup, and later, if NTP is running, it will be adjusted every time NTP update is received.

    It seems a good idea, but it would be worth to check how often in reality it's done, so we avoid sending time to RTC like every minute. I have other devices on this I2C bus. Maybe the preferred solution is to send time to RTC on first time from NTP received during single boot.

    Right now I am focusing on developing clock in Berry on Windows:
    PCB layout with HELLO written in a grid of red dots
    
    autoexec = module("autoexec")
    
    def myLogic()
          runCmd("MAX72XX_Scroll 1")
          runCmd("MAX72XX_refresh")
    end
    
    runCmd("startDriver MAX72XX")
    runCmd("MAX72XX_Setup 10 8 9 5")
    runCmd("MAX72XX_Clear")
    runCmd("MAX72XX_Print Hello")
    setInterval(myLogic, 100)
    
    return autoexec
    
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #16 21759709
    max4elektroda
    Level 23  
    It's no problem to leave setting RTC to the user or do a more sophisticated approach. In the end we only need to set the RTC if the new time differs.

    So maybe something like: set RTC regularly on every hour / once a day / ... only and between this only, if the new time differs more than let's say 10 seconds, so basically on first setting or if I change to a new timezone ;-)...

    To keep it simple we should only make sure, RTC is set if needed, even if the driver is started after ntp. So I could also think of an RTC drivers command to inform about a clock setting and let the driver keep track if it was already set once.

    Let me think and try a bit, or give a hint what you would prefer.
  • #17 21759743
    p.kaczmarek2
    Moderator Smart Home
    Any logic like "on every hour" seems to complicated, doesn't it? And timezone change should be outside RTC I think. RTC should always be in CET? I am not sure. I think the simplest is boolean bFirst to check if it's first packet from NTP.
    NTP is timezone agnostic, isn't it? So RTC could be the same as well. Hm.

    I will merge my changes into main tree now, so we don't get too messy.
    Helpful post? Buy me a coffee.
  • #18 21759913
    max4elektroda
    Level 23  
    p.kaczmarek2 wrote:
    Any logic like "on every hour" seems to complicated, doesn't it? And timezone change should be outside RTC I think. RTC should always be in CET? I am not sure. I think the simplest is boolean bFirst to check if it's first packet from NTP.
    NTP is timezone agnostic, isn't it? So RTC could be the same as well. Hm.

    checking
    (! g_secondsElapsed%3600)
    is easy, but that's not the point ;-)

    And you are of course right, timezone change is independent from UTC time - RTC like local clock will represent UTC. So we have no messing around with DST events allowing for timestamps to be "double" (if time is switched back).

    So my actual approach:
    When time is set (e.g. because of an NTP update packet) we will call RTC drivers "void DS3231_informClockWasSet(bool force);".
    If we set the local (device) time and it changed more than 5 seconds, we will additionally set "force".
    In RTC driver, we have a simple counter, increased on every call of this function.
    If either "force" is set, or counter%60 == 0, we will set RTC time.
    So the first call (counter==0) will always set the RTC, afterwards we will set RTC every hour (for ntp, which is updated every 60 seconds)

    If setting RTC once every hour seems too often, we might also only use the "counter" as an indicator, if RTC was set once, and let deviceclock make sure, it's called with "force" if RTC setting is needed, because time drifted more than 5 seconds.
    Every other approach (I can think of) would involve reading the RTC to compare it, which will use I2C bus, too.

    p.kaczmarek2 wrote:
    I will merge my changes into main tree now, so we don't get too messy.

    Ah, you leave the dull work of resolving merge conflicts to me ;-) - just kidding, there weren't any - PR is updated!
  • #19 21759982
    p.kaczmarek2
    Moderator Smart Home
    Ahh, okay, the module solution is also acceptable. You can do it that way.

    Just try to avoid too large code additions, as this feature seems to be mostly for us and more advanced users, so I think most of the people won't use it anyway. But I, for example, would like my clock to still retain time even after I bring it to family who don't have internet access.

    Review time. My first question - is there still ntp_timeZoneOfs command or did it get lost in update? Please double check that the old commands are still there. Don't worry about new aliases, they are not really needed. You can redirect them to clock driver, I'll agree for little legacy naming not matching the implementation. Namely:
    - ntp_timeZoneOfs
    - ntp_setServer
    - ntp_setLatLong
    etc
    Helpful post? Buy me a coffee.
  • #20 21759996
    max4elektroda
    Level 23  
    All "ntp_XY" commands are still present, calling the corresponding new "CLOCK_XY" commands to retain compatibility:

    $ find src/driver/ -name "*.[ch]" | xargs grep -i 'CMD_RegisterCommand("ntp_'
    src/driver/drv_ntp.c:    CMD_RegisterCommand("ntp_timeZoneOfs",SetTimeZoneOfs, NULL);
    src/driver/drv_ntp.c:    CMD_RegisterCommand("ntp_setServer", NTP_SetServer, NULL);
    src/driver/drv_ntp.c:    CMD_RegisterCommand("ntp_info", NTP_Info, NULL);
    src/driver/drv_deviceclock.c:    CMD_RegisterCommand("ntp_setLatLong", CLOCK_SetLatlong, NULL);
  • #21 21760101
    p.kaczmarek2
    Moderator Smart Home
    I see, acceptable I guess.

    Ok, but now Clock is a driver, right? So everyone sees its as running, as "Clock" on main page. Won't in confuse people? Or maybe we need a bit better name?

    @ElektrodaBot for OpenBeken firmware for BK7231, ESP32, etc, IoT devices - what is the best name of driver that is used to keep current time from RTC or NTP, etc? Manage DST, etc? Give list of proposed names that everyone, even people without good english can understand. We are ourselves considering driver names like "Clock" or "Time".
    Helpful post? Buy me a coffee.
  • #22 21760120
    ElektrodaBot
    AI OpenAI ChatGPT4
    p.kaczmarek2 wrote:
    I see, acceptable I guess.

    Ok, but now Clock is a driver, right? So everyone sees its as running, as "Clock" on main page. Won't in confuse people? Or maybe we need a bit better name?

    @ElektrodaBot for OpenBeken firmware for BK7231, ESP32, etc, IoT devices - what is the best name of driver that is used to keep current time from RTC or NTP, etc? Manage DST, etc? Give list of proposed names that everyone, even people without good english can understand. We are ourselves considering driver names like "Clock" or "Time".
    Initial assessment
    - You’re consolidating “NTP + RTC + TZ/DST” into one module. Old ntp_* commands still exist and forward to new CLOCK_* handlers.
    - Concern: showing a running driver named “Clock” on the main page may mislead users (they may expect a display/face), while the module is actually a time source/synchronization service.

    Direct answer
    My recommendation: use “Time Sync” as the visible name and “time” as the driver ID/prefix. Keep ntp_* as aliases for backward compatibility, but add time_* (or TIME_*) as the official commands.

    - Display name (UI): Time Sync
    - Driver name (startDriver): time
    - Command prefix: time_ (keep ntp_* as aliases)
    - Optional UI subtitle: NTP + RTC

    This avoids confusion with “Clock” displays, is short, and is understandable for non‑native English speakers.

    Detailed analysis and naming rationale
    What the module does:
    - Maintains system time from multiple sources (NTP, RTC, manual).
    - Applies time zone offset and DST rules when converting UTC for display/schedules.
    - Optionally synchronizes RTC from system time.

    Implications for naming:
    - “Clock” is overloaded and commonly associated with a visual display or alarm.
    - “NTP” is too narrow (excludes RTC/manual).
    - Terms like “Chrono/Temporal” are less accessible.
    - “Sync” is globally recognizable and strongly signals the background nature of the service.

    Shortlist of simple, unambiguous names (ranked)
    Pick 1 for the UI label; keep the driver ID short (“time”).

    1) Time Sync — keeps time correct from NTP/RTC; manages time zone/DST.
    2) System Time — the device’s official time service (neutral, clear).
    3) Date & Time — very familiar from OS settings; friendly in UI lists.
    4) Time Keeper — “keeps” time accurate; easy to grasp.
    5) Time Service — background service maintaining device time.
    6) Network Time — emphasizes NTP; pair with RTC in subtitle: “Network/RTC”.
    7) RTC Sync — good if the primary role is syncing RTC from system time.
    8) Time Manager — suggests configuration + policy (DST, sources).
    9) Time Source — highlights that it provides time to others.
    10) Time Base — engineering term; compact, but a bit more technical.

    Names I’d avoid for the main UI:
    - Clock — likely confused with a display/face or alarm driver.
    - NTP — excludes RTC/manual; users without Internet may think it’s useless.
    - Chrono/Temporal — not universally understood.

    Practical guidelines
    - Separation of concerns in naming:
    - Time service: “Time Sync” (driver “time”).
    - Any display driver: e.g., “Clock Display”, “Matrix Clock”, “LCD Clock”.
    - Command aliases and migration:
    - Keep ntp_* → time_* forwarding to preserve scripts.
    - Introduce time_* as canonical:
    - time_setServer / time_server
    - time_zoneOfs (or time_tzOfs)
    - time_setLocation (lat,long)
    - time_info
    - UI string suggestion on main page:
    - “Time Sync (NTP+RTC) — OK, UTC+01:00”
    - Technical note for docs/tooltips:
    - “RTC and NTP keep UTC. Time zone and DST apply on display/schedules.”

    Possible disclaimers or notes
    - Make clear that the RTC stores UTC; DST/offset is applied on conversion, not by shifting RTC.
    - If “DST” is shown, consider “DST (Summer Time)” in help text to aid non‑English users.

    Suggestions for further work
    - Add a deprecation note: ntp_* will remain as aliases indefinitely or at least for one major release.
    - Provide a short help page: “Time Sync — keeps device time from Internet (NTP) or RTC. Works without Internet if RTC is present.”

    Brief summary
    - Best choice: “Time Sync” (driver ID “time”, commands time_*). It’s short, clear, and avoids confusion with a “Clock” display.
    - Solid alternatives: “System Time”, “Date & Time”, “Time Keeper”, “Time Service”.
    - Keep ntp_* aliases; show “Time Sync (NTP+RTC)” on the main page for extra clarity.

    Questions for you
    - Any hard limits on display label length on the main page?
    - Do you want the official command prefix to be lowercase (time_*) or uppercase (TIME_*)?
    - Should we show a short status (e.g., “source: NTP/RTC/manual; last sync: 12 min”) next to the driver name on the main page?
    You can call me in any topic by writing @ElektrodaBot. Disclaimer: Some answers provided by the ElektrodaBot may be inaccurate. Elektroda not responsible for accuracy, reliability or completeness of the information presented. All ElektrodaBot responses should be verified by the user. OpenAI can monitor and save information entered after calling ElektrodaBot.
  • #23 21760144
    p.kaczmarek2
    Moderator Smart Home
    Probably "Time" would be best
    Helpful post? Buy me a coffee.
  • #24 21760242
    max4elektroda
    Level 23  
    Sure, I can try to change everything to "Time", but won't be able today, hopefully I can try the next days.
    And as a first "fix", we can also hide the clock driver from main page, I only used a driver to have "CLOCK_OnEverySecond()" - to run calendar-events or change offset on DST switch.
    We could also move this two (conditional) functions (only if ENABLE_CALENDAR_EVENTS or ENABLE_CLOCK_DST are set) to main OnEverySecond() loop, since this "driver" is always running.
  • #25 21760347
    p.kaczmarek2
    Moderator Smart Home
    So maybe hide it that way.... if nothing else from drivers is used
    Helpful post? Buy me a coffee.
  • #26 21762887
    max4elektroda
    Level 23  
    You might try https://github.com/MaxineMuster/OpenBK7231T_App/tree/ESP8266temp now.
    It has the ESP8266 changes (unused IO pins as "NC" but hidden in GUI, ADC roles only with ADC pins)
    And DS3231 plus my actual try for "CLOCK":
    Names not changed, but driver still a driver, but "hidden".

    To achieve this, I slightly changed struct "driver_t" in drv_main.c : Instead of "bool bLoaded" I used "int8_t LoadedFlag".
    This way I can assign negative numbers which will decide how to handle the driver:
    A negative number means: Not loaded
    A positive number means: Loaded

    During start/stop the number is inverted (* -1)
    A 1 (as before) means: Driver loaded and shown
    Any number > 1 means: Driver loaded, but not shown in GUI (so we might use this for other "flags")

    I think this will only slightly change the code, but give more flexibility.

    BTW: Changing the "false" to "-1" in the driver lines showed some nasty bugs we had for some month:
    When "void(*onHassDiscovery)(const char *topic);" was introduced, some lines where forgotten to be extended, too.
    I added the missing "NULL" entries and rewrote the lines, so you now can easily see the struct members:

    Modified PinMutex and GosundSW2 driver definitions in C source code

    I also fixed the last "XXX_AppendInformationToHTTPIndexPage" where the addition of arg "int bPreState" was not added...
  • #27 21763481
    p.kaczmarek2
    Moderator Smart Home
    Fixes are good, but I'd prefer to stick to simpler solution and do not introduce extra features when they needed just by a single driver. Those are futher potential fault scenarios for hard to find bugs and we can't really do that unless the change is required by our users.
    Helpful post? Buy me a coffee.
  • #28 21764077
    max4elektroda
    Level 23  
    Sorry, the proposed change was because you asked that the running driver should not been shown and this is a very simple change, allowing a more flexible way to handle drivers, e.g. hiding them.
    I can't see this increasing potential "future bugs":
    Setting one argument in the "drivers line" to "-1" instead of "false" will usually be done once by introducing a new driver, where I think it's usually cloned from another driver.
    The new introduced "onHassDiscovery" e.g. is actually used for two drivers...

    But you are the boss ;-)
    So I reverted this approach, now the parts of clock driver are unconditionally started (if OBK_DISABLE_ALL_DRIVERS is not defined):

    DRV_Generic_Init() calls CLOCK_Init();
    DRV_AppendInformationToHTTPIndexPage() calls CLOCK_AppendInformationToHTTPIndexPage();
    DRV_OnEverySecond() calls CLOCK_OnEverySecond();

    (I was wrong when stating, only "onEverySecond" is used, it's also using "XX_AppendInformationToHTTPIndexPage()".)

    New artifacts:
    https://github.com/MaxineMuster/OpenBK7231T_App/actions/runs/19740102912
  • #29 21766326
    max4elektroda
    Level 23  
    I think I misunderstood your request and thought you wanted to hide the driver, because it was "automatically" started, but I think, you meant the name "CLOCK" would be misleading, sorry.

    So now I hope I did what you expected:

    Changed the name (and the functions) from "CLOCK" to "TIME" in the original PR#1792
    (included the fixes, too)

    So now the driver is "TIME" and the commands added are:

    time_setLatLong    (plus "ntp_setLatLong" for compatibility)
    time_setDST        (plus "clock_calcDST"  for compatibility)
    time_setTZ         (plus "ntp_timeZoneOfs") 
    time_setTime
    
  • #30 21766370
    p.kaczmarek2
    Moderator Smart Home
    I think name change to time is good, but I would still think it would be better to avoid having this feature in drivers list, so we don't get question "why is driver Time running, I didn't start it" :D
    Helpful post? Buy me a coffee.
📢 Listen (AI):
ADVERTISEMENT