1. Trang chủ
  2. » Công Nghệ Thông Tin

Practical Arduino Cool Projects for Open Source Hardware- P6 docx

10 304 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 205,19 KB

Nội dung

CHAPTER 2  APPLIANCE REMOTE CONTROL } else if(val == '2') { // Pulse the 2nd button Serial.println("Output 2 ON"); digitalWrite(output2, HIGH); delay(buttonPressTime); digitalWrite(output2, LOW); Serial.println("Output 2 OFF"); } else if(val == '3') { // Pulse the 3rd button Serial.println("Output 3 ON"); digitalWrite(output3, HIGH); delay(buttonPressTime); digitalWrite(output3, LOW); Serial.println("Output 3 OFF"); } else if(val == '4') { // Pulse the 4th button Serial.println("Output 4 ON"); digitalWrite(output4, HIGH); delay(buttonPressTime); digitalWrite(output4, LOW); Serial.println("Output 4 OFF"); } else if(val == '5') { // Pulse the 5th button Serial.println("Output 5 ON"); digitalWrite(output5, HIGH); delay(buttonPressTime); digitalWrite(output5, LOW); Serial.println("Output 5 OFF"); } else if(val == '6') { // Pulse the 6th button Serial.println("Output 6 ON"); digitalWrite(output6, HIGH); delay(buttonPressTime); digitalWrite(output6, LOW); Serial.println("Output 6 OFF"); } else if(val == '7') { // Pulse the 7th button Serial.println("Output 7 ON"); digitalWrite(output7, HIGH); delay(buttonPressTime); digitalWrite(output7, LOW); Serial.println("Output 7 OFF"); } else if(val == '8') { // Pulse the 8th button Serial.println("Output 8 ON"); digitalWrite(output8, HIGH); delay(buttonPressTime); digitalWrite(output8, LOW); Serial.println("Output 8 OFF"); } } } 29 CHAPTER 2  APPLIANCE REMOTE CONTROL One subtlety that may not be apparent on first inspection of the code above is what sort of data is being examined in the series of “if” comparisons. You’ll notice that the variable that holds the data from the serial port is of type “byte,” which is not a numeric type: it could actually be any character at all. Each “if” condition is comparing the data in the variable “val” with a string in quotes, such as '1', or '2', not with the actual number 1 or 2. If that’s beyond you right now, don’t worry about it. Things like variable types will become second nature as you spend more time working with Arduino. Once you’ve loaded the sketch in the Arduino IDE, plug your Arduino into the USB port, select the port from Tools h Serial Port, select your Arduino board type from Tools h Boards, click “verify” to compile the sketch, and if there were no errors, click “upload” to push it across to the Arduino. ApplianceRemoteControlCompact One thing you’ll notice from the version of the preceding program is that although it is conceptually quite simple there is a lot of repetition in it. There are eight nearly identical lines defining output pins, and eight nearly identical lines forcing them low. There are also eight nearly identical blocks of code in the main loop, which makes it very long for such a simple program. The compact version of the program uses a number of techniques to reduce the repetition in the code. The button press definition doesn’t change, but the definition of the output pins is much shorter because it lists them in an array rather than defining each of them as a separate variable. We also need to know how many outputs are listed in the array. We could have done that manually by simply counting them ourselves and assigning that value to a variable, but then we would have to remember to change the value if we changed the array. To avoid that problem we do a little trick that gets the total size of the array and then divides it by the size of a single element to get the number of elements. It doesn’t actually matter which element we use as the divisor, because every element takes up the same number of bytes in memory. We’ll just use the first element (element 0) in this case. // Use pins 5 through 12 as the digital outputs int pinMap[] = {5, 6, 7, 8, 9, 10, 11, 12}; byte pinCount = sizeof(pinMap) / sizeof(pinMap[0]; As before ,we also set a variable to specify how long to pulse each button for. //Number of milliseconds to hold the outputs on int buttonPressTime = 250; An array is a list of values with the positions in the array numbered from 0. What that means is that the first entry is position 0 and has value 5, the second entry is position 1 and has value 6, the third entry is position 2 and has value 7, and so on. What this allows us to do is simplify the setup function because instead of listing every single pin and setting it as an output and forcing it low, we can loop through the elements in the array and use each one in turn. void setup() { // Open the serial connection to listen for commands from the host Serial.begin(38400); int count = 0; // Variable to store current array position 30 CHAPTER 2  APPLIANCE REMOTE CONTROL // Set up the pins as outputs and force them LOW for(count; count < pinCount; count++) { pinMode(outputArray[count], OUTPUT); digitalWrite(outputArray[count], LOW); } } The for loop uses a simple counter that starts at 0 to read the first position in the array, then increments up through the positions to read each in turn. The biggest change is in the main program loop which no longer has to check for every possible value explicitly, but can just check that it falls within an acceptable range. void loop() { byte val; // The raw character read from the serial port int channel; // Integer version of channel ID // Check if a value has been sent by the host if(Serial.available()) { val = Serial.read(); channel = (int)val - 48; // Convert ASCII value to digit if(channel > 0 && channel <= pinCount) { pulseOutput(channel); // Pulse the appropriate button } } } That’s certainly a much shorter function than in the first version! There are a few things to pay careful attention to in the new version of the loop, though. You’ll notice that we have a new variable called “channel,” which is an integer. While reading the serial port there is a cryptic line that sets the value of “channel” by taking the integer value of the “val” variable and subtracting 48 from it. What’s going on here? The byte received from the serial port is not actually a number, as you would generally expect. It’s an ASCII value that represents a character, and that character may (or may not) be a number. The ASCII code for the character “1” is 49, and the ASCII code for the character “2” is 50, and so on. So when we receive a value of “1” from the serial port, the ASCII code that is transmitted (and loaded into the variable “val”) is “49.”What that line does is “cast” (convert) the value of “val” into an integer using the (int) prefix, then subtract 48 from it to convert it to the equivalent number. If the value sent via the serial port is “1” it will come through as ASCII code 49, then have 48 subtracted from it, and end up as the integer 1. The end result of all this trickery is that you send “1” at one end and get “1” out at the other end, but unfortunately it’s not as simple as you might expect it to be! After converting the received value, “val,” to an integer value, “channel,” it is then tested to see if it falls inside the acceptable range from 1 to “pinCount,” which is the number of pins defined in the array. Finally, if that test is met, the loop calls another function called pulseOutput(channel) which is where the actual work of firing the relay takes place. void pulseOutput(int channel) { Serial.print("Output "); Serial.print(channel); 31 CHAPTER 2  APPLIANCE REMOTE CONTROL Serial.println(" ON"); digitalWrite(outputArray[channel - 1], HIGH); // Channel number is 1 higher than array position delay(buttonPressTime); digitalWrite(outputArray[channel - 1], LOW); Serial.print("Output "); Serial.print(channel); Serial.println(" OFF"); } The pulseOutput function accepts a single integer value passed to it from the main program loop, and then sends notification via the serial port that it is about to turn on that channel. It then looks up the array listing the output pins (outputArray) to find the pin number that corresponds to the requested output. Because arrays are numbered starting from 0, while our output channels are numbered starting from 1, we have to subtract 1 from the requested channel to access the correct position in the array: output channel 1 is array position 0, and so on. The function then pauses briefly, turns the appropriate relay back off, and sends notification that it’s all done. As you can see the compact version of the program is much shorter than the original. Once you’re used to the way things such as arrays and functions work, you’ll find it much less clumsy working with programs structured to remove repetition using techniques such as these. Test Reed Relay Shield and Sketch Your Arduino should now be connected to the appliance remote control transmitter using the reed relay shield, the transmitter should have its battery in place, and your Arduino will be listening on the serial port for an instruction to “press” a button. Click the “monitor” button in the IDE to switch to serial-monitor mode where you can see values being sent to you by the Arduino and also send values to it. Select 38400 from the baud rate drop-down box (see Figure 2-13) to match the value we set the Arduino to in the setup function. 32 CHAPTER 2  APPLIANCE REMOTE CONTROL Figure 2-13. Serial monitor in Arduino IDE Now for the moment of truth! Enter the value 1 into the text input area on the right and click Send or press Enter, and you should immediately see your Arduino send you a response saying that it received the command and is activating output 1, followed almost immediately by notification that it is turning the output off again. If everything is working as expected your appliance should turn on, and sending a value of 2 to the Arduino should turn it off again. You can see this at work in Figure 2-14. 33 CHAPTER 2  APPLIANCE REMOTE CONTROL Figure 2-14. Arduino and shield using an appliance remote control to activate a lamp Variations Wireless Link Rather than having the Arduino tethered to a computer, you could replace the USB connection with a wireless link such as an XBee or 433MHz wireless module or even with an Ethernet shield to provide you with a web-services interface to your appliances. WiFi and Ethernet connectivity are discussed in later projects. Automatic Trigger The example programs rely on messages being sent to the Arduino via a serial connection. By connecting an Arduino I/O line as an input and checking the status of a device, such as a motion detector, it could instead trigger outputs based on events such as a motion detector being triggered, a shop door-minder beam being broken, or a window being opened. Connecting to various devices including security sensors is covered later in the book. 34 CHAPTER 2  APPLIANCE REMOTE CONTROL 35 Socket Connections Using the serial monitor in the Arduino IDE is fine for testing, but to make this project useful you probably want to be able to control devices from a scripting language such as Python, Perl, or PHP so that events can be triggered automatically rather than manually through the IDE. A utility such as ser2net (on Linux) or serproxy (on MacOS and Windows) will take a serial connection and expose it as a network socket so that it can be accessed over a network. This is also a huge help when working with scripts running on the computer directly connected to the Arduino because most scripting languages are great at making socket connections but terrible at connecting to serial ports. Using a serial-to-network proxy allows you to use any scripting language that can open a network socket and have it talk to your Arduino via the USB connection as easily as if it were a network service. There is more information on serial-to-netw ork proxies on the Arduino web site at www.arduino.cc/playground/Interfacing/Flash. C H A P T E R 3    Time-Lapse Camera Controller Simple digital cameras can produce remarkably good quality photos and are now cheap enough that it doesn’t hurt the wallet too much to buy one with the intention of modifying it for use in a project. You may even have an old digital camera lying around that you don’t mind sacrificing for a good cause! Modifying a camera to control it from an Arduino opens up a world of possibilities. This project lets your Arduino take control of the camera to take photos at regular intervals so they can be reconstructed as a time-lapse movie. Set your frame interval to suit your subject and you could make a movie of plants growing, or a house being painted, or a house being built, or flowers blooming. Time lapse movies can be spectacular and this project will give you the tools to let your imagination run wild. Parts Required 1 Digital camera 1 Arduino Duemilanove, Arduino Pro, Seeeduino, or equivalent 1 Prototyping shield 2 Reed relay 2 1N4001 diode or equivalent 1 3.5mm stereo socket 1 Light-dependent resistor (optional) 1 10K resistor (optional) Camera connection for Canon: 2 3.5mm stereo line plug 50cm shielded stereo cable Camera connection for Panasonic: 1 3.5mm stereo line plug 1 2.5mm 4-connection line plug 1 1K8 resistor 1 27K resistor 1 33K resistor 37 CHAPTER 3  TIME-LAPSE CAMERA CONTROLLER 50cm shielded mono cable Camera connection via infrared: 1 IR LED Source code available from www.practicalarduino.com/projects/time-lapse- camera-controller. Figure 3-1. Parts required for Time-Lapse Camera Controller 38 . connection via infrared: 1 IR LED Source code available from www.practicalarduino.com /projects/ time-lapse- camera-controller. Figure 3-1. Parts required for Time-Lapse Camera Controller 38. can open a network socket and have it talk to your Arduino via the USB connection as easily as if it were a network service. There is more information on serial-to-netw ork proxies on the Arduino. modifying it for use in a project. You may even have an old digital camera lying around that you don’t mind sacrificing for a good cause! Modifying a camera to control it from an Arduino opens up

Ngày đăng: 03/07/2014, 20:20

TỪ KHÓA LIÊN QUAN