Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug in flipdisplay with colon : #18

Open
stef-ladefense opened this issue Jul 30, 2022 · 10 comments
Open

bug in flipdisplay with colon : #18

stef-ladefense opened this issue Jul 30, 2022 · 10 comments
Labels
bug Something isn't working

Comments

@stef-ladefense
Copy link
Contributor

hi,

i use this for write time

void ShowTime(uint8_t _mins, uint8_t _secs, bool _Colon, bool _zns) {
display.showNumberDec(_mins, 0b01000000 * _Colon, _zns, 2, 0);
display.showNumber(_secs, true, 2, 2);
}

but with display.flipDisplay(true) not colon write ...

@jasonacox
Copy link
Owner

jasonacox commented Jul 30, 2022

HI @stef-ladefense - thanks for opening this issue!

The Problem

The challenge we have with flipping the display is that the "colon" is hardwired to be set by the 2nd digit in "non-flip" orientation. The same happens for "decimal" displays where the digit to the left of the decimal is what sets that dot. For example:

Non-Flip Display
0. 1. 2. 3. (index for digit)
[0] [1:] [2] [3] - The colon is set by the "1" (index 1) - which would be your _mins setting.

Flip Display Over
0. 1. 2. 3. (flip index)
[3] [2] [:1] [0] - The colon is still set by the "1" (index 2) - which would now be your _secs setting in this orientation.

The flip code in the library knows that the colon moves and shifts the setting, but it can only set values in the range of digits you give it (for minutes, you are telling it to limit the change to only length=2 spaces - digits index 0 and 1). If we go outside the length value, we would need to know the value in index 2 (my example = "1") to be able to toggle the colon bit.

The Fix?

The function that drives the setting of the segments and dots is TM1637TinyDisplay::setSegments() - If you have any suggestions on how we could adjust it to handle this situation, I would love help.

For your particular use case, I would recommend making a slight change to your function that would work in both orientations, something like this:

void ShowTime(uint8_t _mins, uint8_t _secs, bool _Colon, bool _zns) {
    int output = _secs + (100 * _mins);
    display.showNumberDec(output, 0b01000000 * _Colon, _zns);
}

Alternatively, since there is only one "colon" the the display, you could cheat and force a colon set for all digits:

void ShowTime(uint8_t _mins, uint8_t _secs, bool _Colon, bool _zns) {
    display.showNumberDec(_mins, 0b11110000 * _Colon, _zns, 2, 0);
    display.showNumberDec(_secs, 0b11110000 * _Colon, true, 2, 2);
}

@stef-ladefense
Copy link
Contributor Author

thank
the 1st dont work, colon work but zns dont, for 0mn et 5s : __:_5
the 2th not colon with flip

I need to think about how to send it
I will need time to dissect the setSegments routine and see how the points are transmitted and how to make the distinction with colon

@jasonacox
Copy link
Owner

Ah, yes, you are correct! Sorry about that.

Here is a possible workaround, not elegant but works:

void ShowTime3(uint8_t _mins, uint8_t _secs, bool _Colon, bool _zns) {
  char output[MAXDIGITS+1];
  if(_zns) sprintf(output, "%02d%02d", _mins, _secs);
  else sprintf(output, "%2d%02d", _mins, _secs);
  display.showString(output, 4, 0, 0b01000000 * _Colon);
}

I'll see if there is something more we can do to setSegments() to make this more intuitive.

@jasonacox
Copy link
Owner

The challenge is really caused by the approach of using direct address writes (position and length) to the display. If we were to use a intermediate memory buffer (e.g. digits[]) for manipulation of the display so that showNumber(), etc., calls just update the buffer and then always write the full buffer to the display, we would be able to control the decimal/colon flip. It is a bit of a rewrite but could be worth it. I doubt it would introduce much latency and could likely reduce some code. I'll run some tests.

@jasonacox
Copy link
Owner

Hi @stef-ladefense - I created a test class (TM1637TinyDisplayB) using my buffer idea. It seems to work well but I plan to run more tests. It works with your original ShowTime() function. I would love your thoughts on this.

#include <TM1637TinyDisplayB.h>
TM1637TinyDisplayB display(CLK, DIO);

void setup() {
  display.setBrightness(BRIGHT_HIGH);
  display.clear();
}

void ShowTime(uint8_t _mins, uint8_t _secs, bool _Colon, bool _zns) {
  display.showNumberDec(_mins, 0b01000000 * _Colon, _zns, 2, 0);
  display.showNumber(_secs, true, 2, 2);
}

void loop() {
  display.flipDisplay(false);
  display.showNumber(1234);
  delay(5000);
  display.flipDisplay(true);  // with flip will render w/o redraw
  delay(5000);

  ShowTime(0, 5, true, false);
  delay(5000);

  ShowTime(0, 5, true, true);
  delay(5000);
}

@stef-ladefense
Copy link
Contributor Author

i test your B
it's work with flip for me!
like this new approach !

@stef-ladefense
Copy link
Contributor Author

question
how to mix a string to display a text (showString) with a patern on a specific character?

@jasonacox
Copy link
Owner

Thanks @stef-ladefense ! The tests all look good for me too so I'm going to fold it into TM1637TinyDisplay and TM1637TinyDisplay6 and release it to Arduino, along with your brightness update.

For the string question, are you talking about sending a specific pattern not in the string dictionary? If so, you would use setSegments() for the new pattern:

uint8_t data[] = { 0x03, 0x18, 0x0c, 0x21 };
display.setSegments(data)

If you wanted a mix, you can use the position and length and position parameters:

  uint8_t data[] = { 0x2a, 0x00, 0x00, 0x00 };
  display.showString("YES ");
  display.setSegments(data, 1, 3);

You can use this tool to get the codes for the pattern: https://jasonacox.github.io/TM1637TinyDisplay/examples/7-segment-animator.html

image

@stef-ladefense
Copy link
Contributor Author

yes I know that, but what bothers me is having to declare a data[] variable of 4 bytes to be able to use setSegments.
so I made a other definition of setSegments as follows:

in .h
void setSegments(const uint8_t A, uint8_t pos = 0);

in .cpp
void TM1637TinyDisplayB::setSegments( uint8_t A, uint8_t pos) {
digitsbuf[pos] = A;  
writeBuffer();
}

which allows me to write a byte of segments wherever I want

@stef-ladefense stef-ladefense reopened this Aug 1, 2022
@jasonacox
Copy link
Owner

Great suggestion! I'll add it.

jasonacox added a commit that referenced this issue Aug 1, 2022
@jasonacox jasonacox added the bug Something isn't working label Aug 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants