Digital Master Lock

Team 4.3’s Digital Lock Project

This team did a lock based on a dial, much like a gym locker or “Master” lock. They took the Spring 2015 lab 4 in a direction nobody anticipated, and added a servo to open a box when the right combination was dialed in. There’s a lot of great build tips here for putting your project in a beautiful metal case. This team also went off the grid with their OWN WordPress site, here’s the link with a video, code, and more:

https://group4p3.wordpress.com/

 

Schematic: Team 4.1’s U-box

The schematic for Team 4.1’s U-Box seems complicated but is actually fairly straightforward. There is essentially a circuit for the LED and LCD screen, and a second circuit for the servo motor. From the A3BU, 3.3V runs through a 330 Ohm resistor to a red LED and back to ground. A switch completes the loop so that the LED will only light up when the switch is flipped. The other side of the switch runs back to an input pin on the A3BU that just lets the micro-controller know which position the switch is in. This is necessary so that our LCD screen knows when to show the different faces.

Unfortunately, the 3.3V from the A3BU were not enough to power the 5V servo, so a second part of the schematic is designed to run this servo. When the switch is flipped, the A3BU tells an Arduino to run its code, and the Arduino outputs the 5V necessary to turn the servo 35 degrees. The servo will rotate and hit the switch back into the off position, causing the LED to turn back off.

Team 1.2 – Schematics

3x4_Matrix_CircuitAbove is the main schematic we used for our project which helped us figure out what pins corresponded to which row and column as well as how a specific keys location was relayed to the board. The schematic details the conductors associated with each row and each column. The keypad we used for our project has 4 rows and 3 columns for 12 total buttons, but only 7 data pins. To read which button was pressed at any given time, we energized the voltage on each row while checking for a column inputs.

Here is a diagram of how each row and column was wired to the A3BU:keypad_hardware_schematic (1)

Team 1.2 – Keypad Lock

The intent of our final project was to create a keypad lock using a 12-key membrane keyboard and the XMEGA-A3BU board that would trigger a stepper motor to open a mechanical lock. We ran into a problem early on that forced us to change course slightly. The EasyDriver for the stepper motor we were planning on using for our lock did not arrive in time so we decided to go with an alternate driver. This ended poorly for us as the alternate driver caught fire during initial testing, much like our hopes and dreams.

As an alternative, we printed messages to the LCD while also flashing the onboard LEDs to signal that the provided password was correct or incorrect. We also implemented a menu system through which the user can either set or try a password. Passwords can be 10 digits or less, and are hashed upon entry for added security.  If the user attempts to try a password before one has been set, an error message is displayed and the user is returned to the main menu.

Team 1.2 – Code

codeblockWhat you see above is how we went about getting user input from the keypad. We initially set a row high then wait 50ms to ensure the voltage has a chance to ramp up to solid logic levels. We then check to see which column goes high. This tells us which key is pressed by creating a coordinate pair (row, column). We then set the row back low and move on to the next row. This continues until all rows (total of 4) have been set high and then low again.

This could be easily improved by moving the input handler to an interrupt service routine that gets called when changes are detected on the input pins. However, this would also require more time and consideration to pull off without it having adverse effects on the sequential flow of our program.

Arduino code for team 4.1’s U-box

Team 4.1 Arduino controled armSince our 5v servo motor needed more juice to run than our A3BU could provide we opted to use an Arduino to power the motor for the arm. Below is the fairly simple code needed to flip the switch on our U-box. An initial position is set, then once the pin state is read high the arm position is moved to flip the switch and then return to its initial position.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

// twelve servo objects can be created on most boards

const int pin = 2;

int pos = 0;    // variable to store the servo position

int state = 0;

void setup()

{

myservo.attach(9);  // attaches the servo on pin 9 to the servo object

pinMode(pin, INPUT);

}   Continue reading Arduino code for team 4.1’s U-box

Big picture: Team 4.1’s U-box

11173644_10204267139946834_797817752_n

For our final project our goal was to do something fun that would be entertaining to anyone who used our project. Thus we came up with the idea of the U-box. Our slightly more useful box does everything your typical useless box would do except it also has a cool LCD user interface thanks to the A3BU micro controller.

