Notifications
Clear all

I fell in love with the LED & KEY board

120 Posts
7 Users
19 Likes
38.1 K Views
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

If that inline function is just reversing the boolean value, why wouldn't the following code work instead?

case 1:
Serial.println("Switch 1 was pressed");
if (!button_1)
{
toggleButton(0xc0, 0x06);
}
else
{
toggleButton(0xc0, 0x00);
}
break;

 

 


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  
Posted by: @pugwash

@robo-pi

If that inline function is just reversing the boolean value, why wouldn't the following code work instead?

case 1:
Serial.println("Switch 1 was pressed");
if (!button_1)
{
toggleButton(0xc0, 0x06);
}
else
{
toggleButton(0xc0, 0x00);
}
break;

That doesn't toggle the button_1 boolean variable.

In fact, I just tried it on the actual board.  The code you have posted above will turn the numeral 1 ON the first time button 1 is pressed, but then it's on for good.  A second press of button 1 won't turn it back off again.

You need to actually update the value of the button_1 variable.  Your code above isn't updating the variable to the opposite value it previously had.  So it won't toggle.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

As we are toggling the buttons in the switch case conditional then I would probably change toggleButton() to setRegister(), it is a better function description.

This should solve the button turning off, perhaps????

case 1:
Serial.println("Switch 1 was pressed");
if (!button_1)
{
toggleButton(0xc0, 0x06);
button_1 = !button_1;
}
else
{
toggleButton(0xc0, 0x00);
button_1 = !button_1;
}
break;

 

Which is just another way of skinning the same cat ?

Your initial method is just as valid.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

I am really verbose today!

case 1:
Serial.println("Switch 1 was pressed");
if (!button_1)
{
toggleButton(0xc0, 0x06);
}
else
{
toggleButton(0xc0, 0x00);
}
button_1 = !button_1; 
break;

   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  

I would prefer to toggle the button first and then use direct logic for the following if statement.  This is because the button_1 variable is set to false initially at the beginning of the program before setup.  So the first time through it will toggle from false to true, and then the logic that follows can be straight-forward instead of reversed.

Posted by: @pugwash

