This is the fourth blog update after I started to build the infrared remote control code learner in a Cypress PSoC5LP chip. I am happy to see it working now. It was a quite difficult job, much harder than I expected. In my previous three blog posts I showed how I built a circuit and algorithm that captures the infrared signal from a remote control and stores the raw symbols in an array. Then the raw symbols are decoded and compressed/encoded into a format that can fit in the 2k EEPROM memory block of the PSoC5LP chip. In this update I will show how I built an interface for users to be able to control this code learner system. Users can select one of the eight storage blocks in EEPROM (blocks that I defined in a table posted in my previous update ), then store a new infrared remote control code in the selected block, and after that retrieve it by pressing a button. The retrieve function reconstructs the infrared signal by pulse-modulating a carrier signal and sends it to an infrared LED. This code learner system will be added to my brainwaves appliance controller project so users can “teach” the brainwaves appliance controller specific codes needed to control their TVs, cable or satellite receivers, and other electronic devices that use infrared remote controls.
So let’s take a look at how this interface works. After power-up the code learner system enters into an “idle” mode until the user presses one of the three control buttons. First button selects one of the eight memory blocks mapped in the 2k EEPROM of the PSoC5LP. Subsequent pressings advance the location, which is displayed on a 7-segment LED module. At each memory location the user has the option to either press a “code learn” button or “code retrieve” button. The “code learn” button puts the system in code learning mode, in which the user points a remote control to the infrared sensors and pushes the button on that remote control that corresponds to the function that needs to be learned. Then, the user can advance to another memory location and store another function of the infrared remote control. For example, the user can store the power ON/OFF at location zero, channel up and location one, channel down at location two, volume up at location three, and volume down at location four. After storing these functions the user can push the “code select” button multiple times until the LED display shows the desired memory location and then push the “code retrieve” button to send the memorized code to the infrared LED and thus to control the corresponding appliance (TV, DVD player…)
Here is a picture of this remote control code learner prototype implemented in the PSoC5LP of the Cypress CY8CKIT-001 kit.
The user buttons are switch 1, 2, and 6 on the development board. Notice the 7-segments LED module on the attached breadboard. The infrared LED is hanging on two wires. On the left side there are two infrared sensors. In the back there is a satellite receiver with a small LCD monitor on top.
But before showing how it works I would like to share two stories of things that did not work from the beginning and challenged me. First, the control of the 7-segment LED module; I would have never thought that this control would be a problem for me, but it was. I tried first to use the Segment LCD block in the PSoC Creator library. That is a very powerful block which I am happy to see available in the library; however, it gave me so much trouble to make it control my simple 7-segment LED module. So after about two hours I gave up. Next I tried the Segment LCD Static block in the PSoC Creator library. This one looked a lot easier to configure but I still could not make it work for my LCD module. After these two tries I decided that it would have been faster actually to build a controller from scratch by just using simple components in PSoC Creator library. So I built the circuit shown in the picture below.
The circuit works in two modes, one continuous display and the other one blinking display, by using a 2.4Hz clock source.
The code is shown in the picture below.
The numerical values that I send to the 7-segment LED display correspond to the segments that need to light up for each of the numbers 0,1,2…7. I computed these values using the spreadsheet below.
So this “home-made” display controller worked well and I was able to develop it quite fast compared to the time I lost with the Segment LCD library components.
This was the first problem that I wanted to share; now the second one. The second one was so weird that it puzzled me for many hours. Let’s start by looking at the portion of the code shown below:
Line 385 says that if user presses switch 3 the system goes in code learning mode. Line 392 calls a function that receives the infrared code from sensors. The variable “current_eeprom_code” represents the location in EEPROM where the learned code will be stored, so possible values are 0,,1,2,3…7 only. Line 402 calls the function that stores the received code in the “current_eeprom_code” location. This is quite easy so far, but the problem was that during program execution after line 392 the value of variable “current_eeprom_code” changed to 0xFF. I spent a lot of time to find out what changes that value to 0xFF, and this is what I found:
Inside the function receive_ir_code() there was a piece of code that initializes two arrays, that I am showing below:
Notice the “for” statement from 0 to <113, so it initializes the array up to location 112. Now the problem: The array was defined with 112 locations, as I am showing below,
but that means 112 locations total. So my error in the function was that I was initializing an extra location in the array, a 113th location since I started from zero not from one. Since my initialization of this array was to decimal 65535 (hexadecimal 0xFFFF) at each location, the extra location outside of the array definition length was receiving the 0xFFFF value. Now you would ask the question: what would be the odds that out of the entire PSoC5LP program memory the “current_eeprom_code” variable to be assigned by the compiler exactly in that extra (out of range) array location initialized by my code to 0xFFFF? According to Murphy’s law if there were a chance that this could happen it will happen, and it did for me. The “current_eeprom_code” variable was assigned by compiler exactly into the program memory location that changed to value to 0xFFFF during the array initialization. You can imagine how happy I was when I found this problem, and when after changing the <113 to <112 in the “for” statement above the “current_eeprom_code” variable did not change the value to 0xFF anymore. It is interesting that the compiler did not signal any warning about this error in the code; here is a screenshot of the warnings that I received (all about things that I knew about and let them be like this for now), but there is nothing about overflowing the array length during that initialization code.
Anyway, I am glad that finally I made this infrared remote control code learner work. Here is a video that shows how it works.
This is where I am so far with developing the brainwave appliance controller. Next step will integrate this infrared code learner system into the brainwave appliance controller.
That’s it for now; I will come back with a new update as I get more work done.