ansemjo / chronovfd

hardware project for a clock around a russian ivl2-5/7 vfd and an esp32-wroom module
MIT License
10 stars 0 forks source link

Problem finding how to set GMT #3

Closed nikkisstuff closed 5 months ago

nikkisstuff commented 5 months ago

I have built the clock and it works flawlessly But i am not very good with coding please could you tell me what i need to change to configure GMT

Thanks

ansemjo commented 5 months ago

That is wonderful to hear! ☺️

The timezone is configured in main.c with a setenv( ) call: https://github.com/ansemjo/chronovfd/blob/c2c7b33cb1a6d2b7752a84c55f2d39de58642ff3/firmware/src/main.c#L162-L165

According to the linked CSV file you should simply change that to:

setenv("TZ", "GMT0", 1);
nikkisstuff commented 5 months ago

Thank you i will try it now

nikkisstuff commented 5 months ago

I made the changes and set it for GMT/London from the list in the link but its not worked. I took the picture at 3:51pm

IMG_0008

Copyright (c) 2020 Anton Semjonov
// Licensed under the MIT License

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <freertos/event_groups.h>

#include <esp_system.h>
#include <esp_log.h>
#include <esp_types.h>
#include <esp_event.h>
#include <nvs_flash.h>
#include <esp_wifi.h>

#include <wifi_provisioning/manager.h>
#include <wifi_provisioning/scheme_ble.h>

#include <driver/gpio.h>

#include "ds1307.h"
#include "vfddriver.h"
#include "segments.h"
#include "realtimeclock.h"
#include "ambientlight.h"
#include "animations.h"
#include "wireless.h"

#define SECONDS configTICK_RATE_HZ

// turn on the usr led, yay
#define LED 5
void led_init() {

  gpio_set_level(LED, 1);
}

/*
  TODO LIST
  - erase nvs and reprovision on long gpio0 button press
  - manage "foreground" task in stack with push/pop
  - use the temperature sensor
*/

void do_sync(TaskHandle_t clock) {

  esp_err_t err;
  if (clock) vTaskSuspend(clock);
  TaskHandle_t loading;
  animation_spinner(&loading);

  wireless_connect();
  err = xEventGroupWaitBits(wireless, WIFI_CONNECTED, false, true, 30 * SECONDS);
  if (err == ESP_ERR_TIMEOUT) goto fail;
  err = sntp_sync(60 * SECONDS);
  if (err == ESP_ERR_TIMEOUT) goto fail;
  wireless_disconnect();
  goto out;

  fail:
  vTaskSuspend(loading);
  vfd_text("FAIL");
  vTaskDelay(2 * SECONDS);

  out:
  vTaskDelete(loading);
  if (clock) vTaskResume(clock);

}

TaskHandle_t factory_reset;

void factory_reset_task(void *arg) {

  ESP_LOGW("factory_reset", "button pressed");
  TickType_t t = xTaskGetTickCount();
  for (int i = 0; i < 5; i++) {
    ESP_LOGW("factory_reset", "in %d ...", 5 - i);
    gpio_set_level(LED, 1);
    vTaskDelayUntil(&t, 0.2 * SECONDS);
    gpio_set_level(LED, 0);
    vTaskDelayUntil(&t, 0.8 * SECONDS);
  }
  gpio_set_level(LED, 1);
  ESP_LOGW("factory_reset", "erase nvs partition & reboot");
  nvs_flash_erase();
  esp_restart();

}

static void IRAM_ATTR factory_reset_isr(void *arg) {

  int level = gpio_get_level(GPIO_NUM_0);
  if (!level) {
    // falling edge, button press
    xTaskCreate(factory_reset_task, "factory reset", 2048, NULL, ESP_TASK_PRIO_MIN + 1, &factory_reset);
  } else {
    // rising edge, release
    if (factory_reset) vTaskDelete(factory_reset);
    gpio_set_level(LED, 0);
  }

}

void factory_reset_watcher_init() {

  gpio_config_t factrst = {
    .mode = GPIO_MODE_INPUT,
    .pin_bit_mask = (1ULL << GPIO_NUM_0),
    .pull_up_en = true,
    .intr_type = GPIO_INTR_ANYEDGE,
  };
  gpio_config(&factrst);

  gpio_install_isr_service(0);
  gpio_isr_handler_add(GPIO_NUM_0, factory_reset_isr, NULL);

}

