Notifications
Clear all

I fell in love with the LED & KEY board

120 Posts
7 Users
19 Likes
32.2 K Views
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  

I have a couple projects I'm working on that I needed to have both highly visable display output and a few function buttons.  I was going to design my own board and then I ran across these:

 

Boy are these nice!  They have 8 LEDs across the top.  And eight 7-segement displays.   And across the bottom they have 8 push button switches.

I bought two of these to experiment with @ $1.80 a piece.  I just got done programming one (or I should say that I programmed an Arduino UNO to send and receive data from one of these boards) and I can tell you they are extremely easy to use.  And very readable.   I got so excited I just ordered 10 more of them for $13.50 with free shipping.    That's only $1.35 a piece.  You'd be hard-pressed to try to build anything similar using only $1.35 worth of parts.   So these are super fantastic to have in my parts drawer.   I'm sure I'll be using these everywhere and probably end up wanting to order even more. ? 

DroneBot Workshop Robotics Engineer
James


   
Pugwash reacted
Quote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

I could see some uses for a few of those!

Would you care to share your sourcing link?


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  
Posted by: @pugwash

Would you care to share your sourcing link?

10 pcs Key Display TM1638 module - AliExpress

I buy a lot of stuff from AliExpress and haven't been disappointed yet.  These can be found on eBay too but they are closer to $3 to $4 a piece there.  On Amazon they go for $6 to $7 a piece.   So at $1.35 a piece I just can't ignore AliExpress. ? 

When you're buying 10 pieces at a time to fill up a parts drawer the price per board becomes highly relevant.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  

Here's a nice article that explains how to use them along with sample code that can be pasted directly into the Arudino IDE.  The article explains how to address and set all the LEDs and 7-seg displays individually, as well as including a short piece of code that detects which buttons have been pressed.

Using a TM1638 based board with Arduino

DroneBot Workshop Robotics Engineer
James


   
Chrissy reacted
ReplyQuote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

@robo-pi

I agree with you James, can't resist this sort of stuff. Already ordered!

My wallet is suffering severely today, already ordered some NRF24Lo1s. I must stop watching the Brexit debate on TV, it seems that every time John Bercow shouts "ORDAHHH", I buy something!

I think I may be getting something wrong here ? ? ? ? ? 


   
ReplyQuote
Spyder
(@spyder)
Noble Member
Joined: 4 years ago
Posts: 927
 
Posted by: @pugwash

every time John Bercow shouts "ORDAHHH", I buy something!

Somehow I don't think he's speaking directly to you when he says that


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  

I just wrote a simple program for this display.  All it does is light up a numeral on a 7-seg display that corresponds to a button that is pushed.  Push the button once and the number of the button shows on the display.  Push the button again and the display goes dark.

It's just a little program to demonstrate how to map each button to a particular method.  Instead of having the buttons turn these displays on and off just replace the display on/off code with a call to a method you want the button to activate.  You can also use the button_x booleans I defined at the top of the code to keep track of whether a particular function is on or off.

By the way I'm sure this code could be cleaned up and made more succinct, but I thought I'd leave it as-is for demonstration purposes.

 

// LED_KEY_Buttons_V1.ino

// UNO pins for the LED&KEY board control
const int strb = 8;
const int clk = 10;
const int data = 9;

// Booleans to keep track of button functions 
bool button_1 = false;
bool button_2 = false;
bool button_3 = false;
bool button_4 = false;
bool button_5 = false;
bool button_6 = false; 
bool button_7 = false;
bool button_8 = false;

 
void sendCommand(uint8_t value)
{
  digitalWrite(strb, LOW);
  shiftOut(data, clk, LSBFIRST, value);
  digitalWrite(strb, HIGH);
}
 
void setup()
{
  pinMode(strb, OUTPUT);
  pinMode(clk, OUTPUT);
  pinMode(data, OUTPUT);
  Serial.begin(9600);
  sendCommand(0x88);  // activate and set brightness to low (change to 0x8f for full brightness)
  reset();
}
void loop()
{
// Continually scan the buttons.
  uint8_t buttons = readButtons();
  
    if (buttons != 0)
    {
      // Call the method that determines what to do for each button.
      Button_Pressed(buttons);
      delay(250); // Used to prevent double bounce.
    }

  }


