The code above is used to maintain and countdown time for the timer/stopwatch in this project. It is set in the interrupt and is calculated for every second. Due to the nature of the LCD, it is required to use and display the time using an array. Therefore, the ten’s place of the minute, one’s place of the minute, ten’s place of the seconds and one’s place of the seconds is used to calculate time along with the interrupts. For the purpose of this project, the maximum value of time is 59 minutes, therefore the if else statement above considers the value in the format of ##:## and counts up from the one’s place of the seconds and once that reaches 0, increments the ten’s place by one and then repeats this til stop watch is stopped.
This code was intended for an ATMega328p and was coded using Atmel Studio 7. The purpose of the code is to detect if the microcontroller gets a shock and if it does send a signal to the buzzer to let the user know the won. We accomplished this by creating a while-true loop that goes on continuously until it detects a signal from the shock sensor, that is set as an input in PIN 5 of Port B, if it detects a shock it will generate a random integer between 0 and 5. If the integer that was generated is the same as the one specified in the code, in this case a 3, it will activate and deactivate the buzzer, set as an output on PIN 5 of Port C, letting the user know if they have won or not.
In a portion of our code we needed to look for a button press to change a variable. To do this we used a while loop that incremented a counter when the button was not pressed and changed the value when the button was pressed. This allowed for the user to edit the value for a set amount of time and then move on to the next portion of the code. Below is the code
counter = 0;
LCDWriteIntXY(1, 2, minutes, 2);
while(counter < 10)
int temp = PIND & 0x01;
if (temp == 0x00)
counter += 1;
minutes += 1;
if (minutes > 59)
minutes = 0;
LCDWriteIntXY(1, 2, minutes, 2);
The programming of the microcontroller was accomplished using Atmel studio 7 on Windows 10. The goal of converting the analog voltage produced by the Sharp IR sensor to a digital signal was accomplished using the ADC of the microcontroller. The ADC was setup in an ADC initializing function, ADCinit. PC5 was selected as the input for the ADC by setting the MUX0 and MUX2 to 1. The ADCSRA register was set up to enable the ADC, enable auto trigger, enable interrupts and set the prescaler to 64. Global interrupts were enabled in this function using the sei instruction. The output voltage of the sharp IR sensor was found to have a range of 0 to 3 volts depending on the distance. The ADC voltage reference was set to 3.3 volts to more closely match the output of the IR sensor as opposed to the 5 volt default. This was accomplished using AREF as the voltage reference by connecting the 3.3 volt output of the microcontroller to AREF pin with a jumper wire. The LED brightness was controlled with PWM. PWM was set up in the PWMinit function. The clock was set up with no prescaler and using CTC mode. In this mode the OCR1A acts as the top value of the counter while the OCR1B is the value to be compared to. Interrupt service routines were used to change the duty cycle based on the ADC value passed into the duty variable and then by setting OCR1B compare value to duty. The result of the program was a smooth fluctuation in the brightness of the LED based on the distance of a hand or object from the sensor.
The Wah circuit was combined with the microcontroller by inserting the LED and LDR into a heat-shrink tube in order to have the light passed to the LDR directly related to the LED without outside light interference. The resulting behavior of the LED based on hand position can be observed in the video above.
We wrote code for the project for both the Atmel Xplained board in Atmel Studio and an Arduino Uno (has the same processor as the Xplained Board). Originally, the Arduino was used just for proof-of-concept testing and for a user friendly testing platform to iron out any unforeseen kinks with the program flow or mathematical computations. Once that was completed, development switched to Atmel Xplained board. The end functionality of the code written for both boards is fairly comparable except for the speedometer module. A critical component to the speed calculation is the elapsed time between the voltage drops of the Hall effect sensor. For the Arduino Uno this was no problem as an external clock source separate from the Atmega 328p is integrated into the board. In addition to build in functions that make interfacing with the clock extremely easy. On the other hand, the Atmel Xplained board has no external clock source. So all timing had to be done utilizing timers based off the CPU clock speed. Overall, this created a more complex piece of code with worse functionality.
From our project, the interesting thing about our code is how the output signals are converted into realistic musical notes. The original approach we were going to use the received signals as a corresponding output using a speakers. But, we actually decided to create a realistic version which takes in the signal and translates them into real-world musical notes; therefore that is the most interesting portion of our code. The above photo only portray the first few conversion because including more would just be repetitive. Also, all the code is a series of if statements which tells certain signals to convert to particular musical notes.
One interesting aspect of the code is the implementation of ray tracing. Ray tracing is basically casting a “ray” from a point outwards, gathering data about when the ray encounters an object, and using that data to interact with the surroundings. In this project, Ray tracing is used to find out where the visible walls will be. A ray is cast from the user’s current position, and when it encounters a wall in the maze, it instructs the program to activate the led at that position. It repeats this all the way around the user, until the entire view of the maze that the user would have while within the maze is constructed. This is referred to as the “frame” and is how the program decides which LEDs to have on after each move made by the user. This does result in a small delay between each move until the next frame is displayed, but also gets the desired result of only showing the parts of the maze wold be visible in the maze to a user.
One interesting thing about our design was that we were able to code the different angles we wanted the motor to turn. We had different cases based off user input that selected which angle to use. We then had a variable in each of those cases to store the degrees chosen, so that the return motor function would know how far to come back so that the catapult could be shot again.
One of the two main components which we had to program for the house project was the ATmega328PB board that we’ve been using previously throughout the class. We did so using the Atmel Studio 7 application and accomplished our tasks using both the C and Assembly languages, very similar to the style of Lab 3. Both the C and Assembly sections utilized the base sample code from Lab 3 as we decided to use the LCD interface to have a function relating to our door lock on the house. The board is receiving this input anytime the door lock is engaged or disengaged on the Arduino, and is receiving a separate signal to the LCD than what is going to the Actuator.
The ball’s rotation is done through the implementation of a Timer Compare Interrupt. Each time this interrupt occurs, a global flag is set in the code. The main program loop checks this flag each loop and updates the servo position each time it is set. The flag is then cleared and the loop continues until the interrupt occurs again. A snippet of the code that changes the servo position is shown below along with a video of the spinning.