case 1:
Serial.println("Switch 1 was pressed");
button_1 = !button_1;
if (button_1)
{
toggleButton(0xc0, 0x06);
}
else
{
toggleButton(0xc0, 0x00);

break;

The other thing that might do well for this example program is to use two calls to two different methods.

Call them functionOn() and functionOff().

Because the main idea of this sample code is to use the buttons to turn things on and off.  The user can then rename their methods accordingly.  For example.

roomLightsOn()

roomLightsOff()

Or whatever it is they are using the buttons to control.

And of course if they don't want the buttons to toggle they can change the code accordingly.  Just remove or comment-out the button_n = !button_n line. Then just have one method called each time the button is pressed.   Like if you need to have a button increment something with every press.   Then if you want to decrement down you'd need to use a second button.

The main idea of this sketch is to just get the things up and running.   It can no doubt be written better as a basic framework.  Maybe I'll work on that later if I can find time.

I just thought I'd share what I did in case anyone else was having trouble trying to figure out how to detect which button is press and use that in a practical way.  But yeah, this can be improved upon for sure.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

Have you seen this?

I agree with Julian Ilett that the datasheet is a real mess!

I have searched the internet to find a full register description, to no avail. Have you found one?

Apparently the TM1638 was originally a 64 LED controller that has been bastardised to something else. There must be a list of registers somewhere. What I like to do is read all the register values into an array on the Arduino and then write them ALL back when a value changes. I did this with a real-time clock, somewhere else on this forum, to avoid using libraries.

If you have found anything like a register list, I would be very grateful if you could share it. The alternative would be to dig out software that addresses the LEDs, seven-segment displays and buttons, and try to decipher the register addresses and contents.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

I think I am barking up the wrong tree i.e. I haven't understood the concept of this unit.

I started wondering when I noticed that in the switch/case routine i.e. 0xc1, 0xc3, 0xc5 etc. were not being used/addressed.

Have to go and look at some more explanations before THIS sinks in!


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  
Posted by: @pugwash

I agree with Julian Ilett that the datasheet is a real mess!

The datasheet could be better.  I won't argue with that.  But keep in mind that the data sheet is just for the TM1638 chip, and not this whole board.  There are actually quite a few different display boards that use the TM1638 chip.

I watched Julian's video but I found the article I linked to in an earlier post to be much more useful

Using a TM1638 based board with Arduino

Posted by: @pugwash

I started wondering when I noticed that in the switch/case routine i.e. 0xc1, 0xc3, 0xc5 etc. were not being used/addressed.

Those addresses are for the LEDs directly above the 7-seg displays.

All the even addresses address the 7-seg displays.  All the odd addresses address the LED's above the displays.  So addressing them is simple.  Just start with either c0 and add 2 every time to address the next 7-seg display, or start with c1 and add 2 every time to address the next LED.

Posted by: @pugwash

If you have found anything like a register list, I would be very grateful if you could share it.

I don't think you need to know the register addresses.  Instead the first byte you send is a command.  So it just goes to the command register automatically.  Therefore you don't need to know the actual address of that register.   The first byte sent  is a command.  That's all you need to know.

There are 4 commands:

Commands

Command 0x8? sets the display brightness. The the question mark represents the last three bits that can be anything from 0 to 7 and will determine how bright the display is.

Command 0x44 allows you to address single addresses (one 7-seg display or one LED at a time directly) The data following this command must be of the form (address : data) which is two bytes, and you can keep sending two byte pairs as long as you wish as long as the strobe remains low.

Command 0x40 increments the addresses for you.  So the first byte you send after this command will be the starting address that you want to start at, and every data byte that follows will be the data for the next addressed element.   Note that when you use this command you must address every element of the display.  In other words if you start at the beginning with address c0 then the next data byte will be for the first 7-seg display and the one following that will be for the first LED, and so on.

Command 0x42 is the command to read the buttons.  You don't need to address them as all the information is sent for all the buttons automatically.  You just need to be ready to read it.  And you can see how that is done in the readButtons() method in the program I posted.

So you don't need to know any register addresses.   The first byte you send  is a command.  All the bytes after that are address and data bytes for the display elements.

The data byte for the 7-seg displays is as follows:

7 seg

That's everything you need to know.  Armed with all the above information you should be able to make the display do anything you want.

The only caveat here is that I didn't really go into details about how to read the data that comes from the buttons, but as I've said, just look at the readButton() method in the program I posted.  That does it for you.  It's reading 4 bytes at a time and then using an OR statement to decode them.  I haven't bothered to look into exactly how that works since the guy who wrote that readButtons() method already did it for me.   So I just use the buttons value he returns.   That return value is an uint8-t variable that will contain one of the following numbers for single buttons pressed

1, 2, 4, 8, 16, 32, 64, or 128 which corresponds to buttons 1 thru 8.

You can also get different numbers returned if you press more than one button at a time.   You can try that using a Serial.print(buttons) statement to see what number you get.   And then, if you want,  you can write code to react to having two buttons pressed simultaneously.

So everything I've just laid out in this post is all you need to know.  There isn't anything more to know about it.  There are no command register addresses that you need to know.   There are four commands and they are recognized as the first byte sent.   So there is probably only one command register and they all go into that and are decoded on the TM1638 chip.   You don't need to know the address for that command register.  It's just the first byte you send.  That's it.

DroneBot Workshop Robotics Engineer
James


   
Pugwash reacted
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  
Posted by: @robo-pi

Command 0x8? sets the display brightness. The the question mark represents the last three bits that can be anything from 0 to 7 and will determine how bright the display is.

Correction on the display brightness command:

The question mark represents the last nibble.   The msb of the nibble turns the display on or off.  Then the last 3 bits are the display brightness from 0 to 7.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  
Posted by: @pugwash

Apparently the TM1638 was originally a 64 LED controller that has been bastardised to something else.

It seems pretty well-designed to me.   Once  you get past the idea that every other address is either a 7-seg display or an LED it should make perfect sense.   Even address = 7-seg display.  Odd address = LED.   

That's pretty well-organized I think.  You might wonder why they didn't address the 7-seg displays consecutively and the LEDs consecutively.   But that most likely has to do with the way the chip is laid out.  It probably just made more sense to do it that way on the microchip level.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

Thank you very much for your detailed explanation!

The penny has finally dropped, I was approaching this from very much the wrong angle.

And as Julian says "it is quite easy" once you get the basic principles.

Once again, my appreciation for putting me on the right track.


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  

Happy to be of help.  By the way, I was as confused as you when I was first trying to figure out what the heck was going on.  But just like you, once I "got it", the simplicity of it all became crystal clear. I imagine this is probably the case for everyone.  So you're not alone in not getting it at first glance. 

 

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

One thing that did puzzle me was the fact that a whole register was being used to turn one LED on and off, by writing either 1 or 0 to the register. Then I came across a slightly more expensive board with both red and green LEDs. I think that each register was controlled like this:

b00 for OFF

b01 for RED

b10 for GREEN

if I understood it correctly.

Still a waste of six registers, but who cares as long as it works!


   
ReplyQuote
Robo Pi
(@robo-pi)
Robotics Engineer
Joined: 5 years ago
Posts: 1669
Topic starter  

Here's another article with example code and explanations for this display board:

Arduino Code for TM1638 Display Board

There's probably lots of examples around.

I don't have time right now to do much more with these.  I need to get back to work on real life projects. ? 

I just wanted to take a moment to learn how they work.   And now that I know that they are easy to use I placed that order for 10 more for my parts drawer for this winter.   So now I have a nice board with buttons that I know how to use.   These will definitely prove to be useful as time goes on.

I'm working on an outdoor boiler and I'm going to have it monitored and controlled with an Arduino.   So I'll need at least two of these displays for that project.  One display on the actual boiler, and the other one in my bedroom so I can see what's going on with the boiler in the middle of the night.   I can also have it sound an alarm if the temperature goes out of bounds.  Too high I need to jump out of bed and go see what's wrong.  Too low and I'll need to get up and put some more wood on the fire.

I'm also using those 433Mhz transmitter and receiver modules to communicate between the Arduino in the boiler and the Arduino in my bedroom.   So I have lots of work to do on that project.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@robo-pi

TM1638 modules have arrived and I am impressed. I ordered these on Sept 05 and they arrive from China on Sept 16.

My guess is that, as there was no postage required, they did not come by airfreight and certainly not by ship, that takes over four weeks. That leaves only one possibility, by train down the new Silk Road, which ends here in Hamburg and in Duisburg. If this is a sign of the things to come, it means that I may not have forgotten what I wanted to do with the stuff I order, during transport. ? 

Now I have the Arduino and the countdown display, I only need to source the rest of the stuff for my Arduino controlled Tactical Thermo Nuclear Weapon. ? 

So, let's get experimenting!


   
ReplyQuote
Page 2 / 8