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.
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.
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.
Our 8-Button Piano is driven purely by interrupts. Utilizing the in-class example for button handling, we configured all 8 of our buttons as input using the GPIO ports available on the ATMega328P Xplained Mini microcontroller. In order to achieve a level of attainable modularity with our design, we utilized predefined macros to indicate the data direction register, port, and pin numbers for each of our buttons. Continue reading 8-Button Piano – Interrupt Driven Code
The code above is used to store a variable length PIN in EEPROM and retrieve it when needed. It starts at address 0x00 and increments by 10 for every successful digit. Once the PIN is stored it saves the last used address into a variable so the GetKey() function knows when to stop.
This snippet of code reads the pins on PORTD. If a pin on PORTD is high, “data” will be larger than 0 and will get stuck in the while loop until the pins on PORTD are low again. Before entering the loop, global interrupts are enabled which allows the interrupt that generates the tone to be called. Then after all pins on PORTD are low, global interrupts are disabled and the program continues. This is used so that a constant tone will be played for however long a laser is blocked.
This is a snippet of our code, more specifically, it is a MIDI handler function that we wrote to handle the “On Note” MIDI event. It takes a channel as a parameter, assigns it to thee appropriate voice, and then checks if the voice is a square channel or drum channel. From here, the code handles the appropriate channel, updates the pitch of the note, and sets the attenuation of the note.