For those unfamiliar with what a useless box does we can explain. Basically you flip a switch, and then an arm comes out of the box and flips the switch back. This continues until either you give up or the box runs out of power. To this our group added a user interface that shows the attitude of the U-box. The first few times you flip the switch the box is disturbed. Keep flipping and the box will become angry. Finally the box will become so angry he gives up and you win. After this the “game” starts over again.

To accomplish the task of the U-box we needed to use PWM to control the servo motor and LED, input pins to determine if the switch was flipped, and additional software to tell the LCD display what to display to the user. Below is a link to download the video!

Team 4.1 U-Box video

Smart House

A3BU code:

#include <asf.h>
#include <board.h>
#include “pwm.h”
#include “gpio.h”
#include “ioport.h”
#include “port_driver.h”
#include “avr\interrupt.h”
#include “gfx_mono.h”
#include <st7565r.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int dutyCycle = 5;
struct pwm_config motorPwm;
#define lightLevel IOPORT_CREATE_PIN(PORTB,0)
#define alarmSense IOPORT_CREATE_PIN(PORTA,0)
int alarmOn = 0;

//Button motor toggle
ISR(PORTF_INT0_vect)
{
if (dutyCycle == 5)
{
dutyCycle = 10;
pwm_start(&motorPwm, dutyCycle);
}
else
{
dutyCycle = 5;
pwm_start(&motorPwm, dutyCycle);
}
}

//Alarm Flag
ISR(PORTA_INT0_vect)
{
int val = ioport_get_pin_level(alarmSense);

if(val == 1 && alarmOn == 0)
{
alarmOn = 1;
gpio_set_pin_low(LED0);
gpio_set_pin_low(LED1);
gfx_mono_draw_string(“\n\nALARM DETECTED!!!!”,0,0,&sysfont);
}
if (val == 0  && alarmOn == 1)
{
alarmOn = 0;
gpio_set_pin_high(LED0);
gpio_set_pin_high(LED1);
gfx_mono_draw_string(“\n\nNo alarm detected.”,0,0,&sysfont);
}
}

//Light flag
ISR(PORTB_INT0_vect)
{
if (ioport_get_pin_level(lightLevel) == 1)
{
gfx_mono_draw_string(“\nLights are on. “,0,0,&sysfont);
}
else if (ioport_get_pin_level(lightLevel) == 0)
{
gfx_mono_draw_string(“\nLights are off.”,0,0,&sysfont);
}
}

int main (void)
{
// Insert system clock initialization code here (sysclk_init()).
sysclk_init();
board_init();
gfx_mono_init();
st7565r_init();

gpio_set_pin_high(LCD_BACKLIGHT_ENABLE_PIN);
gfx_mono_draw_string(“MONITOR ONLINE:”,0,0,&sysfont);
gfx_mono_draw_string(“\nLights are off.”,0,0,&sysfont);
gfx_mono_draw_string(“\n\nNo alarm detected.”,0,0,&sysfont);

pwm_init(&motorPwm, PWM_TCC0, PWM_CH_A, 50);//this is SDA on J1 on the A3BU Xplained
pwm_start(&motorPwm, dutyCycle);

/* Configure PF1 as input, triggered on rising edge. */
PORT_ConfigurePins( &PORTF, 0x02, false, false, PORT_OPC_TOTEM_gc, PORT_ISC_RISING_gc );
PORT_SetPinsAsInput( &PORTF, 0x02 );
/* Configure Interrupt0 to have medium interrupt level, triggered by pin 1. */
PORT_ConfigureInterrupt0( &PORTF, PORT_INT0LVL_MED_gc, 0x02);

//Alarm Flag PA0 J3
PORT_ConfigurePins( &PORTA, 0x01, false, false, PORT_OPC_TOTEM_gc, PORT_ISC_BOTHEDGES_gc );
PORT_SetPinsAsInput( &PORTA, 0x01 );
/* Configure Interrupt0 to have medium interrupt level, triggered by pin 1. */
PORT_ConfigureInterrupt0( &PORTA, PORT_INT0LVL_MED_gc, 0x01);

/* Enable medium level interrupts in the PMIC. */
PMIC.CTRL |= PMIC_MEDLVLEN_bm;
/* Enable the global interrupt flag. */
sei();
while (true)
{
}
}