void app_main() {

  // initialize nonvolatile storage
  esp_err_t err = nvs_flash_init();
  if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    ESP_ERROR_CHECK(nvs_flash_erase());
    err = nvs_flash_init();
  }
  ESP_ERROR_CHECK(err);

  // init usr led
  gpio_set_direction(LED, GPIO_MODE_OUTPUT);
  gpio_set_level(LED, 0);
  factory_reset_watcher_init();

  // initialize vacuum flourescent display
  vfd_pin_t vfdcfg = {
    .enable    = VFD_PIN_ENABLE,
    .clock     = VFD_PIN_CLOCK,
    .data      = VFD_PIN_DATA,
    .strobe    = VFD_PIN_STROBE,
    .blank     = VFD_PIN_BLANK,
    .fil_shdn  = VFD_PIN_FILSHDN,
    .hv_shdn   = VFD_PIN_HVSHDN,
  };
  vfd_init_spi(&vfdcfg);
  TaskHandle_t digitmux;
  vfd_init_mux(0.002, &digitmux);

  // initialize filament dimmer via photodiode
  TaskHandle_t ambientlight;
  ambientlight_init(PHOTODIODE, vfdcfg.fil_shdn, &ambientlight);

  // connect to battery-backed rtc
  realtimeclock_init(I2C_SDA, I2C_SCL);
  time_t lastsync = realtimeclock_read_from_rtc();

  // set timezone to Europe/Berlin
  // https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
  setenv("TZ", "GMT0BST,M3.5.0/1,M10.5.0", 1);
  tzset();

  // enable and possibly provision credentials the first time
  // nvs_flash_erase(); // always clear creds to force conf
  wireless_init();
  wireless_provision();

  // maybe sync once on startup
  time_t now;
  time(&now);
  if ((lastsync == 0) || (lastsync > now) || ((now - lastsync) > (60 * 60))) {
    ESP_LOGI("main", "last sync more than an hour ago");
    do_sync(NULL);
  }

  // display the current time
  TaskHandle_t clock;
  clockface(&clock);

  // all segments for debug purposes
  // vfd_text("88:88");
  // for (;;) { vTaskDelay(2 * SECONDS); }

  for (;;) {
    sntp_sync_schedule(NULL);
    do_sync(clock);
  }

  wireless_end();

}
ansemjo commented 5 months ago

That looks like your clock isn't fetching any time at all, not just a timezone issue ...

nikkisstuff commented 5 months ago

that did not work i am going to reflash with unmodified firmware to see if that makes a difference

nikkisstuff commented 5 months ago

After uploading the unmodified firmware it had moved +1 hour

ansemjo commented 5 months ago

After uploading the unmodified firmware it had moved +1 hour

Which, again, indicates that the timezone is applied correctly but the clock doesn't fetch the current time from NTP.

Have you tried opening the serial console to the ESP32? There are a lot of logging messages, including success or failure of NTP updates.

Maybe you also need to update the NTP server addresses. If you're in a firewalled network, connections to external NTP servers are sometimes not allowed and you need to use a specific host on-campus or something like that. https://github.com/ansemjo/chronovfd/blob/c2c7b33cb1a6d2b7752a84c55f2d39de58642ff3/firmware/src/realtimeclock.c#L170-L173

ansemjo commented 5 months ago

As an aside: I am working on-and-off on the next iteration of this clock, which will fetch the current time from FM radio stations via RDS. No internet and no timezones required. Or at least I hope so ...

nikkisstuff commented 5 months ago

