NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Need help, is there a problem with my DIP switch?

July 15, 2012
by TheFed
TheFed's Avatar

So i finished my dip_arithmetic project and decided to expand it a little to try out my new-found knowledge of electronics.

Here's my idea: I decided that i would try represent each digit from one number with LED's (the binary ones, so like 101 would be: red-LEDoff-green), and then use the DIP switch to alternate between the two different numbers (the ones you add up).

Here's what I did:

So I attached a LED into PB1, PB2 and PB3

Then i wired my DIP switch (which has 8 switches instead of 6, like in the manual) so that additionally to: DP1 -> MCU pin 23 DP2 -> MCU pin 24 DP3 -> MCU pin 25 DP4 -> MCU pin 26 DP5 -> MCU pin 27 DP6 -> MCU pin 28

I had DP7 -> MCU pin 18 and of course wired it to the GND

Here's my code, and its the first C code i've written by myself so there's bound to be some awefull mistakes.

=============================================================================

// dip_arithmetic.c
// for NerdKits with ATmega168
// hevans@mit.edu

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

// PIN DEFINITIONS:
// 
// PC0 -- DIP SWITCH DP1
// PC1 -- DIP SWITCH DP2
// PC2 -- DIP SWITCH DP3
// PC3 -- DIP SWITCH DP4
// PC4 -- DIP SWITCH DP5
// PC5 -- DIP SWITCH DP6
//
// NOTE: (switches connects to GND when closed, otherwise
// the pin is internally pulled up through a pull-up resistor to VCC)

// declare the variables to represent each bit, of our two 3 bit numbers
  uint8_t a1;
  uint8_t a2;
  uint8_t a3;
  uint8_t b1;
  uint8_t b2;
  uint8_t b3;

  uint8_t s1; // for the switch between the two numbers (LED display)
  uint8_t n1; // the resulting number 1
  uint8_t n2; // the resulting number 2
  uint8_t result; // the sum of the 2 numbers

void led_disp1() {
   if ((a1<<2) == 4)
      PORTB |= (1<<PB1);
      else PORTB &= ~(1<<PB1);

      if ((a2<<1) == 2)
            PORTB |= (1<<PB2);
      else PORTB &= ~(1<<PB2);

      if (a3 == 1)
            PORTB |= (1<<PB3);
      else PORTB &= ~(1<<PB3);

}

void led_disp2() {
   if ((b1<<2) == 4)
            PORTB |= (1<<PB1);
      else PORTB &= ~(1<<PB1);

      if ((b2<<1) == 2)
            PORTB |= (1<<PB2);
      else PORTB &= ~(1<<PB2);

      if (b3 == 1)
            PORTB |= (1<<PB3);
      else PORTB &= ~(1<<PB3);

}

int main() {
  // start up the LCD
  lcd_init();
  lcd_home();

  // Set the 6 pins to input mode - Two 3 bit numbers  
  DDRC &= ~(1<<PC0); // set PC0 as input
  DDRC &= ~(1<<PC1);
  DDRC &= ~(1<<PC2);
  DDRC &= ~(1<<PC3);
  DDRC &= ~(1<<PC4);
  DDRC &= ~(1<<PC5);

  DDRB &= ~(1<<PB4);

  // Set the 3 pins to output mode (for the LED's)
  DDRB |= (1<<PB1); 
  DDRB |= (1<<PB2);
  DDRB |= (1<<PB3);

  // turn on the internal resistors for the pins
  PORTC |= (1<<PC0); // turn on internal pull up resistor for PA0
  PORTC |= (1<<PC1);
  PORTC |= (1<<PC2);
  PORTC |= (1<<PC3);
  PORTC |= (1<<PC4);
  PORTC |= (1<<PC5);

  while(1) {

          // (PINC & (1<<PC0)) returns 8 bit number, 0's except position PA0 which is
          // the bit we want
          // shift it back by PA0 to put the bit we want in the 0th position.

      a1 = (PINC & (1<<PC0)) >> PC0;
      a2 = (PINC & (1<<PC1)) >> PC1;
      a3 = (PINC & (1<<PC2)) >> PC2;
      b1 = (PINC & (1<<PC3)) >> PC3;
      b2 = (PINC & (1<<PC4)) >> PC4;
      b3 = (PINC & (1<<PC5)) >> PC5;

      s1 = (PINB & (1<<PB4)) >> PB4;

      n1 = (a1<<2) + (a2<<1) + (a3);
      n2 = (b1<<2) + (b2<<1) + (b3);
      result = n1 + n2;

          if (s1 == 1) 
            led_disp1();
          if (s1 == 0) 
            led_disp2();

          lcd_home();
          lcd_write_string(PSTR(" **The Math Wonder**"));
          lcd_line_two();
          lcd_write_string(PSTR("Adding:"));
          lcd_write_int16(n1);
          lcd_write_string(PSTR("+"));
          lcd_write_int16(n2);
          lcd_line_three();
          lcd_write_string(PSTR("Equals: "));
          lcd_write_int16(result);
          lcd_line_four();
          lcd_write_string(PSTR("© Fedde Hoekstra"));
  }
  return 0;
}

=============================================================================

So, thats it. Now what happens to me is that when i change from one number to the other, the LED change too, but then after a while they change back and then back again and so forth. Also if i push on the DIP switch it tends to work properly. I have rewritten my code and tried different approaches but the same thing keeps happening. So is my DIP switch partly broken or have i made some mistake in the code or in my circuit? (1 through 6 work fine).

July 15, 2012
by TheFed
TheFed's Avatar

Im going away for a week, so i cant answer any questions then...

July 15, 2012
by TheFed
TheFed's Avatar

But please do post them!

July 15, 2012
by pcbolt
pcbolt's Avatar

Hi Fedde -

Try enabling the pull-up resistor on PB4.

PORTB |= (1<<PB4);
July 15, 2012
by TheFed
TheFed's Avatar

Im sorry that i double posted this thread, will not do so in the future. And thanks pcbolt i cant believed i mist something like that. It works great now!

Post a Reply

Please log in to post a reply.

Did you know that Pulse Width Modulation (PWM) can be used to control the speed of a motor digitally? Learn more...