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 » Hexadecimal Code Switch - How to

April 21, 2011
by lnino
lnino's Avatar

Hi everybody.

I thought it could be interesting for some guys to know how to get Hexadecimal Code Switches working. Because I always got a lot of support in this forum I decided to share my current project status. In this project I used a atmega168, two Hartmann PT65 103, one button and two leds.

In this special case it is a part of my safe project. I have a button which sends a 1 if pressed. With the Code Switches you can set the code of the safe. If the code is equal to the input of the button the led turns green. Otherwise it stays/gets red.

Enjoy.

Here you can download a video of how I use the coding switch. VIDEO

alt image text alt image text

Here is the code for my project:

// coding_switch.c
// for NerdKits with ATmega168

#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"

// NOTE: (switches connects to GND when closed, otherwise
// the pin is internally pulled up through a pull-up resistor to VCC)

  // declare the variables
  volatile uint16_t sum = 0;
  volatile uint8_t number;
  volatile uint16_t secret;

  uint8_t nIn;
  uint8_t nIn2;

  void button(void);
  void set_secret(void);

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

  // LED as output
  DDRC |= (1<<PC1); // Green
  DDRC |= (1<<PC0); // Red

  // Button as Input PB1
  DDRB &= ~(1<<PB1);

  // Set the 4 pins to input mode
  DDRC &= ~(1<<PC2); // set PC2 as input - sets a 0 to PC2
  DDRC &= ~(1<<PC3); // set PC3 as input - sets a 0 to PC3
  DDRC &= ~(1<<PC4); // set PC4 as input - sets a 0 to PC4
  DDRC &= ~(1<<PC5); // set PC5 as input - sets a 0 to PC5

  // turn on the internal resistors - Coding Switch 1
  PORTC |= (1<<PC2); // turn on internal pull up resistor for PA2
  PORTC |= (1<<PC3); // turn on internal pull up resistor for PA3
  PORTC |= (1<<PC4); // turn on internal pull up resistor for PA4
  PORTC |= (1<<PC5); // turn on internal pull up resistor for PA5

  // turn on the internal resistors - Coding Switch 2
  PORTB |= (1<<PB2); // turn on internal pull up resistor for PA2
  PORTB |= (1<<PB3); // turn on internal pull up resistor for PA3
  PORTB |= (1<<PB4); // turn on internal pull up resistor for PA4
  PORTB |= (1<<PB5); // turn on internal pull up resistor for PA5

  // turn on the internal resistors - Button
  PORTB |= (1<<PB1); // turn on internal pull up resistor

  while(1) {

      nIn = ~(PINC >> 2) & 0x0F; // Coding Switch 1
      nIn2 = ~(PINB >> 2) & 0x0F; // Coding Switch 2

      set_secret();

      if(!(PINB & (1<<PB1))) // When Button is pressed
      { 
        number=1;
        button();       
      }

      if(secret==sum)
      {
            // turn on Green LED
            PORTC |= (1<<PC1);

            // turn off Red LED
            PORTC &= ~(1<<PC0); 
      }

       else if(secret!=sum)
       {
            // turn on Red LED
            PORTC |= (1<<PC0);

            // turn off Green LED
            PORTC &= ~(1<<PC1);
       }

      // The buttons are connected to PC2. PC3, PC4 and PC5.
      // In this case the coding Switch is set to a 1. In this case we also want the display to show a 1.
      // At the beginning PINC is 111100 (decimal 60)
      // If the button on PC2 is pressed PINC is 111000 (decimal 56)
      // After that you have to invert PINC. PINC is 11000111 (decimal 199) 
      // PINC >> 2 means you have to move two digits from left to right. It has been done with 1s. After that PINC is 11110001 (decimal 241)
      // After that you have to make a sum with a logical AND. 11110001 AND 00001111. You do this because we are only interested in the last four bits(from the right), because they are effected due to the Coding Switch.
      // The sum of the AND is 00000001 (decimal 1). Now the register shows a 1 and on the display you will also see a 1.

      lcd_home();
      lcd_write_string(PSTR("SecPart1: "));
      lcd_write_int16(nIn);
      lcd_write_string(PSTR("        "));

      lcd_line_two();
      lcd_write_string(PSTR("SecPart2: "));
      lcd_write_int16(nIn2);
      lcd_write_string(PSTR("        "));

      lcd_line_three();
      lcd_write_string(PSTR("Bt Sum: "));
      lcd_write_int16(sum);
      lcd_write_string(PSTR("        "));

      lcd_line_four();
      lcd_write_string(PSTR("Sec Sum: "));
      lcd_write_int16(secret);
      lcd_write_string(PSTR("        "));

  }
  return 0;
}

void button(void)
{
    if(sum==0)
    {
        sum=number;
        delay_ms(120);
                    }

    else if(sum > 0 && sum <= 9)
    {   
        sum=(sum*10)+number;
        delay_ms(120);
    }

    else if(sum > 9 && sum <= 99)
    {
    }
}

void set_secret(void)
{
    secret = (nIn*10) + nIn2;
}

Post a Reply

Please log in to post a reply.

Did you know that you can build a digital read out (DRO) for a lathe or milling machine? Learn more...