That sounds very interesting! I Have pulled the boot message

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7188
load:0x40078000,len:14308
load:0x40080400,len:3716
entry 0x40080680
I (27) boot: ESP-IDF 4.3.1 2nd stage bootloader
I (27) boot: compile time 17:41:04
I (27) boot: chip revision: 3
I (30) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (38) boot.esp32: SPI Speed      : 40MHz
I (42) boot.esp32: SPI Mode       : DIO
I (46) boot.esp32: SPI Flash Size : 8MB
I (51) boot: Enabling RNG early entropy source...
I (56) boot: Partition Table:
I (60) boot: ## Label            Usage          Type ST Offset   Length
I (67) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (75) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (82) boot:  2 factory          factory app      00 00 00010000 00100000
I (90) boot: End of partition table
I (94) boot_comm: chip revision: 3, min. application chip revision: 0
I (101) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=203e0h (132064) map
I (157) esp_image: segment 1: paddr=00030408 vaddr=3ffbdb60 size=04ab4h ( 19124) load
I (165) esp_image: segment 2: paddr=00034ec4 vaddr=40080000 size=0b154h ( 45396) load
I (184) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=9db48h (645960) map
I (418) esp_image: segment 4: paddr=000ddb70 vaddr=4008b154 size=13760h ( 79712) load
I (451) esp_image: segment 5: paddr=000f12d8 vaddr=50000000 size=00010h (    16) load
I (466) boot: Loaded app from partition at offset 0x10000
I (466) boot: Disabling RNG early entropy source...
I (477) cpu_start: Pro cpu up.
I (477) cpu_start: Starting app cpu, entry point is 0x40082c74
I (0) cpu_start: App cpu up.
I (543) cpu_start: Pro cpu start user code
I (543) cpu_start: cpu freq: 240000000
I (543) cpu_start: Application information:
I (545) cpu_start: Project name:     chronovfd
I (551) cpu_start: App version:      1
I (555) cpu_start: Compile time:     May 31 2024 17:35:03
I (561) cpu_start: ELF file SHA256:  0f1e0bb3222aaa8a...
I (567) cpu_start: ESP-IDF:          4.3.1
I (572) heap_init: Initializing. RAM available for dynamic allocation:
I (579) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (585) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (591) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (597) heap_init: At 3FFC86A8 len 00017958 (94 KiB): DRAM
I (604) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (610) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (616) heap_init: At 4009E8B4 len 0000174C (5 KiB): IRAM
I (623) spi_flash: detected chip: gd
I (627) spi_flash: flash io: dio
I (632) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (683) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3
I (685) chronovfd: hspi bus configured with { clock: 25, data: 26 }
I (689) chronovfd: device added to bus with { strobe: 27 }
I (695) chronovfd: digitmux timer prepared
I (700) chronovfd: digitmux isr registered & task created
I (706) ambientlight: pwm initialized
I (711) ambientlight: adc configured & task created
I (716) realtimeclock: Maxim DS1338 initialized
I (723) realtimeclock: reading datetime from rtc: 2000-01-01 02:18:31 UTC
I (729) realtimeclock: rtc last synchronized on:  1908-06-25 17:30:28 UTC
I (736) wireless: initialize tcp/ip and wifi stack
I (745) wifi:wifi driver task: 3ffceed0, prio:23, stack:6656, core=0
I (748) system_api: Base MAC address is not set
I (753) system_api: read default base MAC address from EFUSE
I (768) wifi:wifi firmware version: 88c8747
I (768) wifi:wifi certification version: v7.0
I (768) wifi:config NVS flash: enabled
I (771) wifi:config nano formating: disabled
I (775) wifi:Init data frame dynamic rx buffer num: 32
I (779) wifi:Init management frame dynamic rx buffer num: 32
I (785) wifi:Init management short buffer num: 32
I (789) wifi:Init dynamic tx buffer num: 32
I (793) wifi:Init static rx buffer size: 1600
I (797) wifi:Init static rx buffer num: 10
I (801) wifi:Init dynamic rx buffer num: 32
I (806) wifi_init: rx ba win: 6
I (809) wifi_init: tcpip mbox: 32
I (813) wifi_init: udp mbox: 6
I (816) wifi_init: tcp mbox: 6
I (820) wifi_init: tcp tx win: 5744
I (824) wifi_init: tcp rx win: 5744
I (828) wifi_init: tcp mss: 1440
I (832) wifi_init: WiFi IRAM OP enabled
I (837) wifi_init: WiFi RX IRAM OP enabled
I (842) wifi_prov_scheme_ble: BT memory released
I (847) wireless: credentials already provisioned
I (853) wifi_prov_scheme_ble: BTDM memory released
I (858) schedule: next sntp synchronization at 05:00 in 9689 seconds
ansemjo commented 5 months ago
...
I (723) realtimeclock: reading datetime from rtc: 2000-01-01 01:18:42 UTC
I (729) realtimeclock: rtc last synchronized on:  1908-06-25 17:30:28 UTC
...
I (858) schedule: next sntp synchronization at 05:00 in 13278 seconds

wat. I'm afraid there is some kind of over- or underflow happening here.


If you can live with your clock always updating from NTP when plugging in power, you could replace the check entirely and just always force an update:

diff --git a/firmware/src/main.c b/firmware/src/main.c
index e4f65c8..cea49e2 100644
--- a/firmware/src/main.c
+++ b/firmware/src/main.c
@@ -169,13 +169,9 @@ void app_main() {
   wireless_init();
   wireless_provision();

-  // maybe sync once on startup
-  time_t now;
-  time(&now);
-  if ((lastsync == 0) || (lastsync > now) || ((now - lastsync) > (60 * 60))) {
-    ESP_LOGI("main", "last sync more than an hour ago");
-    do_sync(NULL);
-  }
+  // always sync on startup
+  ESP_LOGI("main", "forcing NTP sync on startup");
+  do_sync(NULL);

   // display the current time
   TaskHandle_t clock;
nikkisstuff commented 5 months ago

that's brilliant I will try it now

nikkisstuff commented 5 months ago

Ive Just remembered I had a problem with the platformio.ini the espressif/toolchain-riscv32-esp @ 8.4.0+2021r1 is not available I had to update it to 8.4.0+2021r2-patch5

nikkisstuff commented 5 months ago

I left the clock powered up over night and this morning it looks to have synced up with the ntp server. i left the sync delay as 5 in the firmware