Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16-IN-1 LEDS & BUTTONS FUN

Status
Not open for further replies.

MCU88

Member
I did this project a while back. It is basically what can be done with just 4 buttons and 4 LEDs?

Q: Anyone have any suggestions to add extra features or improve on things?

img01-jpg.91749


tableleds-buttonsfun-jpg.91752


:: Electrical Schematic ::
schematicleds-buttonsfun-jpg.91751

:: MikroC Source Code ::

Code:
// 16 in 1 LEDs 'n Buttons FUN

unsigned short nStart = 0;
unsigned short dir = 0;
unsigned short keyUp = 0;
unsigned short keyDown = 0;
unsigned short keyPress = 0;
unsigned int randomNo = 0;

unsigned short i = 0;
unsigned short j = 0;
unsigned short k = 0;
unsigned short e = 0;
unsigned short s = 0;
unsigned short simon[32]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                           0,0,0,0,0,0,0,0,0,0,0,0,0,0};


#define dSW1 PORTA.F2
#define dSW2 PORTA.F3
#define dSW3 PORTA.F0
#define dSW4 PORTA.F1

#define sw01 PORTB.F3
#define sw02 PORTB.F2
#define sw03 PORTB.F1
#define sw04 PORTB.F0

#define ld01 PORTB.F4
#define ld02 PORTB.F5
#define ld03 PORTB.F6
#define ld04 PORTB.F7


progressiveLed(int dir)
{
   i++;

   if (dir == 0)
   {
      switch (i)
      {
         case 1: ld01 = 1; break;
         case 2: ld02 = 1; break;
         case 3: ld03 = 1; break;
         case 4: ld04 = 1; break;
      }
   }
   else
   {
      switch (i)
      {
         case 1: ld04 = 1; break;
         case 2: ld03 = 1; break;
         case 3: ld02 = 1; break;
         case 4: ld01 = 1; break;
      }
   }

   if (i == 5)
   {
      i = 0;
      ld01 = 0;
      ld02 = 0;
      ld03 = 0;
      ld04 = 0;
   }

   Delay_ms(500);
}

void timer(int period)
{
   do
   { // Wait for user to press a key
   } while (sw01 == 1 && sw02 == 1 && sw03 == 1 && sw04 == 1);

   // All leds on
   ld01 = 1;
   ld02 = 1;
   ld03 = 1;
   ld04 = 1;
   
   // Timer interval
   if (period == 0)
   {
      Delay_ms(10000); // 1 min
   }
   else
   {
      delay_ms(30000); // 3 min
   }
   
   // All leds off
   ld01 = 0;
   ld02 = 0;
   ld03 = 0;
   ld04 = 0;
}

void randomLed(int decision)
{
   randomNo = rand();

   if (decision == 1)
   {
      do
      {
      } while (sw01 == 1 && sw02 == 1 && sw03 == 1 && sw04 == 1);
     
      for (j = 0; j < 10; j++)
      {
         for (i = 0; i < 4; i++)
         {
            ld01 = 0;
            ld02 = 0;
            ld03 = 0;
            ld04 = 0;

            Delay_ms(40);
         
            switch (i)
            {
               case 0: ld01 = 1; break;
               case 1: ld02 = 1; break;
               case 2: ld03 = 1; break;
               case 3: ld04 = 1; break;
            }
         
            Delay_ms(40);
         }
      }
   }

   ld01 = 0;
   ld02 = 0;
   ld03 = 0;
   ld04 = 0;

   if (randomNo <  8000)
   {
      ld01 = 1;
   }
   else if (randomNo < 16000)
   {
      ld02 = 1;
   }
   else if (randomNo < 24000)
   {
      ld03 = 1;
   }
   else
   {
      ld04 = 1;
   }
   
   if (decision == 0)
   {
      Delay_ms(500);
   }
}

void upBCDCounter()
{
   i++;
   j = (i * 16);
   PORTB = j;

   if (i > 15)
   {
      i = 0;
   }

   Delay_ms(500);
}

void dnBCDCounter()
{
   i++;
   j = (240 - (i * 16));
   PORTB = j;

   if (i > 15)
   {
      i = 0;
   }

   Delay_ms(500);
}

void onOffButtons()
{

   if (keyDown == 0)
   {
      if (sw01 == 0)
      {
         ld01 = ! ld01;
         keyDown = 1;
      }
      if (sw02 == 0)
      {
         ld02 = ! ld02;
         keyDown = 1;
      }
      if (sw03 == 0)
      {
         ld03 = ! ld03;
         keyDown = 1;
      }
      if (sw04 == 0)
      {
         ld04 = ! ld04;
         keyDown = 1;
      }
   }

   if (sw01 == 1)
   {
      if (sw02 == 1)
      {
         if (sw03 == 1)
         {
            if (sw04 == 1)
            {
               keyDown = 0;
            }
          }
       }
    }

   // Debounce period
   Delay_ms(50);
}

