joeycastillo / Sensor-Watch

A board replacement for the classic Casio F-91W wristwatch
Other
1.21k stars 244 forks source link

Leading-Zero 24hr Bugs #476

Closed CarpeNoctem closed 1 month ago

CarpeNoctem commented 1 month ago

Branch: next Most recent revision tested & present: c9cbb82 Board color: GREEN

Issue 1: When switching from 024hr mode to 12hr mode, there is a leftover leading zero in front of the hour. This goes away if the user goes back to the usual 24hr mode, then back to 12hr mode. Seems like it could be a stuck "pixel" due to the way simple_clock_face conserves power, except that this happens in both am/pm and an example of this happening includes going from 16:xx to 04:xx PM. (note that the first digit is 1, not 0.) This only appears to be happening in simple_time_face, and not in others such as set_time_face, alarm_face

Issue 2: 24hr Indicator missing from alarm_face when in 024h mode.

matheusmoreira commented 1 month ago
  1. Ah, I see what you mean. The clock faces try to conserve power by comparing timestamps and only drawing what has changed. They do not currently take into account whether the display mode has changed. I'll try to push a fix!

  2. Understood, I'll track it down and put it in.

CarpeNoctem commented 1 month ago
  1. Ah, I see what you mean. The clock faces try to conserve power by comparing timestamps and only drawing what has changed. They do not currently take into account whether the display mode has changed. I'll try to push a fix!

Well, just don't go down too much of a rabbit hole on that one. As I said, it's changing a 1 to a 0, so I'm not sure it's simply a matter of it not updating that digit. (Because it is indeed updating it.) I'm not sure how the leading-zero bit works, but maybe one of the display conditions just isn't quite right?

Thanks for looking into it!

matheusmoreira commented 1 month ago

The 024h mode works by ensuring there are always 2 digits in the hours display. So instead of 1:00 it displays 01:00.

The relevant display logic in the simple_clock_face is just this:

https://github.com/joeycastillo/Sensor-Watch/blob/c9cbb8216365b07b9d8d8a9aa7fd521639fc155b/movement/watch_faces/clock/simple_clock_face.c#L140-L141

I believe the problem happens because it does not unset the 0 pixels in LCD position 4 when the watch is not configured to display it. So if the watch was in 024h mode before and it is switched back to 24h or 12h, the pixels are not cleared, they remain there until the screen fully updates.

Simply adding an else clause to that if should at least partially solve the issue.

if (set_leading_zero) {
    watch_display_string("0", 4);
} else {
    watch_display_string(" ", 4);
}

In the refactored clock_face I already handled that case by using snprintf which has built in support for the leading zero format:

https://github.com/joeycastillo/Sensor-Watch/blob/c9cbb8216365b07b9d8d8a9aa7fd521639fc155b/movement/watch_faces/clock/clock_face.c#L127-L142

A problem remains though: the above lines will only run when a full screen update is done, which occurs only when the current hour changes.

https://github.com/joeycastillo/Sensor-Watch/blob/c9cbb8216365b07b9d8d8a9aa7fd521639fc155b/movement/watch_faces/clock/simple_clock_face.c#L102-L129

https://github.com/joeycastillo/Sensor-Watch/blob/c9cbb8216365b07b9d8d8a9aa7fd521639fc155b/movement/watch_faces/clock/clock_face.c#L144-L174

In order to fully resolve this issue, I will decompose those hours/minutes checks into actual bits of information in the clock's state structure: hours_dirty and minutes_dirty. The display code will simply check those bits instead of concerning itself with computing them. I'll add functions which compute whether the hours or minutes are dirty and set those bits. Finally, the problem will be fixed by simply setting hours_dirty = true when the user changes the display mode via the watch face iself, causing the face to redraw the hours in the new format.

Compared to all this I expect the alarm_face fix to be much simpler, if not a one liner.

matheusmoreira commented 1 month ago

OK issue should be fixed. Turned out to be much simpler than I initially thought it would be.

When I read the code again, I realized there was no way to change the display mode from inside the face, the user must go to preferences screen. That causes a face activation when the user returns to the clock face. Activating the clock face resets the previous time value's bits to all ones which ensures a full repainting. That means the bug actually had nothing to do with what I described above.

The real problem turned out to be the fact that there's a 24h_mode bit and a leading_0 bit, switching from 024h mode back to 12h mode cleared 24h_mode but not leading_0, and only leading_0 was being taken into account when the time came to decide whether to add a leading zero. Changing it to 24h_mode && leading_0 solved the problem, at least in the simulator.

I have also added the 24h indicator back to the alarm face. All issues should be resolved. Would appreciate further testing for confirmation.

CarpeNoctem commented 1 month ago

I've just run through all my testing again, and can confirm that these two issues are fixed. Good job and thanks!

and only leading_0 was being taken into account when the time came to decide whether to add a leading zero. Changing it to 24h_mode && leading_0 solved the problem

Doh. This is exactly what I meant when I said "but maybe one of the display conditions just isn't quite right?" in my comment above. Sorry for not being clearer; it was very late at night here. >__<

Thanks again!