void Button_Pressed(uint8_t buttons)
{
  switch (buttons)
  {
    case 1:
    Serial.println("Switch 1 was pressed");
    if (button_1 ? button_1 = false : button_1 = true){}
    if (button_1)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc0); // Address of 1st digit
      shiftOut(data, clk, LSBFIRST, 0x06); // Numeral 1
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc0); // Address of 1st digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 2:
    Serial.println("Switch 2 was pressed");
    if (button_2 ? button_2=false : button_2=true){}
    if (button_2)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc2); // Address of 2nd digit
      shiftOut(data, clk, LSBFIRST, 0x5b); // Numeral 2
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc2); // Address of 2nd digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 4:
    Serial.println("Switch 3 was pressed");
    if (button_3 ? button_3 = false : button_3 = true){}
    if (button_3)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc4); // Address of 3rd digit
      shiftOut(data, clk, LSBFIRST, 0x4f); // Numeral 3
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc4); // Address of 3rd digit
      shiftOut(data, clk, LSBFIRST, 0x00); // off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 8:
    Serial.println("Switch 4 was pressed");
    if (button_4 ? button_4 = false : button_4 = true){}
    if (button_4)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc6); // Address of 4th digit
      shiftOut(data, clk, LSBFIRST, 0x66); // Numeral 4
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc6); // Address of 4th digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 16:
    Serial.println("Switch 5 was pressed");
    if (button_5 ? button_5 = false : button_5 = true){}
    if (button_5)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc8); // Address of 5th digit
      shiftOut(data, clk, LSBFIRST, 0x6d); // Numeral 5
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xc8); // Address of 5th digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 32:
    Serial.println("Switch 6 was pressed");
    if (button_6 ? button_6 = false : button_6 = true){}
    if (button_6)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xca); // Address of 6th digit
      shiftOut(data, clk, LSBFIRST, 0x7d); // Numeral 6
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xca); // Address of 6th digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 64:
    Serial.println("Switch 7 was pressed");
    if (button_7 ? button_7 = false : button_7 = true){}
    if (button_7)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xcc); // Address of 7th digit
      shiftOut(data, clk, LSBFIRST, 0x07); // Numeral 7
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xcc); // Address of 7th digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
    case 128:
    Serial.println("Switch 8 was pressed");
    if (button_8 ? button_8 = false : button_8 = true){}
    if (button_8)
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xce); // Address of 8th digit
      shiftOut(data, clk, LSBFIRST, 0x7f); // Numeral 8
      digitalWrite(strb, HIGH);    
    }
    else
    {
      digitalWrite(strb, LOW);
      shiftOut(data, clk, LSBFIRST, 0xce); // Address of 8th digit
      shiftOut(data, clk, LSBFIRST, 0x00); // Off
      digitalWrite(strb, HIGH);      
    }
    break;
  } 
}

void reset()
{
  sendCommand(0x40); // set auto increment mode
  digitalWrite(strb, LOW);
  shiftOut(data, clk, LSBFIRST, 0xc0);   // set starting address to 0
  for(uint8_t i = 0; i < 16; i++)
  {
    shiftOut(data, clk, LSBFIRST, 0x00);
  }
  digitalWrite(strb, HIGH);
}

// This routine returns the values of the buttons.
  uint8_t readButtons(void)
{
  // Initialize to zero.
  uint8_t buttons = 0;
  digitalWrite(strb, LOW);
  // Send command to read buttons
  shiftOut(data, clk, LSBFIRST, 0x42); 
  // Prepare to INPUT data
  pinMode(data, INPUT); 

 // Read in four bytes
  for (uint8_t i = 0; i < 4; i++)
  {
    // The following data is shifted i times to the right.
    uint8_t v = shiftIn(data, clk, LSBFIRST) << i;
    // put the results into the buttons variable
    buttons |= v;
  }
  // Change the pinmode back as OUTPUT for normal operation
  pinMode(data, OUTPUT);
  // Bring the strobe back to high
  digitalWrite(strb, HIGH);
  return buttons;
}

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

