Code to have a switch toggle between four LED's

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off, I did do a search but couldn't find any answers or code to figure out exactly how to do this.
Specifically I have an atmega2560 that is using one port for reading switches and two ports for setting LED's. The switches and LED's are all on their own pins.. no multiplexing or anything.

The (4) switches are on Port A
The (16) LED's are on Ports B & C

Each switch is to be mapped to a group of (4) LED's so when the the switch is pressed it will cylce through them.

I guess I could have the program check the switches every 10ms or so using a timer...and then write code to check each of the four pins and set the LED's.
I'm new to microcontrollers so any help with an efficient approach to the main program code would be great.

#define F_CPU 16000000UL

#define SW_PORT_GROUP1 PORTA
#define SW_PIN_GROUP1 PINA
#define SW_DDR_GROUP1 DDRA

#define LED_PORT_GROUP1 PORTB      /* LED Ports */
#define LED_PORT_GROUP2 PORTC
#define LED_DDR_GROUP1 DDRB       
#define LED_DDR_GROUP2 DDRC

#define LED1 0     //PB0
#define LED2 1     //PB1
#define LED3 2     //PB2
#define LED4 3     //PB3
#define LED5 4     //PB4
#define LED6 5     //PB5
#define LED7 6     //PB6
#define LED8 7     //PB7
#define LED9 0     //PC0
#define LED10 1	   //PC1
#define LED11 2    //PC2
#define LED12 3	   //PC3
#define LED13 4    //PC4
#define LED14 5    //PC5
#define LED15 6    //PC6
#define LED16 7    //PC7
#define SW1 0      //PA0
#define SW1 1      //PA1
#define SW2 2      //PA2
#define SW3 3      //PA3

main (void)
{
//Initializations	
LED_DDR_GROUP1 = 0xFF;    //PORTB set as outputs
LED_DDR_GROUP2 = 0xFF;    //PORTC set as outputs
LED_PORT_GROUP1 = 0x0;    // LED's initialized to OFF (they are active high)
LED_PORT_GROUP2 = 0x0;   
SW_DDR_GROUP1 = 0xFF      //PORTA set as inputs

Main Loop.....
Check pin0 on Port A, if changed toggle through LED's on Port B bits 0 through 3.
Check pin1 on Port A, if changed toggle through LED's on Port B bits 4 through 7.
Check pin2 on Port A, if changed toggle through LED's on Port C bits 0 through 3.
Check pin3 on Port A, if changed toggle through LED's on Port C bits 4 through 7.
}
Last Edited: Wed. Jan 22, 2014 - 11:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

SW_DDR_GROUP1 = 0xFF //PORTA set as inputs

0x00 not 0xFF for inputs (it's the default anyway).

Remember that when reading inputs it's PINA not PORTA you use. For output it will be PORTB and PORTC you write to.

To be honest, for early experiments I'm not sure it actually helps to wrap everything up in macros. Just a simple:

int main(void) {
  DDRA = 0x00; // inputs
  DDRB = 0xFF; // outputs
  DDRC = 0xFF; // outputs
  PORTA = 0xFF; // enable pull-ups on input switches
  while (1) {
    if (PINA != 0xFF) { // something pressed
      PORTB = 0xFF;
      PORTC = 0xFF;
    }
    else {
      PORTB = 0x00;
      PORTC = 0x00;
    }
  }
}

That should be enough that all the LEDs change state as long as any button is held. This does rely on the buttons normally being open circuit and connecting to Gnd when they are closed. When open it's the pull-ups in the AVR that will make them read '1'. When pressed the direction to Gnd will over-ride the pull-up and they will read '0'.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...ok thanks for the input!
the four switches actually 'each' toggle four LED's.. so there's four LED banks (16) LED's in all...

Your input helps, I think I can see what I need to do.
1) Set a timer to check switches every few ms
2) Check PINA four times... each time masking all the other bits except the one I'm intersted in.... then each time update the LED banks.
(I also need some sort of debounce routine in there)