void momentaryButtons()
{
   Delay_ms(50); // Debounce period
   ld01 =! sw01;
   ld02 =! sw02;
   ld03 =! sw03;
   ld04 =! sw04;
}

void flasher()
{
   Delay_ms(500);
   
   ld01 = 0;
   ld02 = 0;
   ld03 = 0;
   ld04 = 0;

   Delay_ms(500);

   ld01 = 1;
   ld02 = 1;
   ld03 = 1;
   ld04 = 1;
}

void alternateFlasher()
{
   Delay_ms(500);

   ld01 = 1;
   ld02 = 1;
   ld03 = 0;
   ld04 = 0;

   Delay_ms(500);

   ld01 = 0;
   ld02 = 0;
   ld03 = 1;
   ld04 = 1;
}


void ledChaser(int dir)
{
   if (i == 0)
   {
      if (dir == 0)
      {
         j = 16;
      }
      else
      {
         j = 128;
      }
   }
   else
   {
      if (dir == 0)
      {
         j = j << 1;
      }
      else
      {
         j = j >> 1;
      }
   }

   i++;
   PORTB = j;

   if (i == 4)
   {
      i = 0;
   }

   Delay_ms(500);
}

void ledScanner()
{
   if (i == 3)
   {
      i = 0;
      dir++;

      if (dir == 2)
      {
         dir = 0;
      }
   }

   if (nStart == 0)
   {
      j = 16;
      nStart = 1;
   }

   PORTB = j;

   if (dir == 0)
   {
      j = j << 1;
   }
   else
   {
      j = j >> 1;
   }

   Delay_ms(250);
   i++;
}

void simonSays()
{

   ld01 = 0;
   ld02 = 0;
   ld03 = 0;
   ld04 = 0;

   for (e = 0; e < k; e++)
   {
      randomNo = rand();

      if (randomNo <  8000)
      {
         ld01 = 1;
         simon[e] = 1;
      }
      else if (randomNo < 16000)
      {
         ld02 = 1;
         simon[e] = 2;
      }
      else if (randomNo < 24000)
      {
         ld03 = 1;
         simon[e] = 3;
      }
      else
      {
         ld04 = 1;
         simon[e] = 4;
      }

      Delay_ms(1000);

      ld01 = 0;
      ld02 = 0;
      ld03 = 0;
      ld04 = 0;

      Delay_ms(1000);

   }

   // User to repeat
   for (e = 0; e < k; e++)
   {
      do
      {
         if (keyDown == 0)
         {
            if (sw01 == 0)
            {
               j = 1;
               ld01 = 1;
               keyDown = 1;
            }
            if (sw02 == 0)
            {
               j = 2;
               ld02 = 1;
               keyDown = 1;
            }
            if (sw03 == 0)
            {
               j = 3;
               ld03 = 1;
               keyDown = 1;
            }
            if (sw04 == 0)
            {
               j = 4;
               ld04 = 1;
               keyDown = 1;
            }
         }

         if (keyDown == 1)
         {
            if (sw01 == 1)
            {
               if (sw02 == 1)
               {
                  if (sw03 == 1)
                  {
                     if (sw04 == 1)
                     {
                        keyDown = 0;
                        keyPress = 1;

                        ld01 = 0;
                        ld02 = 0;
                        ld03 = 0;
                        ld04 = 0;
                     }
                  }
               }
            }
         }
      } while (keyPress == 0);

      keyPress = 0;
      Delay_ms(200);
     
      if (simon[e] != j)
      {
         if (j != 0)
         {
            for (s = 0; s < 5; s++)
            {
               Delay_ms(500);
               ld01 = 1;
               ld02 = 1;
               ld03 = 1;
               ld04 = 1;

               Delay_ms(500);
               ld01 = 0;
               ld02 = 0;
               ld03 = 0;
               ld04 = 0;
            }
         }
         k = 0;
         break;
      }
      j = 0;
   }
   k++;
}

