Universal Programmable Remote Control
Cornell University, ECE 476
Our software consists of a state machine that supports the user interface with the keypad and the LCD, and the appropriate
functions to record and transmit the signals. Upon reset, the LCD displays a brief message and then enters the main menu.
From here the user can start programming codes, playing existing ones, clearing existing ones, or viewing which buttons have
been programmed. The most difficult parts to write were the functions to record and play the signals.
When the user initiates a recording sequence, we begin timer 1, clear it, and enable the input capture interrupt. When the user pushes the button on the existing remote, we start to receive a digital signal from the IR receiver. On the first logical change, which is from logic high to logic low, the time from timer 1 is captured and stored in the input capture register. This first time is useless, however, so we do not use it. This time is essentially the time it takes for the user to pick up the remote and press the button after he or she had initiated the sequence, and timer 1 may actually have ran over several times, if the person recording is slow. The timer is reset and we reverse the logical change condition on the input capture interrupt to trigger on a rising edge. The next time that the interrupt is triggered marks then the first time that we need to record. We subtract this time from the time before, which should be zero since we reset the timer within the interrupt, and store it in our array. This time is the length of our first pulse. Also timer 1 is set so that it does not overflow while measuring a pulse. We measure 70 or so transitions in this fashion before the programming sequence is complete. When we were testing we tried recording less than 70 transitions, but found that the radio that we were testing on did not recognize those signals.
The playing function essentially turns on one of the port pins for the specified amount of time and shuts it off again for a certain amount of time as dictated by the times that we saved during the recording function. We have to modulate this signal, however, by a 40 kHz carrier wave. Generating this wave was slightly incommodious, as first we were trying to generate it within the playing function, using a counter variable and an if statement that toggled it every few microseconds. This does not work well because correct and accurate operation would dictate that we knew exactly how many cycles the microcontroller took to execute the instructions around the if statement. We got independent operation with the output compare pin (Port D.7), by setting an OCR number that corresponded to a 40 kHz signal. Thus, the pin would oscillate at that frequency if the timer was enabled and would not oscillate at all if the timer was turned off. After the playing is done, we have to set the pin that we output on to zero because there is a chance that the toggling left the pin high. We play the signal that we record twice, for if we only play it once, the signal would not be registered by the receiving unit and if we play it three or more times, the radio would register multiple button presses, which causes incorrect operation when we are dealing with something like a volume up or down operation. Normally when a user pushes a button on a remote control, it sends the same signal continuously. We cannot do that however because the signal that we record is out of phase, it is not the signal repeated at a constant rate. Because of this, when the user pushes a button, it plays and if the user wants to play it again, he has to push it again.
This last bit brings into mind the fact that a real remote control would be slightly less complicated in terms of recording the signals. If we were implementing a remote control without recording abilities, we would have to determine what pulse lengths correspond to what button and store those in memory. When we play then, we can have the remote just repeat the signal at a constant rate. We would be able to do this because the times in the array that we play from will contain data from exactly one period of the signal and nothing more. Since this is meant to accommodate all IR standards we have to resort to programming with an existing remote, for if not, we would have to have the user input which keys from which brand of remote the user wants to map to each of the ten keys. We have no room to store the transition times for all those keys and we do not have the time to determine all that data anyway.
The software that we used to run the keypad was taken almost directly from our lab 3 code. We changed a few things around since we did not need to analyze the keys entered since we have only 1-button commands.