@robo-pi

Thanks for sharing!

If, when the boards arrive in 5 - 6 weeks time, I can still remember why I "ORDAHHH"ed them, I'll give this a shot. In the meantime, I'll try and adapt this sketch to access the other features.


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  

@pugwash

Even with the instructions I found on the Internet it still took me a while to figure out exactly what was going on with the buttons.   But now that I have this program set up I can easily use it to call any methods I want to call based on which button was pressed.  So at this point I'm ready to move forward and implement it into an actual project.

I didn't include the LEDs above the 7-seg displays.   But they are really easy to implement as well.  It's just every other address.  All the even addresses are the 7-seg displays and all the odd addresses are the LEDs.

So at this point I feel that I have full control over this display board.  I should probably code one of the buttons to step through the display brightness settings and just leave that button dedicated for that purpose.   That's one thing about this display, it doesn't have a light sensor to dim it automatically in a dark setting.   Of course that could be implemented through the UNO.  Just put a light sensor on the UNO and have the UNO adjust the brightness based on light levels.  This is a concern for me because my first project will be right next to my bed and I don't want a bright LED display shining in my face. ? 

So I'll probably hook up an auto display dimmer next.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

@robo-pi

I have taken the liberty of slimming the code down a bit. Have lost about 40 lines.

Can you let me know if it works? I obviously can't test it for a few weeks!


   
ReplyQuote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

@robo-pi

I would also change the name of the reset() function as "reset" is a reserved word.


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  

@pugwash

Yep, it works just fine. ? 

I'm sure there are even more clever ways to reduce the code.  I was thinking more along the lines of calculating the addresses and 7-seg values based on the button number.   But that would get a little more involved.  Especially calculating the 7-seg values. That's probably better left for a data table.

But the reason I left the code in the form I did was so that people can easily see where they can place their calls to the methods they want the buttons to run.   And they can even have a button toggle a particular method on and off.   Of course  your modification makes this even more clear since you are already calling a method in each case. All they need to do now is replace your calls to toggleButton to point to the methods they want to call.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  
Posted by: @pugwash

@robo-pi

I would also change the name of the reset() function as "reset" is a reserved word.

Agreed.  I didn't write that routine.  That was already in the example I was modifying.  In fact, whoever wrote the original code used a lot of keywords as variables and I did change all those.  You can actually get away with that because reset() is not keyword.   reset is the keyword.   So using reset() as a function name works.

But you're right. It's not a good practice to use keywords as arbitrary function names.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Pugwash
(@pugwash)
Noble Member
Joined: 4 years ago
Posts: 1012
 

@robo-pi

if (button_1 ? button_1 = false : button_1 = true){}

Was this also a leftover from the original sketch or did you have something in mind?


   
ReplyQuote
Robo Pi
(@robo-pi)
Noble Member
Joined: 4 years ago
Posts: 1909
Topic starter  
Posted by: @pugwash

@robo-pi

if (button_1 ? button_1 = false : button_1 = true){}

Was this also a leftover from the original sketch or did you have something in mind?

That's what makes the bool button_n variables toggle between true and false.

If you remove that line it won't work.

It looks like it isn't doing anything because there's nothing in the curly braces.   But it has already made the boolean assignments right in the conditional statement. So yeah, it won't work anymore if you remove those lines.

That statement sets button_1 to the opposite bool value it currently has.

If it comes in false (which it will the first time through), it is then updated to be true.

The next time through it will come in true, in which case it will be reset to false.

So yeah, that's my intentional code.  That has to be there to toggle the bool value of the button_n variables.

I probably should have included a comment in the code for that statement.

Edited to add:

Actually that code is overkill. You can replace it with the following code:

button_1 = !button_1;

That will do the same thing and is probably better coding.

I'm sure there are many other ways to do this as well.

I tend to do things stupidly. ?  As long as the code works I just keep on truck'in.

DroneBot Workshop Robotics Engineer
James


   
ReplyQuote
Page 1 / 8