Intro: Control 2 Servo Motors With a Standard Remote
Step 1: Parts
The project is built in two parts, the first part is the development where communication is carried out with the IC over a serial link and the second part is a stand alone project as shown in the video.
* The IC obtained form ByVac There is also a kit available that has the serial lead (£9.50 for the kit)
* A USB to serial device if not purchased with a kit from above.
* Photodiode TSOP2236 or similar device Farnell part number 4913061 about £1 (see below)
* 3.3V regulator 100mA LDO type (only for finished project) Farnell part no 1296588 (see below)
* Remote control - From living room, only to be used in non-telly viewing time
* Breadboard - various sources
* Servo motors - various sources
The Photodiode and regulator can also be purchased from ByVac, Farnell may have a minimum order value. The photodiode is the type that is used in conjunction with remote controls, it has three wires and the one specified works at 36kHz.
Step 2: Development
You could simply skip this, build the final version and download the software to have a working device, however I see this project as an example for other ideas and so to skip this would mean a loss of valuable information. Also the remote you have may not output exactly the same code as the one I have and so some modification of the software is likely to be required.
The basic circuit is shown in the picture, this is built in a previous Instructable on some breadboard so there is no point in going into it again here.
Add the additional components, only one servo is needed for now. We need to do some interactive experimentation to get the best out of the circuit with software.
Both the IR photodiode and the servo motors require 5V, however for testing they both will work on 3v3. I wouldn't recommend using both servos on the 3v3 supplied by a serial interface however one works okay for testing.
Step 3: Development Software
We will start with the infra red side of things and ignore the servo(s) for now. Open BV_COM and communicate with the BV500 (the IC).
Now load this file:
Simply copy the text and place it into the text transfer dialog box, then press send. This may need a couple of attempts until the file is cached, it will all depend on the internet connection. After the send it should say something like lines loaded 120.
The file is quite short but it does load the IR library file hence the number of lines. Obtain a remote control and set it to a Philips TV (I am assuming that you have one of those that you can program using various codes.) The reason for using that is that the IR decoding only works with RC5 code which is what Philips use in their appliances.
Type go, point the remote to the IR photodoide and you should see some results as in the picture. It may not produce the exact same results but that doesn't matter. The results I obtained were:
The first 3 is the start bits and they are always there, the actual code for the key is the last two digits, in this case 11 for minus and 10 for plus. The toggle is the number that changes from 5 to D (numbers are in hex). The actual values are unimportant as long as it is consistent. If you are getting something that is unchanging or inconstant then the remote is not sending out RC5 so choose a different TV or VCR or whatever.
A quick look at the code.
This is shown as a picture so that the line numbers and syntax colouring are maintained.
Line 5: This is the file that does most of the work, if you want to look at the actual code then it is at the URL shown in the picture. The #include loads it onto the chip before the rest of the code.
Line 12: This is the single function that the code consists of. To run the function type in its name which we did when typing 'go' above.
Line 12 to 16: These are functions in the code that is in the include file and they initialise the ports for use and set up a couple of interrupts so that the IC can respond as soon as it receives any infra red. These lines are required to get the IR going.
Line 17: Just the 'Ready' on the terminal so we know everything is okay
Lines 18 & 24: This is a continuous loop that can be exited when a key is received at the terminal, i.e when you press a key at the keyboard. It works because the terminal is connected to UART2 and comkey?(2) will return the number of keys in the UART2 buffer (UART is a serial port). As there are no keys in the buffer until you press a key at the keyboard then it will stay in the loop.
Line 19 to 22: IRDstate (case is important) is a variable that will be set to 1 when there has been a value received by the IR. The value is in currentWord, line 21 simply prints it out as a hex number. The value of currentWord will only be printed out when there is a valid value. It is important that the function resets IRDstate back to 0 after reading the word.
Lines 26 &27: ALWAYS LEAVE A COUPLE OF BLANK LINES AT THE END OF A FILE
Okay so now that we have a working infra-red its time to look at the servo side of things. Copy and paste this URL
into the text transfer dialog as before and press send. You may need to reset the IC as it is running interrupts and the serial interface does not have any handshake.
The servo may spring to life after this command. Now type:
@OC2RS = 200 (This is @ O for Oscar not zero)
and the servo should move. You can discover the limits of your servo and find out the maximum and minimum values, the ones I have range from 121 to 384.
The servo is using the Output Compare module built into the IC. In the mode that it is in it is producing a pulse width modulated signal and the value in register OC2RS controls the width of that pulse so all you are doing when changing the values is actually changing the width of the pulse. The granularity is quite good at just a few microseconds and so that is how we are able to get a resolution of over 200 within the range of the servo.
It is probably beyond the scope of this text to go into the details of how the code works as it is mostly setting up the IC registers, the IC hardware does the work. If you are interested I had 3 goes at this the (details are here) and my first attempt was to emulate PWM in software.
Step 4: Putting It Together
From a software point of view we have a keypad that is able to give us lots of code and we also have a means of accurately positioning a couple of servos so it is only a question of relating one to the other.
The final circuit with battery is shown in one of the pictures. Don't disconnect the serial just yet there are a couple of things to do first. Copy and paste this url and use send as before. This is the final program.
The function main()
This looks complicated but it isn't. Type main and see how it works, it may not work at all depending on what your IR is decoding so lets take a look at the main() function. To get out of the function you will need to reset.
Lines 67 to 74: These initialise the IR and servo as before. I have two constants at the top of the file that I found to be the maximum and minimum values of the servo. The line @OC2RS = ((SERVOMAX-SERVOMIN)/2)+SERVOMIN plases the servo to mid position at start up.
Line 75: This time we will loop forever with no get out, this is a good idea on a stand alone application as using the comkey?(2) method may stop the loop if a spurious value is received in the key buffer for whatever reason. However during testing it is probably a good idea to leave the get out - in.
Line 78: I have an LED attached to pin 4 and so this is just for a bit of added information.
Line 79: The IR word received is in two parts, the last 8 bits is the code associated with the key and bits 11 to 8 hold the toggle value, so this line is just getting the key value (into irkey) without the toggle.
Line 81: As said before the toggle is part of the high byte of the 16 bit word, actually this line will also get the start and any address bits as well but that doesn't really matter in this application we just need to see if the toggle is different from last time. The toggle will be the same if the user has kept a finger on the remote key but will be different if the user lets go of the key and presses it again. We use this feature to increase the speed of the servo by adding 1 to the speed variable if there is no change in the toggle. If there has been a change in the toggle then speed gets reset to 0 (Line 82).
Lines 85 to 90: This is the bit that detects which keys are being pressed, in this case we are looking for 2 keys according to this table:
+V 10 (+ volume)
+P 20 (+channel)
-V 11 (- volume)
-P 21 (-channel)
These values were found during the development stage, any other keys of course could be chosen. The plus keys add 1 to speed and the - keys take one away.
Lines 92 to 96: Deal with the volume key and add speed to the servo PWM value, a check is made at 95 and 96 that the servo values have not been exceeded, this just gives nice tight control.
When you are happy with the software type flsave("") and it will save the current functions in ram to flash. Because the function is called main() it will also run at reset.
Back to developing
It may or may not have crossed your mind that one the function main() is saved to flash and this starts on reset - how do I do any other projects with this IC - or worse still if you have a non-working project that has been saved to main() is it stuck there forever? Well no, obviously there has to be a get out.
This has been a demonstration of control of servo motors via IR. It really is a demonstration of IR and servo. The IR does not have to be connected to a servo but could be a relay for example and the servo does not have to be controlled by the IR, this could have a fixed set of movements applied to it. Or it could be controlled via the PC, or a keypad perhaps to open a locked door.