Closed ArnieO closed 6 months ago
Hi @ArnieO ,
For using 7-segment Common Anode LED displays you need to include TM1618Anode.h and use the TM1618Anode class.
As mentioned earlier: "I tested your chip with both a common cathode display (8 segments x 4 digits) and a common anode display (7 segments x 4 digits). Use the TM1618 class for CC and TM1618Anode for CA. Note that you need to install both classes. Also note that the default is 4 digits. I tested the 5th digit by connecting its wire to SEG5 and specified it in the constructor. I also tested using buttons."
You only need one include statement:
#include <TM1618Anode.h>
In your case you're using 5 digits, so you need to mention that when declaring the object:
TM1618Anode module(DIO_TM, CLOCK_TM , STROBE_TM, 5);
The TM16xx_setSegments example is a bit like your sketch and lights up the individual segment. The TM16xxDisplay_Print example shows how to use the familiar Arduino println() function.
Could you give it another try?
Hi @maxint-rd,
I'm still breadboarding, so I am currently testing only one display - to learn how to use your library before I move on. But thank you for the tip; I will add more digits to the declaration when I need it.
FYI, I'm running the code on an ATtiny1616, could that be an issue?
Yes, it was in the TM16xx_setSegments example I found the command to light up individual segments. But that example is a bit too complex to run directly - wo I stripped it down.
(An overview over usable commands would have been really helpful - if/when you find time to write a Wiki!)
However, changing to TM1618Anode.h
did not do the trick. Now. only segment A lights up, not B, C or D (and still not E, F, G).
You wrote: Use the TM1618 class for CC and TM1618Anode for CA. Note that you need to install both classes.
I tried both with and without including TM1618.h
, the result is the same in both cases.
So there is something here I still don't understand; my code now looks like this:
//#include <TM1618.h>
#include <TM1618Anode.h>
// GPIO I/O pins on the Arduino connected to strobe, clock, data,
#define STROBE_TM PIN_PB3 // strobe = GPIO connected to strobe line of module. PB3: Pin 8
#define CLOCK_TM PIN_PB2 // clock = GPIO connected to clock line of module PB2: Pin 9
#define DIO_TM PIN_PB1 // data = GPIO connected to data line of module PB1: Pin 10
// Constructors
TM1618Anode module(DIO_TM, CLOCK_TM , STROBE_TM);
void setup() {
module.setupDisplay(true, 7);
}
void loop() {
for (int i=0; i<=7; i++)
{
module.setSegments(1,i);
delay(200);
module.clearDisplay();
}
}
There are now control signals from TM1618 to each of the segments - so this is definitively looking better. However, there seems to be a timing issue.
This is segment A (that lights up). GRID1 is yellow, SEG1 is blue.
This is segment B, GRID2 is yellow, SEG1 is blue.
This is segment C, GRID3 is yellow, SEG1 is blue.
This is segment D, GRID4 is yellow, SEG1 is blue.
I see that short "spurious" pulse on the GRID lines a lot, you may want to look into it. It has always the same duration and appears seemingly at random times. Here it is with a bit more magnification; I measure it to around 65 ms:
To give you complete input, here are timing plots for segments E, F and G (note: changed time scale):
Apparently, it is just the setSegments
function that is not working as expected.
This code runs as it should, running through the digits 0-9 on the display:
void loop() {
for (char i = '0'; i <= '9'; i++)
{
module.setDisplayToString(&i);
delay(500);
}
}
I expected I could use module.setDisplayToDecNumber(i)
- but cannot make it work: It only shows "0" on the display. Probably me still not understanding how to use the library! 😅
https://github.com/maxint-rd/TM16xx/assets/10295178/4ee4eb60-70e3-42b5-8976-e10e628ac3d7
Hi @ArnieO , thank you for the elaborate response to illustrate your findings. Unfortunately I don't have such a nice scope. Usually I use my logical analyzer to check on the input signals (DIN, CLK, STB). If not yet analyzed the chips output, so I can't confirm that short "spurious" 65us pulse.
Good to see you got the single digits working. The setSegments should work too. I think that in your code you reversed segments and digits. For ease of use the Anode class still uses the term segments to refer to the segments of a display, even though the display anodes are connected to SEGx pins and the segments to the GRDx pins. (The TM1618Anode class transposes the SEG/GRD lines, so you don't have to do that). I think this modified version of your code should be working correctly. I changed it a bit and also added some comments to clarify:
#include <TM1618Anode.h> // this includes TM1618.h to extend the parent class with transposed segments
// GPIO I/O pins on the Arduino connected to strobe, clock, data,
#define STROBE_TM PIN_PB3 // strobe = GPIO connected to strobe line of module. PB3: Pin 8
#define CLOCK_TM PIN_PB2 // clock = GPIO connected to clock line of module PB2: Pin 9
#define DIO_TM PIN_PB1 // data = GPIO connected to data line of module PB1: Pin 10
// object declaration specifying the pinout and number of digits
TM1618Anode module(DIO_TM, CLOCK_TM, STROBE_TM, 5); // specify the number of digits connected with their anode to the SEGx pins of the TM1618
void setup() {
module.setupDisplay(true, 7); // set display mode to use 7GRID as segments, switch display on at highest brightness
}
void loop() {
module.clearDisplay(); // blank all segments of all digits
for (int i=0; i<=127; i++)
{
module.setSegments(i, 0); // show all 7 segments of digit 0, wired with anode to SEG1 (show binary count)
delay(100);
}
}
Just to be clear: the TM1618Anode class modifies the setSegment method of the parent TM1618 class by transposing GRD and SEG using a memory bitmap and writing the entire memory to the display. SEG1 becomes GRD1 and vise versa for all SEGx and GRDx. That way the methods of the TM16xx base class to write a number or a string can be used as intended, along with the extended methods such as println() from TM16xxDisplay and all examples will still work without further modification.
Please try the modified code and let me know. As soon as I have some time I will run the code with a single CA display on an ATtiny to see what it does for me. In my test I used the CH32V003. I don't have an ATtiny1616, but I do have other ATtiny's, such as the ATtiny84A and ATtiny85. Good luck!
P.S. I agree with your call to make a Wiki. While more functionality is added, the basic README becomes increasingly cluttered and lacking a clear overview of the full API.
Thank you for your kind assistance! I understand from your answer that I had misunderstood (missing documentation...) the arguments of the setSegments() function, they should be swapped compared to my previous code.
My understanding now is that the first argument to setSegments() is a byte, where:
So I modified my code like this:
void loop() {
for (int i=0; i<=7; i++)
{
module.setSegments(byte(pow(2,i)), 0);
delay(1000);
module.clearDisplay();
}
}
The 1st argument will now be 1, 2, 4, 8, 16, 32, 64, 128 - and I expect the LED segments to light up in sequence.
However, this is the result:
https://github.com/maxint-rd/TM16xx/assets/10295178/709bf712-8444-4054-8e47-4e76c38ce740
At first glance your code seems correct. The segments shown in your video are unexpected. It should show only one segment at a time. I will try your code and see if I can reproduce your findings. One moment please...
... [A few minutes later] ...
Hmm.. Time for some debugging.
The part byte(pow(2,i))
created code to large for my flash. Using this instead:
module.setSegments(1<<i, 0);
It gives the same values, but I couldn't reproduce your findings. To be continued...
Huh...
I changed to module.setSegments(1<<i, 0);
and now it works as expected!
So for some reason byte(pow(2,i))
does not give the expected result.
Your version to obtain the same (1, 2, 4, 8, ...) is easier and more elegant.
Before I close the thread: Can you help me on how to use module.setDisplayToDecNumber()
?
Thank you in advance!
So for some reason
byte(pow(2,i))
does not give the expected result.
I found the issue. The pow()
function returns a double precision float, so to be sure the conversion to byte
works as expected I need to add 0.5 first, as the calculated float could be slightly below the target value.
So this works as expected: module.setSegments(byte(pow(2,i)+0.5), 0);
Your code with bitshifting is of course far more elegant, and does not involve float mathematics. But at least I now understand why my attempt did not work.
Code size on ATtiny1616:
Often understanding why takes much time in the short run, but saves lots of future time.
Now you should find the other functions working too. I'm sorry for the lack of documentation. For now I have to refer to the function definitions in the various header files and to the various examples. Good luck with further testing and development!
BTW: On my CH32V003 the code without pow() was 7900 bytes. With pow() it jumped to 5220 bytes over the 16Kb flash limit, increase of a whopping 13704 bytes just for pow()!
Yes, there is always some learning to take away.
I updated my library, but still cannot make setDisplayToDecNumber()
work.
The display shows a zero for all values of i with the below code.
Any hint as to what I could be doing wrong here?
void loop() {
for (int i = 0; i <= 9; i++)
{
module.setDisplayToDecNumber(i,0);
delay(500);
module.clearDisplay();
}
}
OK, I figured it out. There seems to be an inconsistency between how setDisplayToString an setDisplayToDecNumber work.
While setDisplayToString works without indicating number of displays connected in the constructor, it is necessary to provide number of displays to get setDisplayToDecNumber working.
I assume the reason I got zeroes is that the default value for number of displays is different in the two cases, and I have incorrectly assumed that SEG1 line controls the least significant digit - while it is the most significant. Which is why it always showed zero.
Working code:
#include <TM1618Anode.h>
// GPIO I/O pins on the Arduino connected to strobe, clock, data,
#define STROBE_TM PIN_PB3 // strobe = GPIO connected to strobe line of module. PB3: Pin 8
#define CLOCK_TM PIN_PB2 // clock = GPIO connected to clock line of module PB2: Pin 9
#define DIO_TM PIN_PB1 // data = GPIO connected to data line of module PB1: Pin 10
// Constructors
TM1618Anode module(DIO_TM, CLOCK_TM , STROBE_TM, 1); // Last parameter is number of displays connected
void setup() {
module.setupDisplay(true, 1);
}
void loop() {
for (byte i = 0; i <= 9; i++)
{
module.setDisplayToDecNumber(i);
delay(500);
}
}
Nice to see you get working results.
Indeed, that behavior likely has to do with right-alignment of numbers versus left-alignment for strings.
In most of my own projects I use the TM16xxDisplay
class and call display.println()
to print both strings and numbers.
Many of the functions found in the base class are there to be compatible with the TM1638 library by Ricardo Batista. After restructuring the library I moved some functions to TM16xxDisplay
, including variations of setDisplayToDecNumber()
, allowing you to specify if you want leading zero's or not. For complete overview I must refer to the .h files, which include comments as a basic form of documentation.
Thank you so much for your time and attention! I have what I need now to get the code running on the display unit I showed you in an other thread.
I ordered the PCB yesterday, and realize now that I have wrong sequence on the SEGx pins: The rightmost digit is the most significant one... 😅
Not a big deal, I can compensate that in the code.
Thank you so much for your time and attention! I have what I need now to get the code running on the display unit I showed you in an other thread.
You're welcome. Thank you for your contribution to my collection. Good luck coding! (Feel free to post an update in the other thread once the LEDs are blinking your way),
I ordered the PCB yesterday, and realize now that I have wrong sequence on the SEGx pins
Been there done that... Funny how some things hide until after you click send. I ordered a PCB for a TM1637 based LED matrix, only to find out that I managed to remove the connection to a whole column of LEDs...
Running this test code on a CA 7-segment display without dot:
Segments A, B, C and D are working correctly: Segments A, B, C, D are connected to GRID1, GRID2, GRID3 and GRID4.
I get nothing on E, F or G. Segment E is connected to SEG14/GRID5 pin Segment F is connected to SEG13/GRID6 pin Segment G is connected to SEG12/GRID7 pin
Checked with oscilloscope: Nothing on those 3 outputs.
Am I doing something wrong here?