void main()
{

  // Configuration of ports etc ...

  CMCON      = 7;       // Disable analog comparators
  TRISA      = 0x0F;    // 4 inputs 4 outputs
  TRISB      = 0x0F;    // 4 inputs 4 outputs
  PORTA      = 0x00;    // Init port, all pins low
  PORTB      = 0x00;    // Init port, all pins low

  while(1)
  {
     if (dSW1 == 1 && dSW2 == 1 && dSW3 == 1 && dSW4 == 1)
     {
        momentaryButtons();
     }
     else if (dSW1 == 0 && dSW2 == 1 && dSW3 == 1 && dSW4 == 1)
     {
        ledChaser(0);
     }
     else if (dSW1 == 1 && dSW2 == 0 && dSW3 == 1 && dSW4 == 1)
     {
        ledChaser(1);
     }
     else if (dSW1 == 0 && dSW2 == 0 && dSW3 == 1 && dSW4 == 1)
     {
        ledScanner();
     }
     else if (dSW1 == 1 && dSW2 == 1 && dSW3 == 0 && dSW4 == 1)
     {
        onOffButtons();
     }
     else if (dSW1 == 0 && dSW2 == 1 && dSW3 == 0 && dSW4 == 1)
     {
        upBCDCounter();
     }
     else if (dSW1 == 1 && dSW2 == 0 && dSW3 == 0 && dSW4 == 1)
     {
        dnBCDCounter();
     }
     else if (dSW1 == 0 && dSW2 == 0 && dSW3 == 0 && dSW4 == 1)
     {
        randomLed(0);
     }
     else if (dSW1 == 1 && dSW2 == 1 && dSW3 == 1 && dSW4 == 0)
     {
        progressiveLed(0);
     }
     else if (dSW1 == 0 && dSW2 == 1 && dSW3 == 1 && dSW4 == 0)
     {
        progressiveLed(1);
     }
     else if (dSW1 == 1 && dSW2 == 0 && dSW3 == 1 && dSW4 == 0)
     {
        simonSays();
     }
     else if (dSW1 == 0 && dSW2 == 0 && dSW3 == 1 && dSW4 == 0)
     {
        randomLed(1); // Decision Maker
     }
     else if (dSW1 == 1 && dSW2 == 1 && dSW3 == 0 && dSW4 == 0)
     {
        timer(0);
     }
     else if (dSW1 == 0 && dSW2 == 1 && dSW3 == 0 && dSW4 == 0)
     {
        timer(1);
     }
     else if (dSW1 == 1 && dSW2 == 0 && dSW3 == 0 && dSW4 == 0)
     {
        flasher();
     }
     else if (dSW1 == 0 && dSW2 == 0 && dSW3 == 0 && dSW4 == 0)
     {
        alternateFlasher();
     }
  }
}

Best Regards,

Trent Jackson
 

Attachments

  • img01.jpg
    img01.jpg
    231.1 KB · Views: 592
  • img02.jpg
    img02.jpg
    190.4 KB · Views: 247
  • schematicLeds&ButtonsFUN.jpg
    schematicLeds&ButtonsFUN.jpg
    152 KB · Views: 471
  • tableLeds&ButtonsFUN.jpg
    tableLeds&ButtonsFUN.jpg
    128.1 KB · Views: 515
If you want to revise it...
Move LEDs to PORTA and put all the push buttons & DIP switch on PORTB. Set /RBPU to 0 (enable weak pull-ups) and get rid of the eight pull-up resistors.
Omit the crystal and its caps, use the internal 4MHz oscillator.
Diode D2 is unnecessary since you have D1
Lower the reset button's pull-up to ~22K
Options: Use the spare 3 PORTA pins for more LEDs or a buzzer.
 
If you want to revise it...
Move LEDs to PORTA and put all the push buttons & DIP switch on PORTB. Set /RBPU to 0 (enable weak pull-ups) and get rid of the eight pull-up resistors.
Omit the crystal and its caps, use the internal 4MHz oscillator.
Diode D2 is unnecessary since you have D1
Lower the reset button's pull-up to ~22K
Options: Use the spare 3 PORTA pins for more LEDs or a buzzer.
Thanks buddy for the feedback & suggestions. I like them ;)

I agree there is no need for D2. Just habit on my part... And it would not work either since D1 prevents D2 from sinking current.

Can you explain to me how to enable weak internal pull-up resistors in mikroC? Also the internal oscillator can you give an example of this too. Much appreciated ;)

Why not the 100K instead 22K for MCLR? I have never had any dramas using 100K. Seems like the higher you go the better right? (less current used) I have gotten away with using 1M ohm pull-up / down resistors for CMOS ICs. No problems whatsoever. The projects all work.

Kind regards,

Trent Jackson
 
Why not the 100K instead 22K for MCLR? I have never had any dramas using 100K. Seems like the higher you go the better right? (less current used) I have gotten away with using 1M ohm pull-up / down resistors for CMOS ICs. No problems whatsoever. The projects all work.
Not a problem for display-less systems.... If I use any more than a 10k the boot time is too long and the LCD display shows uninitialized screen for a small while... It doesn't look good!!

The small reset cap inside the MCLR circuit needs charging to above brownout... 100k just gets there longer!
 
Not a problem for display-less systems.... If I use any more than a 10k the boot time is too long and the LCD display shows uninitialized screen for a small while... It doesn't look good!!

The small reset cap inside the MCLR circuit needs charging to above brownout... 100k just gets there longer!
OK I am convinced. I start and use 10K...
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top