does this sound logical?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Friend if you are new to the micro controllers then try the basic programs, which will help u make good use of syntax. Step by step. i am sure u will enjoy.
Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

the four switches actually 'each' toggle four LED's..

In that case the trick is to remember state. Have variable for each switch which records whether it is "on" or "off". Each time you see the switch activated you toggle that state. The ^ (XOR) operator is good for doing toggle operations.
Quote:

1) Set a timer to check switches every few ms

You probably want to do that anyway. Mechanical switches suffer from an issue called contact bounce so that each time they are operated there's actually about 10-20 on-off or off-on events seen in quick succession until the switch settles into a constant state. If you were going to toggle on each transition within a few milliseconds the switch might go off-on-off-on-off-on-off and just ended up back where it started (if an odd number of transitions were seen). So you have to program to avoid the effects of bounce (google "ganssle bounce" to learn more). The technique used will usually involve a timed process that samples the switch state every few milliseconds and only consider the switch to have made a transition into a definite new state when the same condition has been seen for several samples.

A very common technique is to set up a timer to interrupt every few milliseconds to do all this. Almost as a separate process from your main code (interrupts effectively lead to multitasking) this will watch the inputs and keep as an output a definitive indication of which state they are in (and possibly if that's just changed). You can then poll this shared variable in your main loop to know if any switch has made a transition and, if it has, toggle that bank of LED's state.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At the best use a readymade debouncing lib.
And then the rest was easy:

#include 
#include "getkey.h"

uint8_t toggle[4];

int main()
{
  get_key_init();
  sei();
  
  DDRB = 0xFF;
  DDRC = 0xFF;
  
  for(;;){
    if( get_key_press( 1<<KEY0 )){
      if( ++toggle[0] >= 4 )
        toggle[0] = 0;
    }
    if( get_key_press( 1<<KEY1 )){
      if( ++toggle[1] >= 4 )
        toggle[1] = 0;
    }
    if( get_key_press( 1<<KEY2 )){
      if( ++toggle[2] >= 4 )
        toggle[2] = 0;
    }
    if( get_key_press( 1<<KEY3 )){
      if( ++toggle[3] >= 4 )
        toggle[3] = 0;
    }
    PORTB = 1<<toggle[0] | 0x10<<(toggle[1]);
    PORTC = 1<<toggle[2] | 0x10<<(toggle[3]);
  }
}

Peter

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi

i am new to avr microcontrollers , i am having a problem with code of atmega32. with my code i want that led should glow when switch is closed and not golw when switch is open. my code is-

 

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
 DDRB=0b00000001;
 DDRC=0b00000000;
 
 while(1)
 {
  if(PINC & 0b00000001)
   PORTB |= 0b00000001;
   else
   PORTB &= 0b00000000;
  }
  
  return 0;
  }

led glows when i closes the switch. but then when i again opens my switch led is not turning off. i dont know what is the problem.........

please help me....

NITAI

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

vashisht, next time you have a question please start your own new thread.  Your post has nothing to do with the topic of this thread.  Now that we have that covered we can move forward.

 

Welcome to the forum.

 

EDIT: Deleted sleep deprivation caused nonsense.

 

I think your circuit is wired incorrectly.  Show us a schematic.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sat. Feb 14, 2015 - 07:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

larryvc wrote:

When you bitwise AND any value with 0, the value remains unchanged.


Anything AND 0 is 0.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

christop wrote:
Anything AND 0 is 0.

I really need to stop answering posts in the wee hours of the night.blush Fixed!

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sat. Feb 14, 2015 - 07:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's how I understand the spec. 4 buttons, 16 leds. Press any button and hold. 4 of the leds light every 250ms 1-2-3-4 in a loop until the button is released. No debounce required. Just see if switch is pressed and 250ms oneshot is on and light the next led. Release switch, leds out. Repeat for 4 buttons. Am I on the right wave length?

Imagecraft compiler user