Team 5 Electromagnetic Lock Code

The code for controlling the speaker and electromagnet is honestly trivial. For driving the speaker, we used Pulse Width Modulation to output a sequence of frequencies to output specific tones. We also used PWM to drive the relay switch that activates & deactivates the power to the electromagnet, but we could have also simply used gpio (general purpose input output).

The only interesting things to note about our code is how the 4×3 keypad was set up, and that we found an odd quirk in how PWM behaves.

First, the odd quirk involving PWM. Say we setup 4 pins on header J1 for PWM use, and then we try to change the frequency on just one of those pins. You’d think that the other 3 pins wouldn’t be affected since you aren’t doing anything to them, but their behavior follows the reinitialization of the single pin you tried to change. Here’s code to replicate this odd behavior:


struct pwm_config mypwm[4];

int main(void)
{
//Set up 4 pins on header J1 for 500 Hz
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 500);
pwm_init(&mypwm[1], PWM_TCC0, PWM_CH_B, 500);
pwm_init(&mypwm[2], PWM_TCC0, PWM_CH_C, 500);
pwm_init(&mypwm[3], PWM_TCC0, PWM_CH_D, 500);

//Start the pin outputs at specific duty cycles
pwm_start(&mypwm[0], 95);
pwm_start(&mypwm[1], 95);
pwm_start(&mypwm[2], 95);
pwm_start(&mypwm[3], 95);

//Now reinitialize just one pin to a sequence of different
//frequencies, connect to a piezo speaker, and observe that
//all four of the pins have the same behavior, which shouldn't
//be the case.
for(;;){
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 400);
pwm_start(&mypwm[0], 95);
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 300);
pwm_start(&mypwm[0], 95);
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 200);
pwm_start(&mypwm[0], 95);
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 100);
pwm_start(&mypwm[0], 95);
pwm_init(&mypwm[0], PWM_TCC0, PWM_CH_A, 500);
pwm_start(&mypwm[0], 95);
}
}

Only pin 0 on port C should be affected, yet pins 1 through 3 follow suite for some reason. All I can guess is that the act of reinitializing shouldn’t be done this frequently, but in my investigation of controlling the output frequency, I didn’t find a better alternative.

Now, the code for the 4×3 Keypad. Our team didn’t want to reinvent the wheel, so we actually reached out for the keypad code done by a previous semester’s ECE 412 team. Thankfully they gave us the source code for controlling the keypad, and gave us permission to use it in our project. Special thanks to Benjamin Fuson and his team.

The gist of the code behind the 4×3 keypad is as follows: First, we define the 7 connections of the keypad to whichever pins we connect them to, initialize the rows as outputs, and the columns as inputs. The reason why we set rows as outputs is because of the nature of using 7 lines to define 12 buttons.

In order to see which button is pressed on the grid, we loop through sending a high signal along the rows until one of the buttons on a corresponding column is pressed. After receiving input from one of the columns when we are on a specific row, we can determine which button on the grid is pressed. Below is the some of the loop that waits for input by sending high signals to rows:


// get_numpad_input waits for user input on the keypad
int get_numpad_input(void)
{
int inputs = (-1);

while (inputs == (-1)) {
inputs = check_numpad_input();
}
return inputs;
}

 

// check_numpad_input pulses an output high across each ROW pin,
// checking the COL pins for inputs
int check_numpad_input()
{
int inputs = (-1);

gpio_set_pin_high(ROW1);
delay_ms(INPUTDELAY);
if (ioport_get_pin_level(COL1) > 0) {
inputs = 1;
}
if (ioport_get_pin_level(COL2) > 0) {
inputs = 2;
}
if (ioport_get_pin_level(COL3) > 0) {
inputs = 3;
}
gpio_set_pin_low(ROW1);

gpio_set_pin_high(ROW2);
delay_ms(INPUTDELAY);
if (ioport_get_pin_level(COL1) > 0) {
inputs = 4;
}
if (ioport_get_pin_level(COL2) > 0) {
inputs = 5;
}
if (ioport_get_pin_level(COL3) > 0) {
inputs = 6;
}
gpio_set_pin_low(ROW2);

//code for other rows...

}

 

Hopefully this post helps out others struggling with keypad logic and PWM funkyness.

-Michael Dudrey